/* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ using System; using System.Collections.Generic; using Amazon.EC2.Model; using Amazon.Runtime; using System.Reflection; using System.Net; using Amazon.Util.Internal; namespace Amazon.EC2 { /// /// Implementation for accessing AmazonEC2. /// /// Amazon Elastic Compute Cloud (Amazon EC2) is a web service that provides resizable compute capacity in the cloud. It is designed to /// make web-scale computing easier for developers. Amazon EC2's simple web service interface allows you to obtain and configure /// capacity with minimal friction. It provides you with complete control of your computing resources and lets you run on Amazon's proven /// computing environment. Amazon EC2 reduces the time required to obtain and boot new server instances to minutes, allowing you to quickly /// scale capacity, both up and down, as your computing requirements change. Amazon EC2 changes the economics of computing by allowing you to /// pay only for capacity that you actually use. Amazon EC2 provides developers the tools to build failure resilient applications and isolate /// themselves from common failure scenarios. Visit http://aws.amazon.com/ec2/ for more information. /// public partial class AmazonEC2Client { #region DryRun private class DryRunInfo { public MethodInfo Method { get; private set; } public DryRunInfo(MethodInfo method) { Method = method; } public void DryRun(AmazonEC2Client client, AmazonEC2Request request, ref DryRunResponse response) { response.IsSuccessful = false; SetDryRun(request, true); try { Method.Invoke(client, new object[] { request }); // If no exception thrown, consider this a failure response.Message = "Unrecognized service response for the dry-run request."; } catch (Exception invokeException) { Exception actualException = invokeException.InnerException; AmazonEC2Exception ec2e = actualException as AmazonEC2Exception; response.Message = actualException.Message; if (ec2e != null) { response.IsSuccessful = ec2e.StatusCode == HttpStatusCode.PreconditionFailed; response.ResponseMetadata = new ResponseMetadata { RequestId = ec2e.RequestId }; } if (!response.IsSuccessful) response.Error = actualException; } finally { SetDryRun(request, false); } } private void SetDryRun(AmazonEC2Request request, bool value) { if (value) ((Amazon.Runtime.Internal.IAmazonWebServiceRequest )request).AddBeforeRequestHandler(SetDryRunParameterCallback); else ((Amazon.Runtime.Internal.IAmazonWebServiceRequest)request).RemoveBeforeRequestHandler(SetDryRunParameterCallback); } private void SetDryRunParameterCallback(object sender, RequestEventArgs args) { WebServiceRequestEventArgs wsrea = args as WebServiceRequestEventArgs; if (wsrea != null) { wsrea.Parameters["DryRun"] = "true"; } } } private static Dictionary _methodCache = null; private static Dictionary MethodCache { get { if (_methodCache == null) { _methodCache = new Dictionary(); var ec2RequestType = typeof(AmazonEC2Request); var ec2RequestTypeInfo = TypeFactory.GetTypeInfo(ec2RequestType); var allMembers = TypeFactory.GetTypeInfo(typeof(AmazonEC2Client)).GetMembers(); foreach (var member in allMembers) { MethodInfo method = member as MethodInfo; if (method == null) continue; // Return type must be named "*Response" var returnType = method.ReturnType; if (!returnType.Name.EndsWith("Response", StringComparison.OrdinalIgnoreCase)) continue; // There must be only one input parameter var parameters = method.GetParameters(); if (parameters.Length != 1) continue; // The input parameter must extend EC2Request, but must not be EC2Request var inputType = parameters[0].ParameterType; var inputTypeInfo = TypeFactory.GetTypeInfo(inputType); if (inputType == ec2RequestType || !ec2RequestTypeInfo.IsAssignableFrom(inputTypeInfo)) continue; // Method name must match: [Name]Request = [InputTypeName] if (!string.Equals(method.Name + "Request", inputType.Name, StringComparison.OrdinalIgnoreCase)) continue; _methodCache[inputType] = new DryRunInfo(method); } } return _methodCache; } } /// /// Checks whether you have the required permissions for the action, without actually making the request. /// /// Request to do a dry run of. /// Result of the dry run. public DryRunResponse DryRun(AmazonEC2Request request) { DryRunResponse response = new DryRunResponse { IsSuccessful = false }; if (request == null) { response.Message = "Request must not be null"; return response; } DryRunInfo dryRunInfo; Type requestType = request.GetType(); if (!MethodCache.TryGetValue(requestType, out dryRunInfo) || dryRunInfo == null) { response.Message = "Unrecognized request"; return response; } dryRunInfo.DryRun(this, request, ref response); return response; } #endregion } }