Example #1
0
 Task <Util.Option <ICloudProxy> > GetCloudProxy(IRoutingMessage routingMessage)
 {
     return(this.GetIdentity(routingMessage).Map(
                async id =>
     {
         Util.Option <ICloudProxy> cloudProxy = await this.cloudEndpoint.cloudProxyGetterFunc(id);
         if (!cloudProxy.HasValue)
         {
             Events.IoTHubNotConnected(id);
         }
         return cloudProxy;
     })
            .GetOrElse(() => Task.FromResult(Option.None <ICloudProxy>())));
 }
Example #2
0
            async Task <ISinkResult <IRoutingMessage> > ProcessClientMessagesBatch(string id, List <IRoutingMessage> routingMessages, CancellationToken token)
            {
                if (string.IsNullOrEmpty(id))
                {
                    return(HandleNoIdentity(routingMessages));
                }

                if (token.IsCancellationRequested)
                {
                    return(HandleCancelled(routingMessages));
                }

                Util.Option <ICloudProxy> cloudProxy = await this.cloudEndpoint.cloudProxyGetterFunc(id);

                ISinkResult result = await cloudProxy.Match(
                    async cp =>
                {
                    try
                    {
                        List <IMessage> messages = routingMessages
                                                   .Select(r => this.cloudEndpoint.messageConverter.ToMessage(r))
                                                   .ToList();

                        using (MetricsV0.CloudLatency(id))
                        {
                            if (messages.Count == 1)
                            {
                                await cp.SendMessageAsync(messages[0]);
                            }
                            else
                            {
                                await cp.SendMessageBatchAsync(messages);
                            }
                        }

                        MetricsV0.MessageCount(id, messages.Count);

                        return(new SinkResult <IRoutingMessage>(routingMessages));
                    }
                    catch (Exception ex)
                    {
                        return(this.HandleException(ex, id, routingMessages));
                    }
                },
                    () => Task.FromResult(HandleNoConnection(id, routingMessages)));

                return(result);
            }
            public async Task <ISinkResult> ProcessAsync(IRoutingMessage routingMessage, CancellationToken token)
            {
                Preconditions.CheckNotNull(routingMessage, nameof(routingMessage));
                var succeeded = new List <IRoutingMessage>();
                var failed    = new List <IRoutingMessage>();
                var invalid   = new List <InvalidDetails <IRoutingMessage> >();
                SendFailureDetails sendFailureDetails = null;

                IMessage message = this.cloudEndpoint.messageConverter.ToMessage(routingMessage);

                Util.Option <ICloudProxy> cloudProxy = this.GetCloudProxy(routingMessage);
                if (!cloudProxy.HasValue)
                {
                    sendFailureDetails = new SendFailureDetails(FailureKind.None, new EdgeHubConnectionException("IoT Hub is not connected"));
                    failed.Add(routingMessage);
                }
                else
                {
                    await cloudProxy.ForEachAsync(async cp =>
                    {
                        try
                        {
                            await cp.SendMessageAsync(message);
                            succeeded.Add(routingMessage);
                        }
                        catch (Exception ex)
                        {
                            if (IsRetryable(ex))
                            {
                                failed.Add(routingMessage);
                            }
                            else
                            {
                                Events.InvalidMessage(ex);
                                invalid.Add(new InvalidDetails <IRoutingMessage>(routingMessage, FailureKind.None));
                            }

                            if (failed.Count > 0)
                            {
                                Events.RetryingMessage(routingMessage, ex);
                                sendFailureDetails = new SendFailureDetails(FailureKind.Transient, new EdgeHubIOException($"Error sending messages to IotHub for device {this.cloudEndpoint.Id}"));
                            }
                        }
                    });
                }

                return(new SinkResult <IRoutingMessage>(succeeded, failed, invalid, sendFailureDetails));
            }
 Util.Option <ICloudProxy> GetCloudProxy(IRoutingMessage routingMessage)
 {
     if (routingMessage.SystemProperties.TryGetValue(SystemProperties.ConnectionDeviceId, out string deviceId))
     {
         string id = routingMessage.SystemProperties.TryGetValue(SystemProperties.ConnectionModuleId, out string moduleId)
             ? $"{deviceId}/{moduleId}"
             : deviceId;
         Util.Option <ICloudProxy> cloudProxy = this.cloudEndpoint.cloudProxyGetterFunc(id);
         if (!cloudProxy.HasValue)
         {
             Events.IoTHubNotConnected(id);
         }
         return(cloudProxy);
     }
     Events.DeviceIdNotFound(routingMessage);
     return(Option.None <ICloudProxy>());
 }
Example #5
0
 Util.Option <IDeviceProxy> GetDeviceProxy()
 {
     this.devicePoxy = this.devicePoxy.Filter(d => d.IsActive)
                       .Map(d => Option.Some(d))
                       .GetOrElse(
         () =>
     {
         Util.Option <IDeviceProxy> currentDeviceProxy = this.moduleEndpoint.connectionManager.GetDeviceConnection(this.moduleEndpoint.moduleId).Filter(d => d.IsActive);
         if (currentDeviceProxy.HasValue)
         {
             if (this.moduleEndpoint.connectionManager.GetSubscriptions(this.moduleEndpoint.moduleId)
                 .Filter(s => s.TryGetValue(DeviceSubscription.ModuleMessages, out bool isActive) && isActive)
                 .HasValue)
             {
                 return(currentDeviceProxy);
             }
             else
             {
                 Events.NoMessagesSubscription(this.moduleEndpoint.moduleId);
             }
         }
Example #6
0
            public async Task <ISinkResult> ProcessAsync(IRoutingMessage routingMessage, CancellationToken token)
            {
                Preconditions.CheckNotNull(routingMessage, nameof(routingMessage));

                if (token.IsCancellationRequested)
                {
                    Events.CancelledProcessingMessage(routingMessage);
                    var failed = new List <IRoutingMessage> {
                        routingMessage
                    };
                    var sendFailureDetails = new SendFailureDetails(FailureKind.Transient, new EdgeHubConnectionException($"Cancelled sending messages to IotHub for device {this.cloudEndpoint.Id}"));

                    return(new SinkResult <IRoutingMessage>(ImmutableList <IRoutingMessage> .Empty, failed, sendFailureDetails));
                }

                Util.Option <string> identity = this.GetIdentity(routingMessage);

                ISinkResult result = await identity.Match(
                    id => this.ProcessAsync(routingMessage, id),
                    () => this.ProcessNoIdentity(routingMessage));

                return(result);
            }
                RetrieveNextBatch()
                {
                    Seq <
                        Util.Try <ReplayCompletion> > msg;
                    using (var conn =
                               _connectionFactory.GetConnection())
                    {
                        var waited = Messages(conn, persistenceId,
                                              opt.Item1,
                                              toSequenceNr, batchSize);
                        msg = await waited
                              .RunWith(
                            ExtSeq.Seq <Util.Try <ReplayCompletion> >(), mat);
                    }

                    var hasMoreEvents          = msg.Count == batchSize;
                    var lastMsg                = msg.LastOrDefault();
                    Util.Option <long> lastSeq = Util.Option <long> .None;
                    if (lastMsg != null && lastMsg.IsSuccess)
                    {
                        lastSeq = lastMsg.Success.Select(r => r.repr.SequenceNr);
                    }
                    else if (lastMsg != null && lastMsg.Failure.HasValue)
                    {
                        throw lastMsg.Failure.Value;
                    }

                    var hasLastEvent =
                        lastSeq.HasValue &&
                        lastSeq.Value >= toSequenceNr;
                    FlowControl nextControl = null;
                    if (hasLastEvent || opt.Item1 > toSequenceNr)
                    {
                        nextControl = FlowControl.Stop.Instance;
                    }
                    else if (hasMoreEvents)
                    {
                        nextControl = FlowControl.Continue.Instance;
                    }
                    else if (refreshInterval.HasValue == false)
                    {
                        nextControl = FlowControl.Stop.Instance;
                    }
                    else
                    {
                        nextControl = FlowControl.ContinueDelayed
                                      .Instance;
                    }

                    long nextFrom = 0;
                    if (lastSeq.HasValue)
                    {
                        nextFrom = lastSeq.Value + 1;
                    }
                    else
                    {
                        nextFrom = opt.Item1;
                    }

                    return(new Util.Option <((long, FlowControl), Seq <Util.Try <ReplayCompletion> >)>((
                                                                                                           (nextFrom, nextControl), msg)));
                }