Beispiel #1
0
        public async Task <HttpResponseMessage> OnInboundMessageReceived(string connectorName, HttpRequestMessage request, CancellationToken cancellationToken)
        {
            try
            {
                var metadata = await this.credentialManager.GetMetadata(connectorName);

                if (metadata != null)
                {
                    InboundAgent agent = null;
                    try
                    {
                        agent = new InboundAgent(metadata.ConnectorUri);

                        // Get credential
                        var connectorId = await agent.ParseConnectorIdFromInboundMessageAsync(request, cancellationToken);

                        if (string.IsNullOrEmpty(connectorId))
                        {
                            SmsProviderEventSource.Current.Warning(SmsProviderEventSource.EmptyTrackingId, this, nameof(OnInboundMessageReceived), OperationStates.FailedMatch, $"Failed to get connector key for '{connectorName}'.");
                            return(request.CreateResponse(HttpStatusCode.Unauthorized));
                        }

                        var identifier = new ConnectorIdentifier(connectorName, connectorId);
                        SmsConnectorCredential credential = null;

                        try
                        {
                            credential = await this.credentialManager.GetConnectorCredentialByIdAsync(identifier);
                        }
                        catch
                        {
                            SmsProviderEventSource.Current.Warning(SmsProviderEventSource.EmptyTrackingId, this, nameof(OnInboundMessageReceived), OperationStates.FailedMatch, $"Failed to get credential for {identifier}.");
                            return(request.CreateResponse(HttpStatusCode.Unauthorized));
                        }

                        // Parse and save messages
                        var result = await agent.ParseInboundRequestAsync(request, credential.ToDataContract(metadata), cancellationToken);

                        SmsProviderEventSource.Current.Info(SmsProviderEventSource.EmptyTrackingId, this, nameof(OnInboundMessageReceived), OperationStates.InProgress, $"Complete parsing code={result.Response.HttpStatusCode} message={result.Messages?.Count ?? 0}");

                        if (result.Type == InboundType.MoMessage)
                        {
                            await SaveMoMessageAsync(result.Messages, agent, cancellationToken);
                        }
                        else if (result.Type == InboundType.Report)
                        {
                            var saveResult = await SaveReportMessageAsync(result.Messages, identifier);

                            if (!saveResult)
                            {
                                result.Response.HttpStatusCode = (int)HttpStatusCode.InternalServerError;
                            }
                        }

                        SmsProviderEventSource.Current.Info(SmsProviderEventSource.EmptyTrackingId, this, nameof(OnInboundMessageReceived), OperationStates.Succeeded, $"Complete parsing code={result.Response.HttpStatusCode} message={result.Messages?.Count ?? 0}");
                        return(result.Response.ToHttpResponseMessage());
                    }
                    finally
                    {
                        if (agent != null)
                        {
                            agent.Dispose();
                        }
                    }
                }

                SmsProviderEventSource.Current.Warning(SmsProviderEventSource.EmptyTrackingId, this, nameof(OnInboundMessageReceived), OperationStates.FailedMatch, $"Inbound message received from invalid connector '{connectorName}'.");
                return(request.CreateResponse(HttpStatusCode.Forbidden));
            }
            catch (Exception ex)
            {
                SmsProviderEventSource.Current.ErrorException(SmsProviderEventSource.EmptyTrackingId, this, nameof(this.OnInboundMessageReceived), OperationStates.Failed, "Failed to process inbound message", ex);
                return(request.CreateResponse(HttpStatusCode.InternalServerError));
            }
        }
Beispiel #2
0
        private async Task SaveMoMessageAsync(Dictionary <ConnectorIdentifier, List <InboundMessage> > messages, InboundAgent agent, CancellationToken cancellationToken)
        {
            if (messages == null || messages.Count <= 0)
            {
                return;
            }

            foreach (var kv in messages)
            {
                var sharedAccounts = await this.credentialManager.ListCredentialAssignmentsById(kv.Key, true);

                if (sharedAccounts == null || sharedAccounts.Count <= 0)
                {
                    continue;
                }

                var groups = kv.Value.Where(v => v.MoMessage != null).GroupBy(m => m.MoMessage.ExtendedCode);
                foreach (var group in groups)
                {
                    var extended = group.Key;
                    var segments = await agent.ParseExtendedCodeAsync(extended, Constants.ExtendedCodeSegmentLengths, cancellationToken);

                    if (segments != null && segments.Count != 3)
                    {
                        SmsProviderEventSource.Current.Error(SmsProviderEventSource.EmptyTrackingId, this, nameof(this.SaveMoMessageAsync), OperationStates.Dropped, $"Dropped the message as connector parsing extended code error with segment={segments.Count}.");
                        continue;
                    }

                    var accountCode = segments?[0];
                    var sigCode     = segments?[1];
                    var customCode  = segments?[2];

                    ConnectorCredentialAssignment account = null;

                    // case #1: credential is not shared by multiple accounts
                    if ((segments == null || string.IsNullOrEmpty(accountCode)) && sharedAccounts.Count == 1)
                    {
                        account = sharedAccounts.SingleOrDefault();
                    }

                    // case #2: credentials are shared between accounts
                    else if (!string.IsNullOrEmpty(accountCode) && !string.IsNullOrEmpty(sigCode))
                    {
                        account = sharedAccounts.SingleOrDefault(a => a.ExtendedCode.Equals(accountCode, StringComparison.OrdinalIgnoreCase));
                    }

                    if (account != null)
                    {
                        Signature signature = null;
                        if (!string.IsNullOrEmpty(sigCode))
                        {
                            var signatureList = await this.store.ListSignaturesAsync(account.EngagementAccount, new Common.Pagination.DbContinuationToken(null), -1);

                            signature = signatureList?.Signatures?.SingleOrDefault(s => s.ExtendedCode.Equals(sigCode));
                        }
                        else
                        {
                            signature = new Signature
                            {
                                EngagementAccount = account.EngagementAccount,
                                Value             = null
                            };
                        }

                        if (signature != null)
                        {
                            await this.telemetryManager.InsertInboundMessagesAsync(signature, group.ToList(), customCode);

                            continue;
                        }
                    }

                    SmsProviderEventSource.Current.Warning(SmsProviderEventSource.EmptyTrackingId, this, nameof(this.SaveMoMessageAsync), OperationStates.Dropped, $"Dropped the message as we cannot find the owner. connector={kv.Key} extended={extended}");
                }
            }
        }