/// <summary> /// Gets the response from method. /// </summary> /// <param name="transactionServiceInvoker">Delegate that invokes a specific operation on channel object.</param> /// <param name="methodName">Name of the method.</param> /// <param name="parameterCount">Number of parameters used during the call. Used for instrumentation purposes.</param> /// <returns>The service response.</returns> private CP.RetailTransactionServiceResponse GetResponseFromMethod(TransactionServiceInvoker transactionServiceInvoker, string methodName, int parameterCount) { CP.RetailTransactionServiceResponse response = null; using (RealTimeServiceClientBoundaryPerfContext perfContext = new RealTimeServiceClientBoundaryPerfContext()) { Guid correlationId = Guid.NewGuid(); Guid relatedActivityId = Guid.NewGuid(); RetailLogger.Log.CrtTransactionServiceClientRtsCallStarted(correlationId, methodName, parameterCount, relatedActivityId); int resultCount = -1; string language = null; string company = null; CP.RetailRealTimeServiceContractChannel channel = null; Exception exception = null; try { channel = this.clientFactory.CreateTransactionServiceClient(); // Add HTTP header attribute named 'ms-dyn-aid' with value as activity id. using (var contextScope = new OperationContextScope(channel)) { this.SetActivityIdInHttpHeader(relatedActivityId); CP.RetailTransactionServiceRequestInfo requestInfo = this.clientFactory.CreateRequestInfo(); company = requestInfo.Company; language = requestInfo.Language; response = transactionServiceInvoker(channel, requestInfo); channel.Close(); } } catch (System.ServiceModel.CommunicationException ex) { // Retrieves the SubCode in the fault exception, and maps them to corresponding error resources and diagnostic entries. CommunicationErrors errorResourceId = CommunicationErrors.Microsoft_Dynamics_Commerce_Runtime_HeadquarterCommunicationFailure; string errorMessage = string.Empty; Tuple <string, string> faultCodes = TransactionServiceClient.ParseFaultException(ex); if (faultCodes.Item2.Equals(TransactionServiceClient.FailedAuthenticationFaultCode, StringComparison.OrdinalIgnoreCase)) { errorMessage = string.Format( "Real-time Service call for method '{0}' failed due to security reason such as misconfigured, or expired Real-time Service certificate. Please also verify if the Real-time Service certificate is being properly configured in AX.", methodName); errorResourceId = CommunicationErrors.Microsoft_Dynamics_Commerce_Runtime_TransactionServiceAuthenticationFailedFault; } else if (faultCodes.Item2.Equals(TransactionServiceClient.ForbiddenFaultCode, StringComparison.OrdinalIgnoreCase)) { errorMessage = string.Format( "Real-time Service call for method '{0}' failed due to invalid Real-time Service profile settings. Please make sure the Real-time Service profile user and identity provider fields are defined correctly in AX.", methodName); errorResourceId = CommunicationErrors.Microsoft_Dynamics_Commerce_Runtime_TransactionServiceForbiddenFault; } else if (faultCodes.Item1.Equals(TransactionServiceClient.SenderFaultCode, StringComparison.OrdinalIgnoreCase)) { errorMessage = string.Format( "Real-time Service call for method '{0}' failed due to an unhandled exception, or due to invalid user permissions settings in Real-time Service profile. Please refer to the exception details for more information.", methodName); errorResourceId = CommunicationErrors.Microsoft_Dynamics_Commerce_Runtime_TransactionServiceSenderFault; } exception = TransactionServiceClient.CreateCommunicationException(methodName, ex, errorResourceId, errorMessage); } catch (SecurityTokenException ex) { // channel.Abort() will never throw if (channel != null) { channel.Abort(); } exception = TransactionServiceClient.CreateCommunicationException(methodName, ex, CommunicationErrors.Microsoft_Dynamics_Commerce_Runtime_HeadquarterCommunicationFailure); } catch (TimeoutException ex) { exception = TransactionServiceClient.CreateCommunicationException(methodName, ex, CommunicationErrors.Microsoft_Dynamics_Commerce_Runtime_TransactionServiceTimeOut); } catch (Exception ex) { // channel.Abort() will never throw if (channel != null) { channel.Abort(); } exception = TransactionServiceClient.CreateCommunicationException(methodName, ex, CommunicationErrors.Microsoft_Dynamics_Commerce_Runtime_TransactionServiceException); } // Throws an exception wrapping localized AX message for unsuccessful request. if (exception == null && !response.Success) { exception = new HeadquarterTransactionServiceException( response.Data, string.Format("Real-time Service was successfully connected, but the method call {0} failed with this error : {1}", methodName, response.Message)) { // Since content in the response.Message is already localized on AX, we copy it directly to user message field. LocalizedMessage = response.Message }; } else if (response != null && response.Data != null) { resultCount = response.Data.Length; } if (exception != null) { RetailLogger.Log.CrtTransactionServiceClientRtsCallError(correlationId, methodName, parameterCount, language, company, exception.GetType().ToString(), exception, relatedActivityId); throw exception; } perfContext.ResultsCount = resultCount; perfContext.CallWasSuccessful(); RetailLogger.Log.CrtTransactionServiceClientRtsCallSuccessful(correlationId, methodName, parameterCount, resultCount, language, company, relatedActivityId); } return(response); }
/// <summary> /// Creates the mapped exception for <see cref="Exception"/> returned during invoking realtime transaction service method. /// </summary> /// <param name="methodName">The method name.</param> /// <param name="exception">The exception.</param> /// <param name="errorResourceId">The <see cref="CommunicationErrors"/> enumeration.</param> /// <param name="errorMessage">The error message in the communication exception.</param> /// <returns>The <see cref="CommunicationException"/>.</returns> public static CRT.CommunicationException CreateCommunicationException(string methodName, Exception exception, CommunicationErrors errorResourceId, string errorMessage = "") { ThrowIf.Null(methodName, "methodName"); ThrowIf.Null(exception, "exception"); errorMessage = string.IsNullOrWhiteSpace(errorMessage) ? string.Format("Exception while calling invoke method {0}: {1}", methodName, exception.Message) : errorMessage; return(new CRT.CommunicationException( errorResourceId, exception, errorMessage)); }