/// <summary> /// Deactivate a device in AX. /// </summary> /// <param name="deviceNumber">The device number.</param> /// <param name="terminalId">The terminal identifier.</param> /// <param name="staffId">The staff identifier.</param> /// <param name="deviceToken">The device token.</param> /// <returns>The deactivated device.</returns> internal DeviceDeactivationResult DeactivateDevice(string deviceNumber, string terminalId, string staffId, string deviceToken) { const int InvalidTokenError = 1; ThrowIf.Null(deviceNumber, "deviceNumber"); ThrowIf.Null(terminalId, "terminalId"); ThrowIf.Null(staffId, "staffId"); ReadOnlyCollection <object> data; HeadquarterTransactionServiceException deactivationException = null; try { data = this.InvokeMethod(DeactivateDeviceMethodName, new object[] { deviceNumber, terminalId, staffId, deviceToken }); } catch (HeadquarterTransactionServiceException exception) { data = exception.HeadquartersErrorData; if (data.Count == DeviceDeactivationInvalidTokenResponseSize) { int errorCode = (int)data[DeviceDeactivationInvalidTokenResponseSize - 1]; if (errorCode == InvalidTokenError) { RetailLogger.Log.CrtServicesDeactiveDeviceFailedDueToInvalidToken(staffId, deviceNumber, terminalId); deactivationException = exception; } else { throw; } } else { throw; } } if (data == null || data.Count < DeviceDeactivationResponseSize) { throw new Microsoft.Dynamics.Commerce.Runtime.CommunicationException(CommunicationErrors.Microsoft_Dynamics_Commerce_Runtime_HeadquarterResponseParsingError); } Microsoft.Dynamics.Commerce.Runtime.DataModel.Device device = this.CreateDevice(data); return(new DeviceDeactivationResult() { Device = device, ErrorMessage = deactivationException == null ? null : deactivationException.Message }); }
/// <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); }