/// <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
                });
            }
Exemplo n.º 2
0
            /// <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);
            }