Beispiel #1
0
        static async Task Main(string[] args)
        {
            Logger.LogInformation($"Starting Relayer with the following settings: \r\n{Settings.Current}");
            ModuleClient moduleClient = null;

            try
            {
                moduleClient = await ModuleUtil.CreateModuleClientAsync(
                    Settings.Current.TransportType,
                    new ClientOptions(),
                    ModuleUtil.DefaultTimeoutErrorDetectionStrategy,
                    ModuleUtil.DefaultTransientRetryStrategy,
                    Logger);

                DuplicateMessageAuditor duplicateMessageAuditor = new DuplicateMessageAuditor(Settings.Current.MessageDuplicateTolerance);
                MessageHandlerContext   messageHandlerContext   = new MessageHandlerContext(moduleClient, duplicateMessageAuditor);

                (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(TimeSpan.FromSeconds(5), Logger);

                await SetIsFinishedDirectMethodAsync(moduleClient);

                // Receive a message and call ProcessAndSendMessageAsync to send it on its way
                await moduleClient.SetInputMessageHandlerAsync(Settings.Current.InputName, ProcessAndSendMessageAsync, messageHandlerContext);

                await cts.Token.WhenCanceled();

                completed.Set();
                handler.ForEach(h => GC.KeepAlive(h));
                Logger.LogInformation("Relayer Main() finished.");
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, "Error occurred during Relayer.");
            }
            finally
            {
                moduleClient?.CloseAsync();
                moduleClient?.Dispose();
            }
        }
Beispiel #2
0
        static async Task <MessageResponse> ProcessAndSendMessageAsync(Message message, object userContext)
        {
            Logger.LogInformation($"Received message from device: {message.ConnectionDeviceId}, module: {message.ConnectionModuleId}");

            var testResultCoordinatorUrl = Option.None <Uri>();

            if (Settings.Current.EnableTrcReporting)
            {
                var builder = new UriBuilder(Settings.Current.TestResultCoordinatorUrl);
                builder.Host             = Dns.GetHostEntry(Settings.Current.TestResultCoordinatorUrl.Host).AddressList[0].ToString();
                testResultCoordinatorUrl = Option.Some(builder.Uri);
            }

            try
            {
                if (!(userContext is MessageHandlerContext messageHandlerContext))
                {
                    throw new InvalidOperationException("UserContext doesn't contain expected value");
                }

                ModuleClient            moduleClient            = messageHandlerContext.ModuleClient;
                DuplicateMessageAuditor duplicateMessageAuditor = messageHandlerContext.DuplicateMessageAuditor;

                // Must make a new message instead of reusing the old message because of the way the SDK sends messages
                string trackingId                = string.Empty;
                string batchId                   = string.Empty;
                string sequenceNumber            = string.Empty;
                var    messageProperties         = new List <KeyValuePair <string, string> >();
                var    testResultReportingClient = Option.None <TestResultReportingClient>();

                if (Settings.Current.EnableTrcReporting)
                {
                    foreach (KeyValuePair <string, string> prop in message.Properties)
                    {
                        switch (prop.Key)
                        {
                        case TestConstants.Message.TrackingIdPropertyName:
                            trackingId = prop.Value ?? string.Empty;
                            break;

                        case TestConstants.Message.BatchIdPropertyName:
                            batchId = prop.Value ?? string.Empty;
                            break;

                        case TestConstants.Message.SequenceNumberPropertyName:
                            sequenceNumber = prop.Value ?? string.Empty;
                            break;
                        }

                        messageProperties.Add(new KeyValuePair <string, string>(prop.Key, prop.Value));
                    }

                    if (string.IsNullOrWhiteSpace(trackingId) || string.IsNullOrWhiteSpace(batchId) || string.IsNullOrWhiteSpace(sequenceNumber))
                    {
                        Logger.LogWarning($"Received message missing info: trackingid={trackingId}, batchId={batchId}, sequenceNumber={sequenceNumber}");
                        return(MessageResponse.Completed);
                    }

                    if (duplicateMessageAuditor.ShouldFilterMessage(sequenceNumber))
                    {
                        return(MessageResponse.Completed);
                    }

                    // Report receiving message successfully to Test Result Coordinator
                    testResultReportingClient = Option.Some(new TestResultReportingClient {
                        BaseUrl = testResultCoordinatorUrl.OrDefault().AbsoluteUri
                    });
                    var testResultReceived = new MessageTestResult(Settings.Current.ModuleId + ".receive", DateTime.UtcNow)
                    {
                        TrackingId     = trackingId,
                        BatchId        = batchId,
                        SequenceNumber = sequenceNumber
                    };

                    await ModuleUtil.ReportTestResultAsync(testResultReportingClient.OrDefault(), Logger, testResultReceived);

                    Logger.LogInformation($"Successfully received message: trackingid={trackingId}, batchId={batchId}, sequenceNumber={sequenceNumber}");
                }

                if (!Settings.Current.ReceiveOnly)
                {
                    byte[] messageBytes = message.GetBytes();
                    var    messageCopy  = new Message(messageBytes);
                    messageProperties.ForEach(kvp => messageCopy.Properties.Add(kvp));
                    await moduleClient.SendEventAsync(Settings.Current.OutputName, messageCopy);

                    Logger.LogInformation($"Message relayed upstream for device: {message.ConnectionDeviceId}, module: {message.ConnectionModuleId}");

                    if (Settings.Current.EnableTrcReporting)
                    {
                        // Report sending message successfully to Test Result Coordinator
                        var testResultSent = new MessageTestResult(Settings.Current.ModuleId + ".send", DateTime.UtcNow)
                        {
                            TrackingId     = trackingId,
                            BatchId        = batchId,
                            SequenceNumber = sequenceNumber
                        };

                        await ModuleUtil.ReportTestResultAsync(testResultReportingClient.OrDefault(), Logger, testResultSent);

                        Logger.LogInformation($"Successfully reported message: trackingid={trackingId}, batchId={batchId}, sequenceNumber={sequenceNumber}");
                    }
                }
                else
                {
                    int uniqueResultsExpected = Settings.Current.UniqueResultsExpected.Expect <ArgumentException>(() => throw new ArgumentException("Must supply this value if in ReceiveOnly mode"));
                    if (!resultsReceived.Contains(sequenceNumber))
                    {
                        resultsReceived.Add(sequenceNumber);
                    }

                    if (resultsReceived.Count == uniqueResultsExpected)
                    {
                        isFinished = true;
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, $"Error in {nameof(ProcessAndSendMessageAsync)} method");
            }

            return(MessageResponse.Completed);
        }
Beispiel #3
0
 public MessageHandlerContext(ModuleClient moduleClient, DuplicateMessageAuditor duplicateMessageAuditor)
 {
     this.ModuleClient            = moduleClient;
     this.DuplicateMessageAuditor = duplicateMessageAuditor;
 }