From 9cd37ded0849cc69b7a57aecedb1895b7389c092 Mon Sep 17 00:00:00 2001 From: Jackson Tian Date: Wed, 31 Jul 2024 16:37:56 +0800 Subject: [PATCH] Add back dybaseapi --- aliyun-net-sdk-dybaseapi/ChangeLog.txt | 8 + .../Dybaseapi/MNS/IMNS.cs | 30 ++ .../Dybaseapi/MNS/IQueue.cs | 247 +++++++++ .../MNS/Internal/ResponseValidationHandler.cs | 88 ++++ .../Dybaseapi/MNS/MNSClient.cs | 111 ++++ .../Dybaseapi/MNS/MNSConfig.cs | 44 ++ .../Dybaseapi/MNS/MNSErrorCode.cs | 64 +++ .../Dybaseapi/MNS/MNSException.cs | 42 ++ .../MNS/Model/BatchDeleteFailException.cs | 67 +++ .../MNS/Model/BatchDeleteMessageRequest.cs | 30 ++ .../MNS/Model/BatchDeleteMessageResponse.cs | 13 + .../MNS/Model/BatchReceiveMessageRequest.cs | 41 ++ .../MNS/Model/BatchReceiveMessageResponse.cs | 20 + .../MNS/Model/DeleteMessageRequest.cs | 45 ++ .../MNS/Model/DeleteMessageResponse.cs | 17 + .../BatchDeleteMessageRequestMarshaller.cs | 45 ++ .../BatchDeleteMessageResponseUnmarshaller.cs | 113 ++++ .../BatchReceiveMessageRequestMarshaller.cs | 38 ++ ...BatchReceiveMessageResponseUnmarshaller.cs | 105 ++++ .../DeleteMessageRequestMarshaller.cs | 37 ++ .../DeleteMessageResponseUnmarshaller.cs | 49 ++ .../ErrorResponseUnmarshaller.cs | 98 ++++ .../ReceiveMessageRequestMarshaller.cs | 37 ++ .../ReceiveMessageResponseUnmarshaller.cs | 99 ++++ .../MNS/Model/InvalidArgumentException.cs | 35 ++ .../MNS/Model/MD5ValidateException.cs | 49 ++ .../Dybaseapi/MNS/Model/MNSRequest.cs | 16 + .../Dybaseapi/MNS/Model/Message.cs | 141 +++++ .../MNS/Model/MessageNotExistException.cs | 34 ++ .../MNS/Model/QueueNotExistException.cs | 34 ++ .../MNS/Model/ReceiptHandleErrorException.cs | 34 ++ .../MNS/Model/ReceiveMessageRequest.cs | 44 ++ .../MNS/Model/ReceiveMessageResponse.cs | 26 + .../Dybaseapi/MNS/Model/SimpleMNSRequest.cs | 51 ++ .../Dybaseapi/MNS/Queue.cs | 222 ++++++++ .../MNS/Runtime/AliyunServiceClient.cs | 255 +++++++++ .../MNS/Runtime/AliyunServiceException.cs | 93 ++++ .../Dybaseapi/MNS/Runtime/ClientConfig.cs | 241 +++++++++ .../Dybaseapi/MNS/Runtime/Enumerations.cs | 22 + .../Runtime/Internal/Auth/IServiceSigner.cs | 12 + .../MNS/Runtime/Internal/Auth/MNSSigner.cs | 273 ++++++++++ .../MNS/Runtime/Internal/DefaultRequest.cs | 289 +++++++++++ .../MNS/Runtime/Internal/ErrorResponse.cs | 37 ++ .../MNS/Runtime/Internal/IRequest.cs | 173 ++++++ .../Transform/HttpWebRequestResponseData.cs | 108 ++++ .../Runtime/Internal/Transform/IMarshaller.cs | 7 + .../Transform/IResponseUnmarshaller.cs | 21 + .../Internal/Transform/IUnmarshaller.cs | 15 + .../Internal/Transform/IWebResponseData.cs | 24 + .../Transform/RequestMarshallException.cs | 29 ++ .../Transform/ResponseUnmarshallException.cs | 31 ++ .../Transform/ResponseUnmarshallers.cs | 91 ++++ .../Internal/Transform/UnmarshallerContext.cs | 70 +++ .../Internal/Transform/XmlMarshaller.cs | 42 ++ .../Internal/Transform/XmlUnmarshaller.cs | 57 ++ .../MNS/Runtime/Internal/Util/Extensions.cs | 17 + .../MNS/Runtime/Internal/Util/Metrics.cs | 491 ++++++++++++++++++ .../MNS/Runtime/Internal/WebServiceRequest.cs | 131 +++++ .../MNS/Runtime/Pipeline/Contexts.cs | 151 ++++++ .../Pipeline/ErrorHandler/ErrorHandler.cs | 148 ++++++ .../Pipeline/ErrorHandler/ExceptionHandler.cs | 30 ++ .../HttpErrorResponseExceptionHandler.cs | 142 +++++ .../ErrorHandler/IExceptionHandler.cs | 43 ++ .../ErrorHandler/WebExceptionHandler.cs | 30 ++ .../Pipeline/Handlers/CredentialsRetriever.cs | 49 ++ .../Pipeline/Handlers/GenericHandler.cs | 63 +++ .../Runtime/Pipeline/Handlers/Marshaller.cs | 68 +++ .../Pipeline/Handlers/MetricsHandler.cs | 57 ++ .../MNS/Runtime/Pipeline/Handlers/Signer.cs | 59 +++ .../Runtime/Pipeline/Handlers/Unmarshaller.cs | 100 ++++ .../Pipeline/HttpErrorResponseException.cs | 33 ++ .../Pipeline/HttpHandler/HttpHandler.cs | 286 ++++++++++ .../HttpHandler/HttpWebRequestFactory.cs | 364 +++++++++++++ .../HttpHandler/IHttpRequestFactory.cs | 114 ++++ .../MNS/Runtime/Pipeline/IPiplelineHandler.cs | 54 ++ .../MNS/Runtime/Pipeline/PipelineHandler.cs | 123 +++++ .../RetryHandler/DefaultRetryPolicy.cs | 198 +++++++ .../Pipeline/RetryHandler/RetryHandler.cs | 143 +++++ .../Pipeline/RetryHandler/RetryPolicy.cs | 64 +++ .../Runtime/Pipeline/RuntimeAsyncResult.cs | 116 +++++ .../MNS/Runtime/Pipeline/RuntimePipeline.cs | 404 ++++++++++++++ .../MNS/Runtime/ServiceCredentials.cs | 135 +++++ .../MNS/Runtime/WebServiceResponse.cs | 44 ++ .../Dybaseapi/MNS/Util/AliyunSDKUtils.cs | 385 ++++++++++++++ .../Dybaseapi/MNS/Util/CryptoUtil.cs | 110 ++++ .../Dybaseapi/MNS/Util/HttpHeader.cs | 23 + .../Dybaseapi/MNS/Util/MNSConstants.cs | 112 ++++ .../Dybaseapi/MNS/Util/TypeWrapper.cs | 335 ++++++++++++ .../V20170525/QueryTokenForMnsQueueRequest.cs | 117 +++++ .../QueryTokenForMnsQueueResponse.cs | 158 ++++++ ...eryTokenForMnsQueueResponseUnmarshaller.cs | 49 ++ .../aliyun-net-sdk-dybaseapi.vs2010.csproj | 60 +++ .../aliyun-net-sdk-dybaseapi.vs2017.csproj | 40 ++ 93 files changed, 9110 insertions(+) create mode 100644 aliyun-net-sdk-dybaseapi/ChangeLog.txt create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/IMNS.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/IQueue.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Internal/ResponseValidationHandler.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/MNSClient.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/MNSConfig.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/MNSErrorCode.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/MNSException.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/BatchDeleteFailException.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/BatchDeleteMessageRequest.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/BatchDeleteMessageResponse.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/BatchReceiveMessageRequest.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/BatchReceiveMessageResponse.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/DeleteMessageRequest.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/DeleteMessageResponse.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/BatchDeleteMessageRequestMarshaller.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/BatchDeleteMessageResponseUnmarshaller.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/BatchReceiveMessageRequestMarshaller.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/BatchReceiveMessageResponseUnmarshaller.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/DeleteMessageRequestMarshaller.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/DeleteMessageResponseUnmarshaller.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/ErrorResponseUnmarshaller.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/ReceiveMessageRequestMarshaller.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/ReceiveMessageResponseUnmarshaller.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/InvalidArgumentException.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/MD5ValidateException.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/MNSRequest.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Message.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/MessageNotExistException.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/QueueNotExistException.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/ReceiptHandleErrorException.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/ReceiveMessageRequest.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/ReceiveMessageResponse.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/SimpleMNSRequest.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Queue.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/AliyunServiceClient.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/AliyunServiceException.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/ClientConfig.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Enumerations.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Auth/IServiceSigner.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Auth/MNSSigner.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/DefaultRequest.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/ErrorResponse.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/IRequest.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/HttpWebRequestResponseData.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/IMarshaller.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/IResponseUnmarshaller.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/IUnmarshaller.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/IWebResponseData.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/RequestMarshallException.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/ResponseUnmarshallException.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/ResponseUnmarshallers.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/UnmarshallerContext.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/XmlMarshaller.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/XmlUnmarshaller.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Util/Extensions.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Util/Metrics.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/WebServiceRequest.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/Contexts.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/ErrorHandler/ErrorHandler.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/ErrorHandler/ExceptionHandler.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/ErrorHandler/HttpErrorResponseExceptionHandler.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/ErrorHandler/IExceptionHandler.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/ErrorHandler/WebExceptionHandler.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/Handlers/CredentialsRetriever.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/Handlers/GenericHandler.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/Handlers/Marshaller.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/Handlers/MetricsHandler.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/Handlers/Signer.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/Handlers/Unmarshaller.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/HttpErrorResponseException.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/HttpHandler/HttpHandler.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/HttpHandler/HttpWebRequestFactory.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/HttpHandler/IHttpRequestFactory.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/IPiplelineHandler.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/PipelineHandler.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/RetryHandler/DefaultRetryPolicy.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/RetryHandler/RetryHandler.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/RetryHandler/RetryPolicy.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/RuntimeAsyncResult.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/RuntimePipeline.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/ServiceCredentials.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/WebServiceResponse.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Util/AliyunSDKUtils.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Util/CryptoUtil.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Util/HttpHeader.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Util/MNSConstants.cs create mode 100644 aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Util/TypeWrapper.cs create mode 100755 aliyun-net-sdk-dybaseapi/Dybaseapi/Model/V20170525/QueryTokenForMnsQueueRequest.cs create mode 100755 aliyun-net-sdk-dybaseapi/Dybaseapi/Model/V20170525/QueryTokenForMnsQueueResponse.cs create mode 100755 aliyun-net-sdk-dybaseapi/Dybaseapi/Transform/V20170525/QueryTokenForMnsQueueResponseUnmarshaller.cs create mode 100644 aliyun-net-sdk-dybaseapi/aliyun-net-sdk-dybaseapi.vs2010.csproj create mode 100755 aliyun-net-sdk-dybaseapi/aliyun-net-sdk-dybaseapi.vs2017.csproj diff --git a/aliyun-net-sdk-dybaseapi/ChangeLog.txt b/aliyun-net-sdk-dybaseapi/ChangeLog.txt new file mode 100644 index 0000000000..b192457e40 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/ChangeLog.txt @@ -0,0 +1,8 @@ +2019-06-28 Version 1.0.1 +- Release dybaseapi to nuget. +2019-06-28 Version 1.0.1 +- Release dybaseapi to nuget. +2018-11-20 Version: 1.0.0 +1, Add MNS STS Token Query API +2, Add MNS Minimal Package + diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/IMNS.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/IMNS.cs new file mode 100644 index 0000000000..ce24ba2b42 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/IMNS.cs @@ -0,0 +1,30 @@ +/* + * Copyright (C) Alibaba Cloud Computing + * All rights reserved. + */ + +using System; +using Aliyun.Acs.Dybaseapi.MNS.Model; + +namespace Aliyun.Acs.Dybaseapi.MNS +{ + /// + /// Interface for accessing MNS. + /// + public partial interface IMNS : IDisposable + { + + #region GetNativeQueue + + /// + /// Get a native queue object with the specified queueName. + /// + /// + /// The name of native queue object to be created + /// + /// A native queue object + Queue GetNativeQueue(string queueName); + + #endregion + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/IQueue.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/IQueue.cs new file mode 100644 index 0000000000..9624461e1b --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/IQueue.cs @@ -0,0 +1,247 @@ +/* + * Copyright (C) Alibaba Cloud Computing + * All rights reserved. + */ + +using System; +using Aliyun.Acs.Dybaseapi.MNS.Model; +using System.Collections.Generic; + +namespace Aliyun.Acs.Dybaseapi.MNS +{ + /// + /// Interface for accessing MNS queue + /// + public partial interface IQueue + { + + #region DeleteMessage + + /// + /// Deletes the specified message from the specified queue. + /// + /// The receipt handle associated with the message to delete. + /// + /// The response returned by the MNS DeleteMessage service. + /// + /// The receipt handle you provide is not valid. + /// + /// + /// The queue name you provided is not exist. + /// + /// + /// The value of Element should between Low and High seconds/bytes. + /// + DeleteMessageResponse DeleteMessage(string receiptHandle); + + /// + /// Deletes the specified message from the specified queue. + /// + /// The request object to be sent to MNS DeleteMessage service. + /// + /// The response returned by the MNS DeleteMessage service. + /// + /// The receipt handle you provide is not valid. + /// + /// + /// The queue name you provided is not exist. + /// + /// + /// The value of Element should between Low and High seconds/bytes. + /// + DeleteMessageResponse DeleteMessage(DeleteMessageRequest request); + + /// + /// Deletes the specified message from the specified queue. + /// + /// The request object to be sent to MNS BatchDeleteMessage service. + /// + /// The response returned by the MNS BatchDeleteMessage service. + /// + /// The receipt handle you provide is not valid. + /// + /// + /// The queue name you provided is not exist. + /// + /// + /// The value of Element should between MIN and MAX seconds/bytes. + /// + /// + /// Some messages are not deleted. + /// + BatchDeleteMessageResponse BatchDeleteMessage(BatchDeleteMessageRequest request); + + /// + /// Begins an asynchronous request to MNS DeleteMessage service. + /// + /// + /// The request object to be sent to MNS DeleteMessage service. + /// The AsyncCallback delegate. + /// The state object for this request. + /// + /// An IAsyncResult that references the asynchronous request for a response. + IAsyncResult BeginDeleteMessage(DeleteMessageRequest request, AsyncCallback callback, object state); + + /// + /// Ends an asynchronous request for MNS DeleteMessage service. + /// + /// + /// The IAsyncResult returned by the call to BeginDeleteMessage. + /// + /// The response returned by the MNS DeleteMessage service. + DeleteMessageResponse EndDeleteMessage(IAsyncResult asyncResult); + + /// + /// Begins an asynchronous request to MNS BatchDeleteMessage service. + /// + /// + /// The request object to be sent to MNS BatchDeleteMessage service. + /// The AsyncCallback delegate. + /// The state object for this request. + /// + /// An IAsyncResult that references the asynchronous request for a response. + IAsyncResult BeginBatchDeleteMessage(BatchDeleteMessageRequest request, AsyncCallback callback, object state); + + /// + /// Ends an asynchronous request for MNS BatchDeleteMessage service. + /// + /// + /// The IAsyncResult returned by the call to BeginBatchDeleteMessage. + /// + /// The response returned by the MNS BatchDeleteMessage service. + BatchDeleteMessageResponse EndBatchDeleteMessage(IAsyncResult asyncResult); + + #endregion + + #region ReceiveMessage + + /// + /// Retrieves one message from this queue. + /// + /// + /// The response returned by the MNS ReceiveMessage service. + /// + /// + /// The queue name you provided is not exist. + /// + /// + /// no messages exist. + /// + ReceiveMessageResponse ReceiveMessage(); + + /// + /// Retrieves one message. + /// + /// Wait polling time for this request. + /// + /// The response returned by the MNS ReceiveMessage service. + /// + /// The queue name you provided is not exist. + /// + /// + /// no messages exist. + /// + ReceiveMessageResponse ReceiveMessage(uint waitSeconds); + + /// + /// Retrieves one message. + /// + /// The request object to be sent to MNS ReceiveMessage service. + /// + /// The response returned by the MNS ReceiveMessage service. + /// + /// The queue name you provided is not exist. + /// + /// + /// no messages exist. + /// + ReceiveMessageResponse ReceiveMessage(ReceiveMessageRequest request); + + /// + /// batch retrieves messages. + /// + /// the most count limit of retrieved messages + /// Wait polling time for this request. + /// + /// The response returned by the MNS ReceiveMessage service. + /// + /// The queue name you provided is not exist. + /// + /// + /// no messages exist. + /// + BatchReceiveMessageResponse BatchReceiveMessage(uint batchSize); + + /// + /// batch retrieves messages. + /// + /// the most count limit of retrieved messages + /// Wait polling time for this request. + /// + /// The response returned by the MNS ReceiveMessage service. + /// + /// The queue name you provided is not exist. + /// + /// + /// no messages exist. + /// + BatchReceiveMessageResponse BatchReceiveMessage(uint batchSize, uint waitSeconds); + + /// + /// batch retrieves messages. + /// + /// the most count limit of retrieved messages + /// Wait polling time for this request. + /// + /// The response returned by the MNS ReceiveMessage service. + /// + /// The queue name you provided is not exist. + /// + /// + /// no messages exist. + /// + BatchReceiveMessageResponse BatchReceiveMessage(BatchReceiveMessageRequest request); + + /// + /// Begins an asynchronous request to MNS ReceiveMessage service. + /// + /// + /// The request object to be sent to MNS ReceiveMessage service. + /// The AsyncCallback delegate. + /// The state object for this request. + /// + /// An IAsyncResult that references the asynchronous request for a response. + IAsyncResult BeginReceiveMessage(ReceiveMessageRequest request, AsyncCallback callback, object state); + + /// + /// Ends an asynchronous request for MNS ReceiveMessage service. + /// + /// + /// The IAsyncResult returned by the call to BeginReceiveMessage. + /// + /// The response returned by the MNS ReceiveMessage service. + ReceiveMessageResponse EndReceiveMessage(IAsyncResult asyncResult); + + /// + /// Begins an asynchronous request to MNS BatchReceiveMessage service. + /// + /// + /// The request object to be sent to MNS BatchReceiveMessage service. + /// The AsyncCallback delegate. + /// The state object for this request. + /// + /// An IAsyncResult that references the asynchronous request for a response. + IAsyncResult BeginBatchReceiveMessage(BatchReceiveMessageRequest request, AsyncCallback callback, object state); + + /// + /// Ends an asynchronous request for MNS BatchReceiveMessage service. + /// + /// + /// The IAsyncResult returned by the call to BeginBatchReceiveMessage. + /// + /// The response returned by the MNS BatchReceiveMessage service. + BatchReceiveMessageResponse EndBatchReceiveMessage(IAsyncResult asyncResult); + + #endregion + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Internal/ResponseValidationHandler.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Internal/ResponseValidationHandler.cs new file mode 100644 index 0000000000..52da5c5423 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Internal/ResponseValidationHandler.cs @@ -0,0 +1,88 @@ +using System; +using System.Globalization; +using System.Text; +using Aliyun.Acs.Dybaseapi.MNS.Model; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline.Handlers; +using Aliyun.Acs.Dybaseapi.MNS.Util; + +namespace Aliyun.Acs.Dybaseapi.MNS.Internal +{ + /// + /// This handler validates response returned by MNS. + /// + internal class ResponseValidationHandler : GenericHandler + { + /// + /// Validates the response returned by MNS. + /// + /// The execution context which contains both the + /// requests and response context. + protected override void PostInvoke(IExecutionContext executionContext) + { + return; + /* + var request = executionContext.RequestContext.Request; + var response = executionContext.ResponseContext.Response; + ReceiveMessageResponse receiveMessageResponse = response as ReceiveMessageResponse; + if (receiveMessageResponse != null) + { + ValidateReceiveMessage(receiveMessageResponse); + } + + SendMessageResponse sendMessageResponse = response as SendMessageResponse; + SendMessageRequest sendMessageRequest = request.OriginalRequest as SendMessageRequest; + if (sendMessageRequest != null && sendMessageResponse != null) + { + ValidateSendMessage(sendMessageRequest, sendMessageResponse); + } + */ + } + + public static string CalculateMD5(string message) + { + var messageBytes = Encoding.UTF8.GetBytes(message); + return CalculateMD5(messageBytes); + } + public static string CalculateMD5(byte[] bytes) + { + var md5Hash = CryptoUtilFactory.CryptoInstance.ComputeMD5Hash(bytes); + var calculatedMd5 = BitConverter.ToString(md5Hash).Replace("-", string.Empty).ToLower(CultureInfo.InvariantCulture); + return calculatedMd5; + } + public static bool CompareMD5(string message, string md5FromService) + { + var calculatedMd5 = CalculateMD5(message); + return (string.Equals(calculatedMd5, md5FromService, StringComparison.OrdinalIgnoreCase)); + } + + public static void ValidateMD5(string message, string md5FromService) + { + if (!CompareMD5(message, md5FromService)) + throw new MD5ValidateException("MD5 hash mismatch"); + } + + public static void ValidateMD5(string message, string messageId, string md5FromService) + { + if (!CompareMD5(message, md5FromService)) + throw new MD5ValidateException(string.Format(CultureInfo.InvariantCulture, "MD5 hash mismatch for message id {0}", messageId)); + } + public static void ValidateMD5(string message, string messageId, string md5FromService, string receiptHandle) + { + if (!CompareMD5(message, md5FromService)) + throw new MD5ValidateException(string.Format(CultureInfo.InvariantCulture, "MD5 hash mismatch for message id {0}", messageId), receiptHandle); + } + public static void ValidateMD5(Message message) + { + ValidateMD5(message.Body, message.Id, message.BodyMD5, message.ReceiptHandle); + } + + public static void ValidateReceiveMessage(ReceiveMessageResponse response) + { + if (response != null && response.Message != null) + { + ValidateMD5(response.Message); + } + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/MNSClient.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/MNSClient.cs new file mode 100644 index 0000000000..2880891cdc --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/MNSClient.cs @@ -0,0 +1,111 @@ +/* + * Copyright (C) Alibaba Cloud Computing + * All rights reserved. + */ + +using System; +using Aliyun.Acs.Dybaseapi.MNS.Internal; +using Aliyun.Acs.Dybaseapi.MNS.Model; +using Aliyun.Acs.Dybaseapi.MNS.Model.Internal.MarshallTransformations; +using Aliyun.Acs.Dybaseapi.MNS.Runtime; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Auth; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline.Handlers; + +namespace Aliyun.Acs.Dybaseapi.MNS +{ + /// + /// Implementation for accessing MNS + /// + public partial class MNSClient : AliyunServiceClient, IMNS + { + #region Constructors + + /// + /// Constructs MNSClient with Aliyun Service Credentials. + /// + /// Aliyun Service Credentials + /// The region endpoint to connect. + public MNSClient(ServiceCredentials credentials, String regionEndpoint) + : this(credentials, new MNSConfig { RegionEndpoint = new Uri(regionEndpoint) }) + { + } + + /// + /// Constructs MNSClient with Aliyun Service Credentials and an + /// MNSClient Configuration object. + /// + /// Aliyun Service Credentials + /// The MNSClient Configuration Object + public MNSClient(ServiceCredentials credentials, MNSConfig clientConfig) + : base(credentials, clientConfig) + { + } + + /// + /// Constructs MNSClient with Aliyun Access Key ID and Aliyun Secret Key + /// + /// Aliyun Access Key ID + /// Aliyun Secret Access Key + /// The region endpoint to connect. + /// http://$AccountID.mns..aliyuncs.com + public MNSClient(string accessKeyId, string secretAccessKey, string regionEndpoint) + : this(accessKeyId, secretAccessKey, new MNSConfig { RegionEndpoint = new Uri(regionEndpoint) }, null) + { + } + + public MNSClient(string accessKeyId, string secretAccessKey, string regionEndpoint, string stsToken) + : this(accessKeyId, secretAccessKey, new MNSConfig { RegionEndpoint = new Uri(regionEndpoint) }, stsToken) + { + } + + /// + /// Constructs MNSClient with Aliyun Access Key ID, Secret Access Key and an + /// MNSClient Configuration object. + /// + /// Aliyun Access Key ID + /// Aliyun Secret Access Key + /// The MNSClient Configuration Object + public MNSClient(string accessKeyId, string secretAccessKey, MNSConfig clientConfig, string stsToken) + : base(accessKeyId, secretAccessKey, clientConfig, stsToken) + { + } + + #endregion + + #region Overrides + + protected override IServiceSigner CreateSigner() + { + return new MNSSigner(); + } + + protected override void CustomizeRuntimePipeline(RuntimePipeline pipeline) + { + pipeline.AddHandlerAfter(new ResponseValidationHandler()); + } + + #endregion + + #region Dispose + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + } + + #endregion + + + #region GetNativeQueue + + /// + public Queue GetNativeQueue(string queueName) + { + return new Queue(queueName, this); + } + + #endregion + + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/MNSConfig.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/MNSConfig.cs new file mode 100644 index 0000000000..e02138f5e4 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/MNSConfig.cs @@ -0,0 +1,44 @@ +/* + * Copyright (C) Alibaba Cloud Computing + * All rights reserved. + */ + +using Aliyun.Acs.Dybaseapi.MNS.Runtime; + +namespace Aliyun.Acs.Dybaseapi.MNS +{ + /// + /// Configuration for accessing Aliyun MNS Service + /// + public partial class MNSConfig : ClientConfig + { + /// + /// Default constructor + /// + public MNSConfig() + { + } + + /// + /// Gets the ServiceVersion property. + /// + public override string ServiceVersion + { + get + { + return "2015-06-06"; + } + } + + /// + /// Gets the ServiceName property. + /// + public override string ServiceName + { + get + { + return "Aliyun.Acs.Dybaseapi.MNS"; + } + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/MNSErrorCode.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/MNSErrorCode.cs new file mode 100644 index 0000000000..d1fe612a90 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/MNSErrorCode.cs @@ -0,0 +1,64 @@ +/* + * Copyright (C) Alibaba Cloud Computing + * All rights reserved. + */ + +namespace Aliyun.Acs.Dybaseapi.MNS +{ + /// + /// All erorr codes returned by MNS. + /// + public static class MNSErrorCode + { + public const string AccessDenied = "AccessDenied"; + public const string InternalError = "InternalError"; + + public const string InvalidAccessKeyId = "InvalidAccessKeyId"; + public const string InvalidAuthorizationHeader = "InvalidAuthorizationHeader"; + public const string InvalidDateHeader = "InvalidDateHeader"; + public const string InvalidArgument = "InvalidArgument"; + public const string InvalidDigest = "InvalidDigest"; + public const string InvalidRequestURL = "InvalidRequestURL"; + public const string InvalidQueryString = "InvalidQueryString"; + public const string InvalidQueueName = "InvalidQueueName"; + public const string InvalidVersionHeader = "InvalidVersionHeader"; + public const string InvalidContentType = "InvalidContentType"; + + public const string MissingAuthorizationHeader = "MissingAuthorizationHeader"; + public const string MissingDateHeader = "MissingDateHeader"; + public const string MissingVersionHeader = "MissingVersionHeader"; + public const string MissingReceiptHandle = "MissingReceiptHandle"; + public const string MissingVisibilityTimeout = "MissingVisibilityTimeout"; + + public const string MessageNotExist = "MessageNotExist"; + + public const string TopicAlreadyExist = "TopicAlreadyExist"; + public const string TopicDeletedRecently = "TopicDeletedRecently"; + public const string TopicNameLengthError = "TopicNameLengthError"; + public const string TopicNameInvalid = "TopicNameInvalid"; + public const string TopicNotExist = "TopicNotExist"; + + public const string SubscriptionNameLengthError = "SubscriptionNameLengthError"; + public const string SubscriptionNameInvalid = "SubscriptionNameInvalid"; + public const string SubscriptionAlreadyExist = "SubscriptionAlreadyExist"; + public const string SubscriptionNotExist = "SubscriptionNotExist"; + public const string EndpointInvalid = "EndpointInvalid"; + + public const string QueueAlreadyExist = "QueueAlreadyExist"; + public const string QueueDeletedRecently = "QueueDeletedRecently"; + public const string QueueNameLengthError = "QueueNameLengthError"; + public const string QueueNotExist = "QueueNotExist"; + + public const string ReceiptHandleError = "ReceiptHandleError"; + public const string SignatureDoesNotMatch = "SignatureDoesNotMatch"; + public const string TimeExpired = "TimeExpired"; + public const string MalformedXML = "MalformedXML"; + + // BatchDeleteFail is used by BatchDeleteFailException + // ErrorDetails are in BatchDeleteFailException.ErrorItems + public const string BatchDeleteFail = "BatchDeleteFail"; + + // BatchSendFail is used by BatchSendFailException + public const string BatchSendFail = "BatchSendFail"; + } +} \ No newline at end of file diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/MNSException.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/MNSException.cs new file mode 100644 index 0000000000..b463a08483 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/MNSException.cs @@ -0,0 +1,42 @@ +/* + * Copyright (C) Alibaba Cloud Computing + * All rights reserved. + */ + +using System; +using System.Net; +using Aliyun.Acs.Dybaseapi.MNS.Runtime; + +namespace Aliyun.Acs.Dybaseapi.MNS +{ + /// + /// Base class for all MNS exception classes. + /// + public class MNSException : AliyunServiceException + { + public MNSException(string message) + : base(message) + { + } + + public MNSException(string message, Exception innerException) + : base(message, innerException) + { + } + + public MNSException(Exception innerException) + : base(innerException.Message, innerException) + { + } + + public MNSException(string message, string errorCode, string requestId, string hostId, HttpStatusCode statusCode) + : base(message, errorCode, requestId, hostId, statusCode) + { + } + + public MNSException(string message, Exception innerException, string errorCode, string requestId, string hostId, HttpStatusCode statusCode) + : base(message, innerException, errorCode, requestId, hostId, statusCode) + { + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/BatchDeleteFailException.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/BatchDeleteFailException.cs new file mode 100644 index 0000000000..2d9a2b8322 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/BatchDeleteFailException.cs @@ -0,0 +1,67 @@ +using Aliyun.Acs.Dybaseapi.MNS.Runtime; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Text; + +namespace Aliyun.Acs.Dybaseapi.MNS.Model +{ + public class BatchDeleteFailException : AliyunServiceException + { + private List _errorItems = new List(); + + public BatchDeleteFailException() : base(MNSErrorCode.BatchDeleteFail) + { + this.ErrorCode = MNSErrorCode.BatchDeleteFail; + } + + public List ErrorItems + { + get { return this._errorItems; } + set { this._errorItems = value; } + } + } + + public class BatchDeleteErrorItem + { + private string _errorCode; + private string _errorMessage; + private string _receiptHandle; + + public BatchDeleteErrorItem() + { + } + + public BatchDeleteErrorItem(string errorCode, string errorMessage, string receiptHandle) + { + this._errorCode = errorCode; + this._errorMessage = errorMessage; + this._receiptHandle = receiptHandle; + } + + public override string ToString() + { + return string.Format("ErrorCode is {0}, ErrorMessage is {1}, ReceiptHandle is {2}", + _errorCode, _errorMessage, _receiptHandle); + } + + public string ErrorCode + { + get { return this._errorCode; } + set { this._errorCode = value; } + } + + public string ErrorMessage + { + get { return this._errorMessage; } + set { this._errorMessage = value; } + } + + public string ReceiptHandle + { + get { return this._receiptHandle; } + set { this._receiptHandle = value; } + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/BatchDeleteMessageRequest.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/BatchDeleteMessageRequest.cs new file mode 100644 index 0000000000..e2201f0077 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/BatchDeleteMessageRequest.cs @@ -0,0 +1,30 @@ +using Aliyun.Acs.Dybaseapi.MNS.Runtime; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Transform; +using Aliyun.Acs.Dybaseapi.MNS.Util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Aliyun.Acs.Dybaseapi.MNS.Model +{ + public partial class BatchDeleteMessageRequest : SimpleMNSRequest + { + private List _receiptHandles = new List(); + + /// + /// Gets and sets the property ReceiptHandle. + /// + public List ReceiptHandles + { + get { return this._receiptHandles; } + set { this._receiptHandles = value; } + } + + public bool IsSetReceiptHandles() + { + return _receiptHandles.Any(); + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/BatchDeleteMessageResponse.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/BatchDeleteMessageResponse.cs new file mode 100644 index 0000000000..b6dae4df48 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/BatchDeleteMessageResponse.cs @@ -0,0 +1,13 @@ +using Aliyun.Acs.Dybaseapi.MNS.Runtime; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Aliyun.Acs.Dybaseapi.MNS.Model.Internal.MarshallTransformations; + +namespace Aliyun.Acs.Dybaseapi.MNS.Model +{ + public partial class BatchDeleteMessageResponse : WebServiceResponse + { + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/BatchReceiveMessageRequest.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/BatchReceiveMessageRequest.cs new file mode 100644 index 0000000000..b1f99ca23a --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/BatchReceiveMessageRequest.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Aliyun.Acs.Dybaseapi.MNS.Model +{ + public partial class BatchReceiveMessageRequest : SimpleMNSRequest + { + private uint _batchSize; + private uint? _waitSeconds; + + public BatchReceiveMessageRequest(uint batchSize) + { + this._batchSize = batchSize; + } + + public BatchReceiveMessageRequest(uint batchSize, uint waitSeconds) + { + this._batchSize = batchSize; + this._waitSeconds = waitSeconds; + } + + public bool IsSetWaitSeconds() + { + return this._waitSeconds.HasValue; + } + + public uint WaitSeconds + { + get { return this._waitSeconds.GetValueOrDefault(); } + set { this._waitSeconds = value; } + } + + public uint BatchSize + { + get { return this._batchSize; } + set { this._batchSize = value; } + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/BatchReceiveMessageResponse.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/BatchReceiveMessageResponse.cs new file mode 100644 index 0000000000..0c0d457cc5 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/BatchReceiveMessageResponse.cs @@ -0,0 +1,20 @@ +using Aliyun.Acs.Dybaseapi.MNS.Model.Internal.MarshallTransformations; +using Aliyun.Acs.Dybaseapi.MNS.Runtime; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Aliyun.Acs.Dybaseapi.MNS.Model +{ + public partial class BatchReceiveMessageResponse : WebServiceResponse + { + private List _messages = new List(); + + public List Messages + { + get { return this._messages; } + set { this._messages = value; } + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/DeleteMessageRequest.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/DeleteMessageRequest.cs new file mode 100644 index 0000000000..71e70f0721 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/DeleteMessageRequest.cs @@ -0,0 +1,45 @@ +/* + * Copyright (C) Alibaba Cloud Computing + * All rights reserved. + */ + +namespace Aliyun.Acs.Dybaseapi.MNS.Model +{ + /// + /// Container for request parameters that needed by MNS DeleteMessage service. + /// + public partial class DeleteMessageRequest : SimpleMNSRequest + { + private string _receiptHandle; + + /// + /// Empty constructor + /// + public DeleteMessageRequest() { } + + /// + /// Instantiates DeleteMessageRequest with the parameterized properties + /// + /// The receipt handle associated with the message to delete. + public DeleteMessageRequest(string receiptHandle) + { + _receiptHandle = receiptHandle; + } + + /// + /// Gets and sets the property ReceiptHandle. + /// + public string ReceiptHandle + { + get { return this._receiptHandle; } + set { this._receiptHandle = value; } + } + + // Check to see if ReceiptHandle property is set + internal bool IsSetReceiptHandle() + { + return this._receiptHandle != null; + } + + } +} \ No newline at end of file diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/DeleteMessageResponse.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/DeleteMessageResponse.cs new file mode 100644 index 0000000000..9d47419bb1 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/DeleteMessageResponse.cs @@ -0,0 +1,17 @@ +/* + * Copyright (C) Alibaba Cloud Computing + * All rights reserved. + */ + +using Aliyun.Acs.Dybaseapi.MNS.Runtime; + +namespace Aliyun.Acs.Dybaseapi.MNS.Model +{ + /// + /// Response for MNS DeleteMessage service + /// + public partial class DeleteMessageResponse : WebServiceResponse + { + + } +} \ No newline at end of file diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/BatchDeleteMessageRequestMarshaller.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/BatchDeleteMessageRequestMarshaller.cs new file mode 100644 index 0000000000..50d8be6cff --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/BatchDeleteMessageRequestMarshaller.cs @@ -0,0 +1,45 @@ +using Aliyun.Acs.Dybaseapi.MNS.Runtime; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Transform; +using Aliyun.Acs.Dybaseapi.MNS.Util; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Xml; +using System.Xml.Serialization; + +namespace Aliyun.Acs.Dybaseapi.MNS.Model.Internal.MarshallTransformations +{ + public partial class BatchDeleteMessageRequestMarshaller : IMarshaller, IMarshaller + { + public IRequest Marshall(WebServiceRequest input) + { + return this.Marshall((BatchDeleteMessageRequest)input); + } + + public IRequest Marshall(BatchDeleteMessageRequest publicRequest) + { + MemoryStream stream = new MemoryStream(); + XmlTextWriter writer = new XmlTextWriter(stream, Encoding.UTF8); + writer.WriteStartDocument(); + writer.WriteStartElement(MNSConstants.XML_ROOT_RECEIPT_HANDLES, MNSConstants.MNS_XML_NAMESPACE); + foreach (string receiptHandle in publicRequest.ReceiptHandles) + { + writer.WriteElementString(MNSConstants.XML_ELEMENT_RECEIPT_HANDLE, receiptHandle); + } + writer.WriteEndElement(); + writer.WriteEndDocument(); + writer.Flush(); + stream.Seek(0, SeekOrigin.Begin); + + IRequest request = new DefaultRequest(publicRequest, MNSConstants.MNS_SERVICE_NAME); + request.HttpMethod = HttpMethod.DELETE.ToString(); + request.ContentStream = stream; + request.ResourcePath = MNSConstants.MNS_MESSAGE_PRE_RESOURCE + publicRequest.QueueName + + MNSConstants.MNS_MESSAGE_SUB_RESOURCE; + return request; + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/BatchDeleteMessageResponseUnmarshaller.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/BatchDeleteMessageResponseUnmarshaller.cs new file mode 100644 index 0000000000..032926ee71 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/BatchDeleteMessageResponseUnmarshaller.cs @@ -0,0 +1,113 @@ +using Aliyun.Acs.Dybaseapi.MNS.Runtime; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Transform; +using Aliyun.Acs.Dybaseapi.MNS.Util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Text; +using System.Xml; +using System.Xml.Serialization; + +namespace Aliyun.Acs.Dybaseapi.MNS.Model.Internal.MarshallTransformations +{ + public class BatchDeleteMessageResponseUnmarshaller : XmlResponseUnmarshaller + { + public override WebServiceResponse Unmarshall(XmlUnmarshallerContext context) + { + return new BatchDeleteMessageResponse(); + } + + public override AliyunServiceException UnmarshallException(XmlUnmarshallerContext context, Exception innerException, HttpStatusCode statusCode) + { + XmlTextReader reader = new XmlTextReader(context.ResponseStream); + + ErrorResponse errorResponse = new ErrorResponse(); + while (reader.Read()) + { + switch (reader.NodeType) + { + case XmlNodeType.Element: + if (reader.LocalName == MNSConstants.XML_ROOT_ERROR_RESPONSE) + { + return UnmarshallNormalError(reader, innerException, statusCode); + } + else + { + return UnmarshallBatchDeleteError(reader); + } + } + } + return new MNSException(errorResponse.Message, innerException, errorResponse.Code, errorResponse.RequestId, errorResponse.HostId, statusCode); + } + + private BatchDeleteFailException UnmarshallBatchDeleteError(XmlTextReader reader) + { + BatchDeleteFailException batchDeleteFailException = new BatchDeleteFailException(); + BatchDeleteErrorItem item = null; + + while (reader.Read()) + { + switch (reader.NodeType) + { + case XmlNodeType.Element: + switch (reader.LocalName) + { + case MNSConstants.XML_ROOT_ERROR_RESPONSE: + item = new BatchDeleteErrorItem(); + break; + case MNSConstants.XML_ELEMENT_ERROR_CODE: + reader.Read(); + item.ErrorCode = reader.Value; + break; + case MNSConstants.XML_ELEMENT_ERROR_MESSAGE: + reader.Read(); + item.ErrorMessage = reader.Value; + break; + case MNSConstants.XML_ELEMENT_RECEIPT_HANDLE: + reader.Read(); + item.ReceiptHandle = reader.Value; + break; + } + break; + case XmlNodeType.EndElement: + if (reader.LocalName == MNSConstants.XML_ROOT_ERROR_RESPONSE) + { + batchDeleteFailException.ErrorItems.Add(item); + } + break; + } + } + reader.Close(); + return batchDeleteFailException; + } + + private AliyunServiceException UnmarshallNormalError(XmlTextReader reader, Exception innerException, HttpStatusCode statusCode) + { + ErrorResponse errorResponse = ErrorResponseUnmarshaller.Instance.Unmarshall(reader); + if (errorResponse.Code != null) + { + switch (errorResponse.Code) + { + case MNSErrorCode.QueueNotExist: + return new QueueNotExistException(errorResponse.Message, innerException, errorResponse.Code, errorResponse.RequestId, errorResponse.HostId, statusCode); + case MNSErrorCode.InvalidArgument: + return new InvalidArgumentException(errorResponse.Message, innerException, errorResponse.Code, errorResponse.RequestId, errorResponse.HostId, statusCode); + case MNSErrorCode.ReceiptHandleError: + return new ReceiptHandleErrorException(errorResponse.Message, innerException, errorResponse.Code, errorResponse.RequestId, errorResponse.HostId, statusCode); + } + } + return new MNSException(errorResponse.Message, innerException, errorResponse.Code, errorResponse.RequestId, errorResponse.HostId, statusCode); + } + + private static BatchDeleteMessageResponseUnmarshaller _instance = new BatchDeleteMessageResponseUnmarshaller(); + public static BatchDeleteMessageResponseUnmarshaller Instance + { + get + { + return _instance; + } + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/BatchReceiveMessageRequestMarshaller.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/BatchReceiveMessageRequestMarshaller.cs new file mode 100644 index 0000000000..1f2ded5045 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/BatchReceiveMessageRequestMarshaller.cs @@ -0,0 +1,38 @@ +using Aliyun.Acs.Dybaseapi.MNS.Runtime; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Transform; +using Aliyun.Acs.Dybaseapi.MNS.Util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Aliyun.Acs.Dybaseapi.MNS.Model.Internal.MarshallTransformations +{ + class BatchReceiveMessageRequestMarshaller : IMarshaller, IMarshaller + { + public IRequest Marshall(WebServiceRequest input) + { + return this.Marshall((BatchReceiveMessageRequest)input); + } + + public IRequest Marshall(BatchReceiveMessageRequest publicRequest) + { + IRequest request = new DefaultRequest(publicRequest, MNSConstants.MNS_SERVICE_NAME); + request.HttpMethod = HttpMethod.GET.ToString(); + request.ResourcePath = MNSConstants.MNS_MESSAGE_PRE_RESOURCE + publicRequest.QueueName + + MNSConstants.MNS_MESSAGE_SUB_RESOURCE; + PopulateSpecialParameters(publicRequest, request.Parameters); + return request; + } + + private static void PopulateSpecialParameters(BatchReceiveMessageRequest request, IDictionary paramters) + { + if (request.IsSetWaitSeconds()) + { + paramters.Add(MNSConstants.MNS_PARAMETER_WAIT_SECONDS, request.WaitSeconds.ToString()); + } + paramters.Add(MNSConstants.MNS_PARAMETER_BATCH_SIZE, request.BatchSize.ToString()); + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/BatchReceiveMessageResponseUnmarshaller.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/BatchReceiveMessageResponseUnmarshaller.cs new file mode 100644 index 0000000000..5210d186b7 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/BatchReceiveMessageResponseUnmarshaller.cs @@ -0,0 +1,105 @@ +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Transform; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Aliyun.Acs.Dybaseapi.MNS.Runtime; +using System.Net; +using Aliyun.Acs.Dybaseapi.MNS.Util; +using System.Xml.Serialization; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal; + +namespace Aliyun.Acs.Dybaseapi.MNS.Model.Internal.MarshallTransformations +{ + class BatchReceiveMessageResponseUnmarshaller : XmlResponseUnmarshaller + { + public override WebServiceResponse Unmarshall(XmlUnmarshallerContext context) + { + System.Xml.XmlTextReader reader = new System.Xml.XmlTextReader(context.ResponseStream); + BatchReceiveMessageResponse batchReceiveMessageResponse = new BatchReceiveMessageResponse(); + Message message = null; + + while (reader.Read()) + { + switch (reader.NodeType) + { + case System.Xml.XmlNodeType.Element: + switch (reader.LocalName) + { + case MNSConstants.XML_ROOT_MESSAGE: + message = new Message(); + break; + case MNSConstants.XML_ELEMENT_MESSAGE_ID: + reader.Read(); + message.Id = reader.Value; + break; + case MNSConstants.XML_ELEMENT_RECEIPT_HANDLE: + reader.Read(); + message.ReceiptHandle = reader.Value; + break; + case MNSConstants.XML_ELEMENT_MESSAGE_BODY_MD5: + reader.Read(); + message.BodyMD5 = reader.Value; + break; + case MNSConstants.XML_ELEMENT_MESSAGE_BODY: + reader.Read(); + message.Body = reader.Value; + break; + case MNSConstants.XML_ELEMENT_ENQUEUE_TIME: + reader.Read(); + message.EnqueueTime = AliyunSDKUtils.ConvertFromUnixEpochSeconds(long.Parse(reader.Value)); + break; + case MNSConstants.XML_ELEMENT_NEXT_VISIBLE_TIME: + reader.Read(); + message.NextVisibleTime = AliyunSDKUtils.ConvertFromUnixEpochSeconds(long.Parse(reader.Value)); + break; + case MNSConstants.XML_ELEMENT_FIRST_DEQUEUE_TIME: + reader.Read(); + message.FirstDequeueTime = AliyunSDKUtils.ConvertFromUnixEpochSeconds(long.Parse(reader.Value)); + break; + case MNSConstants.XML_ELEMENT_DEQUEUE_COUNT: + reader.Read(); + message.DequeueCount = uint.Parse(reader.Value); + break; + case MNSConstants.XML_ELEMENT_PRIORITY: + reader.Read(); + message.Priority = uint.Parse(reader.Value); + break; + } + break; + case System.Xml.XmlNodeType.EndElement: + if (reader.LocalName == MNSConstants.XML_ROOT_MESSAGE) + { + batchReceiveMessageResponse.Messages.Add(message); + } + break; + } + } + reader.Close(); + return batchReceiveMessageResponse; + } + + public override AliyunServiceException UnmarshallException(XmlUnmarshallerContext context, Exception innerException, HttpStatusCode statusCode) + { + ErrorResponse errorResponse = ErrorResponseUnmarshaller.Instance.Unmarshall(context); + if (errorResponse.Code != null && errorResponse.Code.Equals(MNSErrorCode.QueueNotExist)) + { + return new QueueNotExistException(errorResponse.Message, innerException, errorResponse.Code, errorResponse.RequestId, errorResponse.HostId, statusCode); + } + if (errorResponse.Code != null && errorResponse.Code.Equals(MNSErrorCode.MessageNotExist)) + { + return new MessageNotExistException(errorResponse.Message, innerException, errorResponse.Code, errorResponse.RequestId, errorResponse.HostId, statusCode); + } + return new MNSException(errorResponse.Message, innerException, errorResponse.Code, errorResponse.RequestId, errorResponse.HostId, statusCode); + } + + private static BatchReceiveMessageResponseUnmarshaller _instance = new BatchReceiveMessageResponseUnmarshaller(); + public static BatchReceiveMessageResponseUnmarshaller Instance + { + get + { + return _instance; + } + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/DeleteMessageRequestMarshaller.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/DeleteMessageRequestMarshaller.cs new file mode 100644 index 0000000000..95535828a0 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/DeleteMessageRequestMarshaller.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; +using Aliyun.Acs.Dybaseapi.MNS.Runtime; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Transform; +using Aliyun.Acs.Dybaseapi.MNS.Util; + +namespace Aliyun.Acs.Dybaseapi.MNS.Model.Internal.MarshallTransformations +{ + /// + /// DeleteMessage Request Marshaller + /// + internal class DeleteMessageRequestMarshaller : IMarshaller, IMarshaller + { + public IRequest Marshall(WebServiceRequest input) + { + return this.Marshall((DeleteMessageRequest)input); + } + + public IRequest Marshall(DeleteMessageRequest publicRequest) + { + IRequest request = new DefaultRequest(publicRequest, MNSConstants.MNS_SERVICE_NAME); + request.HttpMethod = HttpMethod.DELETE.ToString(); + request.ResourcePath = MNSConstants.MNS_MESSAGE_PRE_RESOURCE + publicRequest.QueueName + + MNSConstants.MNS_MESSAGE_SUB_RESOURCE; + PopulateSpecialParameters(publicRequest, request.Parameters); + return request; + } + + private void PopulateSpecialParameters(DeleteMessageRequest request, IDictionary paramters) + { + if (request.IsSetReceiptHandle()) + { + paramters.Add(MNSConstants.MNS_PARAMETER_RECEIPT_HANDLE, request.ReceiptHandle); + } + } + } +} \ No newline at end of file diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/DeleteMessageResponseUnmarshaller.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/DeleteMessageResponseUnmarshaller.cs new file mode 100644 index 0000000000..f21f4e9c25 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/DeleteMessageResponseUnmarshaller.cs @@ -0,0 +1,49 @@ +using System; +using System.Net; +using Aliyun.Acs.Dybaseapi.MNS.Runtime; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Transform; + +namespace Aliyun.Acs.Dybaseapi.MNS.Model.Internal.MarshallTransformations +{ + /// + /// Response Unmarshaller for DeleteMessage operation + /// + internal class DeleteMessageResponseUnmarshaller : XmlResponseUnmarshaller + { + public override WebServiceResponse Unmarshall(XmlUnmarshallerContext context) + { + var response = new DeleteMessageResponse(); + // Nothing need to do with this response here + return response; + } + + public override AliyunServiceException UnmarshallException(XmlUnmarshallerContext context, Exception innerException, HttpStatusCode statusCode) + { + ErrorResponse errorResponse = ErrorResponseUnmarshaller.Instance.Unmarshall(context); + if (errorResponse.Code != null && errorResponse.Code.Equals(MNSErrorCode.QueueNotExist)) + { + return new QueueNotExistException(errorResponse.Message, innerException, errorResponse.Code, errorResponse.RequestId, errorResponse.HostId, statusCode); + } + if (errorResponse.Code != null && errorResponse.Code.Equals(MNSErrorCode.InvalidArgument)) + { + return new InvalidArgumentException(errorResponse.Message, innerException, errorResponse.Code, errorResponse.RequestId, errorResponse.HostId, statusCode); + } + if (errorResponse.Code != null && errorResponse.Code.Equals(MNSErrorCode.ReceiptHandleError)) + { + return new ReceiptHandleErrorException(errorResponse.Message, innerException, errorResponse.Code, errorResponse.RequestId, errorResponse.HostId, statusCode); + } + return new MNSException(errorResponse.Message, innerException, errorResponse.Code, errorResponse.RequestId, errorResponse.HostId, statusCode); + } + + private static DeleteMessageResponseUnmarshaller _instance = new DeleteMessageResponseUnmarshaller(); + public static DeleteMessageResponseUnmarshaller Instance + { + get + { + return _instance; + } + } + + } +} \ No newline at end of file diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/ErrorResponseUnmarshaller.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/ErrorResponseUnmarshaller.cs new file mode 100644 index 0000000000..33643d56cd --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/ErrorResponseUnmarshaller.cs @@ -0,0 +1,98 @@ +using System.Xml.Serialization; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Transform; +using Aliyun.Acs.Dybaseapi.MNS.Util; +using System.Xml; + +namespace Aliyun.Acs.Dybaseapi.MNS.Model.Internal.MarshallTransformations +{ + /// + /// Response Unmarshaller for all Errors + /// + internal class ErrorResponseUnmarshaller : IUnmarshaller + { + /// + /// Build an ErrorResponse from XML + /// + public ErrorResponse Unmarshall(XmlUnmarshallerContext context) + { + XmlTextReader reader = new XmlTextReader(context.ResponseStream); + + ErrorResponse errorResponse = new ErrorResponse(); + while (reader.Read()) + { + switch (reader.NodeType) + { + case XmlNodeType.Element: + if (reader.LocalName == MNSConstants.XML_ELEMENT_CODE) + { + reader.Read(); + errorResponse.Code = reader.Value; + } + if (reader.LocalName == MNSConstants.XML_ELEMENT_MESSAGE) + { + reader.Read(); + errorResponse.Message = reader.Value; + } + if (reader.LocalName == MNSConstants.XML_ELEMENT_REQUEST_ID) + { + reader.Read(); + errorResponse.RequestId = reader.Value; + } + if (reader.LocalName == MNSConstants.XML_ELEMENT_HOST_ID) + { + reader.Read(); + errorResponse.HostId = reader.Value; + } + break; + } + } + reader.Close(); + return errorResponse; + } + + public ErrorResponse Unmarshall(XmlTextReader reader) + { + ErrorResponse errorResponse = new ErrorResponse(); + do + { + switch (reader.NodeType) + { + case XmlNodeType.Element: + if (reader.LocalName == MNSConstants.XML_ELEMENT_CODE) + { + reader.Read(); + errorResponse.Code = reader.Value; + } + if (reader.LocalName == MNSConstants.XML_ELEMENT_MESSAGE) + { + reader.Read(); + errorResponse.Message = reader.Value; + } + if (reader.LocalName == MNSConstants.XML_ELEMENT_REQUEST_ID) + { + reader.Read(); + errorResponse.RequestId = reader.Value; + } + if (reader.LocalName == MNSConstants.XML_ELEMENT_HOST_ID) + { + reader.Read(); + errorResponse.HostId = reader.Value; + } + break; + } + } while (reader.Read()); + reader.Close(); + return errorResponse; + } + + private static ErrorResponseUnmarshaller _instance = new ErrorResponseUnmarshaller(); + public static ErrorResponseUnmarshaller Instance + { + get + { + return _instance; + } + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/ReceiveMessageRequestMarshaller.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/ReceiveMessageRequestMarshaller.cs new file mode 100644 index 0000000000..e4615631e0 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/ReceiveMessageRequestMarshaller.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; +using Aliyun.Acs.Dybaseapi.MNS.Runtime; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Transform; +using Aliyun.Acs.Dybaseapi.MNS.Util; + +namespace Aliyun.Acs.Dybaseapi.MNS.Model.Internal.MarshallTransformations +{ + /// + /// ReceiveMessage Request Marshaller + /// + public class ReceiveMessageRequestMarshaller : IMarshaller , IMarshaller + { + public IRequest Marshall(WebServiceRequest input) + { + return this.Marshall((ReceiveMessageRequest)input); + } + + public IRequest Marshall(ReceiveMessageRequest publicRequest) + { + IRequest request = new DefaultRequest(publicRequest, MNSConstants.MNS_SERVICE_NAME); + request.HttpMethod = HttpMethod.GET.ToString(); + request.ResourcePath = MNSConstants.MNS_MESSAGE_PRE_RESOURCE + publicRequest.QueueName + + MNSConstants.MNS_MESSAGE_SUB_RESOURCE; + PopulateSpecialParameters(publicRequest, request.Parameters); + return request; + } + + private static void PopulateSpecialParameters(ReceiveMessageRequest request, IDictionary paramters) + { + if (request.IsSetWaitSeconds()) + { + paramters.Add(MNSConstants.MNS_PARAMETER_WAIT_SECONDS, request.WaitSeconds.ToString()); + } + } + } +} \ No newline at end of file diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/ReceiveMessageResponseUnmarshaller.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/ReceiveMessageResponseUnmarshaller.cs new file mode 100644 index 0000000000..805b793e0b --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Internal/MarshallTransformations/ReceiveMessageResponseUnmarshaller.cs @@ -0,0 +1,99 @@ +using System; +using System.Net; +using System.Xml.Serialization; +using Aliyun.Acs.Dybaseapi.MNS.Runtime; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Transform; +using Aliyun.Acs.Dybaseapi.MNS.Util; + +namespace Aliyun.Acs.Dybaseapi.MNS.Model.Internal.MarshallTransformations +{ + /// + /// Response Unmarshaller for ReceiveMessage operation + /// + public class ReceiveMessageResponseUnmarshaller : XmlResponseUnmarshaller + { + public override WebServiceResponse Unmarshall(XmlUnmarshallerContext context) + { + System.Xml.XmlTextReader reader = new System.Xml.XmlTextReader(context.ResponseStream); + Message message = new Message(); + + while (reader.Read()) + { + switch (reader.NodeType) + { + case System.Xml.XmlNodeType.Element: + switch (reader.LocalName) + { + case MNSConstants.XML_ELEMENT_MESSAGE_ID: + reader.Read(); + message.Id = reader.Value; + break; + case MNSConstants.XML_ELEMENT_RECEIPT_HANDLE: + reader.Read(); + message.ReceiptHandle = reader.Value; + break; + case MNSConstants.XML_ELEMENT_MESSAGE_BODY_MD5: + reader.Read(); + message.BodyMD5 = reader.Value; + break; + case MNSConstants.XML_ELEMENT_MESSAGE_BODY: + reader.Read(); + message.Body = reader.Value; + break; + case MNSConstants.XML_ELEMENT_ENQUEUE_TIME: + reader.Read(); + message.EnqueueTime = AliyunSDKUtils.ConvertFromUnixEpochSeconds(long.Parse(reader.Value)); + break; + case MNSConstants.XML_ELEMENT_NEXT_VISIBLE_TIME: + reader.Read(); + message.NextVisibleTime = AliyunSDKUtils.ConvertFromUnixEpochSeconds(long.Parse(reader.Value)); + break; + case MNSConstants.XML_ELEMENT_FIRST_DEQUEUE_TIME: + reader.Read(); + message.FirstDequeueTime = AliyunSDKUtils.ConvertFromUnixEpochSeconds(long.Parse(reader.Value)); + break; + case MNSConstants.XML_ELEMENT_DEQUEUE_COUNT: + reader.Read(); + message.DequeueCount = uint.Parse(reader.Value); + break; + case MNSConstants.XML_ELEMENT_PRIORITY: + reader.Read(); + message.Priority = uint.Parse(reader.Value); + break; + } + break; + } + } + reader.Close(); + return new ReceiveMessageResponse() + { + Message = message + }; + } + + public override AliyunServiceException UnmarshallException(XmlUnmarshallerContext context, Exception innerException, HttpStatusCode statusCode) + { + ErrorResponse errorResponse = ErrorResponseUnmarshaller.Instance.Unmarshall(context); + if (errorResponse.Code != null && errorResponse.Code.Equals(MNSErrorCode.QueueNotExist)) + { + return new QueueNotExistException(errorResponse.Message, innerException, errorResponse.Code, errorResponse.RequestId, errorResponse.HostId, statusCode); + } + if (errorResponse.Code != null && errorResponse.Code.Equals(MNSErrorCode.MessageNotExist)) + { + return new MessageNotExistException(errorResponse.Message, innerException, errorResponse.Code, errorResponse.RequestId, errorResponse.HostId, statusCode); + } + return new MNSException(errorResponse.Message, innerException, errorResponse.Code, errorResponse.RequestId, errorResponse.HostId, statusCode); + } + + private static ReceiveMessageResponseUnmarshaller _instance = new ReceiveMessageResponseUnmarshaller(); + public static ReceiveMessageResponseUnmarshaller Instance + { + get + { + return _instance; + } + } + + } +} \ No newline at end of file diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/InvalidArgumentException.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/InvalidArgumentException.cs new file mode 100644 index 0000000000..e9918c68d6 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/InvalidArgumentException.cs @@ -0,0 +1,35 @@ +/* + * Copyright (C) Alibaba Cloud Computing + * All rights reserved. + */ + +using System; +using System.Net; + +namespace Aliyun.Acs.Dybaseapi.MNS.Model +{ + /// + /// InvalidArgumentException + /// + public class InvalidArgumentException : MNSException + { + /// + /// Constructs a new InvalidArgumentException with the specified error message. + /// + public InvalidArgumentException(string message) + : base(message) {} + + public InvalidArgumentException(string message, Exception innerException) + : base(message, innerException) {} + + public InvalidArgumentException(Exception innerException) + : base(innerException) {} + + public InvalidArgumentException(string message, Exception innerException, string errorCode, string requestId, string hostId, HttpStatusCode statusCode) + : base(message, innerException, errorCode, requestId, hostId, statusCode) {} + + public InvalidArgumentException(string message, string errorCode, string requestId, string hostId, HttpStatusCode statusCode) + : base(message, errorCode, requestId, hostId, statusCode) {} + + } +} \ No newline at end of file diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/MD5ValidateException.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/MD5ValidateException.cs new file mode 100644 index 0000000000..dfafdb4cb0 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/MD5ValidateException.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Text; + +namespace Aliyun.Acs.Dybaseapi.MNS.Model +{ + public class MD5ValidateException : MNSException + { + private string _receiptHandle = null; + + public string ReceiptHandle + { + get { return this._receiptHandle; } + set { this._receiptHandle = value; } + } + + /// + /// Constructs a new InvalidArgumentException with the specified error message. + /// + public MD5ValidateException(string message) + : base(message) + { } + + public MD5ValidateException(string message, string receiptHandle) + : base(message) + { + this._receiptHandle = receiptHandle; + } + + public MD5ValidateException(string message, Exception innerException) + : base(message, innerException) + { } + + public MD5ValidateException(Exception innerException) + : base(innerException) + { } + + public MD5ValidateException(string message, Exception innerException, string errorCode, string requestId, string hostId, HttpStatusCode statusCode) + : base(message, innerException, errorCode, requestId, hostId, statusCode) + { } + + public MD5ValidateException(string message, string errorCode, string requestId, string hostId, HttpStatusCode statusCode) + : base(message, errorCode, requestId, hostId, statusCode) + { } + + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/MNSRequest.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/MNSRequest.cs new file mode 100644 index 0000000000..8d36bfb1cf --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/MNSRequest.cs @@ -0,0 +1,16 @@ +/* + * Copyright (C) Alibaba Cloud Computing + * All rights reserved. + */ + +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal; + +namespace Aliyun.Acs.Dybaseapi.MNS.Model +{ + /// + /// Base class for MNS operation requests. + /// + public partial class MNSRequest : WebServiceRequest + { + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Message.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Message.cs new file mode 100644 index 0000000000..611b607594 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/Message.cs @@ -0,0 +1,141 @@ +/* + * Copyright (C) Alibaba Cloud Computing + * All rights reserved. + */ + +using Aliyun.Acs.Dybaseapi.MNS.Model.Internal.MarshallTransformations; +using Aliyun.Acs.Dybaseapi.MNS.Util; +using System; + +namespace Aliyun.Acs.Dybaseapi.MNS.Model +{ + /// + /// An Aliyun MNS message. + /// + public partial class Message + { + private string _id; + private string _receiptHandle; + private string _bodyMD5; + private string _body; + + private DateTime _enqueueTime; + private DateTime _nextVisibleTime; + private DateTime _firstDequeueTime; + + private uint _dequeueCount; + + private uint _priority; + + /// + /// Empty constructor + /// + public Message() { } + + /// + /// Gets and sets the property Id. + /// + public string Id + { + get { return this._id; } + set { this._id = value; } + } + + // Check to see if Id property is set + internal bool IsSetId() + { + return this._id != null; + } + + /// + /// Gets and sets the property ReceiptHandle. + /// + public string ReceiptHandle + { + get { return this._receiptHandle; } + set { this._receiptHandle = value; } + } + + // Check to see if ReceiptHandle property is set + internal bool IsSetReceiptHandle() + { + return this._receiptHandle != null; + } + + /// + /// Gets and sets the property Body. + /// + public string Body + { + get { return this._body; } + set { this._body = value; } + } + + // Check to see if Body property is set + internal bool IsSetBody() + { + return this._body != null; + } + + /// + /// Gets and sets the property BodyMD5. + /// + public string BodyMD5 + { + get { return this._bodyMD5; } + set { this._bodyMD5 = value; } + } + + // Check to see if BodyMD5 property is set + internal bool IsSetBodyMD5() + { + return this._bodyMD5 != null; + } + + /// + /// Gets and sets the property EnqueueTime. + /// + public DateTime EnqueueTime + { + get { return this._enqueueTime; } + set { this._enqueueTime = value; } + } + + /// + /// Gets and sets the property NextVisibleTime. + /// + public DateTime NextVisibleTime + { + get { return this._nextVisibleTime; } + set { this._nextVisibleTime = value; } + } + + /// + /// Gets and sets the property FirstDequeueTime. + /// + public DateTime FirstDequeueTime + { + get { return this._firstDequeueTime; } + set { this._firstDequeueTime = value; } + } + + /// + /// Gets and sets the property DequeueCount. + /// + public uint DequeueCount + { + get { return this._dequeueCount; } + set { this._dequeueCount = value; } + } + + /// + /// Gets and sets the property Priority. + /// + public uint Priority + { + get { return this._priority; } + set { this._priority = value; } + } + + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/MessageNotExistException.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/MessageNotExistException.cs new file mode 100644 index 0000000000..1ba3e042e4 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/MessageNotExistException.cs @@ -0,0 +1,34 @@ +/* + * Copyright (C) Alibaba Cloud Computing + * All rights reserved. + */ + +using System; +using System.Net; + +namespace Aliyun.Acs.Dybaseapi.MNS.Model +{ + /// + /// MessageNotExistException + /// + public class MessageNotExistException : MNSException + { + /// + /// Constructs a new MessageNotExistException with the specified error message. + /// + public MessageNotExistException(string message) + : base(message) {} + + public MessageNotExistException(string message, Exception innerException) + : base(message, innerException) {} + + public MessageNotExistException(Exception innerException) + : base(innerException) {} + + public MessageNotExistException(string message, string errorCode, string requestId, string hostId, HttpStatusCode statusCode) + : base(message, errorCode, requestId, hostId, statusCode) { } + + public MessageNotExistException(string message, Exception innerException, string errorCode, string requestId, string hostId, HttpStatusCode statusCode) + : base(message, innerException, errorCode, requestId, hostId, statusCode) { } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/QueueNotExistException.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/QueueNotExistException.cs new file mode 100644 index 0000000000..69087b0623 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/QueueNotExistException.cs @@ -0,0 +1,34 @@ +/* + * Copyright (C) Alibaba Cloud Computing + * All rights reserved. + */ + +using System; +using System.Net; + +namespace Aliyun.Acs.Dybaseapi.MNS.Model +{ + /// + /// QueueNotExistException + /// + public class QueueNotExistException : MNSException + { + /// + /// Constructs a new QueueNotExistException with the specified error message. + /// + public QueueNotExistException(string message) + : base(message) {} + + public QueueNotExistException(string message, Exception innerException) + : base(message, innerException) {} + + public QueueNotExistException(Exception innerException) + : base(innerException) {} + + public QueueNotExistException(string message, string errorCode, string requestId, string hostId, HttpStatusCode statusCode) + : base(message, errorCode, requestId, hostId, statusCode) { } + + public QueueNotExistException(string message, Exception innerException, string errorCode, string requestId, string hostId, HttpStatusCode statusCode) + : base(message, innerException, errorCode, requestId, hostId, statusCode) { } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/ReceiptHandleErrorException.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/ReceiptHandleErrorException.cs new file mode 100644 index 0000000000..881e9e2755 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/ReceiptHandleErrorException.cs @@ -0,0 +1,34 @@ +/* + * Copyright (C) Alibaba Cloud Computing + * All rights reserved. + */ + +using System; +using System.Net; + +namespace Aliyun.Acs.Dybaseapi.MNS.Model +{ + /// + /// ReceiptHandleErrorException + /// + public class ReceiptHandleErrorException : MNSException + { + /// + /// Constructs a new ReceiptHandleErrorException with the specified error message. + /// + public ReceiptHandleErrorException(string message) + : base(message) {} + + public ReceiptHandleErrorException(string message, Exception innerException) + : base(message, innerException) {} + + public ReceiptHandleErrorException(Exception innerException) + : base(innerException) {} + + public ReceiptHandleErrorException(string message, string errorCode, string requestId, string hostId, HttpStatusCode statusCode) + : base(message, errorCode, requestId, hostId, statusCode) { } + + public ReceiptHandleErrorException(string message, Exception innerException, string errorCode, string requestId, string hostId, HttpStatusCode statusCode) + : base(message, innerException, errorCode, requestId, hostId, statusCode) { } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/ReceiveMessageRequest.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/ReceiveMessageRequest.cs new file mode 100644 index 0000000000..3e8c0ffd84 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/ReceiveMessageRequest.cs @@ -0,0 +1,44 @@ +/* + * Copyright (C) Alibaba Cloud Computing + * All rights reserved. + */ + +namespace Aliyun.Acs.Dybaseapi.MNS.Model +{ + /// + /// Container for request parameters that needed by MNS ReceiveMessage service. + /// + public partial class ReceiveMessageRequest : SimpleMNSRequest + { + private uint? _waitSeconds; + + /// + /// Empty constructor + /// + public ReceiveMessageRequest() { } + + /// + /// Instantiates ReceiveMessageRequest with the parameterized properties, + /// + public ReceiveMessageRequest(uint waitSeconds) + { + _waitSeconds = waitSeconds; + } + + /// + /// Gets and sets the property WaitSeconds. + /// + public uint WaitSeconds + { + get { return this._waitSeconds.GetValueOrDefault(); } + set { this._waitSeconds = value; } + } + + // Check to see if WaitSeconds property is set + internal bool IsSetWaitSeconds() + { + return this._waitSeconds.HasValue; + } + + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/ReceiveMessageResponse.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/ReceiveMessageResponse.cs new file mode 100644 index 0000000000..5aa4e51322 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/ReceiveMessageResponse.cs @@ -0,0 +1,26 @@ +/* + * Copyright (C) Alibaba Cloud Computing + * All rights reserved. + */ + +using Aliyun.Acs.Dybaseapi.MNS.Runtime; + +namespace Aliyun.Acs.Dybaseapi.MNS.Model +{ + /// + /// Response for MNS ReceiveMessage service + /// + public partial class ReceiveMessageResponse : WebServiceResponse + { + private Message _message = new Message(); + + /// + /// Gets and sets the property Message. + /// + public Message Message + { + get { return this._message; } + set { this._message = value; } + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/SimpleMNSRequest.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/SimpleMNSRequest.cs new file mode 100644 index 0000000000..739e01914f --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Model/SimpleMNSRequest.cs @@ -0,0 +1,51 @@ +/* + * Copyright (C) Alibaba Cloud Computing + * All rights reserved. + */ + +namespace Aliyun.Acs.Dybaseapi.MNS.Model +{ + /// + /// A simple wrapper of MNSRequest to message releated requests. + /// + public partial class SimpleMNSRequest : MNSRequest + { + private string _queueName; + private string _topicName; + + /// + /// Empty constructor + /// + public SimpleMNSRequest() { } + + /// + /// Gets and sets the property queueName. + /// + internal string QueueName + { + get { return this._queueName; } + set { this._queueName = value; } + } + + // Check to see if queueName property is set + internal bool IsSetQueueName() + { + return this._queueName != null; + } + + /// + /// Gets and sets the property TopicName. + /// + internal string TopicName + { + get { return this._topicName; } + set { this._topicName = value; } + } + + // Check to see if TopicName property is set + internal bool IsSetTopicName() + { + return this._topicName != null; + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Queue.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Queue.cs new file mode 100644 index 0000000000..c98a028781 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Queue.cs @@ -0,0 +1,222 @@ +/* + * Copyright (C) Alibaba Cloud Computing + * All rights reserved. + */ + +using System; +using Aliyun.Acs.Dybaseapi.MNS.Model; +using Aliyun.Acs.Dybaseapi.MNS.Model.Internal.MarshallTransformations; +using Aliyun.Acs.Dybaseapi.MNS.Runtime; +using Aliyun.Acs.Dybaseapi.MNS.Util; +using System.Collections.Generic; + +namespace Aliyun.Acs.Dybaseapi.MNS +{ + /// + /// Implementation for accessing MNS queue + /// + public partial class Queue : IQueue + { + #region Properties + + private string _queueName; + private readonly AliyunServiceClient _serviceClient; + + #endregion + + #region Constructor + + /// + /// Instantiates Queue with the parameterized properties + /// + public Queue(string queueName, AliyunServiceClient serviceClient) + { + _queueName = queueName; + _serviceClient = serviceClient; + } + + #endregion + + #region Public methods + + /// + /// Gets and sets the property QueueName + /// + public string QueueName + { + get { return this._queueName; } + set { this._queueName = value; } + } + + /// + /// Check to see if QueueName property is set + /// + public bool IsSetQueueName() + { + return this._queueName != null; + } + + #endregion + + + #region DeleteMessage + + /// + public DeleteMessageResponse DeleteMessage(string receiptHandle) + { + var request = new DeleteMessageRequest {ReceiptHandle = receiptHandle}; + return DeleteMessage(request); + } + + /// + public DeleteMessageResponse DeleteMessage(DeleteMessageRequest request) + { + request.QueueName = this.QueueName; + + var marshaller = new DeleteMessageRequestMarshaller(); + var unmarshaller = DeleteMessageResponseUnmarshaller.Instance; + + return _serviceClient.Invoke(request, marshaller, unmarshaller); + } + + /// + public BatchDeleteMessageResponse BatchDeleteMessage(BatchDeleteMessageRequest request) + { + request.QueueName = this.QueueName; + + var marshaller = new BatchDeleteMessageRequestMarshaller(); + var unmarshaller = BatchDeleteMessageResponseUnmarshaller.Instance; + + return _serviceClient.Invoke(request, marshaller, unmarshaller); + } + + /// + public IAsyncResult BeginDeleteMessage(DeleteMessageRequest request, AsyncCallback callback, object state) + { + request.QueueName = this.QueueName; + + var marshaller = new DeleteMessageRequestMarshaller(); + var unmarshaller = DeleteMessageResponseUnmarshaller.Instance; + + return _serviceClient.BeginInvoke(request, marshaller, unmarshaller, + callback, state); + } + + /// + public DeleteMessageResponse EndDeleteMessage(IAsyncResult asyncResult) + { + return AliyunServiceClient.EndInvoke(asyncResult); + } + + /// + public IAsyncResult BeginBatchDeleteMessage(BatchDeleteMessageRequest request, AsyncCallback callback, object state) + { + request.QueueName = this.QueueName; + + var marshaller = new BatchDeleteMessageRequestMarshaller(); + var unmarshaller = BatchDeleteMessageResponseUnmarshaller.Instance; + + return _serviceClient.BeginInvoke(request, marshaller, unmarshaller, + callback, state); + } + + /// + public BatchDeleteMessageResponse EndBatchDeleteMessage(IAsyncResult asyncResult) + { + return AliyunServiceClient.EndInvoke(asyncResult); + } + + #endregion + + #region ReceiveMessage + + /// + public ReceiveMessageResponse ReceiveMessage() + { + var request = new ReceiveMessageRequest(); + return ReceiveMessage(request); + } + + /// + public ReceiveMessageResponse ReceiveMessage(uint waitSeconds) + { + var request = new ReceiveMessageRequest() {WaitSeconds = waitSeconds}; + return ReceiveMessage(request); + } + + /// + public ReceiveMessageResponse ReceiveMessage(ReceiveMessageRequest request) + { + request.QueueName = this.QueueName; + + var marshaller = new ReceiveMessageRequestMarshaller(); + var unmarshaller = ReceiveMessageResponseUnmarshaller.Instance; + + return _serviceClient.Invoke(request, marshaller, unmarshaller); + } + + /// + public BatchReceiveMessageResponse BatchReceiveMessage(uint batchSize) + { + var request = new BatchReceiveMessageRequest(batchSize); + return BatchReceiveMessage(request); + } + + /// + public BatchReceiveMessageResponse BatchReceiveMessage(uint batchSize, uint waitSeconds) + { + var request = new BatchReceiveMessageRequest(batchSize, waitSeconds); + return BatchReceiveMessage(request); + } + + /// + public BatchReceiveMessageResponse BatchReceiveMessage(BatchReceiveMessageRequest request) + { + request.QueueName = this.QueueName; + + var marshaller = new BatchReceiveMessageRequestMarshaller(); + var unmarshaller = BatchReceiveMessageResponseUnmarshaller.Instance; + + return _serviceClient.Invoke(request, marshaller, unmarshaller); + } + + + /// + public IAsyncResult BeginReceiveMessage(ReceiveMessageRequest request, AsyncCallback callback, object state) + { + request.QueueName = this.QueueName; + + var marshaller = new ReceiveMessageRequestMarshaller(); + var unmarshaller = ReceiveMessageResponseUnmarshaller.Instance; + + return _serviceClient.BeginInvoke(request, marshaller, unmarshaller, + callback, state); + } + + /// + public ReceiveMessageResponse EndReceiveMessage(IAsyncResult asyncResult) + { + return AliyunServiceClient.EndInvoke(asyncResult); + } + + /// + public IAsyncResult BeginBatchReceiveMessage(BatchReceiveMessageRequest request, AsyncCallback callback, object state) + { + request.QueueName = this.QueueName; + + var marshaller = new BatchReceiveMessageRequestMarshaller(); + var unmarshaller = BatchReceiveMessageResponseUnmarshaller.Instance; + + return _serviceClient.BeginInvoke(request, marshaller, unmarshaller, + callback, state); + } + + /// + public BatchReceiveMessageResponse EndBatchReceiveMessage(IAsyncResult asyncResult) + { + return AliyunServiceClient.EndInvoke(asyncResult); + } + + #endregion + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/AliyunServiceClient.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/AliyunServiceClient.cs new file mode 100644 index 0000000000..17078342d7 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/AliyunServiceClient.cs @@ -0,0 +1,255 @@ +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Auth; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Transform; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Util; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline.ErrorHandler; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline.Handlers; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline.HttpHandler; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline.RetryHandler; +using Aliyun.Acs.Dybaseapi.MNS.Util; +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Text; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime +{ + public abstract class AliyunServiceClient : IDisposable + { + private bool _disposed; + + protected RuntimePipeline RuntimePipeline { get; set; } + protected ServiceCredentials Credentials { get; private set; } + internal ClientConfig Config { get; private set; } + + #region Constructors + + internal AliyunServiceClient(ServiceCredentials credentials, ClientConfig config) + { + RequestMetrics.IsEnabled = config.LogMetrics; + ServicePointManager.Expect100Continue = true; + ServicePointManager.DefaultConnectionLimit = config.ConnectionLimit; + ServicePointManager.MaxServicePointIdleTime = config.MaxIdleTime; + + this.Config = config; + this.Credentials = credentials; + Signer = CreateSigner(); + + Initialize(); + + BuildRuntimePipeline(); + } + + protected IServiceSigner Signer + { + get; + private set; + } + + internal AliyunServiceClient(string accessKeyId, string secretAccessKey, ClientConfig config, string stsToken) + : this(new BasicServiceCredentials(accessKeyId, secretAccessKey, stsToken), config) + { + } + + protected virtual void Initialize() + { + } + + #endregion + + #region Invoke methods + + internal TResponse Invoke(TRequest request, + IMarshaller marshaller, ResponseUnmarshaller unmarshaller) + where TRequest: WebServiceRequest + where TResponse : WebServiceResponse + { + ThrowIfDisposed(); + + var executionContext = new ExecutionContext( + new RequestContext() + { + ClientConfig = this.Config, + Marshaller = marshaller, + OriginalRequest = request, + Signer = Signer, + Unmarshaller = unmarshaller, + IsAsync = false + }, + new ResponseContext() + ); + + var response = (TResponse)this.RuntimePipeline.InvokeSync(executionContext).Response; + return response; + } + + internal IAsyncResult BeginInvoke(TRequest request, + IMarshaller marshaller, ResponseUnmarshaller unmarshaller, + AsyncCallback callback, object state) + where TRequest : WebServiceRequest + { + ThrowIfDisposed(); + + var executionContext = new AsyncExecutionContext( + new AsyncRequestContext() + { + ClientConfig = this.Config, + Marshaller = marshaller, + OriginalRequest = request, + Signer = Signer, + Unmarshaller = unmarshaller, + Callback = callback, + State = state, + IsAsync = true + }, + new AsyncResponseContext() + ); + + var asyncResult = this.RuntimePipeline.InvokeAsync(executionContext); + return asyncResult; + } + + internal static TResponse EndInvoke(IAsyncResult result) + where TResponse : WebServiceResponse + { + if (result == null) + throw new ArgumentNullException("result", "Parameter result cannot be null."); + + var asyncResult = result as RuntimeAsyncResult; + + if (asyncResult == null) + throw new ArgumentOutOfRangeException("result", "Parameter result is not of type RuntimeAsyncResult."); + + using (asyncResult) + { + if (!asyncResult.IsCompleted) + { + asyncResult.AsyncWaitHandle.WaitOne(); + } + + if (asyncResult.Exception != null) + { + AliyunSDKUtils.PreserveStackTrace(asyncResult.Exception); + throw asyncResult.Exception; + } + + return (TResponse) asyncResult.Response; + } + } + + #endregion + + #region Dispose methods + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (_disposed) + return; + + if (disposing) + { + if (RuntimePipeline != null) + RuntimePipeline.Dispose(); + + _disposed = true; + } + } + + private void ThrowIfDisposed() + { + if (this._disposed) + throw new ObjectDisposedException(GetType().FullName); + } + + #endregion + + protected abstract IServiceSigner CreateSigner(); + protected virtual void CustomizeRuntimePipeline(RuntimePipeline pipeline) { } + + private void BuildRuntimePipeline() + { + var httpRequestFactory = new HttpWebRequestFactory(); + var httpHandler = new HttpHandler(httpRequestFactory, this); + + // Build default runtime pipeline. + if (RequestMetrics.IsEnabled) + { + this.RuntimePipeline = new RuntimePipeline(new List + { + httpHandler, + new Unmarshaller(), + new ErrorHandler(), + new Signer(), + new CredentialsRetriever(this.Credentials), + new RetryHandler(new DefaultRetryPolicy(this.Config.MaxErrorRetry)), + new Marshaller(), + new MetricsHandler() + } + ); + } + else + { + this.RuntimePipeline = new RuntimePipeline(new List + { + httpHandler, + new Unmarshaller(), + new ErrorHandler(), + new Signer(), + new CredentialsRetriever(this.Credentials), + new RetryHandler(new DefaultRetryPolicy(this.Config.MaxErrorRetry)), + new Marshaller() + } + ); + } + + CustomizeRuntimePipeline(this.RuntimePipeline); + } + + internal static Uri ComposeUrl(IRequest iRequest) + { + Uri url = iRequest.Endpoint; + var resourcePath = iRequest.ResourcePath; + if (resourcePath == null) + resourcePath = string.Empty; + else + { + if (resourcePath.StartsWith("//", StringComparison.Ordinal)) + resourcePath = resourcePath.Substring(2); + else if (resourcePath.StartsWith("/", StringComparison.Ordinal)) + resourcePath = resourcePath.Substring(1); + } + + var delim = "?"; + var sb = new StringBuilder(); + + if (iRequest.SubResources.Count > 0) + { + foreach (var subResource in iRequest.SubResources) + { + sb.AppendFormat("{0}{1}", delim, subResource.Key); + if (subResource.Value != null) + sb.AppendFormat("={0}", subResource.Value); + delim = "&"; + } + } + + if (iRequest.Parameters.Count > 0) + { + var queryString = AliyunSDKUtils.GetParametersAsString(iRequest.Parameters); + sb.AppendFormat("{0}{1}", delim, queryString); + } + + var parameterizedPath = string.Concat(resourcePath, sb); + var uri = new Uri(url.AbsoluteUri + parameterizedPath); + return uri; + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/AliyunServiceException.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/AliyunServiceException.cs new file mode 100644 index 0000000000..b4255ef099 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/AliyunServiceException.cs @@ -0,0 +1,93 @@ +using System; +using System.Net; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime +{ + public class AliyunServiceException : Exception + { + private HttpStatusCode statusCode; + private string errorCode; + private string requestId; + private string hostId; + + public AliyunServiceException() + : base() + { + } + + public AliyunServiceException(string message) + : base(message) + { + } + + public AliyunServiceException(string message, Exception innerException) + : base(message, innerException) + { + } + + public AliyunServiceException(string message, Exception innerException, HttpStatusCode statusCode) + : base(message, innerException) + { + this.statusCode = statusCode; + } + + public AliyunServiceException(Exception innerException) + : base(innerException.Message, innerException) + { + } + + public AliyunServiceException(string message, string errorCode, string requestId, string hostId, HttpStatusCode statusCode) + : base(message) + { + this.statusCode = statusCode; + this.errorCode = errorCode; + this.requestId = requestId; + this.hostId = hostId; + } + + public AliyunServiceException(string message, Exception innerException, string errorCode, string requestId, string hostId, HttpStatusCode statusCode) + : base(message, innerException) + { + this.statusCode = statusCode; + this.errorCode = errorCode; + this.requestId = requestId; + this.hostId = hostId; + } + + /// + /// The HTTP status code from the service response + /// + public HttpStatusCode StatusCode + { + get { return this.statusCode; } + set { this.statusCode = value; } + } + + /// + /// The error code returned by the service + /// + public string ErrorCode + { + get { return this.errorCode; } + set { this.errorCode = value; } + } + + /// + /// The id of the request which generated the exception. + /// + public string RequestId + { + get { return this.requestId; } + set { this.requestId = value; } + } + + /// + /// The host id of the request which generated the exception. + /// + public string HostId + { + get { return this.hostId; } + set { this.hostId = value; } + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/ClientConfig.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/ClientConfig.cs new file mode 100644 index 0000000000..44781d720c --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/ClientConfig.cs @@ -0,0 +1,241 @@ +using System; +using System.Net; +using Aliyun.Acs.Dybaseapi.MNS.Util; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime +{ + /// + /// Base class of all configurations of MNS. + /// + public abstract partial class ClientConfig + { + private Uri _regionEndpoint; + + private readonly string _userAgent = AliyunSDKUtils.SDKUserAgent; + private int _maxErrorRetry = 3; + private bool _logMetrics = false; + private int _bufferSize = AliyunSDKUtils.DefaultBufferSize; + private bool _resignRetries = false; + private ICredentials _proxyCredentials; + private bool _disableLogging = true; + private TimeSpan? _timeout = null; + private bool _allowAutoRedirect = false; + + private string _proxyHost; + private int _proxyPort = -1; + private int? _connectionLimit = 200; + private int? _maxIdleTime; + private TimeSpan? _readWriteTimeout = null; + + private static readonly TimeSpan InfiniteTimeout = TimeSpan.FromMilliseconds(-1); + private static readonly TimeSpan MaxTimeout = TimeSpan.FromMilliseconds(int.MaxValue); + + /// + /// Gets Service Version. + /// + public abstract string ServiceVersion + { + get; + } + + /// + /// Gets Service Name. + /// + public abstract string ServiceName + { + get; + } + + /// + /// Gets of the UserAgent property. + /// + public string UserAgent + { + get { return this._userAgent; } + } + + /// + /// Gets and sets the RegionEndpoint property. + /// + public Uri RegionEndpoint + { + get + { + if (_regionEndpoint == null) + { + throw new ArgumentException("Endpoint of MNSConfig must be specified."); + } + return _regionEndpoint; + } + set { _regionEndpoint = value; } + } + + /// + /// Gets and sets of the MaxErrorRetry property. + /// + public int MaxErrorRetry + { + get { return this._maxErrorRetry; } + set { this._maxErrorRetry = value; } + } + + /// + /// Flag on whether to log metrics for service calls. + /// + public bool LogMetrics + { + get { return this._logMetrics; } + set { this._logMetrics = value; } + } + + /// + /// Gets and Sets the BufferSize property. + /// The BufferSize controls the buffer used to read in from input streams and write + /// out to the request. + /// + public int BufferSize + { + get { return this._bufferSize; } + set { this._bufferSize = value; } + } + + /// + /// Flag on whether to resign requests on retry or not. + /// + internal bool ResignRetries + { + get { return this._resignRetries; } + set { this._resignRetries = value; } + } + + /// + /// This flag controls if .NET HTTP infrastructure should follow redirection responses. + /// + internal bool AllowAutoRedirect + { + get + { + return this._allowAutoRedirect; + } + set + { + this._allowAutoRedirect = value; + } + } + + /// + /// Flag on whether to completely disable logging for this client or not. + /// + internal bool DisableLogging + { + get { return this._disableLogging; } + set { this._disableLogging = value; } + } + + /// + /// Credentials to use with a proxy. + /// + public ICredentials ProxyCredentials + { + get { return this._proxyCredentials; } + set { this._proxyCredentials = value; } + } + + #region Constructor + public ClientConfig() + { + Initialize(); + } + #endregion + + protected virtual void Initialize() + { + } + + /// + /// Gets and sets of the ProxyHost property. + /// + public string ProxyHost + { + get { return this._proxyHost; } + set { this._proxyHost = value; } + } + + + /// + /// Gets and sets of the ProxyPort property. + /// + public int ProxyPort + { + get { return this._proxyPort; } + set { this._proxyPort = value; } + } + + /// + /// Gets and sets the max idle time set on the ServicePoint for the WebRequest. + /// + public int MaxIdleTime + { + get { return AliyunSDKUtils.GetMaxIdleTime(this._maxIdleTime); } + set { this._maxIdleTime = value; } + } + + /// + /// Gets and sets the connection limit set on the ServicePoint for the WebRequest. + /// + public int ConnectionLimit + { + get { return AliyunSDKUtils.GetConnectionLimit(this._connectionLimit); } + set { this._connectionLimit = value; } + } + + /// + /// Overrides the default read-write timeout value. + /// + public TimeSpan? ReadWriteTimeout + { + get { return this._readWriteTimeout; } + set + { + ValidateTimeout(value); + this._readWriteTimeout = value; + } + } + + /// + /// Overrides the default request timeout value. + /// + public TimeSpan? Timeout + { + get { return this._timeout; } + set + { + ValidateTimeout(value); + this._timeout = value; + } + } + + internal static void ValidateTimeout(TimeSpan? timeout) + { + if (!timeout.HasValue) + { + throw new ArgumentNullException("timeout"); + } + + if (timeout != InfiniteTimeout && (timeout <= TimeSpan.Zero || timeout > MaxTimeout)) + { + throw new ArgumentOutOfRangeException("timeout"); + } + } + + /// + /// Returns the request timeout value if its value is set, + /// else returns client timeout value. + /// + internal static TimeSpan? GetTimeoutValue(TimeSpan? clientTimeout, TimeSpan? requestTimeout) + { + return requestTimeout.HasValue ? requestTimeout + : (clientTimeout.HasValue ? clientTimeout : null); + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Enumerations.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Enumerations.cs new file mode 100644 index 0000000000..c321884851 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Enumerations.cs @@ -0,0 +1,22 @@ +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime +{ + /// + /// The valid hashing algorithm supported by MNS for request signing. + /// + public enum SigningAlgorithm + { + HmacSHA1, + HmacSHA256 + }; + + /// + /// The http methods supported by MNS. + /// + public enum HttpMethod + { + GET, + PUT, + POST, + DELETE + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Auth/IServiceSigner.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Auth/IServiceSigner.cs new file mode 100644 index 0000000000..e2f397983a --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Auth/IServiceSigner.cs @@ -0,0 +1,12 @@ +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Util; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Auth +{ + /// + /// Interface for signing MNS request. + /// + public partial interface IServiceSigner + { + void Sign(IRequest request, RequestMetrics metrics, string accessKeyId, string secretAccessKey, string stsToken); + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Auth/MNSSigner.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Auth/MNSSigner.cs new file mode 100644 index 0000000000..738d5ede7d --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Auth/MNSSigner.cs @@ -0,0 +1,273 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Globalization; +using System.Text.RegularExpressions; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Util; +using Aliyun.Acs.Dybaseapi.MNS.Util; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Auth +{ + /// + /// A signer for generating MNS request header named 'Authorization'. + /// + internal class MNSSigner : IServiceSigner + { + #region Immutable Properties + + static readonly Regex CompressWhitespaceRegex = new Regex("\\s+"); + const SigningAlgorithm SignerAlgorithm = SigningAlgorithm.HmacSHA1; + + #endregion + + #region Public Signing Methods + + public void Sign(IRequest request, + RequestMetrics metrics, + string accessKeyId, + string secretAccessKey, + string stsToken) + { + var signingRequest = SignRequest(request, metrics, secretAccessKey); + var signingResult = new StringBuilder(); + signingResult.AppendFormat("{0} {1}:{2}", + MNSConstants.MNS_AUTHORIZATION_HEADER_PREFIX, + accessKeyId, + signingRequest); + request.Headers[HttpHeader.AuthorizationHeader] = signingResult.ToString(); + + if (!string.IsNullOrEmpty(stsToken)) + { + request.Headers[HttpHeader.SecurityToken] = stsToken; + } + } + + public string SignRequest(IRequest request, + RequestMetrics metrics, + string secretAccessKey) + { + InitializeHeaders(request.Headers); + + var parametersToCanonicalize = GetParametersToCanonicalize(request); + var canonicalParameters = CanonicalizeQueryParameters(parametersToCanonicalize); + var canonicalResource = CanonicalizeResource(canonicalParameters, request.ResourcePath); + var canonicalMNSHeaders = CanonoicalizeMNSHeaders(request.Headers); + + var canonicalRequest = CanonicalizeRequest(request.HttpMethod, + request.Headers, + canonicalMNSHeaders, + canonicalResource); + if (metrics != null) + metrics.AddProperty(Metric.CanonicalRequest, canonicalRequest); + + return ComputeSignature(secretAccessKey, canonicalRequest); + } + + #endregion + + #region Public Signing Helpers + + /// + /// Initializes request headers. + /// + /// The request headers + private static void InitializeHeaders(IDictionary headers) + { + // clean up any prior signature in the headers if resigning + headers.Remove(HttpHeader.AuthorizationHeader); + } + + /// + /// Computes and returns an Service signature for the specified canonicalized request + /// + /// + /// + /// + public static string ComputeSignature(string secretAccessKey, string canonicalRequest) + { + return ComputeKeyedHash(SignerAlgorithm, secretAccessKey, canonicalRequest); + } + + /// + /// Compute and return the hash of a data blob using the specified key + /// + /// Algorithm to use for hashing + /// Hash key + /// Data blob + /// Hash of the data + public static string ComputeKeyedHash(SigningAlgorithm algorithm, string key, string data) + { + return CryptoUtilFactory.CryptoInstance.HMACSign(data, key, algorithm); + } + + #endregion + + #region Private Signing Helpers + + protected static string CanonoicalizeMNSHeaders(IDictionary headers) + { + var headersToCanonicalize = new SortedDictionary(StringComparer.OrdinalIgnoreCase); + if (headers != null && headers.Count > 0) + { + foreach (var header in headers.Where(header => + header.Key.ToLowerInvariant().StartsWith(MNSConstants.X_MNS_HEADER_PREFIX))) + { + headersToCanonicalize.Add(header.Key.ToLowerInvariant(), header.Value); + } + } + return CanonicalizeHeaders(headersToCanonicalize); + } + + protected static string CanonicalizeResource(string canonicalQueryString, string resourcePath) + { + var canonicalResource = new StringBuilder(); + canonicalResource.Append(CanonicalizeResourcePath(resourcePath)); + if (canonicalQueryString != string.Empty) + canonicalResource.AppendFormat("?{0}", canonicalQueryString); + return canonicalResource.ToString(); + } + + /// + /// Returns the canonicalized resource path for the service endpoint + /// + /// Resource path for the request + /// Canonicalized resource path for the endpoint + protected static string CanonicalizeResourcePath(string resourcePath) + { + if (string.IsNullOrEmpty(resourcePath) || resourcePath == "/") + return "/"; + + var pathSegments = resourcePath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); + var canonicalizedPath = new StringBuilder(); + foreach (var segment in pathSegments) + { + canonicalizedPath.AppendFormat("/{0}", segment); + } + + if (resourcePath.EndsWith("/", StringComparison.Ordinal)) + canonicalizedPath.Append("/"); + + return canonicalizedPath.ToString(); + } + + /// + /// Computes and returns the canonical request. + /// + /// The http method used for the request + /// The entire request headers + /// The canonicalMNSHeaders for the request + /// The canonicalResource for the request + /// Canonicalised request as a string + protected static string CanonicalizeRequest(string httpMethod, + IDictionary headers, + string canonicalMNSHeaders, + string canonicalResource) + { + var canonicalRequest = new StringBuilder(); + canonicalRequest.AppendFormat("{0}\n", httpMethod); + + var contentMD5 = string.Empty; + if (headers.ContainsKey(HttpHeader.ContentMD5Header)) + contentMD5 = headers[HttpHeader.ContentMD5Header]; + canonicalRequest.AppendFormat("{0}\n", contentMD5); + + var contentType = string.Empty; + if (headers.ContainsKey(HttpHeader.ContentTypeHeader)) + contentType = headers[HttpHeader.ContentTypeHeader]; + canonicalRequest.AppendFormat("{0}\n", contentType); + + canonicalRequest.AppendFormat("{0}\n", headers[HttpHeader.DateHeader]); + canonicalRequest.Append(canonicalMNSHeaders); + canonicalRequest.Append(canonicalResource); + + return canonicalRequest.ToString(); + } + + /// + /// Computes the canonical headers with values for the request. + /// + /// All sorted request headers + /// The canonical headers. + protected static string CanonicalizeHeaders(ICollection> sortedHeaders) + { + if (sortedHeaders == null || sortedHeaders.Count == 0) + return string.Empty; + + var builder = new StringBuilder(); + foreach (var entry in sortedHeaders) + { + builder.Append(entry.Key.ToLower(CultureInfo.InvariantCulture)); + builder.Append(":"); + builder.Append(CompressSpaces(entry.Value)); + builder.Append("\n"); + } + + return builder.ToString(); + } + + /// + /// Collects all subresources and query string parameters. + /// + /// The request being signed + /// A set of parameters + protected static IDictionary GetParametersToCanonicalize(IRequest request) + { + var parametersToCanonicalize = new Dictionary(); + + if (request.SubResources != null && request.SubResources.Count > 0) + { + foreach (var subResource in request.SubResources) + { + parametersToCanonicalize.Add(subResource.Key, subResource.Value); + } + } + + if (request.Parameters != null && request.Parameters.Count > 0) + { + foreach (var queryParameter in request.Parameters.Where(queryParameter => queryParameter.Value != null)) + { + parametersToCanonicalize.Add(queryParameter.Key, queryParameter.Value); + } + } + + return parametersToCanonicalize; + } + + /// + /// Computes and returns the canonicalized query string + /// + /// The set of query string parameters + /// The canonical query string parameters + protected static string CanonicalizeQueryParameters(IDictionary parameters) + { + if (parameters == null || parameters.Count == 0) + return string.Empty; + + var canonicalQueryString = new StringBuilder(); + var queryParams = new SortedDictionary(parameters, StringComparer.Ordinal); + foreach (var p in queryParams) + { + if (canonicalQueryString.Length > 0) + canonicalQueryString.Append("&"); + if (string.IsNullOrEmpty(p.Value)) + canonicalQueryString.AppendFormat("{0}=", p.Key); + else + canonicalQueryString.AppendFormat("{0}={1}", p.Key, p.Value); + } + + return canonicalQueryString.ToString(); + } + + static string CompressSpaces(string data) + { + if (data == null || !data.Contains(" ")) + return data; + + var compressed = CompressWhitespaceRegex.Replace(data, " "); + return compressed; + } + + #endregion + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/DefaultRequest.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/DefaultRequest.cs new file mode 100644 index 0000000000..7dfd8343e5 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/DefaultRequest.cs @@ -0,0 +1,289 @@ +using System; +using System.Collections.Generic; +using System.IO; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal +{ + /// + /// Default implementation of the IRequest interface. + /// + internal class DefaultRequest : IRequest + { + readonly IDictionary parameters = new Dictionary(StringComparer.Ordinal); + readonly IDictionary headers = new Dictionary(StringComparer.OrdinalIgnoreCase); + readonly IDictionary subResources = new Dictionary(StringComparer.OrdinalIgnoreCase); + + Uri endpoint; + string resourcePath; + string serviceName; + readonly WebServiceRequest originalRequest; + byte[] content; + Stream contentStream; + string httpMethod = "GET"; + bool useQueryString = false; + string requestName; + long originalStreamLength; + + /// + /// Constructs a new DefaultRequest with the specified service name and the + /// original, user facing request object. + /// + /// The orignal request that is being wrapped + /// The service name + public DefaultRequest(WebServiceRequest request, String serviceName) + { + if (request == null) throw new ArgumentNullException("request"); + if (string.IsNullOrEmpty(serviceName)) throw new ArgumentNullException("serviceName"); + + this.serviceName = serviceName; + this.originalRequest = request; + this.requestName = this.originalRequest.GetType().Name; + + foreach (var header in request.Headers) + this.Headers.Add(header.Key, header.Value); + foreach (var param in request.Parameters) + this.Parameters.Add(param.Key, param.Value); + } + + + /// + /// The name of the request + /// + public string RequestName + { + get { return this.requestName; } + } + + + /// + /// Gets and sets the type of http request to make, whether it should be POST,GET or DELETE + /// + public string HttpMethod + { + get + { + return this.httpMethod; + } + set + { + this.httpMethod = value; + } + } + + /// + /// Gets and sets a flag that indicates whether the request is sent as a query string instead of the request body. + /// + public bool UseQueryString + { + get + { + return this.useQueryString; + } + set + { + this.useQueryString = value; + } + } + + /// + /// Returns the original, user facing request object which this internal + /// request object is representing. + /// + public WebServiceRequest OriginalRequest + { + get + { + return originalRequest; + } + } + + /// + /// Returns a dictionary of the headers included in this request. + /// + public IDictionary Headers + { + get + { + return this.headers; + } + } + + + /// + /// Returns a dictionary of the parameters included in this request. + /// + public IDictionary Parameters + { + get + { + return this.parameters; + } + } + + /// + /// Returns the subresources that should be appended to the resource path. + /// This is used primarily for mns, where object keys can contain '?' + /// characters, making string-splitting of a resource path potentially + /// hazardous. + /// + public IDictionary SubResources + { + get + { + return this.subResources; + } + } + + /// + /// Adds a new null entry to the SubResources collection for the request + /// + /// The name of the subresource + public void AddSubResource(string subResource) + { + AddSubResource(subResource, null); + } + + /// + /// Adds a new entry to the SubResources collection for the request + /// + /// The name of the subresource + /// Value of the entry + public void AddSubResource(string subResource, string value) + { + SubResources.Add(subResource, value); + } + + /// + /// Gets and Sets the endpoint for this request. + /// + public Uri Endpoint + { + get + { + return this.endpoint; + } + set + { + this.endpoint = value; + } + } + + /// + /// Gets and Sets the resource path added on to the endpoint. + /// + public string ResourcePath + { + get + { + return this.resourcePath; + } + set + { + this.resourcePath = value; + } + } + + /// + /// Gets and Sets the content for this request. + /// + public byte[] Content + { + get + { + return this.content; + } + set + { + this.content = value; + } + } + + /// + /// Gets and sets the content stream. + /// + public Stream ContentStream + { + get { return this.contentStream; } + set + { + this.contentStream = value; + OriginalStreamPosition = -1; + if (this.contentStream != null && this.contentStream.CanSeek) + OriginalStreamPosition = this.contentStream.Position; + } + } + + /// + /// Gets and sets the original stream position. + /// If ContentStream is null or does not support seek, this propery + /// should be equal to -1. + /// + public long OriginalStreamPosition + { + get { return this.originalStreamLength; } + set { this.originalStreamLength = value; } + } + + /// + /// The name of the service to which this request is being sent. + /// + public string ServiceName + { + get + { + return this.serviceName; + } + } + + /// + /// Gets and sets the Suppress404Exceptions property. If true then 404s return back from MNS will not cause an exception and + /// an empty response object will be returned. + /// + public bool Suppress404Exceptions + { + get; + set; + } + + /// + /// Checks if the request stream can be rewinded. + /// + /// Returns true if the request stream can be rewinded , + /// else false. + public bool IsRequestStreamRewindable() + { + // Retries may not be possible with a stream + if (this.ContentStream != null) + { + // Retry is possible if stream is seekable + return this.ContentStream.CanSeek; + } + return true; + } + + /// + /// Returns true if the request can contain a request body, else false. + /// + /// Returns true if the currect request can contain a request body, else false. + public bool MayContainRequestBody() + { + return !this.UseQueryString && + (this.HttpMethod == "POST" || + this.HttpMethod == "PUT" || + this.HttpMethod == "DELETE"); + } + + /// + /// Returns true if the request has a body, else false. + /// + /// Returns true if the request has a body, else false. + public bool HasRequestBody() + { + return (this.HttpMethod == "POST" || + this.HttpMethod == "PUT" || + this.HttpMethod == "DELETE") && + ((this.Content != null) || + this.ContentStream != null); + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/ErrorResponse.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/ErrorResponse.cs new file mode 100644 index 0000000000..3913125ef3 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/ErrorResponse.cs @@ -0,0 +1,37 @@ +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal +{ + /// + /// Error information returned by MNS. + /// + public class ErrorResponse + { + private string _code; + private string _message; + private string _requestId; + private string _hostId; + + public string Code + { + get { return _code; } + set { _code = value; } + } + + public string Message + { + get { return _message; } + set { _message = value; } + } + + public string RequestId + { + get { return _requestId; } + set { _requestId = value; } + } + + public string HostId + { + get { return _hostId; } + set { _hostId = value; } + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/IRequest.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/IRequest.cs new file mode 100644 index 0000000000..1a12efe479 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/IRequest.cs @@ -0,0 +1,173 @@ +using System; +using System.Collections.Generic; +using System.IO; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal +{ + /// + /// Represents a request being sent to an Aliyun Web Service, including the + /// parameters being sent as part of the request, the endpoint to which the + /// request should be sent, etc. + /// + public interface IRequest + { + /// + /// The name of the request + /// + string RequestName + { + get; + } + + /// + /// Returns a dictionary of the headers included in this request. + /// + IDictionary Headers + { + get; + } + + /// + /// Gets and sets a flag that indicates whether the request is sent as a query string instead of the request body. + /// + bool UseQueryString + { + get; + set; + } + + /// + /// Returns a dictionary of the parameters included in this request. + /// + IDictionary Parameters + { + get; + } + + /// + /// Returns the subresources that should be appended to the resource path. + /// This is used primarily for mns, where object keys can contain '?' + /// characters, making string-splitting of a resource path potentially + /// hazardous. + /// + IDictionary SubResources + { + get; + } + + /// + /// Adds a new null entry to the SubResources collection for the request + /// + /// The name of the subresource + void AddSubResource(string subResource); + + /// + /// Adds a new entry to the SubResources collection for the request + /// + /// The name of the subresource + /// Value of the entry + void AddSubResource(string subResource, string value); + + /// + /// Gets and sets the type of http request to make, whether it should be PUT, POST,GET or DELETE + /// + string HttpMethod + { + get; + set; + } + + /// + /// Gets and Sets the endpoint for this request. + /// + Uri Endpoint + { + get; + set; + } + + /// + /// Gets and Sets the resource path added on to the endpoint. + /// + string ResourcePath + { + get; + set; + } + + /// + /// Gets and Sets the content for this request. + /// + byte[] Content + { + get; + set; + } + + /// + /// Gets and sets the content stream. + /// + Stream ContentStream + { + get; + set; + } + + /// + /// Gets and sets the original stream position. + /// If ContentStream is null or does not support seek, this propery + /// should be equal to -1. + /// + long OriginalStreamPosition + { + get; + set; + } + + /// + /// The name of the service to which this request is being sent. + /// + string ServiceName + { + get; + } + + /// + /// Returns the original, user facing request object which this internal + /// request object is representing. + /// + WebServiceRequest OriginalRequest + { + get; + } + + /// + /// Gets and sets the Suppress404Exceptions property. If true then 404s return back from MNS will not cause an exception and + /// an empty response object will be returned. + /// + bool Suppress404Exceptions + { + get; + set; + } + + /// + /// Checks if the request stream can be rewinded. + /// + /// Returns true if the request stream can be rewinded , + /// else false. + bool IsRequestStreamRewindable(); + + /// + /// Returns true if the request can contain a request body, else false. + /// + /// Returns true if the currect request can contain a request body, else false. + bool MayContainRequestBody(); + + /// + /// Returns true if the request has a body, else false. + /// + /// Returns true if the request has a body, else false. + bool HasRequestBody(); + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/HttpWebRequestResponseData.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/HttpWebRequestResponseData.cs new file mode 100644 index 0000000000..542bf21905 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/HttpWebRequestResponseData.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Transform +{ + public class HttpWebRequestResponseData : IWebResponseData + { + HttpWebResponse _response; + string[] _headerNames; + HashSet _headerNamesSet; + HttpWebResponseBody _responseBody; + + public HttpWebRequestResponseData(HttpWebResponse response) + { + this._response = response; + _responseBody = new HttpWebResponseBody(response); + + this.StatusCode = response.StatusCode; + this.IsSuccessStatusCode = this.StatusCode >= HttpStatusCode.OK && this.StatusCode <= (HttpStatusCode)299; + this.ContentType = response.ContentType; + this.ContentLength = response.ContentLength; + } + + public HttpStatusCode StatusCode { get; private set; } + + public bool IsSuccessStatusCode { get; private set; } + + public string ContentType { get; private set; } + + public long ContentLength { get; private set; } + + public bool IsHeaderPresent(string headerName) + { + if (_headerNamesSet == null) + SetHeaderNames(); + return _headerNamesSet.Contains(headerName); + } + + public string[] GetHeaderNames() + { + if (_headerNames == null) + { + SetHeaderNames(); + } + return _headerNames; + } + + public string GetHeaderValue(string name) + { + return this._response.GetResponseHeader(name); + } + + private void SetHeaderNames() + { + var keys = this._response.Headers.Keys; + _headerNames = new string[keys.Count]; + for (int i = 0; i < keys.Count; i++) + _headerNames[i] = keys[i]; + _headerNamesSet = new HashSet(_headerNames, StringComparer.OrdinalIgnoreCase); + } + + public IHttpResponseBody ResponseBody + { + get { return _responseBody; } + } + } + + public class HttpWebResponseBody : IHttpResponseBody + { + HttpWebResponse _response; + bool _disposed = false; + + public HttpWebResponseBody(HttpWebResponse response) + { + _response = response; + } + + public Stream OpenResponse() + { + if (_disposed) + throw new ObjectDisposedException("HttpWebResponseBody"); + + return _response.GetResponseStream(); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (_disposed) + return; + + if (disposing) + { + if (_response != null) + _response.Close(); + + _disposed = true; + } + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/IMarshaller.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/IMarshaller.cs new file mode 100644 index 0000000000..3738434d61 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/IMarshaller.cs @@ -0,0 +1,7 @@ +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Transform +{ + public interface IMarshaller + { + T Marshall(R input); + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/IResponseUnmarshaller.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/IResponseUnmarshaller.cs new file mode 100644 index 0000000000..3f8601dd82 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/IResponseUnmarshaller.cs @@ -0,0 +1,21 @@ +using System; +using System.Net; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Transform +{ + /// + /// Interface for unmarshallers which unmarshall service responses. + /// + public interface IResponseUnmarshaller : IUnmarshaller + { + /// + /// Extracts an exeption with data from an ErrorResponse. + /// + /// The XML parsing context. + /// An inner exception to be included with the returned exception + /// The HttpStatusCode from the ErrorResponse + /// Either an exception based on the ErrorCode from the ErrorResponse, or the + /// general service exception for the service in question. + AliyunServiceException UnmarshallException(R input, Exception innerException, HttpStatusCode statusCode); + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/IUnmarshaller.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/IUnmarshaller.cs new file mode 100644 index 0000000000..7e232bfc1a --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/IUnmarshaller.cs @@ -0,0 +1,15 @@ +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Transform +{ + /// + /// Interface for unmarshallers which unmarshall objects from response data. + /// + public interface IUnmarshaller + { + /// + /// Given the current position in the XML stream, extract a T. + /// + /// The XML parsing context + /// An object of type T populated with data from the XML stream. + T Unmarshall(R input); + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/IWebResponseData.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/IWebResponseData.cs new file mode 100644 index 0000000000..4a3239f83a --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/IWebResponseData.cs @@ -0,0 +1,24 @@ +using System; +using System.IO; +using System.Net; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Transform +{ + public interface IWebResponseData + { + long ContentLength { get; } + string ContentType { get; } + HttpStatusCode StatusCode { get; } + bool IsSuccessStatusCode { get; } + string[] GetHeaderNames(); + bool IsHeaderPresent(string headerName); + string GetHeaderValue(string headerName); + + IHttpResponseBody ResponseBody { get; } + } + + public interface IHttpResponseBody : IDisposable + { + Stream OpenResponse(); + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/RequestMarshallException.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/RequestMarshallException.cs new file mode 100644 index 0000000000..d23ac019d6 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/RequestMarshallException.cs @@ -0,0 +1,29 @@ +using System; +using System.Runtime.Serialization; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Transform +{ + /// + /// RequestMarshallException + /// + internal class RequestMarshallException : InvalidOperationException, ISerializable + { + /// + /// Constructs a new QueueAlreadyExistException with the specified error message. + /// + public RequestMarshallException(string message) + : base(message) + { + } + + public RequestMarshallException(string message, Exception innerException) + : base(message, innerException) + { + } + + protected RequestMarshallException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/ResponseUnmarshallException.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/ResponseUnmarshallException.cs new file mode 100644 index 0000000000..89e0261538 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/ResponseUnmarshallException.cs @@ -0,0 +1,31 @@ +using System; +using System.Runtime.Serialization; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Transform +{ + /// + /// Exception thrown during deserializing response. + /// + [Serializable] + internal class ResponseUnmarshallException : InvalidOperationException, ISerializable + { + public ResponseUnmarshallException() + { + } + + public ResponseUnmarshallException(string message) + : base(message) + { + } + + public ResponseUnmarshallException(string message, Exception innerException) + : base(message, innerException) + { + } + + protected ResponseUnmarshallException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } +} \ No newline at end of file diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/ResponseUnmarshallers.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/ResponseUnmarshallers.cs new file mode 100644 index 0000000000..c86973ed4c --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/ResponseUnmarshallers.cs @@ -0,0 +1,91 @@ +using System; +using System.Net; +using System.IO; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Util; +using Aliyun.Acs.Dybaseapi.MNS.Util; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Transform +{ + /// + /// Abstract class for unmarshalling service responses. + /// + public abstract class ResponseUnmarshaller : IResponseUnmarshaller + { + public virtual UnmarshallerContext CreateContext(IWebResponseData response, Stream stream, RequestMetrics metrics) + { + if (response == null) + { + throw new WebException("The Web Response for a successful request is null!"); + } + + return ConstructUnmarshallerContext(stream, response); + } + + internal virtual bool HasStreamingProperty + { + get { return false; } + } + + #region IResponseUnmarshaller Members + + public virtual AliyunServiceException UnmarshallException(UnmarshallerContext input, Exception innerException, HttpStatusCode statusCode) + { + throw new NotImplementedException(); + } + + #endregion + + public WebServiceResponse UnmarshallResponse(UnmarshallerContext context) + { + var response = this.Unmarshall(context); + response.ContentLength = context.ResponseData.ContentLength; + response.HttpStatusCode = context.ResponseData.StatusCode; + return response; + } + + #region IUnmarshaller Members + + public abstract WebServiceResponse Unmarshall(UnmarshallerContext input); + + #endregion + + protected abstract UnmarshallerContext ConstructUnmarshallerContext(Stream responseStream, IWebResponseData response); + } + + /// + /// Class for unmarshalling XML service responses. + /// + public abstract class XmlResponseUnmarshaller : ResponseUnmarshaller + { + public override WebServiceResponse Unmarshall(UnmarshallerContext input) + { + XmlUnmarshallerContext context = input as XmlUnmarshallerContext; + if (context == null) + throw new InvalidOperationException("Unsupported UnmarshallerContext"); + + WebServiceResponse response = this.Unmarshall(context); + + foreach (var headerName in context.ResponseData.GetHeaderNames()) + response.Headers.Add(headerName, context.ResponseData.GetHeaderValue(headerName)); + + return response; + } + public override AliyunServiceException UnmarshallException(UnmarshallerContext input, Exception innerException, HttpStatusCode statusCode) + { + XmlUnmarshallerContext context = input as XmlUnmarshallerContext; + if (context == null) + throw new InvalidOperationException("Unsupported UnmarshallerContext"); + + return this.UnmarshallException(context, innerException, statusCode); + } + + protected override UnmarshallerContext ConstructUnmarshallerContext(Stream responseStream, IWebResponseData response) + { + return new XmlUnmarshallerContext(responseStream, response); + } + + public abstract WebServiceResponse Unmarshall(XmlUnmarshallerContext input); + + public abstract AliyunServiceException UnmarshallException(XmlUnmarshallerContext input, Exception innerException, HttpStatusCode statusCode); + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/UnmarshallerContext.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/UnmarshallerContext.cs new file mode 100644 index 0000000000..e65e60aad5 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/UnmarshallerContext.cs @@ -0,0 +1,70 @@ +using System; +using System.IO; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Transform +{ + /// + /// Base class for the UnmarshallerContext objects that are used + /// to unmarshall a web-service response. + /// + public abstract class UnmarshallerContext : IDisposable + { + private bool disposed = false; + protected IWebResponseData WebResponseData { get; set; } + + public Stream ResponseStream { get; set; } + + public IWebResponseData ResponseData + { + get { return WebResponseData; } + } + + #region Dispose Pattern Implementation + + /// + /// Implements the Dispose pattern + /// + /// Whether this object is being disposed via a call to Dispose + /// or garbage collected. + protected virtual void Dispose(bool disposing) + { + if (!this.disposed) + { + if (disposing) + { + if (this.ResponseStream != null) + { + ResponseStream.Dispose(); + ResponseStream = null; + } + } + this.disposed = true; + } + } + + /// + /// Disposes of all managed and unmanaged resources. + /// + public void Dispose() + { + this.Dispose(true); + GC.SuppressFinalize(this); + } + + #endregion + } + + public class XmlUnmarshallerContext : UnmarshallerContext + { + + #region Constructors + + public XmlUnmarshallerContext(Stream responseStream, IWebResponseData responseData) + { + this.ResponseStream = responseStream; + this.WebResponseData = responseData; + } + + #endregion + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/XmlMarshaller.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/XmlMarshaller.cs new file mode 100644 index 0000000000..c818c91f01 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/XmlMarshaller.cs @@ -0,0 +1,42 @@ +using Aliyun.Acs.Dybaseapi.MNS.Util; +using System; +using System.IO; +using System.Xml.Serialization; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Transform +{ + /// + /// XML marshaller used for marshalling specfied object to XML content stream. + /// + internal class XmlMarshaller : IMarshaller + { + private static readonly XmlSerializer _serializer = new XmlSerializer(typeof(TRequest)); + + public Stream Marshall(TRequest requestObject) + { + MemoryStream stream = null; + var gotException = false; + try + { + stream = new MemoryStream(); + var namespaces = new XmlSerializerNamespaces(); + namespaces.Add(string.Empty, MNSConstants.MNS_XML_NAMESPACE); + _serializer.Serialize(stream, requestObject, namespaces); + stream.Seek(0, SeekOrigin.Begin); + } + catch (InvalidOperationException ex) + { + gotException = true; + throw new RequestMarshallException(ex.Message, ex); + } + finally + { + if (gotException && stream != null) + { + stream.Close(); + } + } + return stream; + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/XmlUnmarshaller.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/XmlUnmarshaller.cs new file mode 100644 index 0000000000..d4f3e36262 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Transform/XmlUnmarshaller.cs @@ -0,0 +1,57 @@ +using System; +using System.IO; +using System.Text; +using System.Xml; +using System.Xml.Serialization; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Transform +{ + /// + /// Deserializes specified object from XML stream. + /// + internal class XmlUnmarshaller : IUnmarshaller + { + private static readonly XmlSerializer _serializer = new XmlSerializer(typeof(TResponse)); + + public TResponse Unmarshall(Stream responseStream) + { + return this.Unmarshall(responseStream, false); + } + + public TResponse Unmarshall(Stream responseStream, bool keepOpenOnException = false) + { + bool dispose = true; + try + { + return (TResponse)_serializer.Deserialize(responseStream); + } + catch (XmlException ex) + { + if (keepOpenOnException) + { + dispose = false; + } + throw new ResponseUnmarshallException(ex.Message, ex); + } + catch (InvalidOperationException ex) + { + if (keepOpenOnException) + { + dispose = false; + } + throw new ResponseUnmarshallException(ex.Message, ex); + } + finally + { + if (dispose) + { + responseStream.Dispose(); + } + else + { + responseStream.Seek(0, SeekOrigin.Begin); + } + } + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Util/Extensions.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Util/Extensions.cs new file mode 100644 index 0000000000..22bac4d753 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Util/Extensions.cs @@ -0,0 +1,17 @@ +using System; +using System.Diagnostics; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Util +{ + internal static partial class Extensions + { + private static readonly long ticksPerSecond = TimeSpan.FromSeconds(1).Ticks; + private static readonly double tickFrequency = ticksPerSecond / (double)Stopwatch.Frequency; + public static long GetElapsedDateTimeTicks(this Stopwatch self) + { + double stopwatchTicks = self.ElapsedTicks; + long ticks = (long)(stopwatchTicks * tickFrequency); + return ticks; + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Util/Metrics.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Util/Metrics.cs new file mode 100644 index 0000000000..5738aec4a5 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/Util/Metrics.cs @@ -0,0 +1,491 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; + +using Aliyun.Acs.Dybaseapi.MNS.Util; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Util +{ + public class RequestMetrics + { + #region Private members + + private object metricsLock = new object(); + private Stopwatch stopWatch; + private Dictionary inFlightTimings; + private List errors = new List(); + private long CurrentTime { get { return stopWatch.GetElapsedDateTimeTicks(); } } + private void LogError_Locked(Metric metric, string messageFormat, params object[] args) + { + errors.Add(new MetricError(metric, messageFormat, args)); + } + private static void Log(StringBuilder builder, Metric metric, object metricValue) + { + LogHelper(builder, metric, metricValue); + } + private static void Log(StringBuilder builder, Metric metric, List metricValues) + { + if (metricValues == null || metricValues.Count == 0) + LogHelper(builder, metric); + else + LogHelper(builder, metric, metricValues.ToArray()); + } + private static void LogHelper(StringBuilder builder, Metric metric, params object[] metricValues) + { + builder.AppendFormat(CultureInfo.InvariantCulture, "{0} = ", metric); + if (metricValues == null) + { + builder.Append(ObjectToString(metricValues)); + } + else + { + for (int i = 0; i < metricValues.Length; i++) + { + object metricValue = metricValues[i]; + string metricValueString = ObjectToString(metricValue); + if (i > 0) + builder.Append(", "); + builder.Append(metricValueString); + } + } + builder.Append("; "); + } + private static string ObjectToString(object data) + { + if (data == null) + return "NULL"; + return data.ToString(); + } + + #endregion + + #region Properties + + /// + /// Collection of properties being tracked + /// + private Dictionary> Properties { get; set; } + + /// + /// Timings for metrics being tracked + /// + private Dictionary> Timings { get; set; } + + /// + /// Counters being tracked + /// + private Dictionary Counters { get; set; } + + /// + /// Whether metrics are enabled for the request + /// + public static bool IsEnabled { get; internal set; } + + #endregion + + #region Constructor + + /// + /// Constructs an empty, disabled metrics object + /// + public RequestMetrics() + { + stopWatch = Stopwatch.StartNew(); + Properties = new Dictionary>(); + Timings = new Dictionary>(); + Counters = new Dictionary(); + inFlightTimings = new Dictionary(); + } + + #endregion + + #region Internal methods + + /// + /// Starts timing an event. Logs an exception if an event + /// of the same type was started but not stopped. + /// + /// + /// + internal void StartEvent(Metric metric) + { + if (IsEnabled) + { + lock(metricsLock) + { + if (inFlightTimings.ContainsKey(metric)) + LogError_Locked(metric, "Starting multiple events for the same metric"); + inFlightTimings[metric] = new Timing(CurrentTime); + } + } + } + + /// + /// Stops timing an event. Logs an exception if the event wasn't started. + /// + /// + /// + internal void StopEvent(Metric metric) + { + if (IsEnabled) + { + Timing timing; + lock(metricsLock) + { + if (!inFlightTimings.TryGetValue(metric, out timing)) + { + LogError_Locked(metric, "Trying to stop event that has not been started"); + return; + } + inFlightTimings.Remove(metric); + timing.Stop(CurrentTime); + + if (IsEnabled) + { + List list; + if (!Timings.TryGetValue(metric, out list)) + { + list = new List(); + Timings[metric] = list; + } + list.Add(timing); + } + } + return; + } + else + { + return; + } + + } + + /// + /// Adds a property for a metric. If there are multiple, the + /// object is added as a new item in a list. + /// + /// + /// + internal void AddProperty(Metric metric, object property) + { + if (!IsEnabled) return; + + List list; + lock(metricsLock) + { + if (!Properties.TryGetValue(metric, out list)) + { + list = new List(); + Properties[metric] = list; + } + list.Add(property); + } + } + + /// + /// Sets a counter for a specific metric. + /// + /// + /// + internal void SetCounter(Metric metric, long value) + { + if (!IsEnabled) return; + + lock(metricsLock) + { + Counters[metric] = value; + } + } + /// + /// Increments a specific metric counter. + /// If counter doesn't exist yet, it is set to 1. + /// + /// + internal void IncrementCounter(Metric metric) + { + if (!IsEnabled) return; + + lock(metricsLock) + { + long value; + if (!Counters.TryGetValue(metric, out value)) + { + value = 1; + } + else + { + value++; + } + Counters[metric] = value; + } + } + + /// + /// Returns errors associated with the metric, including + /// if there are still any timing events in-flight. + /// + /// + internal string GetErrors() + { + if (!IsEnabled) return null; + + using(StringWriter writer = new StringWriter(CultureInfo.InvariantCulture)) + { + lock(metricsLock) + { + if (inFlightTimings.Count > 0) + { + string inFlightTimingsValue = string.Join(", ", inFlightTimings.Keys.Select(k => k.ToString()).ToArray()); + writer.Write("Timings are still in flight: {0}.", inFlightTimingsValue); + } + if (errors.Count > 0) + { + writer.Write("Logged {0} metrics errors: ", errors.Count); + foreach (MetricError error in errors) + { + // skip empty errors + if (error.Exception == null && string.IsNullOrEmpty(error.Message)) + continue; + + writer.Write("{0} - {1} - ", + error.Time.ToString(AliyunSDKUtils.ISO8601DateFormat, CultureInfo.InvariantCulture), + error.Metric); + if (!string.IsNullOrEmpty(error.Message)) + { + writer.Write(error.Message); + writer.Write(";"); + } + if (error.Exception != null) + { + writer.Write(error.Exception); + writer.Write("; "); + } + } + } + } + + return writer.ToString(); + } + } + + #endregion + + #region Overrides + + /// + /// Returns a string representation of the current metrics. + /// + /// + public override string ToString() + { + if (!IsEnabled) + { + return "Metrics logging disabled"; + } + + StringBuilder builder = new StringBuilder(); + lock(metricsLock) + { + foreach (var kvp in Properties) + { + Metric metric = kvp.Key; + List values = kvp.Value; + Log(builder, metric, values); + } + foreach (var kvp in Timings) + { + Metric metric = kvp.Key; + List list = kvp.Value; + foreach (var timing in list) + { + if (timing.IsFinished) + Log(builder, metric, timing.ElapsedTime); + } + } + foreach (var kvp in Counters) + { + Metric metric = kvp.Key; + long value = kvp.Value; + Log(builder, metric, value); + } + } + builder.Replace("\r", "\\r").Replace("\n", "\\n"); + return builder.ToString(); + } + + #endregion + } + + // Set of predefined Metrics. + internal enum Metric + { + // response enums + ErrorCode, + RequestId, + BytesProcessed, + Exception, + RedirectLocation, + RequestMarshallTime, + ResponseProcessingTime, + ResponseUnmarshallTime, + ResponseReadTime, + StatusCode, + + // request enums + AttemptCount, + CredentialsRequestTime, + HttpRequestTime, + ProxyHost, + ProxyPort, + RequestSigningTime, + RetryPauseTime, + StringToSign, + CanonicalRequest, + + // overall enums + AsyncCall, + ClientExecuteTime, + MethodName, + ServiceEndpoint, + ServiceName, + RequestSize, + } + + /// + /// Timing information for a metric + /// + internal class Timing + { + private long startTime; + private long endTime; + + /// + /// Empty, stopped timing object + /// + public Timing() + { + startTime = endTime = 0; + IsFinished = true; + } + + /// + /// Timing object in a started state + /// + /// + public Timing(long currentTime) + { + startTime = currentTime; + IsFinished = false; + } + + /// + /// Stops timing + /// + /// + public void Stop(long currentTime) + { + endTime = currentTime; + IsFinished = true; + } + + /// + /// Whether the timing has been stopped + /// + public bool IsFinished { get; private set; } + + /// + /// Elapsed ticks from start to stop. + /// If timing hasn't been stopped yet, returns 0. + /// + public long ElapsedTicks { get { return !IsFinished ? 0 : endTime - startTime; } } + + /// + /// Elapsed time from start to stop. + /// If timing hasn't been stopped yet, returns TimeSpan.Zero + /// + public TimeSpan ElapsedTime { get { return TimeSpan.FromTicks(ElapsedTicks); } } + } + + /// + /// Timing event, stops timing of a metric when disposed + /// + internal class TimingEvent : IDisposable + { + private Metric metric; + private RequestMetrics metrics; + private bool disposed; + + internal TimingEvent(RequestMetrics metrics, Metric metric) + { + this.metrics = metrics; + this.metric = metric; + } + + #region Dispose Pattern Implementation + + /// + /// Implements the Dispose pattern + /// + /// Whether this object is being disposed via a call to Dispose + /// or garbage collected. + protected virtual void Dispose(bool disposing) + { + if (!this.disposed) + { + if (disposing) + { + metrics.StopEvent(metric); + } + this.disposed = true; + } + } + + /// + /// Disposes of all managed and unmanaged resources. + /// + public void Dispose() + { + this.Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// The destructor for the client class. + /// + ~TimingEvent() + { + this.Dispose(false); + } + + #endregion + } + + // Error encountered in metrics logging + internal class MetricError + { + public Metric Metric { get; private set; } + public string Message { get; private set; } + public Exception Exception { get; private set; } + public DateTime Time { get; private set; } + + public MetricError(Metric metric, string messageFormat, params object[] args) : this(metric, null, messageFormat, args) { } + public MetricError(Metric metric, Exception exception, string messageFormat, params object[] args) + { + Time = DateTime.UtcNow; + try + { + Message = string.Format(CultureInfo.InvariantCulture, messageFormat, args); + } + catch + { + Message = string.Format(CultureInfo.InvariantCulture, "Error message: {0}", messageFormat); + } + Exception = exception; + Metric = metric; + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/WebServiceRequest.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/WebServiceRequest.cs new file mode 100644 index 0000000000..16ba74b573 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Internal/WebServiceRequest.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections.Generic; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal +{ + public abstract partial class WebServiceRequest + { + readonly IDictionary _parameters = new Dictionary(StringComparer.Ordinal); + readonly IDictionary _headers = new Dictionary(StringComparer.OrdinalIgnoreCase); + private string _contentType; + private string _contentMD5; + + /// + /// Returns a dictionary of the headers included in this request. + /// + public IDictionary Headers + { + get + { + return this._headers; + } + } + + /// + /// Adds a new entry to the Headers collection for the request + /// + /// The name of the header + /// Value of the entry + public void AddHeader(string headerName, string value) + { + Headers.Add(headerName, value); + } + + /// + /// Returns a dictionary of the parameters included in this request. + /// + public IDictionary Parameters + { + get + { + return this._parameters; + } + } + + /// + /// Adds a new entry to the Parameters collection for the request + /// + /// The name of the parameter + /// Value of the entry + public void AddParameter(string paramName, string value) + { + Parameters.Add(paramName, value); + } + + /// + /// Returns the content type of the HTTP request. + /// + public string ContentType + { + get { return this._contentType; } + set { this._contentType = value; } + } + + public bool IsSetContentType() + { + return this._contentType != null; + } + + /// + /// Returns the content MD5 of the HTTP request. + /// + public string ContentMD5 + { + get { return this._contentMD5; } + set { this._contentMD5 = value; } + } + + public bool IsSetContentMD5() + { + return this._contentMD5 != null; + } + + private TimeSpan? _timeoutInternal; + + /// + /// Overrides the default request timeout value. + /// + internal TimeSpan? TimeoutInternal + { + get { return this._timeoutInternal; } + set + { + ClientConfig.ValidateTimeout(value); + this._timeoutInternal = value; + } + } + + private TimeSpan? _readWriteTimeoutInternal; + + /// + /// Overrides the default read-write timeout value. + /// + internal TimeSpan? ReadWriteTimeoutInternal + { + get { return this._readWriteTimeoutInternal; } + set + { + ClientConfig.ValidateTimeout(value); + this._readWriteTimeoutInternal = value; + } + } + + /// + /// Gets or Sets a value indicating if "Expect: 100-continue" HTTP header will be + /// sent by the client for this request. The default value is true. + /// + internal virtual bool Expect100Continue + { + get { return true; } + } + + /// + /// Gets or Sets a value indicating if "KeepAlive" HTTP header will be + /// sent by the client for this request. The default value is true. + /// + internal virtual bool KeepAlive + { + get { return true; } + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/Contexts.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/Contexts.cs new file mode 100644 index 0000000000..7fb61e0209 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/Contexts.cs @@ -0,0 +1,151 @@ +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Auth; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Transform; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Util; +using System; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline +{ + public interface IRequestContext + { + WebServiceRequest OriginalRequest { get; } + string RequestName { get; } + IMarshaller Marshaller { get; } + ResponseUnmarshaller Unmarshaller { get; } + RequestMetrics Metrics { get; } + IServiceSigner Signer { get; } + ClientConfig ClientConfig { get; } + ImmutableCredentials ImmutableCredentials { get; set; } + + IRequest Request { get; set; } + bool IsSigned { get; set; } + bool IsAsync { get; } + int Retries { get; set; } + } + + public interface IResponseContext + { + WebServiceResponse Response { get; set; } + IWebResponseData HttpResponse { get; set; } + } + + public interface IAsyncRequestContext : IRequestContext + { + AsyncCallback Callback { get; } + object State { get; } + } + + public interface IAsyncResponseContext : IResponseContext + { + RuntimeAsyncResult AsyncResult { get; set; } + } + + public interface IExecutionContext + { + IResponseContext ResponseContext { get; } + IRequestContext RequestContext { get; } + } + + public interface IAsyncExecutionContext + { + IAsyncResponseContext ResponseContext { get; } + IAsyncRequestContext RequestContext { get; } + + object RuntimeState { get; set; } + } +} + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal +{ + public class RequestContext : IRequestContext + { + public RequestContext() + { + this.Metrics = new RequestMetrics(); + } + + public IRequest Request { get; set; } + public RequestMetrics Metrics { get; private set; } + public IServiceSigner Signer { get; set; } + public ClientConfig ClientConfig { get; set; } + public int Retries { get; set; } + public bool IsSigned { get; set; } + public bool IsAsync { get; set; } + public WebServiceRequest OriginalRequest { get; set; } + public IMarshaller Marshaller { get; set; } + public ResponseUnmarshaller Unmarshaller { get; set; } + public ImmutableCredentials ImmutableCredentials { get; set; } + + public string RequestName + { + get { return this.OriginalRequest.GetType().Name; } + } + } + + public class AsyncRequestContext : RequestContext, IAsyncRequestContext + { + public AsyncRequestContext(): + base() + { + } + + public AsyncCallback Callback { get; set; } + public object State { get; set; } + } + + public class ResponseContext : IResponseContext + { + public WebServiceResponse Response { get; set; } + public IWebResponseData HttpResponse { get; set; } + } + + public class AsyncResponseContext : ResponseContext, IAsyncResponseContext + { + public RuntimeAsyncResult AsyncResult { get; set; } + } + + public class ExecutionContext : IExecutionContext + { + public IRequestContext RequestContext { get; private set; } + public IResponseContext ResponseContext { get; private set; } + + public ExecutionContext() + { + this.RequestContext = new RequestContext(); + this.ResponseContext = new ResponseContext(); + } + + public ExecutionContext(IRequestContext requestContext, IResponseContext responseContext) + { + this.RequestContext = requestContext; + this.ResponseContext = responseContext; + } + + public static IExecutionContext CreateFromAsyncContext(IAsyncExecutionContext asyncContext) + { + return new ExecutionContext(asyncContext.RequestContext, + asyncContext.ResponseContext); + } + } + + public class AsyncExecutionContext : IAsyncExecutionContext + { + public IAsyncResponseContext ResponseContext { get; private set; } + public IAsyncRequestContext RequestContext { get; private set; } + + public object RuntimeState { get; set; } + + public AsyncExecutionContext() + { + this.RequestContext = new AsyncRequestContext(); + this.ResponseContext = new AsyncResponseContext(); + } + + public AsyncExecutionContext(IAsyncRequestContext requestContext, IAsyncResponseContext responseContext) + { + this.RequestContext = requestContext; + this.ResponseContext = responseContext; + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/ErrorHandler/ErrorHandler.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/ErrorHandler/ErrorHandler.cs new file mode 100644 index 0000000000..89ffbe90f0 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/ErrorHandler/ErrorHandler.cs @@ -0,0 +1,148 @@ +using System; +using System.Collections.Generic; +using System.Net; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Util; +using Aliyun.Acs.Dybaseapi.MNS.Util; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline.ErrorHandler +{ + /// + /// This handler processes exceptions thrown from the HTTP handler and + /// unmarshalls error responses. + /// + public class ErrorHandler : PipelineHandler + { + /// + /// Default set of exception handlers. + /// + private IDictionary _exceptionHandlers; + + /// + /// Default set of exception handlers. + /// + public IDictionary ExceptionHandlers + { + get + { + return _exceptionHandlers; + } + } + + /// + /// Constructor for ErrorHandler. + /// + public ErrorHandler() + { + _exceptionHandlers = new Dictionary + { + {typeof(WebException), new WebExceptionHandler()}, + {typeof(HttpErrorResponseException), new HttpErrorResponseExceptionHandler()} + }; + } + + /// + /// Handles and processes any exception thrown from underlying handlers. + /// + /// The execution context which contains both the + /// requests and response context. + public override void InvokeSync(IExecutionContext executionContext) + { + try + { + base.InvokeSync(executionContext); + return; + } + catch (Exception exception) + { + DisposeReponse(executionContext.ResponseContext); + bool rethrowOriginalException = ProcessException(executionContext, exception); + if (rethrowOriginalException) + { + throw; + } + } + } + + /// + /// Unmarshalls the response returned by the HttpHandler. + /// + /// The execution context, it contains the + /// request and response context. + protected override void InvokeAsyncCallback(IAsyncExecutionContext executionContext) + { + // Unmarshall the response if an exception hasn't occured + var exception = executionContext.ResponseContext.AsyncResult.Exception; + if (exception != null) + { + DisposeReponse(executionContext.ResponseContext); + try + { + bool rethrowOriginalException = ProcessException(ExecutionContext.CreateFromAsyncContext(executionContext), + exception); + if (rethrowOriginalException) + { + executionContext.ResponseContext.AsyncResult.Exception = exception; + } + } + catch (Exception ex) + { + executionContext.ResponseContext.AsyncResult.Exception = ex; + } + } + base.InvokeAsyncCallback(executionContext); + } + + /// + /// Disposes the response body. + /// + /// The response context. + private static void DisposeReponse(IResponseContext responseContext) + { + if (responseContext.HttpResponse != null && + responseContext.HttpResponse.ResponseBody != null) + { + responseContext.HttpResponse.ResponseBody.Dispose(); + } + } + + /// + /// Processes an exception by invoking a matching exception handler + /// for the given exception. + /// + /// The execution context, it contains the + /// request and response context. + /// The exception to be processed. + /// + /// This method returns a boolean value which indicates if the original exception + /// should be rethrown. + /// This method can also throw a new exception that may be thrown by exception + /// processing by a matching exception handler. + /// + private bool ProcessException(IExecutionContext executionContext, Exception exception) + { + executionContext.RequestContext.Metrics.AddProperty(Metric.Exception, exception); + + // Find the matching handler which can process the exception + // Start by checking if there is a matching handler for the specific exception type, + // if not check for handlers for it's base type till we find a match. + var exceptionType = exception.GetType(); + var exceptionTypeInfo = TypeFactory.GetTypeInfo(exception.GetType()); + do + { + IExceptionHandler exceptionHandler = null; + + if (this.ExceptionHandlers.TryGetValue(exceptionType, out exceptionHandler)) + { + return exceptionHandler.Handle(executionContext, exception); + } + exceptionType = exceptionTypeInfo.BaseType; + exceptionTypeInfo = TypeFactory.GetTypeInfo(exceptionTypeInfo.BaseType); + + }while(exceptionType != typeof(Exception)); + + // No match found, rethrow the original exception. + return true; + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/ErrorHandler/ExceptionHandler.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/ErrorHandler/ExceptionHandler.cs new file mode 100644 index 0000000000..4cb3005dbc --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/ErrorHandler/ExceptionHandler.cs @@ -0,0 +1,30 @@ +/* + * Copyright (C) Alibaba Cloud Computing + * All rights reserved. + * + * + */ + +using System; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Util; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline.ErrorHandler +{ + /// + /// The abstract base class for exception handlers. + /// + /// The exception type. + public abstract class ExceptionHandler : IExceptionHandler where T : Exception + { + protected ExceptionHandler() + { + } + + public bool Handle(IExecutionContext executionContext, Exception exception) + { + return HandleException(executionContext, exception as T); + } + + public abstract bool HandleException(IExecutionContext executionContext, T exception); + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/ErrorHandler/HttpErrorResponseExceptionHandler.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/ErrorHandler/HttpErrorResponseExceptionHandler.cs new file mode 100644 index 0000000000..47db833eca --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/ErrorHandler/HttpErrorResponseExceptionHandler.cs @@ -0,0 +1,142 @@ +using System; +using System.Diagnostics; +using System.Net; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Transform; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Util; +using Aliyun.Acs.Dybaseapi.MNS.Util; +using System.IO; +using System.Text; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline.ErrorHandler +{ + /// + /// The exception handler for HttpErrorResponseException exception. + /// + public class HttpErrorResponseExceptionHandler : ExceptionHandler + { + /// + /// The constructor for HttpErrorResponseExceptionHandler. + /// + public HttpErrorResponseExceptionHandler() : + base() + { + } + + /// + /// Handles an exception for the given execution context. + /// + /// The execution context, it contains the + /// request and response context. + /// The exception to handle. + /// + /// Returns a boolean value which indicates if the original exception + /// should be rethrown. + /// This method can also throw a new exception to replace the original exception. + /// + public override bool HandleException(IExecutionContext executionContext, HttpErrorResponseException exception) + { + var requestContext = executionContext.RequestContext; + var httpErrorResponse = exception.Response; + + // If 404 was suppressed and successfully unmarshalled, + // don't rethrow the original exception. + if (HandleSuppressed404(executionContext, httpErrorResponse)) + return false; + + requestContext.Metrics.AddProperty(Metric.StatusCode, httpErrorResponse.StatusCode); + + AliyunServiceException errorResponseException = null; + // Unmarshall the service error response and throw the corresponding service exception + string responseContent = null; + try + { + using (httpErrorResponse.ResponseBody) + { + var unmarshaller = requestContext.Unmarshaller; + + var errorContext = unmarshaller.CreateContext(httpErrorResponse, + httpErrorResponse.ResponseBody.OpenResponse(), + requestContext.Metrics); + + using (MemoryStream stream = new MemoryStream()) + { + AliyunSDKUtils.CopyTo(errorContext.ResponseStream, stream); + stream.Seek(0, SeekOrigin.Begin); + byte[] bytes = new byte[stream.Length]; + stream.Read(bytes, 0, (int)stream.Length); + responseContent = Encoding.UTF8.GetString(bytes); + stream.Seek(0, SeekOrigin.Begin); + + errorContext.ResponseStream = stream; + + errorResponseException = unmarshaller.UnmarshallException(errorContext, + exception, httpErrorResponse.StatusCode); + Debug.Assert(errorResponseException != null); + + requestContext.Metrics.AddProperty(Metric.RequestId, errorResponseException.RequestId); + requestContext.Metrics.AddProperty(Metric.ErrorCode, errorResponseException.ErrorCode); + } + } + } + catch (ResponseUnmarshallException unmarshallException) + { + if (responseContent != null) + { + throw new AliyunServiceException(responseContent, unmarshallException, + MNSErrorCode.InternalError, + null, null, httpErrorResponse.StatusCode); + } + throw; + } + + throw errorResponseException; + } + + /// + /// Checks if a HTTP 404 status code is returned which needs to be suppressed and + /// processes it. + /// If a suppressed 404 is present, it unmarshalls the response and returns true to + /// indicate that a suppressed 404 was processed, else returns false. + /// + /// The execution context, it contains the + /// request and response context. + /// + /// + /// If a suppressed 404 is present, returns true, else returns false. + /// + private bool HandleSuppressed404(IExecutionContext executionContext, IWebResponseData httpErrorResponse) + { + var requestContext = executionContext.RequestContext; + var responseContext = executionContext.ResponseContext; + + // If the error is a 404 and the request is configured to supress it, + // then unmarshall as much as we can. + if (httpErrorResponse != null && + httpErrorResponse.StatusCode == HttpStatusCode.NotFound && + requestContext.Request.Suppress404Exceptions) + { + using (httpErrorResponse.ResponseBody) + { + var unmarshaller = requestContext.Unmarshaller; + + UnmarshallerContext errorContext = unmarshaller.CreateContext( + httpErrorResponse, + httpErrorResponse.ResponseBody.OpenResponse(), + requestContext.Metrics); + try + { + responseContext.Response = unmarshaller.Unmarshall(errorContext); + responseContext.Response.ContentLength = httpErrorResponse.ContentLength; + responseContext.Response.HttpStatusCode = httpErrorResponse.StatusCode; + return true; + } + catch (Exception) + { + return false; + } + } + } + return false; + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/ErrorHandler/IExceptionHandler.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/ErrorHandler/IExceptionHandler.cs new file mode 100644 index 0000000000..cf7bba2139 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/ErrorHandler/IExceptionHandler.cs @@ -0,0 +1,43 @@ +using System; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline.ErrorHandler +{ + /// + /// The interface for an exception handler. + /// + public interface IExceptionHandler + { + /// + /// Handles an exception for the given execution context. + /// + /// The execution context, it contains the + /// request and response context. + /// The exception to handle. + /// + /// Returns a boolean value which indicates if the original exception + /// should be rethrown. + /// This method can also throw a new exception to replace the original exception. + /// + bool Handle(IExecutionContext executionContext, Exception exception); + } + + /// + /// The interface for an exception handler with a generic parameter for the exception type. + /// + /// The exception type. + public interface IExceptionHandler : IExceptionHandler where T : Exception + { + /// + /// Handles an exception for the given execution context. + /// + /// The execution context, it contains the + /// request and response context. + /// The exception to handle. + /// + /// Returns a boolean value which indicates if the original exception + /// should be rethrown. + /// This method can also throw a new exception to replace the original exception. + /// + bool HandleException(IExecutionContext executionContext, T exception); + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/ErrorHandler/WebExceptionHandler.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/ErrorHandler/WebExceptionHandler.cs new file mode 100644 index 0000000000..c837a75f12 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/ErrorHandler/WebExceptionHandler.cs @@ -0,0 +1,30 @@ +using System.Globalization; +using System.Net; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Util; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline.ErrorHandler +{ + /// + /// The exception handler for HttpErrorResponseException exception. + /// + public class WebExceptionHandler : ExceptionHandler + { + public WebExceptionHandler() : + base() + { + } + + public override bool HandleException(IExecutionContext executionContext, WebException exception) + { + var requestContext = executionContext.RequestContext; + var httpErrorResponse = exception.Response as HttpWebResponse; + + if (httpErrorResponse != null) + requestContext.Metrics.AddProperty(Metric.StatusCode, httpErrorResponse.StatusCode); + + var message = string.Format(CultureInfo.InvariantCulture, + "A WebException with status {0} was thrown, caused by {1}", exception.Status, exception.Message); + throw new AliyunServiceException(message, exception); + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/Handlers/CredentialsRetriever.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/Handlers/CredentialsRetriever.cs new file mode 100644 index 0000000000..85ed585edb --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/Handlers/CredentialsRetriever.cs @@ -0,0 +1,49 @@ +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Util; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline.Handlers +{ + /// + /// This handler retrieved the Service credentials to be used for the current call. + /// + public class CredentialsRetriever : GenericHandler + { + /// + /// The constructor for CredentialsRetriever. + /// + /// An Service Credentials instance. + public CredentialsRetriever(ServiceCredentials credentials) + { + this.Credentials = credentials; + } + + protected ServiceCredentials Credentials + { + get; + private set; + } + + /// + /// Retrieves the credentials to be used for the current call before + /// invoking the next handler. + /// + /// + protected override void PreInvoke(IExecutionContext executionContext) + { + ImmutableCredentials ic = null; + if (Credentials != null && (Credentials is BasicServiceCredentials)) + { + try + { + executionContext.RequestContext.Metrics.StartEvent(Metric.CredentialsRequestTime); + ic = Credentials.GetCredentials(); + } + finally + { + executionContext.RequestContext.Metrics.StopEvent(Metric.CredentialsRequestTime); + } + } + + executionContext.RequestContext.ImmutableCredentials = ic; + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/Handlers/GenericHandler.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/Handlers/GenericHandler.cs new file mode 100644 index 0000000000..4edc9d61b9 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/Handlers/GenericHandler.cs @@ -0,0 +1,63 @@ +using System; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline.Handlers +{ + /// + /// A generic handler that provides overridable PreInvoke and PostInvoke methods. + /// This class is intended be used as a base class for handlers which perform simple processing. + /// + public abstract class GenericHandler : PipelineHandler + { + /// + /// Calls the PreInvoke and PostInvoke methods before and after calling the next handler + /// in the pipeline. + /// + /// The execution context which contains both the + /// requests and response context. + public override void InvokeSync(IExecutionContext executionContext) + { + PreInvoke(executionContext); + base.InvokeSync(executionContext); + PostInvoke(executionContext); + } + + /// + /// Calls the PreInvoke method before calling the next handler in the pipeline. + /// + /// The execution context which contains both the + /// requests and response context. + /// IAsyncResult which represent an async operation. + public override IAsyncResult InvokeAsync(IAsyncExecutionContext executionContext) + { + PreInvoke(ExecutionContext.CreateFromAsyncContext(executionContext)); + return base.InvokeAsync(executionContext); + } + + /// + /// Calls the PostInvoke methods after calling the next handler + /// in the pipeline. + /// + /// The execution context, it contains the + /// request and response context. + protected override void InvokeAsyncCallback(IAsyncExecutionContext executionContext) + { + PostInvoke(ExecutionContext.CreateFromAsyncContext(executionContext)); + base.InvokeAsyncCallback(executionContext); + } + + /// + /// This method is invoked before calling the next handler in the pipeline. + /// + /// The execution context, it contains the + /// request and response context. + protected virtual void PreInvoke(IExecutionContext executionContext) { } + + /// + /// This method is invoked after calling the next handler in the pipeline. + /// + /// The execution context, it contains the + /// request and response context. + protected virtual void PostInvoke(IExecutionContext executionContext) { } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/Handlers/Marshaller.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/Handlers/Marshaller.cs new file mode 100644 index 0000000000..b7d4592168 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/Handlers/Marshaller.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal; +using Aliyun.Acs.Dybaseapi.MNS.Util; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Util; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline.Handlers +{ + /// + /// This handler marshalls the request before calling invoking the next handler. + /// + public class Marshaller : GenericHandler + { + /// + /// Marshalls the request before calling invoking the next handler. + /// + /// The execution context, it contains the + /// request and response context. + protected override void PreInvoke(IExecutionContext executionContext) + { + try + { + executionContext.RequestContext.Metrics.StartEvent(Metric.RequestMarshallTime); + + IRequestContext requestContext = executionContext.RequestContext; + requestContext.Request = requestContext.Marshaller.Marshall(requestContext.OriginalRequest); + requestContext.Request.Endpoint = requestContext.ClientConfig.RegionEndpoint; + AddRequiredHeaders(requestContext); + AddOptionalHeaders(requestContext); + } + finally + { + executionContext.RequestContext.Metrics.StopEvent(Metric.RequestMarshallTime); + } + } + + private void AddRequiredHeaders(IRequestContext requestContext) + { + IDictionary headers = requestContext.Request.Headers; + headers[HttpHeader.UserAgentHeader] = requestContext.ClientConfig.UserAgent; + if (requestContext.Request.ContentStream != null) + headers[HttpHeader.ContentLengthHeader] = requestContext.Request.ContentStream.Length.ToString(CultureInfo.InvariantCulture); + headers[HttpHeader.DateHeader] = AliyunSDKUtils.FormattedCurrentTimestampRFC822; + headers[HttpHeader.XMnsVersionHeader] = requestContext.ClientConfig.ServiceVersion; + if (!headers.ContainsKey(HttpHeader.HostHeader)) + { + Uri requestEndpoint = requestContext.Request.Endpoint; + var hostHeader = requestEndpoint.Host; + if (!requestEndpoint.IsDefaultPort) + hostHeader += ":" + requestEndpoint.Port; + headers.Add(HttpHeader.HostHeader, hostHeader); + } + } + + private void AddOptionalHeaders(IRequestContext requestContext) + { + WebServiceRequest originalRequest = requestContext.Request.OriginalRequest; + IDictionary headers = requestContext.Request.Headers; + if (originalRequest.IsSetContentType()) + headers[HttpHeader.ContentTypeHeader] = originalRequest.ContentType; + else + headers[HttpHeader.ContentTypeHeader] = MNSConstants.ContentTypeTextXml; + if (originalRequest.IsSetContentMD5()) + headers[HttpHeader.ContentMD5Header] = originalRequest.ContentMD5; + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/Handlers/MetricsHandler.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/Handlers/MetricsHandler.cs new file mode 100644 index 0000000000..748a245b31 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/Handlers/MetricsHandler.cs @@ -0,0 +1,57 @@ +using System; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Util; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline.Handlers +{ + /// + /// This handler manages the metrics used to time the complete call and + /// logs the final metrics. + /// + public class MetricsHandler : PipelineHandler + { + /// + /// Captures the overall execution time and logs final metrics. + /// + /// The execution context which contains both the + /// requests and response context. + public override void InvokeSync(IExecutionContext executionContext) + { + executionContext.RequestContext.Metrics.AddProperty(Metric.AsyncCall, false); + try + { + executionContext.RequestContext.Metrics.StartEvent(Metric.ClientExecuteTime); + base.InvokeSync(executionContext); + } + finally + { + executionContext.RequestContext.Metrics.StopEvent(Metric.ClientExecuteTime); + } + } + + /// + /// Captures the overall execution time. + /// + /// The execution context which contains both the + /// requests and response context. + /// IAsyncResult which represent an async operation. + public override IAsyncResult InvokeAsync(IAsyncExecutionContext executionContext) + { + executionContext.RequestContext.Metrics.AddProperty(Metric.AsyncCall, true); + executionContext.RequestContext.Metrics.StartEvent(Metric.ClientExecuteTime); + return base.InvokeAsync(executionContext); + } + + /// + /// Captures the overall execution time and logs final metrics. + /// + /// The execution context, it contains the + /// request and response context. + protected override void InvokeAsyncCallback(IAsyncExecutionContext executionContext) + { + executionContext.RequestContext.Metrics.StopEvent(Metric.ClientExecuteTime); + base.InvokeAsyncCallback(executionContext); + } + + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/Handlers/Signer.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/Handlers/Signer.cs new file mode 100644 index 0000000000..c9ca71e034 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/Handlers/Signer.cs @@ -0,0 +1,59 @@ +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Util; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline.Handlers +{ + /// + /// This handler for signing MNS request. + /// + public class Signer : GenericHandler + { + /// + /// Signs the request before invoking the next handler. + /// + /// + /// The execution context, it contains the request and response context. + /// + protected override void PreInvoke(IExecutionContext executionContext) + { + if (ShouldSign(executionContext.RequestContext)) + { + SignRequest(executionContext.RequestContext); + executionContext.RequestContext.IsSigned = true; + } + } + + /// + /// Determines if the request should be signed. + /// + /// The request context. + /// A boolean value that indicated if the request should be signed. + private static bool ShouldSign(IRequestContext requestContext) + { + return !requestContext.IsSigned || + requestContext.ClientConfig.ResignRetries; + } + + /// + /// Signs the request. + /// + /// The request context. + internal static void SignRequest(IRequestContext requestContext) + { + ImmutableCredentials immutableCredentials = requestContext.ImmutableCredentials; + + if (immutableCredentials == null) + return; + + try + { + requestContext.Metrics.StartEvent(Metric.RequestSigningTime); + requestContext.Signer.Sign(requestContext.Request, requestContext.Metrics, + immutableCredentials.AccessKey, immutableCredentials.SecretKey, immutableCredentials.SecurityToken); + } + finally + { + requestContext.Metrics.StopEvent(Metric.RequestSigningTime); + } + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/Handlers/Unmarshaller.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/Handlers/Unmarshaller.cs new file mode 100644 index 0000000000..e956738b25 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/Handlers/Unmarshaller.cs @@ -0,0 +1,100 @@ +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Transform; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Util; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline.Handlers +{ + /// + /// This handler unmarshalls the HTTP response. + /// + public class Unmarshaller : PipelineHandler + { + /// + /// Unmarshalls the response returned by the HttpHandler. + /// + /// The execution context which contains both the + /// requests and response context. + public override void InvokeSync(IExecutionContext executionContext) + { + base.InvokeSync(executionContext); + + if (executionContext.ResponseContext.HttpResponse.IsSuccessStatusCode) + { + // Unmarshall the http response. + Unmarshall(executionContext); + } + } + + /// + /// Unmarshalls the response returned by the HttpHandler. + /// + /// The execution context, it contains the + /// request and response context. + protected override void InvokeAsyncCallback(IAsyncExecutionContext executionContext) + { + // Unmarshall the response if an exception hasn't occured + if (executionContext.ResponseContext.AsyncResult.Exception == null) + { + Unmarshall(ExecutionContext.CreateFromAsyncContext(executionContext)); + } + base.InvokeAsyncCallback(executionContext); + } + + /// + /// Unmarshalls the HTTP response. + /// + /// + /// The execution context, it contains the request and response context. + /// + private void Unmarshall(IExecutionContext executionContext) + { + var requestContext = executionContext.RequestContext; + var responseContext = executionContext.ResponseContext; + + try + { + var unmarshaller = requestContext.Unmarshaller; + try + { + requestContext.Metrics.StartEvent(Metric.ResponseProcessingTime); + var context = unmarshaller.CreateContext(responseContext.HttpResponse, + responseContext.HttpResponse.ResponseBody.OpenResponse(), + requestContext.Metrics); + + var response = UnmarshallResponse(context, requestContext); + responseContext.Response = response; + } + finally + { + if (!unmarshaller.HasStreamingProperty) + responseContext.HttpResponse.ResponseBody.Dispose(); + } + } + finally + { + requestContext.Metrics.StopEvent(Metric.ResponseProcessingTime); + } + } + + private WebServiceResponse UnmarshallResponse(UnmarshallerContext context, + IRequestContext requestContext) + { + var unmarshaller = requestContext.Unmarshaller; + WebServiceResponse response = null; + try + { + requestContext.Metrics.StartEvent(Metric.ResponseUnmarshallTime); + response = unmarshaller.UnmarshallResponse(context); + } + finally + { + requestContext.Metrics.StopEvent(Metric.ResponseUnmarshallTime); + } + + requestContext.Metrics.AddProperty(Metric.StatusCode, response.HttpStatusCode); + requestContext.Metrics.AddProperty(Metric.BytesProcessed, response.ContentLength); + + return response; + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/HttpErrorResponseException.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/HttpErrorResponseException.cs new file mode 100644 index 0000000000..e088558907 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/HttpErrorResponseException.cs @@ -0,0 +1,33 @@ +using System; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Transform; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline +{ + /// + /// HttpErrorResponseException + /// + public class HttpErrorResponseException : Exception + { + /// + /// Gets and sets original response data. + /// + public IWebResponseData Response { get; private set; } + + public HttpErrorResponseException(IWebResponseData response) + { + this.Response = response; + } + + public HttpErrorResponseException(string message, IWebResponseData response) + : base(message) + { + this.Response = response; + } + + public HttpErrorResponseException(string message, Exception innerException, IWebResponseData response) + : base(message,innerException) + { + this.Response = response; + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/HttpHandler/HttpHandler.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/HttpHandler/HttpHandler.cs new file mode 100644 index 0000000000..f2a556a8ff --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/HttpHandler/HttpHandler.cs @@ -0,0 +1,286 @@ +using System; +using System.Globalization; +using System.Text; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Util; +using Aliyun.Acs.Dybaseapi.MNS.Util; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline.HttpHandler +{ + /// + /// The HTTP handler contains common logic for issuing an HTTP request that is + /// independent of the underlying HTTP infrastructure. + /// + /// + public class HttpHandler : PipelineHandler, IDisposable + { + private bool _disposed; + private IHttpRequestFactory _requestFactory; + + /// + /// The sender parameter used in any events raised by this handler. + /// + public object CallbackSender { get; private set; } + + /// + /// The constructor for HttpHandler. + /// + /// The request factory used to create HTTP Requests. + /// The sender parameter used in any events raised by this handler. + public HttpHandler(IHttpRequestFactory requestFactory, object callbackSender) + { + _requestFactory = requestFactory; + this.CallbackSender = callbackSender; + } + + /// + /// Issues an HTTP request for the current request context. + /// + /// The execution context which contains both the + /// requests and response context. + public override void InvokeSync(IExecutionContext executionContext) + { + IHttpRequest httpRequest = null; + try + { + SetMetrics(executionContext.RequestContext); + IRequest wrappedRequest = executionContext.RequestContext.Request; + httpRequest = CreateWebRequest(executionContext.RequestContext); + httpRequest.SetRequestHeaders(wrappedRequest.Headers); + + try + { + executionContext.RequestContext.Metrics.StartEvent(Metric.HttpRequestTime); + // Send request body if present. + if (wrappedRequest.HasRequestBody()) + { + var requestContent = httpRequest.GetRequestContent(); + WriteContentToRequestBody(requestContent, httpRequest, executionContext.RequestContext); + } + + executionContext.ResponseContext.HttpResponse = httpRequest.GetResponse(); + } + finally + { + executionContext.RequestContext.Metrics.StopEvent(Metric.HttpRequestTime); + } + } + finally + { + if (httpRequest != null) + httpRequest.Dispose(); + } + } + + /// + /// Issues an HTTP request for the current request context. + /// + /// The execution context which contains both the + /// requests and response context. + /// IAsyncResult which represent an async operation. + public override IAsyncResult InvokeAsync(IAsyncExecutionContext executionContext) + { + IHttpRequest httpRequest = null; + try + { + SetMetrics(executionContext.RequestContext); + httpRequest = CreateWebRequest(executionContext.RequestContext); + executionContext.RuntimeState = httpRequest; + + IRequest wrappedRequest = executionContext.RequestContext.Request; + if (executionContext.RequestContext.Retries == 0) + { + // First call, initialize an async result. + executionContext.ResponseContext.AsyncResult = + new RuntimeAsyncResult(executionContext.RequestContext.Callback, + executionContext.RequestContext.State); + } + + // Set request headers + httpRequest.SetRequestHeaders(executionContext.RequestContext.Request.Headers); + + executionContext.RequestContext.Metrics.StartEvent(Metric.HttpRequestTime); + if (wrappedRequest.HasRequestBody()) + { + // Send request body if present. + httpRequest.BeginGetRequestContent(new AsyncCallback(GetRequestStreamCallback), executionContext); + } + else + { + // Get response if there is no response body to send. + httpRequest.BeginGetResponse(new AsyncCallback(GetResponseCallback), executionContext); + } + return executionContext.ResponseContext.AsyncResult; + } + catch (Exception) + { + if (executionContext.ResponseContext.AsyncResult != null) + { + // An exception will be thrown back to the calling code. + // Dispose AsyncResult as it will not be used further. + executionContext.ResponseContext.AsyncResult.Dispose(); + executionContext.ResponseContext.AsyncResult = null; + } + + if (httpRequest != null) + { + httpRequest.Dispose(); + } + + throw; + } + } + + private void GetRequestStreamCallback(IAsyncResult result) + { + IAsyncExecutionContext executionContext = null; + IHttpRequest httpRequest = null; + try + { + executionContext = result.AsyncState as IAsyncExecutionContext; + httpRequest = executionContext.RuntimeState as IHttpRequest; + + var requestContent = httpRequest.EndGetRequestContent(result); + WriteContentToRequestBody(requestContent, httpRequest, executionContext.RequestContext); + //var requestStream = httpRequest.EndSetRequestBody(result); + httpRequest.BeginGetResponse(new AsyncCallback(GetResponseCallback), executionContext); + } + catch(Exception exception) + { + httpRequest.Dispose(); + + // Capture the exception and invoke outer handlers to + // process the exception. + executionContext.ResponseContext.AsyncResult.Exception = exception; + base.InvokeAsyncCallback(executionContext); + } + } + + private void GetResponseCallback(IAsyncResult result) + { + IAsyncExecutionContext executionContext = null; + IHttpRequest httpRequest = null; + try + { + executionContext = result.AsyncState as IAsyncExecutionContext; + httpRequest = executionContext.RuntimeState as IHttpRequest; + + var httpResponse = httpRequest.EndGetResponse(result); + executionContext.ResponseContext.HttpResponse = httpResponse; + } + catch (Exception exception) + { + // Capture the exception and invoke outer handlers to + // process the exception. + executionContext.ResponseContext.AsyncResult.Exception = exception; + } + finally + { + executionContext.RequestContext.Metrics.StopEvent(Metric.HttpRequestTime); + httpRequest.Dispose(); + base.InvokeAsyncCallback(executionContext); + } + } + + private static void SetMetrics(IRequestContext requestContext) + { + requestContext.Metrics.AddProperty(Metric.ServiceName, requestContext.Request.ServiceName); + requestContext.Metrics.AddProperty(Metric.ServiceEndpoint, requestContext.Request.Endpoint); + requestContext.Metrics.AddProperty(Metric.MethodName, requestContext.Request.RequestName); + } + + /// + /// Determines the content for request body and uses the HTTP request + /// to write the content to the HTTP request body. + /// + /// Content to be written. + /// The HTTP request. + /// The request context. + private void WriteContentToRequestBody(TRequestContent requestContent, + IHttpRequest httpRequest, + IRequestContext requestContext) + { + IRequest wrappedRequest = requestContext.Request; + + if (wrappedRequest.ContentStream == null) + { + byte[] requestData = wrappedRequest.Content; + requestContext.Metrics.AddProperty(Metric.RequestSize, requestData.Length); + httpRequest.WriteToRequestBody(requestContent, requestData, requestContext.Request.Headers); + } + else + { + var originalStream = wrappedRequest.ContentStream; + httpRequest.WriteToRequestBody(requestContent, originalStream, + requestContext.Request.Headers, requestContext); + + } + } + + /// + /// Creates the HttpWebRequest and configures the end point, content, user agent and proxy settings. + /// + /// The async request. + /// The web request that actually makes the call. + protected virtual IHttpRequest CreateWebRequest(IRequestContext requestContext) + { + IRequest request = requestContext.Request; + Uri url = AliyunServiceClient.ComposeUrl(request); + var httpRequest = _requestFactory.CreateHttpRequest(url); + httpRequest.ConfigureRequest(requestContext); + + httpRequest.Method = request.HttpMethod; + if (request.MayContainRequestBody()) + { + if (request.Content == null && (request.ContentStream == null)) + { + string queryString = AliyunSDKUtils.GetParametersAsString(request.Parameters); + request.Content = Encoding.UTF8.GetBytes(queryString); + } + + if (request.Content!=null) + { + request.Headers[HttpHeader.ContentLengthHeader] = + request.Content.Length.ToString(CultureInfo.InvariantCulture); + } + else if (request.ContentStream != null && !request.Headers.ContainsKey(HttpHeader.ContentLengthHeader)) + { + request.Headers[HttpHeader.ContentLengthHeader] = + request.ContentStream.Length.ToString(CultureInfo.InvariantCulture); + } + } + else if (request.UseQueryString && + (request.HttpMethod == "POST" || + request.HttpMethod == "PUT" || + request.HttpMethod == "DELETE")) + { + request.Content = new Byte[0]; + } + + return httpRequest; + } + + /// + /// Disposes the HTTP handler. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (_disposed) + return; + + if (disposing) + { + if (_requestFactory != null) + _requestFactory.Dispose(); + + _disposed = true; + } + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/HttpHandler/HttpWebRequestFactory.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/HttpHandler/HttpWebRequestFactory.cs new file mode 100644 index 0000000000..6481f90a4d --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/HttpHandler/HttpWebRequestFactory.cs @@ -0,0 +1,364 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Net; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Transform; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Util; +using Aliyun.Acs.Dybaseapi.MNS.Util; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline.HttpHandler +{ + /// + /// The request factory for System.Net.HttpWebRequest. + /// + public class HttpWebRequestFactory : IHttpRequestFactory + { + /// + /// Creates an HTTP request for the given URI. + /// + /// The request URI. + /// An HTTP request. + public IHttpRequest CreateHttpRequest(Uri requestUri) + { + return new HttpRequest(requestUri); + } + + /// + /// Disposes the HttpWebRequestFactory. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + } + } + + /// + /// HTTP request wrapper for System.Net.HttpWebRequest. + /// + public class HttpRequest : IHttpRequest + { + private bool _isAborted = false; + private HttpWebRequest _request; + + /// + /// Constructor for HttpRequest. + /// + /// The request URI. + public HttpRequest(Uri requestUri) + { + _request = WebRequest.Create(requestUri) as HttpWebRequest; + } + + /// + /// The underlying HTTP web request. + /// + public HttpWebRequest Request + { + get { return _request; } + } + + /// + /// The HTTP method or verb. + /// + public string Method + { + get { return _request.Method; } + set { _request.Method = value; } + } + + /// + /// The request URI. + /// + public Uri RequestUri + { + get { return _request.RequestUri; } + } + + /// + /// Returns the HTTP response. + /// + /// The HTTP response. + public virtual IWebResponseData GetResponse() + { + try + { + var response = _request.GetResponse() as HttpWebResponse; + return new HttpWebRequestResponseData(response); + } + catch(WebException webException) + { + var errorResponse = webException.Response as HttpWebResponse; + if (errorResponse != null) + { + throw new HttpErrorResponseException(webException.Message, + webException, + new HttpWebRequestResponseData(errorResponse)); + } + throw; + } + } + + /// + /// Gets a handle to the request content. + /// + /// The request content. + public Stream GetRequestContent() + { + return _request.GetRequestStream(); + } + + /// + /// Writes a stream to the request body. + /// + /// The destination where the content stream is written. + /// The content stream to be written. + /// HTTP content headers. + /// The request context. + public void WriteToRequestBody(Stream requestContent, Stream contentStream, + IDictionary contentHeaders, IRequestContext requestContext) + { + bool gotException = false; + try + { + var buffer = new byte[requestContext.ClientConfig.BufferSize]; + int bytesRead = 0; + int bytesToRead = buffer.Length; + + while ((bytesRead = contentStream.Read(buffer, 0, bytesToRead)) > 0) + { + requestContent.Write(buffer, 0, bytesRead); + } + } + catch(Exception) + { + gotException = true; + + // If an exception occured while reading the input stream, + // Abort the request to signal failure to the server and prevent + // potentially writing an incomplete stream to the server. + this.Abort(); + throw; + } + finally + { + // Only bubble up exception from the close method if we haven't already got an exception + // reading and writing from the streams. + try + { + requestContent.Close(); + } + catch(Exception) + { + if (!gotException) + throw; + } + } + } + + /// + /// Writes a byte array to the request body. + /// + /// The destination where the content stream is written. + /// The content stream to be written. + /// HTTP content headers. + public void WriteToRequestBody(Stream requestContent, byte[] content, IDictionary contentHeaders) + { + using (requestContent) + { + requestContent.Write(content, 0, content.Length); + } + } + + /// + /// Aborts the HTTP request. + /// + public void Abort() + { + if (!_isAborted) + { + _request.Abort(); + _isAborted = true; + } + } + + /// + /// Initiates the operation to gets a handle to the request content. + /// + /// The async callback invoked when the operation completes. + /// The state object to be passed to the async callback. + /// IAsyncResult that represents an async operation. + public IAsyncResult BeginGetRequestContent(AsyncCallback callback, object state) + { + return _request.BeginGetRequestStream(callback, state); + } + + /// + /// Ends the operation to gets a handle to the request content. + /// + /// IAsyncResult that represents an async operation. + /// The request content. + public Stream EndGetRequestContent(IAsyncResult asyncResult) + { + return _request.EndGetRequestStream(asyncResult); + } + + /// + /// Initiates the operation to Returns the HTTP response. + /// + /// The async callback invoked when the operation completes. + /// The state object to be passed to the async callback. + /// IAsyncResult that represents an async operation. + public IAsyncResult BeginGetResponse(AsyncCallback callback, object state) + { + return _request.BeginGetResponse(callback, state); + } + + /// + /// Ends the operation to Returns the HTTP response. + /// + /// IAsyncResult that represents an async operation. + /// The HTTP response. + public virtual IWebResponseData EndGetResponse(IAsyncResult asyncResult) + { + try + { + var response = _request.EndGetResponse(asyncResult) as HttpWebResponse; + return new HttpWebRequestResponseData(response); + } + catch (WebException webException) + { + var errorResponse = webException.Response as HttpWebResponse; + if (errorResponse != null) + { + throw new HttpErrorResponseException(webException.Message, + webException, + new HttpWebRequestResponseData(errorResponse)); + } + throw; + } + } + + /// + /// Configures a request as per the request context. + /// + /// The request context. + public virtual void ConfigureRequest(IRequestContext requestContext) + { + var clientConfig = requestContext.ClientConfig; + var originalRequest = requestContext.OriginalRequest; + + // If System.Net.WebRequest.AllowAutoRedirect is set to true (default value), + // redirects for GET requests are automatically followed and redirects for POST + // requests are thrown back as exceptions. + + // If System.Net.WebRequest.AllowAutoRedirect is set to false, + // redirects are returned as responses. + _request.AllowAutoRedirect = clientConfig.AllowAutoRedirect; + + // Configure timeouts. + if (requestContext.Request.ContentStream != null) + { + _request.Timeout = int.MaxValue; + _request.ReadWriteTimeout = int.MaxValue; + _request.AllowWriteStreamBuffering = false; + } + + // Override the Timeout and ReadWriteTimeout values if set at the request or config level. + // Public Timeout and ReadWriteTimeout properties are present on client config objects. + var timeout = ClientConfig.GetTimeoutValue(clientConfig.Timeout, + originalRequest.TimeoutInternal); + var readWriteTimeout = ClientConfig.GetTimeoutValue(clientConfig.ReadWriteTimeout, + originalRequest.ReadWriteTimeoutInternal); + if (timeout != null) + { + _request.Timeout = (int)timeout.Value.TotalMilliseconds; + } + if (readWriteTimeout != null) + { + _request.ReadWriteTimeout = (int)readWriteTimeout.Value.TotalMilliseconds; + } + _request.KeepAlive = originalRequest.KeepAlive; + + // Set proxy related properties + if (!string.IsNullOrEmpty(requestContext.ClientConfig.ProxyHost) && requestContext.ClientConfig.ProxyPort > 0) + { + WebProxy proxy = new WebProxy(requestContext.ClientConfig.ProxyHost, requestContext.ClientConfig.ProxyPort); + requestContext.Metrics.AddProperty(Metric.ProxyHost, requestContext.ClientConfig.ProxyHost); + requestContext.Metrics.AddProperty(Metric.ProxyHost, requestContext.ClientConfig.ProxyPort); + _request.Proxy = proxy; + + if (requestContext.ClientConfig.ProxyCredentials != null) + { + _request.Proxy.Credentials = requestContext.ClientConfig.ProxyCredentials; + } + } + else + { + _request.Proxy = null; + } + + // Set service point properties. + //_request.ServicePoint.Expect100Continue = originalRequest.Expect100Continue; + } + + /// + /// Sets the headers on the request. + /// + /// A dictionary of header names and values. + public void SetRequestHeaders(IDictionary headers) + { + AddHeaders(_request, headers); + } + + private static System.Reflection.MethodInfo _addWithoutValidateHeadersMethod = + typeof(WebHeaderCollection).GetMethod("AddWithoutValidate", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); + + internal static void AddHeaders(HttpWebRequest request, IDictionary headersToAdd) + { + var headers = request.Headers; + foreach (var kvp in headersToAdd) + { + if (WebHeaderCollection.IsRestricted(kvp.Key)) + { + if (string.Equals(kvp.Key, HttpHeader.AcceptHeader, StringComparison.OrdinalIgnoreCase)) + request.Accept = kvp.Value; + else if (string.Equals(kvp.Key, HttpHeader.ContentTypeHeader, StringComparison.OrdinalIgnoreCase)) + request.ContentType = kvp.Value; + else if (string.Equals(kvp.Key, HttpHeader.ContentLengthHeader, StringComparison.OrdinalIgnoreCase)) + request.ContentLength = long.Parse(kvp.Value, CultureInfo.InvariantCulture); + else if (string.Equals(kvp.Key, HttpHeader.UserAgentHeader, StringComparison.OrdinalIgnoreCase)) + request.UserAgent = kvp.Value; + else if (string.Equals(kvp.Key, HttpHeader.DateHeader, StringComparison.OrdinalIgnoreCase)) + _addWithoutValidateHeadersMethod.Invoke(request.Headers, new[] { HttpHeader.DateHeader, kvp.Value }); + else if (string.Equals(kvp.Key, HttpHeader.HostHeader, StringComparison.OrdinalIgnoreCase)) + _addWithoutValidateHeadersMethod.Invoke(request.Headers, new[] { HttpHeader.HostHeader, kvp.Value }); + else + throw new NotSupportedException("Header with name " + kvp.Key + " is not suppored"); + } + else + { + headers[kvp.Key] = kvp.Value; + } + } + } + + /// + /// Disposes the HttpRequest. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/HttpHandler/IHttpRequestFactory.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/HttpHandler/IHttpRequestFactory.cs new file mode 100644 index 0000000000..3bdd28dabf --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/HttpHandler/IHttpRequestFactory.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.IO; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Transform; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline.HttpHandler +{ + /// + /// The interface for a HTTP request factory. + /// + /// The type used by the underlying HTTP API to represent the request body. + public interface IHttpRequestFactory : IDisposable + { + /// + /// Creates an HTTP request for the given URI. + /// + /// The request URI. + /// An HTTP request. + IHttpRequest CreateHttpRequest(Uri requestUri); + } + + /// + /// The interface for an HTTP request that is agnostic of the underlying HTTP API. + /// + /// The type used by the underlying HTTP API to represent the HTTP request content. + public interface IHttpRequest : IDisposable + { + /// + /// The HTTP method or verb. + /// + string Method { get; set; } + + /// + /// The request URI. + /// + Uri RequestUri { get; } + + /// + /// Configures a request as per the request context. + /// + /// The request context. + void ConfigureRequest(IRequestContext requestContext); + + /// + /// Sets the headers on the request. + /// + /// A dictionary of header names and values. + void SetRequestHeaders(IDictionary headers); + + /// + /// Gets a handle to the request content. + /// + /// The request content. + TRequestContent GetRequestContent(); + + /// + /// Returns the HTTP response. + /// + /// The HTTP response. + IWebResponseData GetResponse(); + + /// + /// Writes a stream to the request body. + /// + /// The destination where the content stream is written. + /// The content stream to be written. + /// HTTP content headers. + /// The request context. + void WriteToRequestBody(TRequestContent requestContent, Stream contentStream, IDictionary contentHeaders, IRequestContext requestContext); + + /// + /// Writes a byte array to the request body. + /// + /// The destination where the content stream is written. + /// The content stream to be written. + /// HTTP content headers. + void WriteToRequestBody(TRequestContent requestContent, byte[] content, IDictionary contentHeaders); + + /// + /// Aborts the HTTP request. + /// + void Abort(); + + /// + /// Initiates the operation to gets a handle to the request content. + /// + /// The async callback invoked when the operation completes. + /// The state object to be passed to the async callback. + /// IAsyncResult that represents an async operation. + IAsyncResult BeginGetRequestContent(AsyncCallback callback, object state); + + /// + /// Ends the operation to gets a handle to the request content. + /// + /// IAsyncResult that represents an async operation. + /// The request content. + TRequestContent EndGetRequestContent(IAsyncResult asyncResult); + + /// + /// Initiates the operation to Returns the HTTP response. + /// + /// The async callback invoked when the operation completes. + /// The state object to be passed to the async callback. + /// IAsyncResult that represents an async operation. + IAsyncResult BeginGetResponse(AsyncCallback callback, object state); + + /// + /// Ends the operation to Returns the HTTP response. + /// + /// IAsyncResult that represents an async operation. + /// The HTTP response. + IWebResponseData EndGetResponse(IAsyncResult asyncResult); + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/IPiplelineHandler.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/IPiplelineHandler.cs new file mode 100644 index 0000000000..84bea4094f --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/IPiplelineHandler.cs @@ -0,0 +1,54 @@ +using System; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Util; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline +{ + /// + /// Interface for a pipeline handler in a pipeline. + /// + public partial interface IPipelineHandler + { + /// + /// The inner handler which is called after the current + /// handler completes it's processing. + /// + IPipelineHandler InnerHandler { get; set; } + + /// + /// The outer handler which encapsulates the current handler. + /// + IPipelineHandler OuterHandler { get; set; } + + /// + /// Contains the processing logic for a synchronous request invocation. + /// This method should call InnerHandler.InvokeSync to continue processing of the + /// request by the pipeline, unless it's a terminating handler. + /// + /// The execution context which contains both the + /// requests and response context. + void InvokeSync(IExecutionContext executionContext); + + /// + /// Contains the processing logic for an asynchronous request invocation. + /// This method should call InnerHandler.InvokeSync to continue processing of the + /// request by the pipeline, unless it's a terminating handler. + /// + /// The execution context which contains both the + /// requests and response context. + /// IAsyncResult which represent a async operation. + IAsyncResult InvokeAsync(IAsyncExecutionContext executionContext); + + /// + /// This callback method contains the processing logic that should be executed + /// after the underlying asynchronous operation completes. + /// This method is called as part of a callback chain which starts + /// from the InvokeAsyncCallback method of the bottommost handler and then invokes + /// each callback method of the handler above it. + /// This method should call OuterHandler.AsyncCallback to continue processing of the + /// request by the pipeline, unless it's the topmost handler. + /// + /// The execution context, it contains the + /// request and response context. + void AsyncCallback(IAsyncExecutionContext executionContext); + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/PipelineHandler.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/PipelineHandler.cs new file mode 100644 index 0000000000..0018097fe8 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/PipelineHandler.cs @@ -0,0 +1,123 @@ +using System; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Util; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline +{ + /// + /// An abstract pipeline handler that has implements IPipelineHandler, + /// and has the default implmentation. This is the base class for most of + /// the handler implementations. + /// + public abstract partial class PipelineHandler : IPipelineHandler + { + /// + /// The inner handler which is called after the current + /// handler completes it's processing. + /// + public IPipelineHandler InnerHandler { get; set; } + + /// + /// The outer handler which encapsulates the current handler. + /// + public IPipelineHandler OuterHandler { get; set; } + + /// + /// Contains the processing logic for a synchronous request invocation. + /// This method calls InnerHandler.InvokeSync to continue processing of the + /// request by the pipeline. + /// + /// The execution context which contains both the + /// requests and response context. + public virtual void InvokeSync(IExecutionContext executionContext) + { + if (this.InnerHandler != null) + { + InnerHandler.InvokeSync(executionContext); + return; + } + throw new InvalidOperationException("Cannot invoke InnerHandler. InnerHandler is not set."); + } + + /// + /// Contains the processing logic for an asynchronous request invocation. + /// This method should calls InnerHandler.InvokeSync to continue processing of the + /// request by the pipeline. + /// + /// The execution context which contains both the + /// requests and response context. + /// IAsyncResult which represent an async operation. + public virtual IAsyncResult InvokeAsync(IAsyncExecutionContext executionContext) + { + if (this.InnerHandler != null) + { + return InnerHandler.InvokeAsync(executionContext); + } + throw new InvalidOperationException("Cannot invoke InnerHandler. InnerHandler is not set."); + } + + /// + /// This callback method is called by the callback method of the inner handler + /// as part of asynchronous processing after any underlying asynchronous + /// operations complete. + /// + /// The execution context, it contains the + /// request and response context. + public void AsyncCallback(IAsyncExecutionContext executionContext) + { + try + { + this.InvokeAsyncCallback(executionContext); + } + catch (Exception exception) + { + executionContext.RequestContext.Metrics.AddProperty(Metric.Exception, exception); + + // An unhandled exception occured in the callback implementation. + // Capture the exception and end the callback processing by signalling the + // wait handle. + executionContext.RequestContext.Metrics.StopEvent(Metric.ClientExecuteTime); + + var asyncResult = executionContext.ResponseContext.AsyncResult; + asyncResult.Exception = exception; + asyncResult.SignalWaitHandle(); + if (asyncResult.AsyncCallback != null) + { + asyncResult.AsyncCallback(asyncResult); + } + } + } + + /// + /// This callback method contains the processing logic that should be executed + /// after the underlying asynchronous operation completes. + /// This method is called as part of a callback chain which starts + /// from the InvokeAsyncCallback method of the bottommost handler and then invokes + /// each callback method of the handler above it. + /// This method calls OuterHandler.AsyncCallback to continue processing of the + /// request by the pipeline, unless it's the topmost handler. + /// + /// The execution context, it contains the + /// request and response context. + protected virtual void InvokeAsyncCallback(IAsyncExecutionContext executionContext) + { + if (this.OuterHandler!=null) + { + this.OuterHandler.AsyncCallback(executionContext); + } + else + { + // No more outer handlers to process, signal completion + executionContext.ResponseContext.AsyncResult.Response = + executionContext.ResponseContext.Response; + + var asyncResult = executionContext.ResponseContext.AsyncResult; + asyncResult.SignalWaitHandle(); + if (asyncResult.AsyncCallback != null) + { + asyncResult.AsyncCallback(asyncResult); + } + } + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/RetryHandler/DefaultRetryPolicy.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/RetryHandler/DefaultRetryPolicy.cs new file mode 100644 index 0000000000..e8602b8597 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/RetryHandler/DefaultRetryPolicy.cs @@ -0,0 +1,198 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Threading; +using Aliyun.Acs.Dybaseapi.MNS.Util; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline.RetryHandler +{ + /// + /// The default implementation of the retry policy. + /// + public class DefaultRetryPolicy : RetryPolicy + { + private int _maxBackoffInMilliseconds = (int)TimeSpan.FromSeconds(30).TotalMilliseconds; + + // Set of web exception status codes to retry on. + private ICollection _webExceptionStatusesToRetryOn = new HashSet + { + WebExceptionStatus.ConnectFailure, + WebExceptionStatus.ConnectionClosed, + WebExceptionStatus.KeepAliveFailure, + WebExceptionStatus.NameResolutionFailure, + WebExceptionStatus.ReceiveFailure + }; + + // Set of error codes to retry on. + private ICollection _errorCodesToRetryOn = new HashSet + { + "Throttling", + "RequestTimeout" + }; + + /// + /// The maximum value of exponential backoff in milliseconds, which will be used to wait + /// before retrying a request. + /// + public int MaxBackoffInMilliseconds + { + get { return _maxBackoffInMilliseconds; } + set { _maxBackoffInMilliseconds = value; } + } + + /// + /// List of MNS specific error codes which are returned as part of the error response. + /// These error codes will be retried. + /// + public ICollection ErrorCodesToRetryOn + { + get { return _errorCodesToRetryOn; } + } + + /// + /// List of WebExceptionStatus for a WebException which will be retried. + /// + public ICollection WebExceptionStatusesToRetryOn + { + get { return _webExceptionStatusesToRetryOn; } + } + + /// + /// Constructor for DefaultRetryPolicy. + /// + /// The maximum number of retries before throwing + /// back a exception. This does not count the initial request. + public DefaultRetryPolicy(int maxRetries) + { + this.MaxRetries = maxRetries; + } + + /// + /// Returns true if the request is in a state where it can be retried, else false. + /// + /// Request context containing the state of the request. + /// Returns true if the request is in a state where it can be retried, else false. + public override bool CanRetry(IExecutionContext executionContext) + { + return executionContext.RequestContext.Request.IsRequestStreamRewindable(); + } + + /// + /// Return true if the request should be retried. + /// + /// Request context containing the state of the request. + /// The exception thrown by the previous request. + /// Return true if the request should be retried. + public override bool RetryForException(IExecutionContext executionContext, Exception exception) + { + // An IOException was thrown by the underlying http client. + if (exception is IOException) + { + // Don't retry IOExceptions that are caused by a ThreadAbortException + if (IsInnerException(exception)) + return false; + + // Retry all other IOExceptions + return true; + } + + // A AliyunServiceException was thrown by ErrorHandler + var serviceException = exception as AliyunServiceException; + if (serviceException != null) + { + /* + * For 500 internal server errors and 503 service + * unavailable errors, we want to retry, but we need to use + * an exponential back-off strategy so that we don't overload + * a server with a flood of retries. If we've surpassed our + * retry limit we handle the error response as a non-retryable + * error and go ahead and throw it back to the user as an exception. + */ + if (serviceException.StatusCode == HttpStatusCode.InternalServerError || + serviceException.StatusCode == HttpStatusCode.ServiceUnavailable) + { + return true; + } + + /* + * Throttling is reported as a 400 or 503 error from services. To try and + * smooth out an occasional throttling error, we'll pause and retry, + * hoping that the pause is long enough for the request to get through + * the next time. + */ + if ((serviceException.StatusCode == HttpStatusCode.BadRequest || + serviceException.StatusCode == HttpStatusCode.ServiceUnavailable)) + { + string errorCode = serviceException.ErrorCode; + if (this.ErrorCodesToRetryOn.Contains(errorCode)) + { + return true; + } + } + + WebException webException; + if (IsInnerException(exception, out webException)) + { + if (this.WebExceptionStatusesToRetryOn.Contains(webException.Status)) + { + return true; + } + } + } + + return false; + } + + /// + /// Checks if the retry limit is reached. + /// + /// Request context containing the state of the request. + /// Return false if the request can be retried, based on number of retries. + public override bool RetryLimitReached(IExecutionContext executionContext) + { + return executionContext.RequestContext.Retries >= this.MaxRetries; + } + + /// + /// Waits before retrying a request. The default policy implements a exponential backoff. + /// + /// Request context containing the state of the request. + public override void WaitBeforeRetry(IExecutionContext executionContext) + { + DefaultRetryPolicy.WaitBeforeRetry(executionContext.RequestContext.Retries, this.MaxBackoffInMilliseconds); + } + + public static void WaitBeforeRetry(int retries, int maxBackoffInMilliseconds) + { + int delay = (int)(Math.Pow(4, retries) * 100); + delay = Math.Min(delay, maxBackoffInMilliseconds); + AliyunSDKUtils.Sleep(delay); + } + + protected static bool IsInnerException(Exception exception) + where T : Exception + { + T innerException; + return IsInnerException(exception, out innerException); + } + + protected static bool IsInnerException(Exception exception, out T inner) + where T : Exception + { + inner = null; + var innerExceptionType = typeof(T); + var currentException = exception; + while (currentException.InnerException != null) + { + inner = currentException.InnerException as T; + if (inner != null) + { + return true; + } + currentException = currentException.InnerException; + } + return false; + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/RetryHandler/RetryHandler.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/RetryHandler/RetryHandler.cs new file mode 100644 index 0000000000..1b206694fc --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/RetryHandler/RetryHandler.cs @@ -0,0 +1,143 @@ +using System; +using System.Net; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Util; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline.RetryHandler +{ + /// + /// The retry handler has the generic logic for retrying requests. + /// It uses a retry policy which specifies when + /// a retry should be performed. + /// + public class RetryHandler : PipelineHandler + { + /// + /// The retry policy which specifies when + /// a retry should be performed. + /// + public RetryPolicy RetryPolicy { get; private set; } + + /// + /// Constructor which takes in a retry policy. + /// + /// Retry Policy + public RetryHandler(RetryPolicy retryPolicy) + { + this.RetryPolicy = retryPolicy; + } + + /// + /// Invokes the inner handler and performs a retry, if required as per the + /// retry policy. + /// + /// The execution context which contains both the + /// requests and response context. + public override void InvokeSync(IExecutionContext executionContext) + { + var requestContext = executionContext.RequestContext; + bool shouldRetry = false; + do + { + try + { + base.InvokeSync(executionContext); + try + { + if (requestContext.Request.ContentStream != null) + { + requestContext.Request.ContentStream.Close(); + } + } + catch (Exception) + { + } + return; + } + catch (Exception exception) + { + shouldRetry = this.RetryPolicy.Retry(executionContext, exception); + if (!shouldRetry) + { + throw; + } + else + { + requestContext.Retries++; + requestContext.Metrics.SetCounter(Metric.AttemptCount, requestContext.Retries); + } + } + + PrepareForRetry(requestContext); + + try + { + requestContext.Metrics.StartEvent(Metric.RetryPauseTime); + this.RetryPolicy.WaitBeforeRetry(executionContext); + } + finally + { + requestContext.Metrics.StopEvent(Metric.RetryPauseTime); + } + + } while (shouldRetry); + } + + /// + /// Invokes the inner handler and performs a retry, if required as per the + /// retry policy. + /// + /// The execution context which contains both the + /// requests and response context. + protected override void InvokeAsyncCallback(IAsyncExecutionContext executionContext) + { + var requestContext = executionContext.RequestContext; + var responseContext = executionContext.ResponseContext; + var exception = responseContext.AsyncResult.Exception; + + if (exception != null) + { + var syncExecutionContext = ExecutionContext.CreateFromAsyncContext(executionContext); + var shouldRetry = this.RetryPolicy.Retry(syncExecutionContext, exception); + if (shouldRetry) + { + requestContext.Retries++; + requestContext.Metrics.SetCounter(Metric.AttemptCount, requestContext.Retries); + + PrepareForRetry(requestContext); + + try + { + requestContext.Metrics.StartEvent(Metric.RetryPauseTime); + this.RetryPolicy.WaitBeforeRetry(syncExecutionContext); + } + finally + { + requestContext.Metrics.StopEvent(Metric.RetryPauseTime); + } + + // Retry by calling InvokeAsync + this.InvokeAsync(executionContext); + return; + } + } + + // Call outer handler + base.InvokeAsyncCallback(executionContext); + } + + /// + /// Prepares the request for retry. + /// + /// Request context containing the state of the request. + internal static void PrepareForRetry(IRequestContext requestContext) + { + if (requestContext.Request.ContentStream != null && + requestContext.Request.OriginalStreamPosition >= 0) + { + var stream = requestContext.Request.ContentStream; + stream.Position = requestContext.Request.OriginalStreamPosition; + } + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/RetryHandler/RetryPolicy.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/RetryHandler/RetryPolicy.cs new file mode 100644 index 0000000000..54c4e4d4d0 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/RetryHandler/RetryPolicy.cs @@ -0,0 +1,64 @@ +using System; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Util; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline.RetryHandler +{ + /// + /// A retry policy specifies all aspects of retry behavior. This includes conditions when the request should be retried, + /// checks of retry limit, preparing the request before retry and introducing delay (backoff) before retries. + /// + public abstract class RetryPolicy + { + /// + /// Maximum number of retries to be performed. + /// This does not count the initial request. + /// + public int MaxRetries { get; protected set; } + + /// + /// Checks if a retry should be performed with the given execution context and exception. + /// + /// The execution context which contains both the + /// requests and response context. + /// The exception throw after issuing the request. + /// Returns true if the request should be retried, else false. + public bool Retry(IExecutionContext executionContext, Exception exception) + { + return !RetryLimitReached(executionContext) && + CanRetry(executionContext) && + RetryForException(executionContext, exception); + } + + /// + /// Returns true if the request is in a state where it can be retried, else false. + /// + /// The execution context which contains both the + /// requests and response context. + /// Returns true if the request is in a state where it can be retried, else false. + public abstract bool CanRetry(IExecutionContext executionContext); + + /// + /// Return true if the request should be retried for the given exception. + /// + /// The execution context which contains both the + /// requests and response context. + /// The exception thrown by the previous request. + /// Return true if the request should be retried. + public abstract bool RetryForException(IExecutionContext executionContext, Exception exception); + + /// + /// Checks if the retry limit is reached. + /// + /// The execution context which contains both the + /// requests and response context. + /// Return false if the request can be retried, based on number of retries. + public abstract bool RetryLimitReached(IExecutionContext executionContext); + + /// + /// Waits before retrying a request. + /// + /// The execution context which contains both the + /// requests and response context. + public abstract void WaitBeforeRetry(IExecutionContext executionContext); + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/RuntimeAsyncResult.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/RuntimeAsyncResult.cs new file mode 100644 index 0000000000..79399ebeb5 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/RuntimeAsyncResult.cs @@ -0,0 +1,116 @@ +using System; +using System.Threading; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline +{ + public class RuntimeAsyncResult : IAsyncResult, IDisposable + { + private object _lockObj; + private ManualResetEvent _waitHandle; + private bool _disposed = false; + private bool _callbackInvoked = false; + + public RuntimeAsyncResult(AsyncCallback asyncCallback, object asyncState) + { + _lockObj = new object(); + _callbackInvoked = false; + + this.AsyncState = asyncState; + this.IsCompleted = false; + this.AsyncCallback = asyncCallback; + this.CompletedSynchronously = false; + } + + public AsyncCallback AsyncCallback { get; private set; } + + public object AsyncState { get; private set; } + + public WaitHandle AsyncWaitHandle + { + get + { + if (this._waitHandle != null) + { + return this._waitHandle; + } + + lock (this._lockObj) + { + if (this._waitHandle == null) + { + this._waitHandle = new ManualResetEvent(this.IsCompleted); + } + } + return this._waitHandle; + } + } + + public bool CompletedSynchronously { get; private set; } + + public bool IsCompleted { get; private set; } + + public Exception Exception { get; set; } + + public WebServiceResponse Response { get; set; } + + internal void SignalWaitHandle() + { + this.IsCompleted = true; + if (this._waitHandle != null) + { + this._waitHandle.Set(); + } + } + + internal void HandleException(Exception exception) + { + this.Exception = exception; + InvokeCallback(); + } + + internal void InvokeCallback() + { + this.SignalWaitHandle(); + if (!_callbackInvoked && this.AsyncCallback != null) + { + _callbackInvoked = true; + this.AsyncCallback(this); + } + } + + #region Dispose Pattern Implementation + + /// + /// Implements the Dispose pattern + /// + /// Whether this object is being disposed via a call to Dispose + /// or garbage collected. + protected virtual void Dispose(bool disposing) + { + if (!this._disposed) + { + if (disposing && _waitHandle != null) + { +#if WIN_RT + _waitHandle.Dispose(); +#else + _waitHandle.Close(); +#endif + _waitHandle = null; + } + this._disposed = true; + } + } + + /// + /// Disposes of all managed and unmanaged resources. + /// + public void Dispose() + { + this.Dispose(true); + GC.SuppressFinalize(this); + } + + #endregion + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/RuntimePipeline.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/RuntimePipeline.cs new file mode 100644 index 0000000000..673a41ad24 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/Pipeline/RuntimePipeline.cs @@ -0,0 +1,404 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.Linq; +using Aliyun.Acs.Dybaseapi.MNS.Runtime.Internal.Util; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime.Pipeline +{ + /// + /// A runtime pipeline contains a collection of handlers which represent + /// different stages of request and response processing. + /// + public partial class RuntimePipeline : IDisposable + { + #region Private members + + bool _disposed; + + // The top-most handler in the pipeline. + IPipelineHandler _handler; + + #endregion + + #region Properties + + /// + /// The top-most handler in the pipeline. + /// + public IPipelineHandler Handler + { + get { return _handler; } + } + + #endregion + + #region Constructors + + /// + /// Constructor for RuntimePipeline. + /// + /// The handler with which the pipeline is initalized. + public RuntimePipeline(IPipelineHandler handler) + { + if (handler == null) + throw new ArgumentNullException("handler"); + + _handler = handler; + } + + /// + /// Constructor for RuntimePipeline. + /// + /// List of handlers with which the pipeline is initialized. + public RuntimePipeline(IList handlers) + { + if (handlers == null || handlers.Count == 0) + throw new ArgumentNullException("handlers"); + + foreach (var handler in handlers) + { + this.AddHandler(handler); + } + } + + #endregion + + #region Invoke methods + + /// + /// Invokes the pipeline synchronously. + /// + /// Request context + /// Response context + public IResponseContext InvokeSync(IExecutionContext executionContext) + { + ThrowIfDisposed(); + + _handler.InvokeSync(executionContext); + return executionContext.ResponseContext; + } + + /// + /// Invokes the pipeline asynchronously. + /// + /// Request context + /// IAsyncResult which represents the in progress asynchronous operation. + public IAsyncResult InvokeAsync(IAsyncExecutionContext executionContext) + { + ThrowIfDisposed(); + + return _handler.InvokeAsync(executionContext); + } + + #endregion + + #region Handler methods + + /// + /// Adds a new handler to the top of the pipeline. + /// + /// The handler to be added to the pipeline. + public void AddHandler(IPipelineHandler handler) + { + if (handler == null) + throw new ArgumentNullException("handler"); + + ThrowIfDisposed(); + + var innerMostHandler = GetInnermostHandler(handler); + + if (_handler != null) + { + innerMostHandler.InnerHandler = _handler; + _handler.OuterHandler = innerMostHandler; + } + + _handler = handler; + + SetHandlerProperties(handler); + } + + /// + /// Adds a handler after the first instance of handler of type T. + /// + /// Type of the handler after which the given handler instance is added. + /// The handler to be added to the pipeline. + public void AddHandlerAfter(IPipelineHandler handler) + where T : IPipelineHandler + { + if (handler == null) + throw new ArgumentNullException("handler"); + + ThrowIfDisposed(); + + var type = typeof(T); + var current = _handler; + while (current != null) + { + if (current.GetType() == type) + { + InsertHandler(handler, current); + SetHandlerProperties(handler); + return; + } + current = current.InnerHandler; + } + throw new InvalidOperationException( + string.Format(CultureInfo.InvariantCulture, "Cannot find a handler of type {0}", type.Name)); + } + + /// + /// Adds a handler before the first instance of handler of type T. + /// + /// Type of the handler before which the given handler instance is added. + /// The handler to be added to the pipeline. + public void AddHandlerBefore(IPipelineHandler handler) + where T : IPipelineHandler + { + if (handler == null) + throw new ArgumentNullException("handler"); + + ThrowIfDisposed(); + + var type = typeof(T); + if (_handler.GetType() == type) + { + // Add the handler to the top of the pipeline + AddHandler(handler); + SetHandlerProperties(handler); + return; + } + + var current = _handler; + while (current != null) + { + if (current.InnerHandler != null && + current.InnerHandler.GetType() == type) + { + InsertHandler(handler, current); + SetHandlerProperties(handler); + return; + } + current = current.InnerHandler; + } + + throw new InvalidOperationException( + string.Format(CultureInfo.InvariantCulture, "Cannot find a handler of type {0}", type.Name)); + } + + /// + /// Removes the first occurance of a handler of type T. + /// + /// Type of the handler which will be removed. + public void RemoveHandler() + { + ThrowIfDisposed(); + + var type = typeof(T); + + IPipelineHandler previous = null; + var current = _handler; + + while (current != null) + { + if (current.GetType() == type) + { + // Cannot remove the handler if it's the only one in the pipeline + if (current == _handler && _handler.InnerHandler == null) + { + throw new InvalidOperationException( + "The pipeline contains a single handler, cannot remove the only handler in the pipeline."); + } + + // current is the top, point top to current's inner handler + if (current == _handler) + _handler = current.InnerHandler; + + + // Wireup outer handler to current's inner handler + if (current.OuterHandler != null) + current.OuterHandler.InnerHandler = current.InnerHandler; + + // Wireup inner handler to current's outer handler + if (current.InnerHandler != null) + current.InnerHandler.OuterHandler = current.OuterHandler; + + // Cleanup current + current.InnerHandler = null; + current.OuterHandler = null; + + return; + } + + previous = current; + current = current.InnerHandler; + } + + throw new InvalidOperationException( + string.Format(CultureInfo.InvariantCulture, "Cannot find a handler of type {0}", type.Name)); + } + + /// + /// Replaces the first occurance of a handler of type T with the given handler. + /// + /// Type of the handler which will be replaced. + /// The handler to be added to the pipeline. + public void ReplaceHandler(IPipelineHandler handler) + where T : IPipelineHandler + { + if (handler == null) + throw new ArgumentNullException("handler"); + + ThrowIfDisposed(); + + var type = typeof(T); + IPipelineHandler previous = null; + var current = _handler; + while (current != null) + { + if (current.GetType() == type) + { + // Replace current with handler. + handler.InnerHandler = current.InnerHandler; + handler.OuterHandler = current.OuterHandler; + if(previous != null) + { + // Wireup previous handler + previous.InnerHandler = handler; + } + else + { + // Current is the top, replace it. + _handler = handler; + } + + if (current.InnerHandler != null) + { + // Wireup next handler + current.InnerHandler.OuterHandler = handler; + } + + // Cleanup current + current.InnerHandler = null; + current.OuterHandler = null; + + SetHandlerProperties(handler); + return; + } + previous = current; + current = current.InnerHandler; + } + throw new InvalidOperationException( + string.Format(CultureInfo.InvariantCulture, "Cannot find a handler of type {0}", type.Name)); + } + + /// + /// Inserts the given handler after current handler in the pipeline. + /// + /// Handler to be inserted in the pipeline. + /// Handler after which the given handler is inserted. + private static void InsertHandler(IPipelineHandler handler, IPipelineHandler current) + { + var next = current.InnerHandler; + current.InnerHandler = handler; + handler.OuterHandler = current; + + if (next!=null) + { + var innerMostHandler = GetInnermostHandler(handler); + innerMostHandler.InnerHandler = next; + next.OuterHandler = innerMostHandler; + } + } + + /// + /// Gets the innermost handler by traversing the inner handler till + /// it reaches the last one. + /// + private static IPipelineHandler GetInnermostHandler(IPipelineHandler handler) + { + Debug.Assert(handler != null); + + var current = handler; + while (current.InnerHandler != null) + { + current = current.InnerHandler; + } + return current; + } + + private void SetHandlerProperties(IPipelineHandler handler) + { + ThrowIfDisposed(); + } + + /// + /// Retrieves a list of handlers, in the order of their execution. + /// + /// Handlers in the current pipeline. + public List Handlers + { + get + { + return EnumerateHandlers().ToList(); + } + } + + /// + /// Retrieves current handlers, in the order of their execution. + /// + /// Handlers in the current pipeline. + public IEnumerable EnumerateHandlers() + { + var handler = this.Handler; + while(handler != null) + { + yield return handler; + handler = handler.InnerHandler; + } + } + + #endregion + + #region Dispose methods + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (_disposed) + return; + + if (disposing) + { + var handler = this.Handler; + while (handler != null) + { + var innerHandler = handler.InnerHandler; + var disposable = handler as IDisposable; + if (disposable != null) + { + disposable.Dispose(); + } + handler = innerHandler; + } + + _disposed = true; + } + } + + private void ThrowIfDisposed() + { + if (this._disposed) + throw new ObjectDisposedException(GetType().FullName); + } + + #endregion + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/ServiceCredentials.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/ServiceCredentials.cs new file mode 100644 index 0000000000..baab96c49a --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/ServiceCredentials.cs @@ -0,0 +1,135 @@ +using System; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime +{ + /// + /// Immutable representation of Aliyun service credentials. + /// + public class ImmutableCredentials + { + #region Properties + + /// + /// Gets the AccessKey property for the current credentials. + /// + public string AccessKey { get; private set; } + + /// + /// Gets the SecretKey property for the current credentials. + /// + public string SecretKey { get; private set; } + + public string SecurityToken { get; private set;} + + #endregion + + + #region Constructors + + /// + /// Constructs an ImmutableCredentials object with supplied accessKey, secretKey. + /// + /// + /// + public ImmutableCredentials(string accessKeyId, string secretAccessKey, string stsToken) + { + if (string.IsNullOrEmpty(accessKeyId)) throw new ArgumentNullException("accessKeyId"); + if (string.IsNullOrEmpty(secretAccessKey)) throw new ArgumentNullException("secretAccessKey"); + if (string.IsNullOrEmpty(stsToken)) + { + SecurityToken = null; + } + else { + SecurityToken = stsToken; + } + + + AccessKey = accessKeyId; + SecretKey = secretAccessKey; + } + + private ImmutableCredentials() { } + + #endregion + + + #region Public methods + + /// + /// Returns a copy of the current credentials. + /// + /// + public ImmutableCredentials Copy() + { + ImmutableCredentials credentials = new ImmutableCredentials + { + AccessKey = this.AccessKey, + SecretKey = this.SecretKey, + SecurityToken = this.SecurityToken, + }; + return credentials; + } + + #endregion + } + + /// + /// Abstract class that represents a credentials object for Aliyun Services. + /// + public abstract class ServiceCredentials + { + /// + /// Returns a copy of ImmutableCredentials + /// + /// + public abstract ImmutableCredentials GetCredentials(); + } + + /// + /// Basic set of credentials consisting of an AccessKey and SecretKey + /// + public class BasicServiceCredentials : ServiceCredentials + { + #region Private members + + private ImmutableCredentials _credentials; + + #endregion + + + #region Constructors + + /// + /// Constructs a BasicServiceCredentials object for the specified accessKey and secretKey. + /// + /// + /// + public BasicServiceCredentials(string accessKey, string secretKey, string stsToken) + { + if (!string.IsNullOrEmpty(accessKey)) + { + _credentials = new ImmutableCredentials(accessKey, secretKey, stsToken); + } + } + + #endregion + + + #region Abstract class overrides + + /// + /// Returns an instance of ImmutableCredentials for this instance + /// + /// + public override ImmutableCredentials GetCredentials() + { + if (this._credentials == null) + return null; + + return _credentials.Copy(); + } + + #endregion + + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/WebServiceResponse.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/WebServiceResponse.cs new file mode 100644 index 0000000000..21fd31da24 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Runtime/WebServiceResponse.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Net; + +namespace Aliyun.Acs.Dybaseapi.MNS.Runtime +{ + /// + /// Abstract class for Response objects, contains response headers, + /// and no result information. + /// + public class WebServiceResponse + { + private IDictionary _headers = new Dictionary(StringComparer.OrdinalIgnoreCase); + private long _contentLength; + private HttpStatusCode _httpStatusCode; + + /// + /// Returns the headers of the HTTP response. + /// + public IDictionary Headers + { + get { return _headers; } + set { _headers = value; } + } + + /// + /// Returns the content length of the HTTP response. + /// + public long ContentLength + { + get { return this._contentLength; } + set { this._contentLength = value; } + } + + /// + /// Returns the status code of the HTTP response. + /// + public HttpStatusCode HttpStatusCode + { + get { return this._httpStatusCode; } + set { this._httpStatusCode = value; } + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Util/AliyunSDKUtils.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Util/AliyunSDKUtils.cs new file mode 100644 index 0000000000..a1561bb9cc --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Util/AliyunSDKUtils.cs @@ -0,0 +1,385 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Net; +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; + +namespace Aliyun.Acs.Dybaseapi.MNS.Util +{ + /// + /// This class defines utilities and constants that can be used by MNS clients. + /// + public static partial class AliyunSDKUtils + { + #region Internal Constants + + internal const string SDKVersionNumber = "1.0.0.0"; + internal static string _userAgentBaseName = "aliyun-sdk-dotnet"; + + private const int DefaultConnectionLimit = 50; + private const int DefaultMaxIdleTime = 50 * 1000; // 50 seconds + + internal static readonly DateTime EPOCH_START = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + + internal const int DefaultBufferSize = 8192; + + internal static Dictionary RFCEncodingSchemes = new Dictionary + { + { 3986, ValidUrlCharacters }, + { 1738, ValidUrlCharactersRFC1738 } + }; + + #endregion + + #region Public Constants + + /// + /// The Set of accepted and valid queueUrl characters per RFC3986. + /// Characters outside of this set will be encoded. + /// + public const string ValidUrlCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~"; + + /// + /// The Set of accepted and valid queueUrl characters per RFC1738. + /// Characters outside of this set will be encoded. + /// + public const string ValidUrlCharactersRFC1738 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_."; + + /// + /// The set of accepted and valid queueUrl path characters per RFC3986. + /// + private static string ValidPathCharacters = DetermineValidPathCharacters(); + + // Checks which path characters should not be encoded + private static string DetermineValidPathCharacters() + { + const string basePathCharacters = "/:'()!*[]"; + + var sb = new StringBuilder(); + foreach (var c in basePathCharacters) + { + var escaped = Uri.EscapeUriString(c.ToString()); + if (escaped.Length == 1 && escaped[0] == c) + sb.Append(c); + } + return sb.ToString(); + } + + /// + /// The ISO8601Date Format string. Used when parsing date objects + /// + public const string ISO8601DateFormat = "yyyy-MM-dd\\THH:mm:ss.fff\\Z"; + + /// + /// The RFC822Date Format string. Used when parsing date objects + /// + public const string RFC822DateFormat = "ddd, dd MMM yyyy HH:mm:ss \\G\\M\\T"; + + #endregion + + #region UserAgent + + static string _versionNumber; + static string _sdkUserAgent; + + /// + /// The MNS SDK User Agent + /// + public static string SDKUserAgent + { + get + { + return _sdkUserAgent; + } + } + + static AliyunSDKUtils() + { + BuildUserAgentString(); + } + + static void BuildUserAgentString() + { + if (_versionNumber == null) + { + _versionNumber = SDKVersionNumber; + } + + _sdkUserAgent = string.Format(CultureInfo.InvariantCulture, "{0}/{1} .NET Runtime/{2} .NET Framework/{3} OS/{4}", + _userAgentBaseName, + _versionNumber, + DetermineRuntime(), + DetermineFramework(), + DetermineOSVersion()); + } + + static string DetermineRuntime() + { + return string.Format(CultureInfo.InvariantCulture, "{0}.{1}", Environment.Version.Major, Environment.Version.MajorRevision); + } + + static string DetermineFramework() + { + try + { + return Environment.Version.Major.ToString(); + + // compatible fix + //if (Environment.Version.Major >= 4 && Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Net Framework Setup\\NDP\\v4") != null) + // return "4.0"; + //if (Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Net Framework Setup\\NDP\\v3.5") != null) + // return "3.5"; + //if (Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Net Framework Setup\\NDP\\v3.0") != null) + // return "3.0"; + //if (Registry.LocalMachine.OpenSubKey(@"Software\\Microsoft\\Net Framework Setup\\NDP\\v2.0.50727") != null) + //return "2.0"; + } + catch (Exception) + { + } + + return "Unknown"; + } + + static string DetermineOSVersion() + { + return Environment.OSVersion.Version.ToString(); + } + + #endregion + + #region HTTP Connection Configurations + + private const int _defaultConnectionLimit = 2; + internal static int GetConnectionLimit(int? clientConfigValue) + { + // Connection limit has been explicitly set on the client. + if (clientConfigValue.HasValue) + return clientConfigValue.Value; + + // If default has been left at the system default return the SDK default. + if (ServicePointManager.DefaultConnectionLimit == _defaultConnectionLimit) + return DefaultConnectionLimit; + + // The system default has been explicitly changed so we will honor that value. + return ServicePointManager.DefaultConnectionLimit; + } + + private const int _defaultMaxIdleTime = 100 * 1000; + internal static int GetMaxIdleTime(int? clientConfigValue) + { + // MaxIdleTime has been explicitly set on the client. + if (clientConfigValue.HasValue) + return clientConfigValue.Value; + + // If default has been left at the system default return the SDK default. + if (ServicePointManager.MaxServicePointIdleTime == _defaultMaxIdleTime) + return DefaultMaxIdleTime; + + // The system default has been explicitly changed so we will honor that value. + return ServicePointManager.MaxServicePointIdleTime; + } + + #endregion + + #region Internal Methods + + /** + * Convert Dictionary of paremeters to queueUrl encoded query string + */ + internal static string GetParametersAsString(IDictionary parameters) + { + string[] keys = new string[parameters.Keys.Count]; + parameters.Keys.CopyTo(keys, 0); + Array.Sort(keys); + + StringBuilder data = new StringBuilder(512); + foreach (string key in keys) + { + string value = parameters[key]; + if (value != null) + { + data.Append(key); + data.Append('='); + data.Append(value); + data.Append('&'); + } + } + string result = data.ToString(); + if (result.Length == 0) + return string.Empty; + + return result.Remove(result.Length - 1); + } + + public static void CopyTo(this Stream input, Stream output) + { + byte[] buffer = new byte[16 * 1024]; + int bytesRead; + + while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0) + { + output.Write(buffer, 0, bytesRead); + } + } + + /// + /// Utility method for converting Unix epoch seconds to DateTime structure. + /// + /// The number of milliSeconds since January 1, 1970. + /// Converted DateTime structure + public static DateTime ConvertFromUnixEpochSeconds(long milliSeconds) + { + return new DateTime(milliSeconds * 10000L + EPOCH_START.Ticks, DateTimeKind.Utc).ToLocalTime(); + } + + #endregion + + #region Public Methods and Properties + + /// + /// Formats the current date as ISO 8601 timestamp + /// + /// An ISO 8601 formatted string representation + /// of the current date and time + /// + public static string FormattedCurrentTimestampRFC822 + { + get + { + return GetFormattedTimestampRFC822(0); + } + } + + /// + /// Gets the RFC822 formatted timestamp that is minutesFromNow + /// in the future. + /// + /// The number of minutes from the current instant + /// for which the timestamp is needed. + /// The ISO8601 formatted future timestamp. + public static string GetFormattedTimestampRFC822(int minutesFromNow) + { + DateTime dateTime = DateTime.UtcNow.AddMinutes(minutesFromNow); + DateTime formatted = new DateTime( + dateTime.Year, + dateTime.Month, + dateTime.Day, + dateTime.Hour, + dateTime.Minute, + dateTime.Second, + dateTime.Millisecond, + DateTimeKind.Local + ); + return formatted.ToString( + RFC822DateFormat, + CultureInfo.InvariantCulture + ); + } + + + /// + /// URL encodes a string per RFC3986. If the path property is specified, + /// the accepted path characters {/+:} are not encoded. + /// + /// The string to encode + /// Whether the string is a URL path or not + /// The encoded string + public static string UrlEncode(string data, bool path) + { + return UrlEncode(3986, data, path); + } + + /// + /// URL encodes a string per the specified RFC. If the path property is specified, + /// the accepted path characters {/+:} are not encoded. + /// + /// RFC number determing safe characters + /// The string to encode + /// Whether the string is a URL path or not + /// The encoded string + /// + /// Currently recognised RFC versions are 1738 (Dec '94) and 3986 (Jan '05). + /// If the specified RFC is not recognised, 3986 is used by default. + /// + internal static string UrlEncode(int rfcNumber, string data, bool path) + { + StringBuilder encoded = new StringBuilder(data.Length * 2); + string validUrlCharacters; + if (!RFCEncodingSchemes.TryGetValue(rfcNumber, out validUrlCharacters)) + validUrlCharacters = ValidUrlCharacters; + + string unreservedChars = String.Concat(validUrlCharacters, (path ? ValidPathCharacters : "")); + + foreach (char symbol in Encoding.UTF8.GetBytes(data)) + { + if (unreservedChars.IndexOf(symbol) != -1) + { + encoded.Append(symbol); + } + else + { + encoded.Append("%").Append(string.Format(CultureInfo.InvariantCulture, "{0:X2}", (int)symbol)); + } + } + + return encoded.ToString(); + } + + public static void Sleep(int ms) + { + Thread.Sleep(ms); + } + + internal static string ExtractQueueName(string queueUrl, string endpoint) + { + if (!queueUrl.StartsWith(endpoint)) + throw new ArgumentException(String.Format("Invalid Queue URL {0}", queueUrl)); + + string queueName = queueUrl.Substring(endpoint.Length); + queueName = Regex.Replace(queueName.Trim(), "/", ""); + if (string.IsNullOrEmpty(queueName)) + throw new ArgumentException(String.Format("Invalid Queue Name {0}", queueName)); + + return queueName; + } + + static readonly object _preserveStackTraceLookupLock = new object(); + static bool _preserveStackTraceLookup = false; + static MethodInfo _preserveStackTrace; + + /// + /// This method is used preserve the stacktrace used from clients that support async calls. This + /// make sure that exceptions thrown during EndXXX methods has the orignal stacktrace that happen + /// in the background thread. + /// + /// + internal static void PreserveStackTrace(Exception exception) + { + if (!_preserveStackTraceLookup) + { + lock (_preserveStackTraceLookupLock) + { + _preserveStackTraceLookup = true; + try + { + _preserveStackTrace = typeof(Exception).GetMethod("InternalPreserveStackTrace", + BindingFlags.Instance | BindingFlags.NonPublic); + } + catch { } + } + } + + if (_preserveStackTrace != null) + { + _preserveStackTrace.Invoke(exception, null); + } + } + + #endregion + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Util/CryptoUtil.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Util/CryptoUtil.cs new file mode 100644 index 0000000000..2c13e40de2 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Util/CryptoUtil.cs @@ -0,0 +1,110 @@ +using System; +using System.Globalization; +using System.IO; +using System.Security.Cryptography; +using System.Text; +using Aliyun.Acs.Dybaseapi.MNS.Runtime; + +namespace Aliyun.Acs.Dybaseapi.MNS.Util +{ + public interface ICryptoUtil + { + string HMACSign(string data, string key, SigningAlgorithm algorithmName); + byte[] HMACSignBinary(byte[] data, byte[] key, SigningAlgorithm algorithmName); + + byte[] ComputeMD5Hash(byte[] data); + byte[] ComputeMD5Hash(Stream steam); + } + + public static partial class CryptoUtilFactory + { + static CryptoUtil util = new CryptoUtil(); + + public static ICryptoUtil CryptoInstance + { + get { return util; } + } + + partial class CryptoUtil : ICryptoUtil + { + public string HMACSign(string data, string key, SigningAlgorithm algorithmName) + { + var binaryData = Encoding.UTF8.GetBytes(data); + return HMACSign(binaryData, key, algorithmName); + } + + public string HMACSign(byte[] data, string key, SigningAlgorithm algorithmName) + { + if (String.IsNullOrEmpty(key)) + throw new ArgumentNullException("key", "Please specify a Secret Signing Key."); + + if (data == null || data.Length == 0) + throw new ArgumentNullException("data", "Please specify data to sign."); + + // KeyedHashAlgorithm algorithm = KeyedHashAlgorithm.Create(algorithmName.ToString().ToUpper(CultureInfo.InvariantCulture)); + // compatible + KeyedHashAlgorithm algorithm = null; + + switch (algorithmName) { + case SigningAlgorithm.HmacSHA1: + algorithm = new HMACSHA1(); + break; + case SigningAlgorithm.HmacSHA256: + algorithm = new HMACSHA256(); + break; + } + + if (null == algorithm) + throw new InvalidOperationException("Please specify a KeyedHashAlgorithm to use."); + + try + { + algorithm.Key = Encoding.UTF8.GetBytes(key); + byte[] bytes = algorithm.ComputeHash(data); + return Convert.ToBase64String(bytes); + } + finally + { + algorithm.Clear(); + } + } + + public byte[] ComputeMD5Hash(byte[] data) + { + byte[] hashed = MD5.Create().ComputeHash(data); + return hashed; + } + + public byte[] ComputeMD5Hash(Stream steam) + { + byte[] hashed = MD5.Create().ComputeHash(steam); + return hashed; + } + + public byte[] HMACSignBinary(byte[] data, byte[] key, SigningAlgorithm algorithmName) + { + if (key == null || key.Length == 0) + throw new ArgumentNullException("key", "Please specify a Secret Signing Key."); + + if (data == null || data.Length == 0) + throw new ArgumentNullException("data", "Please specify data to sign."); + + KeyedHashAlgorithm algorithm = KeyedHashAlgorithm.Create(algorithmName.ToString().ToUpper(CultureInfo.InvariantCulture)); + if (null == algorithm) + throw new InvalidOperationException("Please specify a KeyedHashAlgorithm to use."); + + try + { + algorithm.Key = key; + byte[] bytes = algorithm.ComputeHash(data); + return bytes; + } + finally + { + algorithm.Clear(); + } + } + + } + } +} \ No newline at end of file diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Util/HttpHeader.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Util/HttpHeader.cs new file mode 100644 index 0000000000..46fc74dad6 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Util/HttpHeader.cs @@ -0,0 +1,23 @@ +namespace Aliyun.Acs.Dybaseapi.MNS.Util +{ + internal abstract class HttpHeader + { + public const string ContentTypeHeader = "Content-Type"; + public const string ContentLengthHeader = "Content-Length"; + public const string ContentMD5Header = "Content-MD5"; + public const string AuthorizationHeader = "Authorization"; + public const string SecurityToken = "security-token"; + + + public const string UserAgentHeader = "User-Agent"; + public const string LocationHeader = "Location"; + public const string HostHeader = "Host"; + public const string DateHeader = "Date"; + public const string AcceptHeader = "Accept"; + + public const string XMnsVersionHeader = "x-mns-version"; + public const string XMnsMarkerHeader = "x-mns-marker"; + public const string XMnsMaxReturnsHeader = "x-mns-ret-number"; + public const string XMnsPrefixHeader = "x-mns-prefix"; + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Util/MNSConstants.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Util/MNSConstants.cs new file mode 100644 index 0000000000..f9face977f --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Util/MNSConstants.cs @@ -0,0 +1,112 @@ +namespace Aliyun.Acs.Dybaseapi.MNS.Util +{ + internal static class MNSConstants + { + public const string MNS_SERVICE_NAME = "Aliyun.Acs.Dybaseapi.MNS"; + + public const uint DEFAULT_MAX_RETURNS = 1000; + public const uint DEFAULT_MESSAGE_PRIORITY = 8; + + public const uint DEFAULT_DELAY_SECONDS = 0; + public const uint DEFAULT_VISIBILITY_TIMEOUT = 30; + public const uint DEFAULT_MAXIMUM_MESSAGE_SIZE = 65536; + public const uint DEFAULT_MESSAGE_RETENTION_PERIOD = 345600; + public const uint DEFAULT_POLLING_WAIT_SECONDS = 0; + public const bool DEFAULT_LOGGING_ENABLED = false; + + public const string ATTRIBUTE_DELAY_SECONDS = "DelaySeconds"; + public const string ATTRIBUTE_VISIBILITY_TIMEOUT = "VisibilityTimeout"; + public const string ATTRIBUTE_MAXIMUM_MESSAGE_SIZE = "MaximumMessageSize"; + public const string ATTRIBUTE_MESSAGE_RETENTION_PERIOD = "MessageRetentionPeriod"; + public const string ATTRIBUTE_POLLING_WAIT_SECONDS = "PollingWaitSeconds"; + + public const string ATTRIBUTE_CREAT_TIME = "CreateTime"; + public const string ATTRIBUTE_LAST_MODIFY_TIME = "LastModifyTime"; + + public const string ATTRIBUTE_ACTIVE_MESSAGES = "ActiveMessages"; + public const string ATTRIBUTE_INACTIVE_MESSAGES = "InactiveMessages"; + public const string ATTRIBUTE_DELAY_MESSAGES = "DelayMessages"; + + public const string MNS_XML_NAMESPACE = "http://mns.aliyuncs.com/doc/v1"; + public const string MNS_AUTHORIZATION_HEADER_PREFIX = "MNS"; + public const string X_MNS_VERSION = "2015-06-06"; + public const string X_MNS_HEADER_PREFIX = "x-mns-"; + + public const string XML_ROOT_SUBSCRIPTION = "Subscription"; + public const string XML_ROOT_ERRORS = "Errors"; + public const string XML_ROOT_ERROR_RESPONSE = "Error"; + public const string XML_ROOT_LIST_QUEUE_RESPONSE = "Queues"; + public const string XML_ROOT_QUEUE = "Queue"; + public const string XML_ROOT_TOPIC = "Topic"; + public const string XML_ROOT_TOPICS = "Topics"; + public const string XML_ROOT_MESSAGES = "Messages"; + public const string XML_ROOT_MESSAGE = "Message"; + public const string XML_ROOT_RECEIPT_HANDLES = "ReceiptHandles"; + public const string XML_ROOT_CHANGE_MESSAGE_VISIBILITY_RESPONSE = "ChangeVisibility"; + public const string XML_ROOT_ACCOUNT = "Account"; + + public const string XML_ELEMENT_CODE = "Code"; + public const string XML_ELEMENT_ERROR_CODE = "ErrorCode"; + public const string XML_ELEMENT_MESSAGE = "Message"; + public const string XML_ELEMENT_ERROR_MESSAGE = "ErrorMessage"; + public const string XML_ELEMENT_REQUEST_ID = "RequestId"; + public const string XML_ELEMENT_HOST_ID = "HostId"; + public const string XML_ELEMENT_ENDPOINT = "Endpoint"; + public const string XML_ELEMENT_FILTER_TAG = "FilterTag"; + public const string XML_ELEMENT_NOTIFY_STRATEGY = "NotifyStrategy"; + public const string XML_ELEMENT_NOTIFY_CONTENT_FORMAT = "NotifyContentFormat"; + + public const string XML_ELEMENT_QUEUE = "Queue"; + public const string XML_ELEMENT_QUEUE_URL = "QueueURL"; + public const string XML_ELEMENT_TOPIC_URL = "TopicURL"; + public const string XML_ELEMENT_SUBSCRIPTION_URL = "SubscriptionURL"; + public const string XML_ELEMENT_NEXT_MARKER = "NextMarker"; + + public const string XML_ELEMENT_QUEUE_NAME = "QueueName"; + public const string XML_ELEMENT_TOPIC_NAME = "TopicName"; + public const string XML_ELEMENT_MESSAGE_COUNT = "MessageCount"; + public const string XML_ELEMENT_TOPIC_OWNER = "TopicOwner"; + public const string XML_ELEMENT_SUBSCRIPTION_NAME = "SubscriptionName"; + public const string XML_ELEMENT_CREATE_TIME = "CreateTime"; + public const string XML_ELEMENT_LAST_MODIFY_TIME = "LastModifyTime"; + public const string XML_ELEMENT_VISIBILITY_TIMEOUT = "VisibilityTimeout"; + public const string XML_ELEMENT_MAXIMUM_MESSAGE_SIZE = "MaximumMessageSize"; + public const string XML_ELEMENT_MESSAGE_RETENTION_PERIOD = "MessageRetentionPeriod"; + public const string XML_ELEMENT_DELAY_SECONDS = "DelaySeconds"; + public const string XML_ELEMENT_POLLING_WAIT_SECONDS = "PollingWaitSeconds"; + public const string XML_ELEMENT_INACTIVE_MESSAGES = "InactiveMessages"; + public const string XML_ELEMENT_ACTIVE_MESSAGES = "ActiveMessages"; + public const string XML_ELEMENT_DELAY_MESSAGES = "DelayMessages"; + public const string XML_ELEMENT_LOGGING_ENABLED = "LoggingEnabled"; + public const string XML_ELEMENT_LOGGING_BUCKET = "LoggingBucket"; + + public const string XML_ELEMENT_MESSAGE_BODY = "MessageBody"; + public const string XML_ELEMENT_MESSAGE_TAG = "MessageTag"; + public const string XML_ELEMENT_MESSAGE_ATTRIBUTES = "MessageAttributes"; + public const string XML_ELEMENT_DIRECT_MAIL = "DirectMail"; + public const string XML_ELEMENT_DIRECT_SMS = "DirectSMS"; + public const string XML_ELEMENT_PRIORITY = "Priority"; + public const string XML_ELEMENT_MESSAGE_BODY_MD5 = "MessageBodyMD5"; + public const string XML_ELEMENT_MESSAGE_ID = "MessageId"; + public const string XML_ELEMENT_RECEIPT_HANDLE = "ReceiptHandle"; + public const string XML_ELEMENT_ENQUEUE_TIME = "EnqueueTime"; + public const string XML_ELEMENT_NEXT_VISIBLE_TIME = "NextVisibleTime"; + public const string XML_ELEMENT_FIRST_DEQUEUE_TIME = "FirstDequeueTime"; + public const string XML_ELEMENT_DEQUEUE_COUNT = "DequeueCount"; + + public const string MNS_PARAMETER_ACCOUNT_META = "accountmeta"; + public const string MNS_PARAMETER_META_OVERRIDE = "metaoverride"; + public const string MNS_PARAMETER_WAIT_SECONDS = "waitseconds"; + public const string MNS_PARAMETER_BATCH_SIZE = "numOfMessages"; + public const string MNS_PARAMETER_PEEK_ONLY = "peekonly"; + public const string MNS_PARAMETER_RECEIPT_HANDLE = "ReceiptHandle"; + public const string MNS_PARAMETER_VISIBILITY_TIMEOUT = "VisibilityTimeout"; + + public const string MNS_MESSAGE_SUB_RESOURCE = "/messages"; + public const string MNS_MESSAGE_PRE_RESOURCE = "queues/"; + public const string MNS_TOPIC_PRE_RESOURCE = "topics/"; + public const string MNS_SUBSCRIBE_PRE_RESOURCE = "/subscriptions/"; + + public const string ContentTypeTextXml = "text/xml"; + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Util/TypeWrapper.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Util/TypeWrapper.cs new file mode 100644 index 0000000000..5f0b3386e4 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/MNS/Util/TypeWrapper.cs @@ -0,0 +1,335 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +namespace Aliyun.Acs.Dybaseapi.MNS.Util +{ + internal interface ITypeInfo + { + Type BaseType { get; } + + Type Type { get; } + + Assembly Assembly { get; } + bool IsArray { get; } + + Array ArrayCreateInstance(int length); + + Type GetInterface(string name); + Type[] GetInterfaces(); + + IEnumerable GetProperties(); + + IEnumerable GetFields(); + FieldInfo GetField(string name); + + MethodInfo GetMethod(string name); + MethodInfo GetMethod(string name, ITypeInfo[] paramTypes); + + MemberInfo[] GetMembers(); + + + ConstructorInfo GetConstructor(ITypeInfo[] paramTypes); + + PropertyInfo GetProperty(string name); + + bool IsAssignableFrom(ITypeInfo typeInfo); + + bool IsEnum {get;} + + bool IsClass { get; } + bool IsValueType { get; } + + bool IsInterface { get; } + bool IsAbstract { get; } + + object EnumToObject(object value); + + ITypeInfo EnumGetUnderlyingType(); + + object CreateInstance(); + + ITypeInfo GetElementType(); + + bool IsType(Type type); + + string FullName { get; } + string Name { get; } + + bool IsGenericTypeDefinition { get; } + bool IsGenericType { get; } + bool ContainsGenericParameters { get; } + Type GetGenericTypeDefinition(); + Type[] GetGenericArguments(); + + object[] GetCustomAttributes(bool inherit); + object[] GetCustomAttributes(ITypeInfo attributeType, bool inherit); + + } + + internal static partial class TypeFactory + { + public static readonly ITypeInfo[] EmptyTypes = new ITypeInfo[] { }; + public static ITypeInfo GetTypeInfo(Type type) + { + if (type == null) + return null; + + return new TypeInfoWrapper(type); + } + + abstract class AbstractTypeInfo : ITypeInfo + { + protected Type _type; + + internal AbstractTypeInfo(Type type) + { + this._type = type; + } + + public Type Type + { + get{return this._type;} + } + + public override int GetHashCode() + { + return this._type.GetHashCode(); + } + + public override bool Equals(object obj) + { + var typeWrapper = obj as AbstractTypeInfo; + if (typeWrapper == null) + return false; + + return this._type.Equals(typeWrapper._type); + } + + public bool IsType(Type type) + { + return this._type == type; + } + + public abstract Type BaseType { get; } + public abstract Assembly Assembly { get; } + public abstract Type GetInterface(string name); + public abstract Type[] GetInterfaces(); + public abstract IEnumerable GetProperties(); + public abstract IEnumerable GetFields(); + public abstract FieldInfo GetField(string name); + public abstract MethodInfo GetMethod(string name); + public abstract MethodInfo GetMethod(string name, ITypeInfo[] paramTypes); + public abstract MemberInfo[] GetMembers(); + public abstract PropertyInfo GetProperty(string name); + public abstract bool IsAssignableFrom(ITypeInfo typeInfo); + public abstract bool IsClass { get; } + public abstract bool IsInterface { get; } + public abstract bool IsAbstract { get; } + public abstract bool IsEnum { get; } + public abstract bool IsValueType { get; } + public abstract ConstructorInfo GetConstructor(ITypeInfo[] paramTypes); + + public abstract object[] GetCustomAttributes(bool inherit); + public abstract object[] GetCustomAttributes(ITypeInfo attributeType, bool inherit); + + public abstract bool ContainsGenericParameters { get; } + public abstract bool IsGenericTypeDefinition { get; } + public abstract bool IsGenericType {get;} + public abstract Type GetGenericTypeDefinition(); + public abstract Type[] GetGenericArguments(); + + public bool IsArray + { + get { return this._type.IsArray; } + } + + + public object EnumToObject(object value) + { + return Enum.ToObject(this._type, value); + } + + public ITypeInfo EnumGetUnderlyingType() + { + return TypeFactory.GetTypeInfo(Enum.GetUnderlyingType(this._type)); + } + + public object CreateInstance() + { + return Activator.CreateInstance(this._type); + } + + public Array ArrayCreateInstance(int length) + { + return Array.CreateInstance(this._type, length); + } + + public ITypeInfo GetElementType() + { + return TypeFactory.GetTypeInfo(this._type.GetElementType()); + } + + public string FullName + { + get + { + return this._type.FullName; + } + } + + public string Name + { + get + { + return this._type.Name; + } + } + } + } + + internal static partial class TypeFactory + { + class TypeInfoWrapper : AbstractTypeInfo + { + internal TypeInfoWrapper(Type type) + : base(type) + { + } + + public override Type BaseType + { + get { return this._type.BaseType; } + } + + public override FieldInfo GetField(string name) + { + return this._type.GetField(name); + } + + public override Type GetInterface(string name) + { + return this._type.GetInterfaces().FirstOrDefault(x => (x.Namespace + "." + x.Name) == name); + } + + public override Type[] GetInterfaces() + { + return this._type.GetInterfaces(); + } + + public override IEnumerable GetProperties() + { + return this._type.GetProperties(); + } + + public override IEnumerable GetFields() + { + return this._type.GetFields(); + } + + public override MemberInfo[] GetMembers() + { + return this._type.GetMembers(); + } + + public override bool IsClass + { + get { return this._type.IsClass; } + } + + public override bool IsValueType + { + get { return this._type.IsValueType; } + } + + public override bool IsInterface + { + get { return this._type.IsInterface; } + } + + public override bool IsAbstract + { + get { return this._type.IsAbstract; } + } + + public override bool IsEnum + { + get { return this._type.IsEnum; } + } + + public override MethodInfo GetMethod(string name) + { + return this._type.GetMethod(name); + } + + public override MethodInfo GetMethod(string name, ITypeInfo[] paramTypes) + { + Type[] types = new Type[paramTypes.Length]; + for (int i = 0; i < paramTypes.Length; i++) + types[i] = ((AbstractTypeInfo)paramTypes[i]).Type; + return this._type.GetMethod(name, types); + } + + public override ConstructorInfo GetConstructor(ITypeInfo[] paramTypes) + { + Type[] types = new Type[paramTypes.Length]; + for (int i = 0; i < paramTypes.Length; i++) + types[i] = ((AbstractTypeInfo)paramTypes[i]).Type; + var constructor = this._type.GetConstructor(types); + return constructor; + } + + public override PropertyInfo GetProperty(string name) + { + return this._type.GetProperty(name); + } + + public override bool IsAssignableFrom(ITypeInfo typeInfo) + { + return this._type.IsAssignableFrom(((AbstractTypeInfo)typeInfo).Type); + } + + public override bool ContainsGenericParameters + { + get { return this._type.ContainsGenericParameters; } + } + + public override bool IsGenericTypeDefinition + { + get { return this._type.IsGenericTypeDefinition; } + } + + public override bool IsGenericType + { + get { return this._type.IsGenericType; } + } + + public override Type GetGenericTypeDefinition() + { + return this._type.GetGenericTypeDefinition(); + } + + public override Type[] GetGenericArguments() + { + return this._type.GetGenericArguments(); + } + + public override object[] GetCustomAttributes(bool inherit) + { + return this._type.GetCustomAttributes(inherit); + } + + public override object[] GetCustomAttributes(ITypeInfo attributeType, bool inherit) + { + return this._type.GetCustomAttributes(((TypeInfoWrapper)attributeType)._type, inherit); + } + + public override Assembly Assembly + { + get { return this._type.Assembly; } + } + } + + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/Model/V20170525/QueryTokenForMnsQueueRequest.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/Model/V20170525/QueryTokenForMnsQueueRequest.cs new file mode 100755 index 0000000000..cc6e40c92c --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/Model/V20170525/QueryTokenForMnsQueueRequest.cs @@ -0,0 +1,117 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License 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.Collections.Generic; + +using Aliyun.Acs.Core; +using Aliyun.Acs.Core.Http; +using Aliyun.Acs.Core.Transform; +using Aliyun.Acs.Core.Utils; +using Aliyun.Acs.Dybaseapi.Transform; +using Aliyun.Acs.Dybaseapi.Transform.V20170525; + +namespace Aliyun.Acs.Dybaseapi.Model.V20170525 +{ + public class QueryTokenForMnsQueueRequest : RpcAcsRequest + { + public QueryTokenForMnsQueueRequest() + : base("Dybaseapi", "2017-05-25", "QueryTokenForMnsQueue", "dybaseapi", "openAPI") + { + } + + private string queueName; + + private long? resourceOwnerId; + + private string resourceOwnerAccount; + + private string messageType; + + private long? ownerId; + + public string QueueName + { + get + { + return queueName; + } + set + { + queueName = value; + DictionaryUtil.Add(QueryParameters, "QueueName", value); + } + } + + public long? ResourceOwnerId + { + get + { + return resourceOwnerId; + } + set + { + resourceOwnerId = value; + DictionaryUtil.Add(QueryParameters, "ResourceOwnerId", value.ToString()); + } + } + + public string ResourceOwnerAccount + { + get + { + return resourceOwnerAccount; + } + set + { + resourceOwnerAccount = value; + DictionaryUtil.Add(QueryParameters, "ResourceOwnerAccount", value); + } + } + + public string MessageType + { + get + { + return messageType; + } + set + { + messageType = value; + DictionaryUtil.Add(QueryParameters, "MessageType", value); + } + } + + public long? OwnerId + { + get + { + return ownerId; + } + set + { + ownerId = value; + DictionaryUtil.Add(QueryParameters, "OwnerId", value.ToString()); + } + } + + public override QueryTokenForMnsQueueResponse GetResponse(UnmarshallerContext unmarshallerContext) + { + return QueryTokenForMnsQueueResponseUnmarshaller.Unmarshall(unmarshallerContext); + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/Model/V20170525/QueryTokenForMnsQueueResponse.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/Model/V20170525/QueryTokenForMnsQueueResponse.cs new file mode 100755 index 0000000000..f5a4ffd06a --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/Model/V20170525/QueryTokenForMnsQueueResponse.cs @@ -0,0 +1,158 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License 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.Collections.Generic; + +using Aliyun.Acs.Core; + +namespace Aliyun.Acs.Dybaseapi.Model.V20170525 +{ + public class QueryTokenForMnsQueueResponse : AcsResponse + { + + private string requestId; + + private string code; + + private string message; + + private QueryTokenForMnsQueue_MessageTokenDTO messageTokenDTO; + + public string RequestId + { + get + { + return requestId; + } + set + { + requestId = value; + } + } + + public string Code + { + get + { + return code; + } + set + { + code = value; + } + } + + public string Message + { + get + { + return message; + } + set + { + message = value; + } + } + + public QueryTokenForMnsQueue_MessageTokenDTO MessageTokenDTO + { + get + { + return messageTokenDTO; + } + set + { + messageTokenDTO = value; + } + } + + public class QueryTokenForMnsQueue_MessageTokenDTO + { + + private string accessKeyId; + + private string accessKeySecret; + + private string securityToken; + + private string createTime; + + private string expireTime; + + public string AccessKeyId + { + get + { + return accessKeyId; + } + set + { + accessKeyId = value; + } + } + + public string AccessKeySecret + { + get + { + return accessKeySecret; + } + set + { + accessKeySecret = value; + } + } + + public string SecurityToken + { + get + { + return securityToken; + } + set + { + securityToken = value; + } + } + + public string CreateTime + { + get + { + return createTime; + } + set + { + createTime = value; + } + } + + public string ExpireTime + { + get + { + return expireTime; + } + set + { + expireTime = value; + } + } + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/Dybaseapi/Transform/V20170525/QueryTokenForMnsQueueResponseUnmarshaller.cs b/aliyun-net-sdk-dybaseapi/Dybaseapi/Transform/V20170525/QueryTokenForMnsQueueResponseUnmarshaller.cs new file mode 100755 index 0000000000..f5538b931a --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/Dybaseapi/Transform/V20170525/QueryTokenForMnsQueueResponseUnmarshaller.cs @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License 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 Aliyun.Acs.Core.Transform; +using Aliyun.Acs.Dybaseapi.Model.V20170525; + +namespace Aliyun.Acs.Dybaseapi.Transform.V20170525 +{ + public class QueryTokenForMnsQueueResponseUnmarshaller + { + public static QueryTokenForMnsQueueResponse Unmarshall(UnmarshallerContext context) + { + QueryTokenForMnsQueueResponse queryTokenForMnsQueueResponse = new QueryTokenForMnsQueueResponse(); + + queryTokenForMnsQueueResponse.HttpResponse = context.HttpResponse; + queryTokenForMnsQueueResponse.RequestId = context.StringValue("QueryTokenForMnsQueue.RequestId"); + queryTokenForMnsQueueResponse.Code = context.StringValue("QueryTokenForMnsQueue.Code"); + queryTokenForMnsQueueResponse.Message = context.StringValue("QueryTokenForMnsQueue.Message"); + + QueryTokenForMnsQueueResponse.QueryTokenForMnsQueue_MessageTokenDTO messageTokenDTO = new QueryTokenForMnsQueueResponse.QueryTokenForMnsQueue_MessageTokenDTO(); + messageTokenDTO.AccessKeyId = context.StringValue("QueryTokenForMnsQueue.MessageTokenDTO.AccessKeyId"); + messageTokenDTO.AccessKeySecret = context.StringValue("QueryTokenForMnsQueue.MessageTokenDTO.AccessKeySecret"); + messageTokenDTO.SecurityToken = context.StringValue("QueryTokenForMnsQueue.MessageTokenDTO.SecurityToken"); + messageTokenDTO.CreateTime = context.StringValue("QueryTokenForMnsQueue.MessageTokenDTO.CreateTime"); + messageTokenDTO.ExpireTime = context.StringValue("QueryTokenForMnsQueue.MessageTokenDTO.ExpireTime"); + queryTokenForMnsQueueResponse.MessageTokenDTO = messageTokenDTO; + + return queryTokenForMnsQueueResponse; + } + } +} diff --git a/aliyun-net-sdk-dybaseapi/aliyun-net-sdk-dybaseapi.vs2010.csproj b/aliyun-net-sdk-dybaseapi/aliyun-net-sdk-dybaseapi.vs2010.csproj new file mode 100644 index 0000000000..63c0615f01 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/aliyun-net-sdk-dybaseapi.vs2010.csproj @@ -0,0 +1,60 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {b5caa4e7-6630-40f9-beb3-f9696a53b885} + Library + Properties + Aliyun.Acs + aliyun-net-sdk-dybaseapi + v4.0 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + {bb84cecb-295d-4772-a669-3726e511ccfa} + aliyun-net-sdk-core.vs2010 + + + + + \ No newline at end of file diff --git a/aliyun-net-sdk-dybaseapi/aliyun-net-sdk-dybaseapi.vs2017.csproj b/aliyun-net-sdk-dybaseapi/aliyun-net-sdk-dybaseapi.vs2017.csproj new file mode 100755 index 0000000000..9a60dc9137 --- /dev/null +++ b/aliyun-net-sdk-dybaseapi/aliyun-net-sdk-dybaseapi.vs2017.csproj @@ -0,0 +1,40 @@ + + + + netstandard2.0;net45 + Aliyun.Acs.Dybaseapi + 1.0.1 + Alibaba Cloud + ©2009-2019 Alibaba Cloud + false + https://raw.githubusercontent.com/aliyun/aliyun-openapi-net-sdk/master/LICENSE + https://github.com/aliyun/aliyun-openapi-net-sdk + https://www.alibabacloud.com/favicon.ico + Alibaba Cloud SDK for .NET + + alibaba aliyun SDK Dybaseapi + aliyun-net-sdk-dybaseapi + + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + + + + + + + + + + + \ No newline at end of file