public async Task ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
        {
            var batch = new TableBatchOperation();

            foreach(var msg in messages)
            {
                var snap = JsonConvert.DeserializeObject<BusSnapshotInfo>(Encoding.UTF8.GetString(msg.GetBytes()));

                var entity = new DynamicTableEntity(snap.RouteShortName, snap.VehicleId.ToString());

                entity.Properties.Add("RouteShortName", EntityProperty.GeneratePropertyForString(snap.RouteShortName));
                entity.Properties.Add("VehicleId", EntityProperty.GeneratePropertyForInt(snap.VehicleId));
                entity.Properties.Add("TripId", EntityProperty.GeneratePropertyForInt(snap.TripId));
                entity.Properties.Add("Latitude", EntityProperty.GeneratePropertyForDouble(snap.Latitude));
                entity.Properties.Add("Longitude", EntityProperty.GeneratePropertyForDouble(snap.Longitude));
                entity.Properties.Add("DirectionOfTravel", EntityProperty.GeneratePropertyForString(snap.DirectionOfTravel.ToString()));
                entity.Properties.Add("NextStopId", EntityProperty.GeneratePropertyForInt(snap.NextStopId));
                entity.Properties.Add("Timeliness", EntityProperty.GeneratePropertyForString(snap.Timeliness.ToString()));
                entity.Properties.Add("TimelinessOffset", EntityProperty.GeneratePropertyForInt(snap.TimelinessOffset));
                entity.Properties.Add("Timestamp", EntityProperty.GeneratePropertyForDateTimeOffset(snap.Timestamp));

                batch.Add(TableOperation.InsertOrReplace(entity));
            }

            var tableClient = _account.CreateCloudTableClient();

            var table = tableClient.GetTableReference("snapshots");

            await table.CreateIfNotExistsAsync();

            await table.ExecuteBatchAsync(batch);

            await context.CheckpointAsync();
        }
        async Task IEventProcessor.ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
        {

            foreach (EventData eventData in messages)
            {
                _Logger.LogInfo(string.Format("Event received from partition: {0} - {1}", context.Lease.PartitionId,eventData.PartitionKey));

                try
                {
                    var httpMessage = HttpMessage.Parse(eventData.GetBodyStream());
                    await _MessageContentProcessor.ProcessHttpMessage(httpMessage);
                }
                catch (Exception ex)
                {
                    _Logger.LogError(ex.Message);
                }
            }

            //Call checkpoint every 5 minutes, so that worker can resume processing from the 5 minutes back if it restarts.
            if (this.checkpointStopWatch.Elapsed > TimeSpan.FromMinutes(5))
            {
                _Logger.LogInfo("Checkpointing");
               await context.CheckpointAsync();
                this.checkpointStopWatch.Restart();
            }
        }
        public async Task ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
        {
            foreach (EventData eventData in messages)
            {
                if (eventData.Properties.ContainsKey("time"))
                {
                    if (eventData.Properties.ContainsKey("temp"))
                        Console.WriteLine(string.Format("time = {0}, temp = {1}", eventData.Properties["time"], eventData.Properties["temp"]));

                    if (eventData.Properties.ContainsKey("hmdt"))
                        Console.WriteLine(string.Format("time = {0}, hmdt = {1}", eventData.Properties["time"], eventData.Properties["hmdt"]));

                    if (eventData.Properties.ContainsKey("accx") &&
                        eventData.Properties.ContainsKey("accy") &&
                        eventData.Properties.ContainsKey("accz"))
                        Console.WriteLine(string.Format("time = {0}, accx = {1}, accy = {2}, accz = {3}", eventData.Properties["time"], eventData.Properties["accx"], eventData.Properties["accy"], eventData.Properties["accz"]));

                    if (eventData.Properties.ContainsKey("bpm"))
                        Console.WriteLine(string.Format("time = {0}, bpm = {1}", eventData.Properties["time"], eventData.Properties["bpm"]));
                }
            }

            //Call checkpoint every 5 minutes, so that worker can resume processing from the 5 minutes back if it restarts.
            //if (this.checkpointStopWatch.Elapsed > TimeSpan.FromMinutes(5))
            if (this.checkpointStopWatch.Elapsed > TimeSpan.FromSeconds(30))
            {
                await context.CheckpointAsync();
                this.checkpointStopWatch.Restart();
            }
        }
        public async Task ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
        {
            Trace.TraceInformation("\n");
            Trace.TraceInformation("........ProcessEventsAsync........");
            foreach (EventData eventData in messages)
            {
                try
                {
                    string jsonString = Encoding.UTF8.GetString(eventData.GetBytes());

                    Trace.TraceInformation(string.Format("Message received at '{0}'. Partition: '{1}'",
                        eventData.EnqueuedTimeUtc.ToLocalTime(), this.partitionContext.Lease.PartitionId));

                    Trace.TraceInformation(string.Format("-->Raw Data: '{0}'", jsonString));

                    SensorEvent newSensorEvent = this.DeserializeEventData(jsonString);

                    Trace.TraceInformation(string.Format("-->Serialized Data: '{0}', '{1}', '{2}', '{3}', '{4}'",
                        newSensorEvent.timestart, newSensorEvent.dsplalert, newSensorEvent.alerttype, newSensorEvent.message, newSensorEvent.targetalarmdevice));

                    // Issuing alarm to device.
                    string commandParameterNew = "{\"Name\":\"AlarmThreshold\",\"Parameters\":{\"SensorId\":\"" + newSensorEvent.dsplalert + "\"}}";
                    Trace.TraceInformation("Issuing alarm to device: '{0}', from sensor: '{1}'", newSensorEvent.targetalarmdevice, newSensorEvent.dsplalert);
                    Trace.TraceInformation("New Command Parameter: '{0}'", commandParameterNew);
                    await WorkerRole.iotHubServiceClient.SendAsync(newSensorEvent.targetalarmdevice, new Microsoft.Azure.Devices.Message(Encoding.UTF8.GetBytes(commandParameterNew)));
                }
                catch (Exception ex)
                {
                    Trace.TraceInformation("Error in ProssEventsAsync -- {0}\n", ex.Message);
                }
            }

            await context.CheckpointAsync();
        }
        public async Task ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> events)
        {
            try
            {
                Notifications notifications = new Notifications();
                foreach (EventData eventData in events)
                {
                    var dataString = Encoding.UTF8.GetString(eventData.GetBytes());
                    var newData = JsonConvert.DeserializeObject<MetricEvent>(dataString);

                    EventMessage message = GetMessage(newData.Type, dataString);
                    if (message == null)
                        message = newData.GetMessage();

                    notifications.Notify(message);

                    Console.WriteLine(string.Format("Message received.Partition:'{0}',{1},Device:'{2}'", this.partitionContext.Lease.PartitionId, newData.Type, newData.DeviceId));
                }

                //Call checkpoint every 5 minutes, so that worker can resume processing from the 5 minutes back if it restarts.
                if (this.checkpointStopWatch.Elapsed > TimeSpan.FromMinutes(5))
                {
                    await context.CheckpointAsync();
                    this.checkpointStopWatch.Restart();
                }
            }
            catch (Exception exp)
            {
                Console.WriteLine("Error in processing: " + exp.Message);
            }
        }
예제 #6
0
 public async Task CloseAsync(PartitionContext context, CloseReason reason)
 {
     if (reason == CloseReason.Shutdown)
     {
         await context.CheckpointAsync();
     }
 }
예제 #7
0
        async Task IEventProcessor.ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
        {
            var iDbService = new DbService();
            _client = iDbService.GetFirebaseClient();
            foreach (EventData eventData in messages)
            {
                string data = Encoding.UTF8.GetString(eventData.GetBytes());
                FirebaseResponse response = await _client.PushAsync("event", new EHdata
                {
                    offset = eventData.Offset,
                    body = data,
                    partitionId = context.Lease.PartitionId
                });
                Console.WriteLine(String.Format("Message received.  Partition: '{0}', Data: '{1}', Offset: '{2}'",
                    context.Lease.PartitionId, data, eventData.Offset));
            }

            //Call checkpoint every 5 minutes, so that worker can resume processing from the 5 minutes back if it restarts.
            if (this.checkpointStopWatch.Elapsed > TimeSpan.FromMinutes(5))
            {
                Console.WriteLine(this.checkpointStopWatch.Elapsed);
                await context.CheckpointAsync();
                this.checkpointStopWatch.Restart();
            }
        }
        public async Task ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> events)
        {
            // Workaround for event hub sending null on timeout
            events = events ?? Enumerable.Empty<EventData>();

            foreach (var eventData in events)
            {
                var updateTemperatureEvent = JsonConvert.DeserializeObject<UpdateTemperatureEvent>(Encoding.UTF8.GetString(eventData.GetBytes()));
                eventData.Properties["BuildingId"] = _buildingLookupService.GetBuildingId(updateTemperatureEvent.DeviceId);
            }

            if(!await _elasticSearchWriter.WriteAsync(events.ToList(), _token).ConfigureAwait(false))
            {
                return;
            }

            try
            {
                EventData checkpointEventData = events.LastOrDefault();

                await context.CheckpointAsync(checkpointEventData);

                WarmStorageEventSource.Log.CheckpointCompleted(ProcessorName, _eventHubName, context.Lease.PartitionId, checkpointEventData.Offset);
            }
            catch (Exception ex)
            {
                if (!(ex is StorageException || ex is LeaseLostException))
                {
                    throw;
                }

                WarmStorageEventSource.Log.UnableToCheckpoint(ex, ProcessorName, _eventHubName, context.Lease.PartitionId);
            }
        }
        async Task IEventProcessor.ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
        {
            var partitionedMessages = messages.GroupBy(data => data.PartitionKey).ToDictionary(datas => datas.Key, datas => datas.ToList());

            //For each partition spawn a Task which will sequentially iterate over its own block
            //Wait for all Tasks to complete, before proceeding.
            await Task.WhenAll(partitionedMessages.Select(partition => Task.Run(async () =>
            {
                var block = partition.Value;
                foreach (var eventData in block)
                {
                    try
                    {
                        var data = Encoding.UTF8.GetString(eventData.GetBytes());

                        System.Console.WriteLine(DateTime.Now + ":Message received.  Partition: '{0}', Data: '{1}', Partition Key: '{2}'", context.Lease.PartitionId, data, eventData.PartitionKey);
                    }
                    catch (Exception e)
                    {
                        //do something with your logs..
                    }
                }
            })));

            //Call checkpoint every 5 minutes, so that worker can resume processing from the 5 minutes back if it restarts.
            if (checkpointStopWatch.Elapsed > TimeSpan.FromMinutes(5))
            {
                await context.CheckpointAsync();
                checkpointStopWatch.Restart();
            }
        }
 async Task IEventProcessor.CloseAsync(PartitionContext context, CloseReason reason)
 {
     if (reason == CloseReason.Shutdown)
     {
         await context.CheckpointAsync();
     }
 }
예제 #11
0
        public async Task ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> events)
        {
            // Workaround for event hub sending null on timeout
            events = events ?? Enumerable.Empty<EventData>();

            if(!await _elasticSearchWriter.WriteAsync(events.ToList(), _token).ConfigureAwait(false))
            {
                return;
            }

            try
            {
                EventData checkpointEventData = events.LastOrDefault();

                await context.CheckpointAsync(checkpointEventData);

                WarmStorageEventSource.Log.CheckpointCompleted(ProcessorName, _eventHubName, context.Lease.PartitionId, checkpointEventData.Offset);
            }
            catch (Exception ex)
            {
                if (!(ex is StorageException || ex is LeaseLostException))
                {
                    throw;
                }

                WarmStorageEventSource.Log.UnableToCheckpoint(ex, ProcessorName, _eventHubName, context.Lease.PartitionId);
            }
        }
        public Task ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
        {
            try
            {
                foreach (EventData message in messages)
                {
                    string contents = Encoding.UTF8.GetString(message.GetBytes());
                    Console.WriteLine(string.Format("SimpleEventProcessor: {0}", contents));
                    OnMessageReceived(this, new MessageReceivedEventArgs() { ReceivedOn = DateTimeOffset.UtcNow, Message = message });
                }
                
                if (this.checkpointStopWatch.Elapsed > TimeSpan.FromSeconds(2))
                {
                    lock (this)
                    {
                        this.checkpointStopWatch.Reset();
                        return context.CheckpointAsync();
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }

            return Task.FromResult<object>(null);
        }
 async Task IEventProcessor.CloseAsync(PartitionContext context, CloseReason reason)
 {
     Console.WriteLine("Processor Shutting Down. Partition '{0}', Reason: '{1}'.", context.Lease.PartitionId, reason);
     if (reason == CloseReason.Shutdown)
     {
         await context.CheckpointAsync();
     }
 }
 public async Task CloseAsync(PartitionContext context, CloseReason reason)
 {
     Console.WriteLine(string.Format("Processor Shuting Down.  Partition '{0}', Reason: '{1}'.", context.Lease.PartitionId, reason.ToString()));
     if (reason == CloseReason.Shutdown)
     {
         await context.CheckpointAsync();
     }
 }
예제 #15
0
 public async Task CloseAsync(PartitionContext context, CloseReason reason)
 {
     if (reason == CloseReason.Shutdown)
     {
         Clients.All.showMessageOnClient("XClose");
         await context.CheckpointAsync();
     }
 }
 public Task CloseAsync(PartitionContext context, CloseReason reason)
 {
     if (reason == CloseReason.Shutdown)
     {
         return context.CheckpointAsync();
     }
     return Task.FromResult(false);
 }
예제 #17
0
 public async Task CloseAsync(PartitionContext context, CloseReason reason)
 {
     Console.WriteLine("Shutting Down Event Processor");
     if (reason == CloseReason.Shutdown)
     {
         await context.CheckpointAsync();
     }
 }
 public async Task CloseAsync(PartitionContext context, CloseReason reason)
 {
     Trace.TraceInformation(string.Format("EventProcessor Shuting Down.  Partition '{0}', Reason: '{1}'.", this.partitionContext.Lease.PartitionId, reason.ToString()));
     if (reason == CloseReason.Shutdown)
     {
         await context.CheckpointAsync();
     }
 }
예제 #19
0
        //------------------------------------------------------------------------------------------------------------------------
        #endregion

        #region Functions
        //------------------------------------------------------------------------------------------------------------------------
        async Task IEventProcessor.CloseAsync(PartitionContext context, CloseReason reason)
        {
            DebugEx.TraceLog("Processor Shutting Down. Partition :" + context.Lease.PartitionId + ", Reason: " + reason);
            if (reason == CloseReason.Shutdown)
            {
                await context.CheckpointAsync();
            }
        }
예제 #20
0
 public async Task CloseAsync(PartitionContext context, CloseReason reason)
 {
     Console.WriteLine($"Processor Shutting Down. Partition '{context.Lease.PartitionId}', Reason: '{reason}'.");
     if (reason == CloseReason.Shutdown)
     {
         await context.CheckpointAsync();
     }
 }
        public async Task ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> events)
        {
            try
            {

                foreach (EventData eventData in events)
                {

                    //string key = eventData.PartitionKey;

                    // Get message from the eventData body and convert JSON string into message object
                    string eventBodyAsString = Encoding.UTF8.GetString(eventData.GetBytes());
                    Console.WriteLine();
                    Console.WriteLine(eventBodyAsString);
                    Console.WriteLine();

                    //IList<IDictionary<string, object>> messagePayloads;
                    //try
                    //{
                    //    // Attempt to deserialze event body as single JSON message
                    //    messagePayloads = new List<IDictionary<string, object>> 
                    //    { 
                    //        JsonConvert.DeserializeObject<IDictionary<string, object>>(eventBodyAsString)
                    //    };
                    //}
                    //catch
                    //{
                    //    // Not a single JSON message: attempt to deserialize as array of messages

                    //    // Azure Stream Analytics Preview generates invalid JSON for some multi-values queries
                    //    // Workaround: turn concatenated json objects (ivalid JSON) into array of json objects (valid JSON)
                    //    if (eventBodyAsString.IndexOf("}{") >= 0)
                    //    {
                    //        eventBodyAsString = eventBodyAsString.Replace("}{", "},{");
                    //        eventBodyAsString = "[" + eventBodyAsString + "]";
                    //    }
                    //    messagePayloads = JsonConvert.DeserializeObject<IList<IDictionary<string, object>>>(eventBodyAsString);
                    //}

                }

                //Call checkpoint every 5 minutes, so that worker can resume processing from the 5 minutes back if it restarts.
                if (this.checkpointStopWatch.Elapsed > TimeSpan.FromMinutes(5))
                {
                    Console.WriteLine("Check point");
                    await context.CheckpointAsync();
                    lock (this)
                    {
                        this.checkpointStopWatch.Reset();
                        this.checkpointStopWatch.Start();
                    }
                }
            }
            catch (Exception exp)
            {
                Console.WriteLine("Error in processing: " + exp.Message);
            }
        }
        public Task CloseAsync(PartitionContext context, CloseReason reason)
        {
            Trace.TraceInformation("Processor Shuting Down.  Partition '{0}', Reason: '{1}'.", this.Context.Lease.PartitionId, reason.ToString());

            this.IsClosed = true;
            this.OnProcessorClosed();

            return context.CheckpointAsync();
        }
 public async Task ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
 {
     // Todo: Improve performance by batching items 
     foreach (EventData ev in messages)
     {
         await this.m_Handler.HandleEventData(this.m_ServiceBusNamespace, this.m_EventHubName, this.m_CounsumerGroupName, ev);
         await context.CheckpointAsync();
     }
 }
예제 #24
0
 public async Task CloseAsync(PartitionContext context, CloseReason reason)
 {
     if (sqlConnection != null)
         sqlConnection.Close();
     if (!WebJobsHelper.RunAsWebJobs)
         Console.WriteLine(string.Format("Processor Shuting Down. Partition '{0}', Reason: '{1}'.",
             partitionContext.Lease.PartitionId, reason.ToString()));
     if (reason == CloseReason.Shutdown)
         await context.CheckpointAsync();
 }
 public async Task ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> events)
 {
     foreach (var eventData in events)
     {
         dynamic data = JsonConvert.DeserializeObject(Encoding.Default.GetString(eventData.GetBytes()));
         // process data
     }
     
     await context.CheckpointAsync();
 }
        async Task IEventProcessor.CloseAsync(PartitionContext context, CloseReason reason)
        {
            _logger.EventProcessorStopped(reason.ToString(), context.EventHubPath, context.ConsumerGroupName, context.Lease.PartitionId, context.Lease.Offset, context.Lease.Epoch);

            if (reason == CloseReason.Shutdown)
            {
                await context.CheckpointAsync();
                _logger.EventProcessorCheckpointed(context.EventHubPath, context.ConsumerGroupName, context.Lease.PartitionId, context.Lease.Offset, context.Lease.Epoch);
            }
        }
        async Task IEventProcessor.ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
        {
            await Task.WhenAll(messages.Select(eventData => _processor(eventData)));

            //if (_lastCheckpointTime.Add(_checkpointTimeout) < DateTime.UtcNow)
            //{
                await context.CheckpointAsync();
                _logger.EventProcessorCheckpointed(context.EventHubPath, context.ConsumerGroupName, context.Lease.PartitionId, context.Lease.Offset, context.Lease.Epoch);
            //    _lastCheckpointTime = DateTime.UtcNow;
            //}
        }
 public Task CloseAsync(PartitionContext context, CloseReason reason)
 {
     WriteLog("{0} > Close called for processor with PartitionId '{1}' and Owner: {2} with reason '{3}'.", DateTime.Now.ToString(), context.Lease.PartitionId, context.Lease.Owner ?? string.Empty, reason);
     if (_checkpointingOn)
     {
         return context.CheckpointAsync();
     }
     else
     {
         return Task.FromResult<object>(null);
     }
 }
        public async Task ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
        {
            foreach (var eventData in messages)
            {
                var packetData = Encoding.UTF8.GetString(eventData.GetBytes());
               
                var packetContext = new PacketData(MakeUri(eventData), packetData);
                await _hostedMiddeMiddleware.Invoke(packetContext);
            }

            await context.CheckpointAsync();
        }
        public async Task ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
        {
            foreach(var message in messages)
            {                
                var importantMeasure = ImportantMeasure.FromByteArray(message.GetBytes());

                // Do something with the measure here, like storing it in a table somewhere...

                Trace.WriteLine($"[Partition {context.Lease.PartitionId}] {DateTime.Now.ToString("HH:mm:ss")}: {importantMeasure.ImportantValue.ToString("0.00")}");
            }            
            await context.CheckpointAsync();
        }
        /// <summary>
        /// Receives a <see cref="EventData"/> from the event bus.
        /// </summary>
        protected virtual void ReceiveEvent(PartitionContext context, EventData eventData)
        {
            DateTimeOffset startedAt     = DateTimeOffset.UtcNow;
            Stopwatch      mainStopWatch = Stopwatch.StartNew();
            string         responseCode  = "200";
            // Null means it was skipped
            bool?wasSuccessfull = true;

#if NET452
            string telemetryName = string.Format("Cqrs/Handle/Event/{0}", eventData.SequenceNumber);
#endif
#if NETSTANDARD2_0
            string telemetryName = string.Format("Cqrs/Handle/Event/{0}", eventData.SystemProperties.SequenceNumber);
#endif
            ISingleSignOnToken authenticationToken = null;
            Guid?  guidAuthenticationToken         = null;
            string stringAuthenticationToken       = null;
            int?   intAuthenticationToken          = null;

            IDictionary <string, string> telemetryProperties = new Dictionary <string, string> {
                { "Type", "Azure/EventHub" }
            };
            object value;
            if (eventData.Properties.TryGetValue("Type", out value))
            {
                telemetryProperties.Add("MessageType", value.ToString());
            }
            TelemetryHelper.TrackMetric("Cqrs/Handle/Event", CurrentHandles++, telemetryProperties);
            // Do a manual 10 try attempt with back-off
            for (int i = 0; i < 10; i++)
            {
                try
                {
#if NET452
                    Logger.LogDebug(string.Format("An event message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}'.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset));
#endif
#if NETSTANDARD2_0
                    Logger.LogDebug(string.Format("An event message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}'.", eventData.SystemProperties.PartitionKey, eventData.SystemProperties.SequenceNumber, eventData.SystemProperties.Offset));
#endif
#if NET452
                    string messageBody = Encoding.UTF8.GetString(eventData.GetBytes());
#endif
#if NETSTANDARD2_0
                    string messageBody = Encoding.UTF8.GetString(eventData.Body.Array, eventData.Body.Offset, eventData.Body.Count);
#endif

                    IEvent <TAuthenticationToken> @event = AzureBusHelper.ReceiveEvent(null, messageBody, ReceiveEvent,
#if NET452
                                                                                       string.Format("partition key '{0}', sequence number '{1}' and offset '{2}'", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset),
#endif
#if NETSTANDARD2_0
                                                                                       string.Format("partition key '{0}', sequence number '{1}' and offset '{2}'", eventData.SystemProperties.PartitionKey, eventData.SystemProperties.SequenceNumber, eventData.SystemProperties.Offset),
#endif
                                                                                       ExtractSignature(eventData),
                                                                                       SigningTokenConfigurationKey,
                                                                                       () =>
                    {
                        wasSuccessfull = null;
#if NET452
                        telemetryName = string.Format("Cqrs/Handle/Event/Skipped/{0}", eventData.SequenceNumber);
#endif
#if NETSTANDARD2_0
                        telemetryName = string.Format("Cqrs/Handle/Event/Skipped/{0}", eventData.SystemProperties.SequenceNumber);
#endif
                        responseCode = "204";
                        // Remove message from queue
                        context.CheckpointAsync(eventData);
#if NET452
                        Logger.LogDebug(string.Format("An event message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' but processing was skipped due to event settings.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset));
#endif
#if NETSTANDARD2_0
                        Logger.LogDebug(string.Format("An event message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' but processing was skipped due to event settings.", eventData.SystemProperties.PartitionKey, eventData.SystemProperties.SequenceNumber, eventData.SystemProperties.Offset));
#endif
                        TelemetryHelper.TrackEvent("Cqrs/Handle/Event/Skipped", telemetryProperties);
                    }
                                                                                       );

                    if (wasSuccessfull != null)
                    {
                        if (@event != null)
                        {
                            telemetryName       = string.Format("{0}/{1}/{2}", @event.GetType().FullName, @event.GetIdentity(), @event.Id);
                            authenticationToken = @event.AuthenticationToken as ISingleSignOnToken;
                            if (AuthenticationTokenIsGuid)
                            {
                                guidAuthenticationToken = @event.AuthenticationToken as Guid?;
                            }
                            if (AuthenticationTokenIsString)
                            {
                                stringAuthenticationToken = @event.AuthenticationToken as string;
                            }
                            if (AuthenticationTokenIsInt)
                            {
                                intAuthenticationToken = @event.AuthenticationToken as int?;
                            }

                            var telemeteredMessage = @event as ITelemeteredMessage;
                            if (telemeteredMessage != null)
                            {
                                telemetryName = telemeteredMessage.TelemetryName;
                            }

                            telemetryName = string.Format("Cqrs/Handle/Event/{0}", telemetryName);
                        }
                        // Remove message from queue
                        context.CheckpointAsync(eventData);
                    }
#if NET452
                    Logger.LogDebug(string.Format("An event message arrived and was processed with the partition key '{0}', sequence number '{1}' and offset '{2}'.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset));
#endif
#if NETSTANDARD2_0
                    Logger.LogDebug(string.Format("An event message arrived and was processed with the partition key '{0}', sequence number '{1}' and offset '{2}'.", eventData.SystemProperties.PartitionKey, eventData.SystemProperties.SequenceNumber, eventData.SystemProperties.Offset));
#endif

                    IList <IEvent <TAuthenticationToken> > events;
                    if (EventWaits.TryGetValue(@event.CorrelationId, out events))
                    {
                        events.Add(@event);
                    }

                    wasSuccessfull = true;
                    responseCode   = "200";
                    return;
                }
                catch (UnAuthorisedMessageReceivedException exception)
                {
                    TelemetryHelper.TrackException(exception, null, telemetryProperties);
                    // Indicates a problem, unlock message in queue
#if NET452
                    Logger.LogError(string.Format("An event message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' but was not authorised.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset), exception: exception);
#endif
#if NETSTANDARD2_0
                    Logger.LogError(string.Format("An event message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' but was not authorised.", eventData.SystemProperties.PartitionKey, eventData.SystemProperties.SequenceNumber, eventData.SystemProperties.Offset), exception: exception);
#endif
                    wasSuccessfull = false;
                    responseCode   = "401";
                    telemetryProperties.Add("ExceptionType", exception.GetType().FullName);
                    telemetryProperties.Add("ExceptionMessage", exception.Message);
                }
                catch (NoHandlersRegisteredException exception)
                {
                    TelemetryHelper.TrackException(exception, null, telemetryProperties);
                    // Indicates a problem, unlock message in queue
#if NET452
                    Logger.LogError(string.Format("An event message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' but no handlers were found to process it.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset), exception: exception);
#endif
#if NETSTANDARD2_0
                    Logger.LogError(string.Format("An event message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' but no handlers were found to process it.", eventData.SystemProperties.PartitionKey, eventData.SystemProperties.SequenceNumber, eventData.SystemProperties.Offset), exception: exception);
#endif
                    wasSuccessfull = false;
                    responseCode   = "501";
                    telemetryProperties.Add("ExceptionType", exception.GetType().FullName);
                    telemetryProperties.Add("ExceptionMessage", exception.Message);
                }
                catch (NoHandlerRegisteredException exception)
                {
                    TelemetryHelper.TrackException(exception, null, telemetryProperties);
                    // Indicates a problem, unlock message in queue
#if NET452
                    Logger.LogError(string.Format("An event message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}'s but no handler was found to process it.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset), exception: exception);
#endif
#if NETSTANDARD2_0
                    Logger.LogError(string.Format("An event message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}'s but no handler was found to process it.", eventData.SystemProperties.PartitionKey, eventData.SystemProperties.SequenceNumber, eventData.SystemProperties.Offset), exception: exception);
#endif
                    wasSuccessfull = false;
                    responseCode   = "501";
                    telemetryProperties.Add("ExceptionType", exception.GetType().FullName);
                    telemetryProperties.Add("ExceptionMessage", exception.Message);
                }
                catch (Exception exception)
                {
                    // Indicates a problem, unlock message in queue
#if NET452
                    Logger.LogError(string.Format("An event message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' but failed to be process.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset), exception: exception);
#endif
#if NETSTANDARD2_0
                    Logger.LogError(string.Format("An event message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' but failed to be process.", eventData.SystemProperties.PartitionKey, eventData.SystemProperties.SequenceNumber, eventData.SystemProperties.Offset), exception: exception);
#endif

                    switch (i)
                    {
                    case 0:
                    case 1:
                        // 10 seconds
                        Thread.Sleep(10 * 1000);
                        break;

                    case 2:
                    case 3:
                        // 30 seconds
                        Thread.Sleep(30 * 1000);
                        break;

                    case 4:
                    case 5:
                    case 6:
                        // 1 minute
                        Thread.Sleep(60 * 1000);
                        break;

                    case 7:
                    case 8:
                        // 3 minutes
                        Thread.Sleep(3 * 60 * 1000);
                        break;

                    case 9:
                        telemetryProperties.Add("ExceptionType", exception.GetType().FullName);
                        telemetryProperties.Add("ExceptionMessage", exception.Message);
                        break;
                    }
                    wasSuccessfull = false;
                    responseCode   = "500";
                }
                finally
                {
                    // Eventually just accept it
                    context.CheckpointAsync(eventData);

                    TelemetryHelper.TrackMetric("Cqrs/Handle/Event", CurrentHandles--, telemetryProperties);

                    mainStopWatch.Stop();
                    if (guidAuthenticationToken != null)
                    {
                        TelemetryHelper.TrackRequest
                        (
                            telemetryName,
                            guidAuthenticationToken,
                            startedAt,
                            mainStopWatch.Elapsed,
                            responseCode,
                            wasSuccessfull == null || wasSuccessfull.Value,
                            telemetryProperties
                        );
                    }
                    else if (intAuthenticationToken != null)
                    {
                        TelemetryHelper.TrackRequest
                        (
                            telemetryName,
                            intAuthenticationToken,
                            startedAt,
                            mainStopWatch.Elapsed,
                            responseCode,
                            wasSuccessfull == null || wasSuccessfull.Value,
                            telemetryProperties
                        );
                    }
                    else if (stringAuthenticationToken != null)
                    {
                        TelemetryHelper.TrackRequest
                        (
                            telemetryName,
                            stringAuthenticationToken,
                            startedAt,
                            mainStopWatch.Elapsed,
                            responseCode,
                            wasSuccessfull == null || wasSuccessfull.Value,
                            telemetryProperties
                        );
                    }
                    else
                    {
                        TelemetryHelper.TrackRequest
                        (
                            telemetryName,
                            authenticationToken,
                            startedAt,
                            mainStopWatch.Elapsed,
                            responseCode,
                            wasSuccessfull == null || wasSuccessfull.Value,
                            telemetryProperties
                        );
                    }

                    TelemetryHelper.Flush();
                }
            }
        }
예제 #32
0
            /// <inheritdoc/>
            public async Task ProcessEventsAsync(PartitionContext context,
                                                 IEnumerable <EventData> messages)
            {
                if (messages == null || !messages.Any())
                {
                    return;
                }
                var messagesCount   = 0;
                var messageSequence = 0L;

                foreach (var eventData in messages)
                {
                    messagesCount++;
                    if (_outer._config.SkipEventsOlderThan != null &&
                        eventData.SystemProperties.TryGetValue("x-opt-enqueued-time", out var enqueued) &&
                        (DateTime)enqueued + _outer._config.SkipEventsOlderThan < DateTime.UtcNow)
                    {
                        kOldEvent.WithLabels(_processorId, context.EventHubPath, context.ConsumerGroupName, context.PartitionId).Inc();
                        continue;
                    }
                    var properties = new EventProperties(eventData.SystemProperties,
                                                         eventData.Properties);
                    if (eventData.Body.Array == null)
                    {
                        _logger.Verbose("WARNING: Received empty message with properties {@properties}",
                                        properties);
                        continue;
                    }
                    await _handler.HandleAsync(eventData.Body.Array, properties,
                                               () => CheckpointAsync(context, eventData));

                    if (context.CancellationToken.IsCancellationRequested)
                    {
                        // Checkpoint to the last processed event.
                        await CheckpointAsync(context, eventData);

                        context.CancellationToken.ThrowIfCancellationRequested();
                    }
                    // sequence number of the message in eventhub which is used to calculate lag
                    messageSequence = eventData.SystemProperties.SequenceNumber;
                }
                var lastEnqueuedSequence = context.RuntimeInformation.LastSequenceNumber;
                var sequenceDifference   = lastEnqueuedSequence - messageSequence;

                TotalMessagesCount += messagesCount;
                kEventProcessorMessages.WithLabels(_processorId, context.EventHubPath, context.ConsumerGroupName,
                                                   context.PartitionId).Set(TotalMessagesCount);
                kEventProcessorLag.WithLabels(_processorId, context.EventHubPath, context.ConsumerGroupName,
                                              context.PartitionId).Set(sequenceDifference);

                // Checkpoint if needed
                if (_sw.ElapsedMilliseconds >= _interval)
                {
                    try {
                        _logger.Debug("Checkpointing EventProcessor {id} for partition {partitionId}...",
                                      _processorId, context.PartitionId);
                        await context.CheckpointAsync();

                        _sw.Restart();
                    }
                    catch (Exception ex) {
                        _logger.Warning(ex, "Failed checkpointing EventProcessor {id} for partition {partitionId}...",
                                        _processorId, context.PartitionId);
                        kEventProcessorDetails.WithLabels(_processorId, context.EventHubPath, context.ConsumerGroupName,
                                                          context.PartitionId, "checkpoint_failed").Inc();
                        if (_sw.ElapsedMilliseconds >= 2 * _interval)
                        {
                            // Give up checkpointing after trying a couple more times
                            _sw.Restart();
                        }
                    }
                }
                await Try.Async(_handler.OnBatchCompleteAsync);
            }
예제 #33
0
 public async Task ProcessErrorAsync(PartitionContext context, Exception error)
 {
     await context.CheckpointAsync();
 }
예제 #34
0
        public async Task ProcessEventsAsync(PartitionContext context, IEnumerable <EventData> events)
        {
            try
            {
                var now = DateTime.UtcNow;

                foreach (var eventData in events)
                {
                    // Get message from the eventData body and convert JSON string into message object
                    string eventBodyAsString = Encoding.UTF8.GetString(eventData.GetBytes());

                    IList <IDictionary <string, object> > messagePayloads;
                    try
                    {
                        // Attempt to deserialze event body as single JSON message
                        messagePayloads = new List <IDictionary <string, object> >
                        {
                            JsonConvert.DeserializeObject <IDictionary <string, object> >(eventBodyAsString)
                        };
                    }
                    catch
                    {
                        // Not a single JSON message: attempt to deserialize as array of messages

                        // Azure Stream Analytics Preview generates invalid JSON for some multi-values queries
                        // Workaround: turn concatenated json objects (ivalid JSON) into array of json objects (valid JSON)
                        if (eventBodyAsString.IndexOf("}{") >= 0)
                        {
                            eventBodyAsString = eventBodyAsString.Replace("}{", "},{");
                        }
                        if (!eventBodyAsString.EndsWith("]"))
                        {
                            eventBodyAsString = eventBodyAsString + "]";
                        }
                        if (!eventBodyAsString.StartsWith("["))
                        {
                            eventBodyAsString = "[" + eventBodyAsString;
                        }

                        messagePayloads = JsonConvert.DeserializeObject <IList <IDictionary <string, object> > >(eventBodyAsString);
                    }

                    // Only send messages within the display/buffer interval to clients, to speed up recovery after downtime
                    if ((eventData.EnqueuedTimeUtc + bufferTimeInterval).AddMinutes(1) > now)
                    {
                        foreach (var messagePayload in messagePayloads)
                        {
                            // Build up the list of devices seen so far (in lieu of a formal device repository)
                            // Also keep the last message received per device (not currently used in the sample)
                            string deviceName = null;
                            if (messagePayload.ContainsKey("dspl"))
                            {
                                deviceName = messagePayload["dspl"] as string;
                                if (deviceName != null)
                                {
                                    WebSocketEventProcessor.g_devices.TryAdd(deviceName, messagePayload);
                                }
                            }


                            // Notify clients
                            MyWebSocketHandler.SendToClients(messagePayload);

                            // Buffer messages so we can resend them to clients that connect later
                            // or when a client requests data for a different device

                            // Lock to guard against concurrent reads from client resend
                            // Note that the Add operations are not contentious with each other
                            // because EH processor host serializes per partition, and we use one buffer per partition
                            lock (bufferedMessages)
                            {
                                bufferedMessages.Add(messagePayload);

                                if (messagePayload.ContainsKey("tempavg"))
                                {
                                    bufferedMessagesAvg.Add(messagePayload);
                                }
                            }
                        }
                    }
                    else
                    {
                        Debug.WriteLine("Received event older than {0} in EH {1}, partition {2}: {3} - Sequence Number {4}",
                                        bufferTimeInterval,
                                        context.EventHubPath, context.Lease.PartitionId,
                                        eventData.EnqueuedTimeUtc, eventData.SequenceNumber);

                        eventForNextCheckpoint = eventData;
                    }

                    // Remember first event to checkpoint to later
                    if (eventForNextCheckpoint == null)
                    {
                        eventForNextCheckpoint = eventData;
                    }
                }

                // Checkpoint to an event before the buffer/display time period, so we can recover the events on VM restart
                if (eventForNextCheckpoint != null &&
                    eventForNextCheckpoint.EnqueuedTimeUtc + bufferTimeInterval < now &&
                    lastCheckPoint + maxCheckpointFrequency < now)    // Don't checkpoint too often, as every checkpoint incurs at least one blob storage roundtrip
                {
                    await context.CheckpointAsync(eventForNextCheckpoint);

                    Trace.TraceInformation("Checkpointed EH {0}, partition {1}: offset {2}, Sequence Number {3}, time {4}",
                                           context.EventHubPath, context.Lease.PartitionId,
                                           eventForNextCheckpoint.Offset, eventForNextCheckpoint.SequenceNumber,
                                           eventForNextCheckpoint.EnqueuedTimeUtc);

                    // Remove all older messages from the resend buffer
                    lock (bufferedMessages)
                    {
                        if (this.indexOfLastCheckpoint >= 0)
                        {
                            bufferedMessages.RemoveRange(0, this.indexOfLastCheckpoint);
                        }
                        indexOfLastCheckpoint = bufferedMessages.Count - 1;
                    }

                    // Get ready for next checkpoint
                    lastCheckPoint         = now;
                    eventForNextCheckpoint = events.Last <EventData>();
                }
            }
            catch (Exception e)
            {
                Trace.TraceError("Error processing events in EH {0}, partition {1}: {0}",
                                 context.EventHubPath, context.Lease.PartitionId, e.Message);
            }
        }
예제 #35
0
            public async Task ProcessEventsAsync(PartitionContext context, IEnumerable <EventData> messages)
            {
                EventHubTriggerInput value = new EventHubTriggerInput
                {
                    Events  = messages.ToArray(),
                    Context = context
                };

                // Single dispatch
                if (_parent._singleDispatch)
                {
                    int len = value.Events.Length;

                    List <Task> dispatches = new List <Task>();
                    for (int i = 0; i < len; i++)
                    {
                        if (_cts.IsCancellationRequested)
                        {
                            // If we stopped the listener, then we may lose the lease and be unable to checkpoint.
                            // So skip running the rest of the batch. The new listener will pick it up.
                            continue;
                        }
                        else
                        {
                            TriggeredFunctionData input = new TriggeredFunctionData
                            {
                                ParentId     = null,
                                TriggerValue = value.GetSingleEventTriggerInput(i)
                            };
                            Task task = this._parent._executor.TryExecuteAsync(input, _cts.Token);
                            dispatches.Add(task);
                        }
                    }

                    // Drain the whole batch before taking more work
                    if (dispatches.Count > 0)
                    {
                        await Task.WhenAll(dispatches);
                    }
                }
                else
                {
                    // Batch dispatch

                    TriggeredFunctionData input = new TriggeredFunctionData
                    {
                        ParentId     = null,
                        TriggerValue = value
                    };

                    FunctionResult result = await this._parent._executor.TryExecuteAsync(input, CancellationToken.None);
                }

                // Dispose all messages to help with memory pressure. If this is missed, the finalizer thread will still get them.
                foreach (var message in messages)
                {
                    message.Dispose();
                }

                // There are lots of reasons this could fail. That just means that events will get double-processed, which is inevitable
                // with event hubs anyways.
                // For example, it could fail if we lost the lease. That could happen if we failed to renew it due to CPU starvation or an inability
                // to make the outbound network calls to renew.
                await context.CheckpointAsync();
            }
예제 #36
0
        protected virtual void ReceiveEvent(PartitionContext context, EventData eventData)
        {
            // Do a manual 10 try attempt with back-off
            for (int i = 0; i < 10; i++)
            {
                try
                {
                    Logger.LogDebug(string.Format("An event message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}'.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset));
                    string messageBody = Encoding.UTF8.GetString(eventData.GetBytes());

                    IEvent <TAuthenticationToken> @event = AzureBusHelper.ReceiveEvent(messageBody, ReceiveEvent,
                                                                                       string.Format("partition key '{0}', sequence number '{1}' and offset '{2}'", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset),
                                                                                       () =>
                    {
                        // Remove message from queue
                        context.CheckpointAsync(eventData);
                        Logger.LogDebug(string.Format("An event message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' but processing was skipped due to event settings.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset));
                    }
                                                                                       );

                    // Remove message from queue
                    context.CheckpointAsync(eventData);
                    Logger.LogDebug(string.Format("An event message arrived and was processed with the partition key '{0}', sequence number '{1}' and offset '{2}'.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset));

                    IList <IEvent <TAuthenticationToken> > events;
                    if (EventWaits.TryGetValue(@event.CorrelationId, out events))
                    {
                        events.Add(@event);
                    }

                    return;
                }
                catch (Exception exception)
                {
                    // Indicates a problem, unlock message in queue
                    Logger.LogError(string.Format("An event message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' but failed to be process.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset), exception: exception);

                    switch (i)
                    {
                    case 0:
                    case 1:
                        // 10 seconds
                        Thread.Sleep(10 * 1000);
                        break;

                    case 2:
                    case 3:
                        // 30 seconds
                        Thread.Sleep(30 * 1000);
                        break;

                    case 4:
                    case 5:
                    case 6:
                        // 1 minute
                        Thread.Sleep(60 * 1000);
                        break;

                    case 7:
                    case 8:
                    case 9:
                        // 3 minutes
                        Thread.Sleep(3 * 60 * 1000);
                        break;
                    }
                }
            }
            // Eventually just accept it
            context.CheckpointAsync(eventData);
        }
예제 #37
0
        public async Task ProcessEventsAsync(PartitionContext context, IEnumerable <EventData> events)
        {
            try
            {
                var now = DateTime.UtcNow;

                foreach (var eventData in events)
                {
                    // We don't care about messages that are older than bufferTimeInterval
                    if ((eventData.EnqueuedTimeUtc + bufferTimeInterval) >= now)
                    {
                        // Get message from the eventData body and convert JSON string into message object
                        string eventBodyAsString = Encoding.UTF8.GetString(eventData.GetBytes());

                        // There can be several messages in one
                        IList <IDictionary <string, object> > messagePayloads;
                        try
                        {
                            // Attempt to deserialze event body as single JSON message
                            messagePayloads = new List <IDictionary <string, object> >
                            {
                                JsonConvert.DeserializeObject <IDictionary <string, object> >(eventBodyAsString)
                            };
                        }
                        catch
                        {
                            // Not a single JSON message: attempt to deserialize as array of messages

                            // Azure Stream Analytics Preview generates invalid JSON for some multi-values queries
                            // Workaround: turn concatenated json objects (ivalid JSON) into array of json objects (valid JSON)
                            if (eventBodyAsString.IndexOf("}{") >= 0)
                            {
                                eventBodyAsString = eventBodyAsString.Replace("}{", "},{");
                            }
                            if (!eventBodyAsString.EndsWith("]"))
                            {
                                eventBodyAsString = eventBodyAsString + "]";
                            }
                            if (!eventBodyAsString.StartsWith("["))
                            {
                                eventBodyAsString = "[" + eventBodyAsString.Substring(eventBodyAsString.IndexOf("{"));
                            }

                            messagePayloads = JsonConvert.DeserializeObject <IList <IDictionary <string, object> > >(eventBodyAsString);
                        }

                        var rnd = new Random();
                        foreach (var messagePayload in messagePayloads)
                        {
                            // Read time value
                            if (messagePayload.ContainsKey("timecreated"))
                            {
                                messagePayload["time"] = messagePayload["timecreated"];
                            }
                            if (messagePayload.ContainsKey("timearrived"))
                            {
                                messagePayload["time"] = messagePayload["timearrived"];
                            }
                            // process an alert
                            if (messagePayload.ContainsKey("alerttype") && messagePayload.ContainsKey("timecreated"))
                            {
                                Debug.Print("Alert message received!");

                                DateTime time = DateTime.Parse(messagePayload["timecreated"].ToString());
                                // find the nearest point
                                lock (sortedDataBuffer)
                                {
                                    int    idx       = SearchHelper.FindFirstIndexGreaterThanOrEqualTo(sortedDataBuffer, time);
                                    bool   found     = false;
                                    string alertType = messagePayload["alerttype"] as string;

                                    if (idx >= sortedDataBuffer.Values.Count)
                                    {
                                        idx = sortedDataBuffer.Values.Count - 1;
                                    }

                                    while (idx >= 0)
                                    {
                                        List <IDictionary <string, object> > dictList = sortedDataBuffer.Values[idx];
                                        foreach (IDictionary <string, object> dict in dictList)
                                        {
                                            if (
                                                (dict.ContainsKey("guid") && messagePayload.ContainsKey("guid") && messagePayload["guid"].ToString() == dict["guid"].ToString())
                                                &&
                                                (dict.ContainsKey("measurename") && messagePayload.ContainsKey("measurename") && messagePayload["measurename"].ToString() == dict["measurename"].ToString())
                                                &&
                                                (!messagePayload.ContainsKey("displayname") || dict.ContainsKey("displayname") && messagePayload["measurename"].ToString() == dict["measurename"].ToString())
                                                )
                                            {
                                                // fill anomaly message
                                                if (!messagePayload.ContainsKey("value"))
                                                {
                                                    messagePayload["value"] = dict["value"];
                                                }
                                                if (!messagePayload.ContainsKey("displayname") && dict.ContainsKey("displayname"))
                                                {
                                                    messagePayload["displayname"] = dict["displayname"];
                                                }
                                                if (!messagePayload.ContainsKey("time"))
                                                {
                                                    messagePayload["time"] = messagePayload["timecreated"];
                                                }
                                                found = true;
                                                break;
                                            }
                                        }
                                        if (found)
                                        {
                                            break;
                                        }
                                        idx--;
                                    }
                                }
                            }

                            if (messagePayload.ContainsKey("guid"))
                            {
                                var    guid = messagePayload["guid"].ToString();
                                double val  = Convert.ToDouble(messagePayload["value"]);
                                if (!MinMaxValue.ContainsKey(guid))
                                {
                                    MinMaxValue.Add(guid, new MinMax {
                                        min = val, max = val
                                    });
                                }

                                MinMax tmp = MinMaxValue[messagePayload["guid"].ToString()];
                                if (tmp.min > val)
                                {
                                    tmp.min = val;
                                }
                                if (tmp.max < val)
                                {
                                    tmp.max = val;
                                }
                            }
                            // We want to read the time value from the message itself.
                            // If none is found we will use the enqueued time
                            DateTime messageTimeStamp = new DateTime();
                            if (messagePayload.ContainsKey("time"))
                            {
                                messageTimeStamp = DateTime.Parse(messagePayload["time"].ToString());

                                //data.Timestamp = messagePayload["time"].ToString();
                                //if (GenerateAnomalies && rnd.Next(100) >= 95)
                                //{
                                //    messagePayload.Add("alerttype", "testType");
                                //    messagePayload.Add("dsplalert", "testAlert");
                                //    messagePayload.Add("message", "Anomaly detected by Azure ML model.");
                                //    messagePayload.Add("timestart", messagePayload["time"]);

                                //    // correct value
                                //    if (rnd.Next(2) == 1)
                                //        messagePayload["value"] = MinMaxValue[messagePayload["guid"].ToString()].max * (1.01 + 0.05 * rnd.Next(100) / 100);
                                //    else
                                //        messagePayload["value"] = MinMaxValue[messagePayload["guid"].ToString()].min * (0.99 - 0.05 * rnd.Next(100) / 100);
                                //}
                            }
                            else if (messagePayload.ContainsKey("timestart"))
                            {
                                messageTimeStamp = DateTime.Parse(messagePayload["timestart"].ToString());
                            }
                            else
                            {
                                messageTimeStamp = eventData.EnqueuedTimeUtc;
                            }

                            // Build up the list of devices seen so far (in lieu of a formal device repository)
                            // Also keep the last message received per device (not currently used in the sample)
                            if (messagePayload.ContainsKey("guid") && !messagePayload.ContainsKey("valueAvg"))
                            {
                                string guid = messagePayload["guid"].ToString();
                                if (guid != null)
                                {
                                    WebSocketEventProcessor.g_devices.TryAdd(guid, messagePayload);
                                }
                            }


                            if (messagePayload["measurename"].ToString().ToLower().Equals("temperature"))
                            {
                                if (!String.IsNullOrEmpty(messagePayload["value"].ToString()))
                                {
                                    CloudStorageAccount storageAccount = CloudStorageAccount.Parse("Storage Connection String");

                                    // Create the table client.
                                    CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

                                    // Create the CloudTable object that represents the "people" table.
                                    CloudTable table = tableClient.GetTableReference("Table Storage Name");

                                    // Create a new customer entity.
                                    DeloreanData data = new DeloreanData("Table Storage Primary Key", "");


                                    if (messagePayload.ContainsKey("measurename"))
                                    {
                                        data.measurename = messagePayload["measurename"].ToString();
                                    }
                                    if (messagePayload.ContainsKey("value"))
                                    {
                                        data.value = messagePayload["value"].ToString();
                                    }
                                    if (messagePayload.ContainsKey("unitofmeasure"))
                                    {
                                        data.unitofmeasure = messagePayload["unitofmeasure"].ToString();
                                    }
                                    if (messagePayload.ContainsKey("displayname"))
                                    {
                                        data.displayname = messagePayload["displayname"].ToString();
                                    }
                                    if (messagePayload.ContainsKey("organization"))
                                    {
                                        data.organization = messagePayload["organization"].ToString();
                                    }
                                    if (messagePayload.ContainsKey("location"))
                                    {
                                        data.location = messagePayload["location"].ToString();
                                    }
                                    data.RowKey = DateTime.Parse(messagePayload["timecreated"].ToString()).Ticks.ToString() + "-" + data.measurename;
                                    TableOperation insertOperation = TableOperation.Insert(data);

                                    //var temperature = double.Parse(data.value);
                                    //if (temperature > 75)
                                    // {

                                    //NotificationHubClient hub = NotificationHubClient
                                    //    .CreateClientFromConnectionString("Endpoint=sb://deloreantesthub-ns.servicebus.windows.net/;SharedAccessKeyName=DefaultFullSharedAccessSignature;SharedAccessKey=wSpPlbYOksiifQGSa7qT1lXeWzxOKatCbHoGSqZOKfY=", "deloreantesthub");
                                    //var toast = @"<toast><visual><binding template=""ToastText01""><text id=""1"">Hello from a .NET App!</text></binding></visual></toast>";
                                    //await hub.SendWindowsNativeNotificationAsync(toast);
                                    table.Execute(insertOperation);
                                    //}
                                }
                            }
                            // Create the TableOperation that inserts the customer entity.

                            //table.Execute(insertOperation);

                            // Notify clients
                            MyWebSocketHandler.SendToClients(messagePayload);

                            // Buffer messages so we can resend them to clients that connect later
                            // or when a client requests data for a different device

                            // Lock to guard against concurrent reads from client resend
                            lock (sortedDataBuffer)
                            {
                                if (!sortedDataBuffer.ContainsKey(messageTimeStamp))
                                {
                                    sortedDataBuffer.Add(messageTimeStamp, new List <IDictionary <string, object> >());
                                }

                                sortedDataBuffer[messageTimeStamp].Add(messagePayload);
                            }
                        }
                    }
                    else
                    {
                        Debug.Print("Received old message timestamped:" + eventData.EnqueuedTimeUtc.ToString());
                    }
                }

                //Call checkpoint every minute
                if (this.checkpointStopWatch.Elapsed > TimeSpan.FromMinutes(1))
                {
                    await context.CheckpointAsync();

                    lock (this)
                    {
                        this.checkpointStopWatch.Restart();
                    }

                    // trim data buffer to keep only last 10 minutes of data
                    lock (sortedDataBuffer)
                    {
                        DateTime oldDataPoint = now - bufferTimeInterval;
                        // find the closest point
                        int idx = SearchHelper.FindFirstIndexGreaterThanOrEqualTo(sortedDataBuffer, oldDataPoint);
                        // trim
                        while (idx > 0 && sortedDataBuffer.Count > 0 && sortedDataBuffer.Keys[0] <= oldDataPoint)
                        {
                            sortedDataBuffer.RemoveAt(0);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Trace.TraceError("Error processing events in EH {0}, partition {1}: {0}",
                                 context.EventHubPath, context.Lease.PartitionId, e.Message);
            }
        }
예제 #38
0
 // ReSharper disable once FunctionComplexityOverflow
 public async Task ProcessEventsAsync(PartitionContext context, IEnumerable <EventData> messages)
 {
     try
     {
         if (configuration.CancellationToken.IsCancellationRequested)
         {
             return;
         }
         var events   = messages as IList <EventData> ?? messages.ToList();
         var bodySize = (long)0;
         for (var i = 0; i < events.Count; i++)
         {
             if (configuration.CancellationToken.IsCancellationRequested)
             {
                 break;
             }
             if (configuration.MessageInspector != null)
             {
                 events[i] = configuration.MessageInspector.AfterReceiveMessage(events[i]);
             }
             if (configuration.Logging)
             {
                 var builder = new StringBuilder(string.IsNullOrWhiteSpace(events[i].PartitionKey)?
                                                 string.Format(EventDataSuccessfullyNoPartitionKeyReceived,
                                                               context.Lease.PartitionId,
                                                               events[i].SequenceNumber,
                                                               events[i].Offset,
                                                               events[i].EnqueuedTimeUtc):
                                                 string.Format(EventDataSuccessfullyReceived,
                                                               context.Lease.PartitionId,
                                                               events[i].PartitionKey,
                                                               events[i].SequenceNumber,
                                                               events[i].Offset,
                                                               events[i].EnqueuedTimeUtc));
                 if (configuration.Verbose)
                 {
                     configuration.ServiceBusHelper.GetMessageAndProperties(builder, events[i]);
                 }
                 configuration.WriteToLog(builder.ToString());
             }
             if (configuration.Tracking && !configuration.CancellationToken.IsCancellationRequested)
             {
                 configuration.TrackEvent(events[i]);
             }
             bodySize += events[i].SerializedSizeInBytes;
             if (!configuration.Checkpoint)
             {
                 continue;
             }
             await partitionContext.CheckpointAsync(events[events.Count - 1]);
         }
         configuration.UpdateStatistics(events.Count, configuration.GetElapsedTime(), bodySize);
     }
     catch (LeaseLostException)
     {
     }
     catch (Exception ex)
     {
         HandleException(ex);
     }
 }
 public async Task ProcessEventsAsync(PartitionContext context, IEnumerable <EventData> messages)
 {
     Trace.TraceInformation("CheckPointEventProcessor processing {0} messages from partition {1}...", messages.ToList().Count, context.Lease.PartitionId);
     await context.CheckpointAsync();
 }
예제 #40
0
 private async Task Checkpoint(EventData message, PartitionContext context)
 {
     Log.DebugFormat("Will checkpoint at Offset: {0}, {1}", message.SystemProperties.Offset, new PartitionContextInfo(context));
     await context.CheckpointAsync(message);
 }
        protected override void ReceiveCommand(PartitionContext context, EventData eventData)
        {
            // Do a manual 10 try attempt with back-off
            for (int i = 0; i < 10; i++)
            {
                try
                {
                    Logger.LogDebug(string.Format("A command message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}'.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset));
                    string messageBody = Encoding.UTF8.GetString(eventData.GetBytes());
                    ICommand <TAuthenticationToken> command = MessageSerialiser.DeserialiseCommand(messageBody);

                    CorrelationIdHelper.SetCorrelationId(command.CorrelationId);
                    Logger.LogInfo(string.Format("A command message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' was of type {3}.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset, command.GetType().FullName));

                    Type commandType = command.GetType();

                    string targetQueueName = commandType.FullName;

                    try
                    {
                        object rsn = commandType.GetProperty("Rsn").GetValue(command, null);
                        targetQueueName = string.Format("{0}.{1}", targetQueueName, rsn);
                    }
                    catch
                    {
                        Logger.LogDebug(string.Format("A command message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' was of type {3} but with no Rsn property.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset, commandType));
                        // Do nothing if there is no rsn. Just use command type name
                    }

                    CreateQueueAndAttachListenerIfNotExist(targetQueueName);
                    EnqueueCommand(targetQueueName, command);

                    // remove the original message from the incoming queue
                    context.CheckpointAsync(eventData);

                    Logger.LogDebug(string.Format("A command message arrived and was processed with the partition key '{0}', sequence number '{1}' and offset '{2}'.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset));
                    return;
                }
                catch (Exception exception)
                {
                    // Indicates a problem, unlock message in queue
                    Logger.LogError(string.Format("A command message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' but failed to be process.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset), exception: exception);

                    switch (i)
                    {
                    case 0:
                    case 1:
                        // 10 seconds
                        Thread.Sleep(10 * 1000);
                        break;

                    case 2:
                    case 3:
                        // 30 seconds
                        Thread.Sleep(30 * 1000);
                        break;

                    case 4:
                    case 5:
                    case 6:
                        // 1 minute
                        Thread.Sleep(60 * 1000);
                        break;

                    case 7:
                    case 8:
                    case 9:
                        // 3 minutes
                        Thread.Sleep(3 * 60 * 1000);
                        break;
                    }
                }
            }
            // Eventually just accept it
            context.CheckpointAsync(eventData);
        }
        public async Task ProcessEventsAsync(PartitionContext context, IEnumerable <EventData> events)
        {
            try
            {
                var now = DateTime.UtcNow;

                foreach (var eventData in events)
                {
                    // We don't care about messages that are older than bufferTimeInterval
                    if ((eventData.EnqueuedTimeUtc + bufferTimeInterval) >= now)
                    {
                        // Get message from the eventData body and convert JSON string into message object
                        string eventBodyAsString = Encoding.UTF8.GetString(eventData.GetBytes());

                        // There can be several messages in one
                        IList <IDictionary <string, object> > messagePayloads;
                        try
                        {
                            // Attempt to deserialze event body as single JSON message
                            messagePayloads = new List <IDictionary <string, object> >
                            {
                                JsonConvert.DeserializeObject <IDictionary <string, object> >(eventBodyAsString)
                            };
                        }
                        catch
                        {
                            // Not a single JSON message: attempt to deserialize as array of messages

                            // Azure Stream Analytics Preview generates invalid JSON for some multi-values queries
                            // Workaround: turn concatenated json objects (ivalid JSON) into array of json objects (valid JSON)
                            if (eventBodyAsString.IndexOf("}{") >= 0)
                            {
                                eventBodyAsString = eventBodyAsString.Replace("}{", "},{");
                            }
                            if (eventBodyAsString.IndexOf("}\r\n{") >= 0)
                            {
                                eventBodyAsString = eventBodyAsString.Replace("}\r\n{", "},{");
                            }
                            if (!eventBodyAsString.EndsWith("]"))
                            {
                                eventBodyAsString = eventBodyAsString + "]";
                            }
                            if (!eventBodyAsString.StartsWith("["))
                            {
                                eventBodyAsString = "[" + eventBodyAsString.Substring(eventBodyAsString.IndexOf("{"));
                            }

                            messagePayloads = JsonConvert.DeserializeObject <IList <IDictionary <string, object> > >(eventBodyAsString);
                        }

                        var rnd = new Random();
                        foreach (var messagePayload in messagePayloads)
                        {
                            // Read time value
                            if (messagePayload.ContainsKey("timecreated"))
                            {
                                messagePayload["time"] = messagePayload["timecreated"];
                            }
                            if (messagePayload.ContainsKey("timearrived"))
                            {
                                messagePayload["time"] = messagePayload["timearrived"];
                            }
                            // process an alert
                            if (messagePayload.ContainsKey("alerttype") && messagePayload.ContainsKey("timecreated"))
                            {
                                Debug.Print("Alert message received!");

                                DateTime time = DateTime.Parse(messagePayload["timecreated"].ToString());
                                // find the nearest point
                                lock (sortedDataBuffer)
                                {
                                    int    idx       = SearchHelper.FindFirstIndexGreaterThanOrEqualTo(sortedDataBuffer, time);
                                    bool   found     = false;
                                    string alertType = messagePayload["alerttype"] as string;

                                    if (idx >= sortedDataBuffer.Values.Count)
                                    {
                                        idx = sortedDataBuffer.Values.Count - 1;
                                    }

                                    while (idx >= 0)
                                    {
                                        List <IDictionary <string, object> > dictList = sortedDataBuffer.Values[idx];
                                        foreach (IDictionary <string, object> dict in dictList)
                                        {
                                            if (
                                                (dict.ContainsKey("guid") && messagePayload.ContainsKey("guid") && messagePayload["guid"].ToString() == dict["guid"].ToString())
                                                &&
                                                (dict.ContainsKey("measurename") && messagePayload.ContainsKey("measurename") && messagePayload["measurename"].ToString() == dict["measurename"].ToString())
                                                &&
                                                (!messagePayload.ContainsKey("displayname") || dict.ContainsKey("displayname") && messagePayload["measurename"].ToString() == dict["measurename"].ToString())
                                                )
                                            {
                                                // fill anomaly message
                                                if (!messagePayload.ContainsKey("value"))
                                                {
                                                    messagePayload["value"] = dict["value"];
                                                }
                                                if (!messagePayload.ContainsKey("displayname") && dict.ContainsKey("displayname"))
                                                {
                                                    messagePayload["displayname"] = dict["displayname"];
                                                }
                                                if (!messagePayload.ContainsKey("time"))
                                                {
                                                    messagePayload["time"] = messagePayload["timecreated"];
                                                }
                                                found = true;
                                                break;
                                            }
                                        }
                                        if (found)
                                        {
                                            break;
                                        }
                                        idx--;
                                    }
                                }
                            }

                            if (messagePayload.ContainsKey("guid"))
                            {
                                var    guid = messagePayload["guid"].ToString();
                                double val  = Convert.ToDouble(messagePayload["value"]);

                                if (!MinMaxValue.ContainsKey(guid))
                                {
                                    MinMaxValue.Add(guid, new MinMax {
                                        min = val, max = val
                                    });
                                }

                                MinMax tmp = MinMaxValue[messagePayload["guid"].ToString()];
                                if (tmp.min > val)
                                {
                                    tmp.min = val;
                                }
                                if (tmp.max < val)
                                {
                                    tmp.max = val;
                                }
                            }
                            // We want to read the time value from the message itself.
                            // If none is found we will use the enqueued time
                            DateTime messageTimeStamp = new DateTime();
                            if (messagePayload.ContainsKey("time"))
                            {
                                messageTimeStamp = DateTime.Parse(messagePayload["time"].ToString());

                                //if (GenerateAnomalies && rnd.Next(100) >= 95)
                                //{
                                //    messagePayload.Add("alerttype", "testType");
                                //    messagePayload.Add("dsplalert", "testAlert");
                                //    messagePayload.Add("message", "Anomaly detected by Azure ML model.");
                                //    messagePayload.Add("timestart", messagePayload["time"]);

                                //    // correct value
                                //    if (rnd.Next(2) == 1)
                                //        messagePayload["value"] = MinMaxValue[messagePayload["guid"].ToString()].max * (1.01 + 0.05 * rnd.Next(100) / 100);
                                //    else
                                //        messagePayload["value"] = MinMaxValue[messagePayload["guid"].ToString()].min * (0.99 - 0.05 * rnd.Next(100) / 100);
                                //}
                            }
                            else if (messagePayload.ContainsKey("timestart"))
                            {
                                messageTimeStamp = DateTime.Parse(messagePayload["timestart"].ToString());
                            }
                            else
                            {
                                messageTimeStamp = eventData.EnqueuedTimeUtc;
                            }

                            // Build up the list of devices seen so far (in lieu of a formal device repository)
                            // Also keep the last message received per device (not currently used in the sample)
                            if (messagePayload.ContainsKey("guid") && !messagePayload.ContainsKey("valueAvg"))
                            {
                                string guid = messagePayload["guid"].ToString();
                                if (guid != null)
                                {
                                    WebSocketEventProcessor.g_devices.TryAdd(guid, messagePayload);
                                }
                            }

                            // Notify clients
                            MyWebSocketHandler.SendToClients(messagePayload);

                            // Buffer messages so we can resend them to clients that connect later
                            // or when a client requests data for a different device

                            // Lock to guard against concurrent reads from client resend
                            lock (sortedDataBuffer)
                            {
                                if (!sortedDataBuffer.ContainsKey(messageTimeStamp))
                                {
                                    sortedDataBuffer.Add(messageTimeStamp, new List <IDictionary <string, object> >());
                                }

                                sortedDataBuffer[messageTimeStamp].Add(messagePayload);
                            }
                        }
                    }
                    else
                    {
                        Debug.Print("Received old message timestamped:" + eventData.EnqueuedTimeUtc.ToString());
                    }
                }

                //Call checkpoint every minute
                if (this.checkpointStopWatch.Elapsed > TimeSpan.FromMinutes(1))
                {
                    await context.CheckpointAsync();

                    lock (this)
                    {
                        this.checkpointStopWatch.Restart();
                    }

                    // trim data buffer to keep only last 10 minutes of data
                    lock (sortedDataBuffer)
                    {
                        DateTime oldDataPoint = now - bufferTimeInterval;
                        // find the closest point
                        int idx = SearchHelper.FindFirstIndexGreaterThanOrEqualTo(sortedDataBuffer, oldDataPoint);
                        // trim
                        while (idx > 0 && sortedDataBuffer.Count > 0 && sortedDataBuffer.Keys[0] <= oldDataPoint)
                        {
                            sortedDataBuffer.RemoveAt(0);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Trace.TraceError("Error processing events in EH {0}, partition {1}: {0}",
                                 context.EventHubPath, context.Lease.PartitionId, e.Message);
            }
        }
예제 #43
0
 public async Task ProcessEventsAsync(PartitionContext context, IEnumerable <EventData> messages)
 {
     foreach (var eventData in messages)
     {
         Log.Logger.Information("Processing event: {sequenceNumber}", eventData.SequenceNumber);
         var data = Encoding.UTF8.GetString(eventData.GetBytes());
         try
         {
             if (data.Contains("<"))
             {
                 var eventXml       = XElement.Parse(data);
                 var lastChangeNode =
                     eventXml.Descendants(XName.Get("LastChange"))
                     .SingleOrDefault();
                 if (lastChangeNode != null)
                 {
                     var rawEvent = XElement.Parse(lastChangeNode.Value);
                     var currentTrackMetaDataNode = rawEvent
                                                    .Descendants(XName.Get("CurrentTrackMetaData",
                                                                           "urn:schemas-upnp-org:metadata-1-0/AVT/"))
                                                    .SingleOrDefault(n => !String.IsNullOrEmpty(n.Attribute("val").Value));
                     if (currentTrackMetaDataNode != null)
                     {
                         var metadata      = currentTrackMetaDataNode.Attribute(XName.Get("val")).Value;
                         var metaXml       = XElement.Parse(metadata);
                         var classTypeNode =
                             metaXml.Descendants(XName.Get("class", "urn:schemas-upnp-org:metadata-1-0/upnp/"))
                             .SingleOrDefault();
                         if (classTypeNode != null)
                         {
                             var classType = classTypeNode.Value;
                             switch (classType)
                             {
                             case "object.item.audioItem.musicTrack":
                                 var res =
                                     metaXml.Descendants(XName.Get("res",
                                                                   "urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"))
                                     .SingleOrDefault();
                                 if (res != null)
                                 {
                                     var urlString = res.Value;
                                     var albumNode =
                                         metaXml.Descendants(XName.Get("album",
                                                                       "urn:schemas-upnp-org:metadata-1-0/upnp/"))
                                         .SingleOrDefault();
                                     string album = null;
                                     if (albumNode != null)
                                     {
                                         album = albumNode.Value;
                                     }
                                     var track =
                                         metaXml.Descendants(XName.Get("title",
                                                                       "http://purl.org/dc/elements/1.1/"))
                                         .Single()
                                         .Value;
                                     var artist =
                                         metaXml.Descendants(XName.Get("creator",
                                                                       "http://purl.org/dc/elements/1.1/"))
                                         .Single()
                                         .Value;
                                     urlString = urlString.Replace("pndrradio-", string.Empty);
                                     var fileLocation    = new Uri(urlString);
                                     var albumArtUriNode = metaXml.Descendants(XName.Get("albumArtURI",
                                                                                         "urn:schemas-upnp-org:metadata-1-0/upnp/")).SingleOrDefault();
                                     Uri albumArtUri = null;
                                     if (albumArtUriNode != null)
                                     {
                                         albumArtUri = new Uri(albumArtUriNode.Value);
                                     }
                                     recordCreator.Tell(new NewRecordMessage(artist, album, track,
                                                                             fileLocation, albumArtUri));
                                 }
                                 break;
                             }
                         }
                     }
                 }
             }
         }
         catch (Exception e)
         {
             Log.Logger.Error(e, "Error: {e}");
         }
         await context.CheckpointAsync(eventData);
     }
 }
 public async Task CloseAsync(PartitionContext context, CloseReason reason)
 {
     this.logger.Debug("Event Processor Shutting Down.", () => new { context.PartitionId, reason });
     await context.CheckpointAsync();
 }
예제 #45
0
        protected virtual void ReceiveCommand(PartitionContext context, EventData eventData)
        {
            DateTimeOffset startedAt     = DateTimeOffset.UtcNow;
            Stopwatch      mainStopWatch = Stopwatch.StartNew();
            string         responseCode  = "200";
            // Null means it was skipped
            bool?              wasSuccessfull      = true;
            string             telemetryName       = string.Format("Cqrs/Handle/Command/{0}", eventData.SequenceNumber);
            ISingleSignOnToken authenticationToken = null;

            IDictionary <string, string> telemetryProperties = new Dictionary <string, string> {
                { "Type", "Azure/EventHub" }
            };
            object value;

            if (eventData.Properties.TryGetValue("Type", out value))
            {
                telemetryProperties.Add("MessageType", value.ToString());
            }
            TelemetryHelper.TrackMetric("Cqrs/Handle/Command", CurrentHandles++, telemetryProperties);
            // Do a manual 10 try attempt with back-off
            for (int i = 0; i < 10; i++)
            {
                try
                {
                    Logger.LogDebug(string.Format("A command message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}'.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset));
                    string messageBody = Encoding.UTF8.GetString(eventData.GetBytes());

                    ICommand <TAuthenticationToken> command = AzureBusHelper.ReceiveCommand(messageBody, ReceiveCommand,
                                                                                            string.Format("partition key '{0}', sequence number '{1}' and offset '{2}'", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset),
                                                                                            () =>
                    {
                        wasSuccessfull = null;
                        telemetryName  = string.Format("Cqrs/Handle/Command/Skipped/{0}", eventData.SequenceNumber);
                        responseCode   = "204";
                        // Remove message from queue
                        context.CheckpointAsync(eventData);
                        Logger.LogDebug(string.Format("A command message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' but processing was skipped due to command settings.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset));
                        TelemetryHelper.TrackEvent("Cqrs/Handle/Command/Skipped", telemetryProperties);
                    }
                                                                                            );

                    if (wasSuccessfull != null)
                    {
                        if (command != null)
                        {
                            telemetryName       = string.Format("{0}/{1}", command.GetType().FullName, command.Id);
                            authenticationToken = command.AuthenticationToken as ISingleSignOnToken;

                            var telemeteredMessage = command as ITelemeteredMessage;
                            if (telemeteredMessage != null)
                            {
                                telemetryName = telemeteredMessage.TelemetryName;
                            }

                            telemetryName = string.Format("Cqrs/Handle/Command/{0}", telemetryName);
                        }
                        // Remove message from queue
                        context.CheckpointAsync(eventData);
                    }
                    Logger.LogDebug(string.Format("A command message arrived and was processed with the partition key '{0}', sequence number '{1}' and offset '{2}'.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset));

                    wasSuccessfull = true;
                    responseCode   = "200";
                    return;
                }
                catch (Exception exception)
                {
                    // Indicates a problem, unlock message in queue
                    Logger.LogError(string.Format("A command message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' but failed to be process.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset), exception: exception);

                    switch (i)
                    {
                    case 0:
                    case 1:
                        // 10 seconds
                        Thread.Sleep(10 * 1000);
                        break;

                    case 2:
                    case 3:
                        // 30 seconds
                        Thread.Sleep(30 * 1000);
                        break;

                    case 4:
                    case 5:
                    case 6:
                        // 1 minute
                        Thread.Sleep(60 * 1000);
                        break;

                    case 7:
                    case 8:
                        // 3 minutes
                        Thread.Sleep(3 * 60 * 1000);
                        break;

                    case 9:
                        telemetryProperties.Add("ExceptionType", exception.GetType().FullName);
                        telemetryProperties.Add("ExceptionMessage", exception.Message);
                        break;
                    }
                    wasSuccessfull = false;
                    responseCode   = "500";
                }
                finally
                {
                    // Eventually just accept it
                    context.CheckpointAsync(eventData);

                    TelemetryHelper.TrackMetric("Cqrs/Handle/Command", CurrentHandles--, telemetryProperties);

                    mainStopWatch.Stop();
                    TelemetryHelper.TrackRequest
                    (
                        telemetryName,
                        authenticationToken,
                        startedAt,
                        mainStopWatch.Elapsed,
                        responseCode,
                        wasSuccessfull == null || wasSuccessfull.Value,
                        telemetryProperties
                    );

                    TelemetryHelper.Flush();
                }
            }
        }
예제 #46
0
        public async Task ProcessEventsAsync(PartitionContext context, IEnumerable <EventData> messages)
        {
            Trace.TraceInformation("ActionProcessor: In ProcessEventsAsync");
            List <LocationJerkModel> newLocationJerks = new List <LocationJerkModel>();

            foreach (EventData message in messages)
            {
                try
                {
                    Trace.TraceInformation("ActionProcessor: {0} - Partition {1}", message.Offset, context.Lease.PartitionId);
                    this.LastMessageOffset = message.Offset;

                    string jsonString = Encoding.UTF8.GetString(message.GetBytes());
                    List <TelemetryJerkModel> convertedList = JsonConvert.DeserializeObject <List <TelemetryJerkModel> >(jsonString);
                    var results = convertedList.Distinct(new TelemetryJerkComparer());
                    if (results != null)
                    {
                        foreach (TelemetryJerkModel item in results)
                        {
                            UpdateLocationJerkList(GetLocationJerkFromTelemetry(item), ref newLocationJerks);
                        }
                    }

                    ++_totalMessages;
                }
                catch (Exception e)
                {
                    Trace.TraceError("ActionProcessor: Error in ProcessEventAsync -- " + e.ToString());
                }
            }
            //finally save data to blob
            try
            {
                await SaveToLocationJerkInfo(newLocationJerks);
            }
            catch (Exception ex)
            {
                Trace.TraceError(
                    "{0}{0}*** SaveLocationJerkInfo Exception - ActionProcessor.ProcessEventsAsync ***{0}{0}{1}{0}{0}",
                    Console.Out.NewLine,
                    ex);
            }

            // checkpoint after processing batch
            try
            {
                await context.CheckpointAsync();
            }
            catch (Exception ex)
            {
                Trace.TraceError(
                    "{0}{0}*** CheckpointAsync Exception - ActionProcessor.ProcessEventsAsync ***{0}{0}{1}{0}{0}",
                    Console.Out.NewLine,
                    ex);
            }

            if (this.IsClosed)
            {
                this.IsReceivedMessageAfterClose = true;
            }
        }
예제 #47
0
 async Task ICheckpointer.CheckpointAsync(PartitionContext context)
 {
     await context.CheckpointAsync();
 }
예제 #48
0
        public async Task ProcessEventsAsync(PartitionContext context, IEnumerable <EventData> events)
        {
            try
            {
                var now = DateTime.UtcNow;

                foreach (var eventData in events)
                {
                    // We don't care about messages that are older than bufferTimeInterval
                    if ((eventData.EnqueuedTimeUtc + bufferTimeInterval) >= now)
                    {
                        // Get message from the eventData body and convert JSON string into message object
                        string eventBodyAsString = Encoding.UTF8.GetString(eventData.GetBytes());

                        // There can be several messages in one
                        IList <IDictionary <string, object> > messagePayloads;
                        try
                        {
                            // Attempt to deserialze event body as single JSON message
                            messagePayloads = new List <IDictionary <string, object> >
                            {
                                JsonConvert.DeserializeObject <IDictionary <string, object> >(eventBodyAsString)
                            };
                        }
                        catch
                        {
                            // Not a single JSON message: attempt to deserialize as array of messages

                            // Azure Stream Analytics Preview generates invalid JSON for some multi-values queries
                            // Workaround: turn concatenated json objects (ivalid JSON) into array of json objects (valid JSON)
                            if (eventBodyAsString.IndexOf("}{") >= 0)
                            {
                                eventBodyAsString = eventBodyAsString.Replace("}{", "},{");
                            }
                            if (!eventBodyAsString.EndsWith("]"))
                            {
                                eventBodyAsString = eventBodyAsString + "]";
                            }
                            if (!eventBodyAsString.StartsWith("["))
                            {
                                eventBodyAsString = "[" + eventBodyAsString;
                            }

                            messagePayloads = JsonConvert.DeserializeObject <IList <IDictionary <string, object> > >(eventBodyAsString);
                        }

                        foreach (var messagePayload in messagePayloads)
                        {
                            // We want to read the time value from the message itself.
                            // If none is found we will use the enqueued time
                            DateTime messageTimeStamp = new DateTime();
                            if (messagePayload.ContainsKey("time"))
                            {
                                messageTimeStamp = DateTime.Parse(messagePayload["time"].ToString());
                            }
                            else if (messagePayload.ContainsKey("timeStart"))
                            {
                                messageTimeStamp = DateTime.Parse(messagePayload["timeStart"].ToString());
                            }
                            else
                            {
                                messageTimeStamp = eventData.EnqueuedTimeUtc;
                            }

                            // Build up the list of devices seen so far (in lieu of a formal device repository)
                            // Also keep the last message received per device (not currently used in the sample)
                            string deviceName = null;
                            if (messagePayload.ContainsKey("dspl"))
                            {
                                deviceName = messagePayload["dspl"] as string;
                                if (deviceName != null)
                                {
                                    WebSocketEventProcessor.g_devices.TryAdd(deviceName, messagePayload);
                                }
                            }

                            // Notify clients
                            MyWebSocketHandler.SendToClients(messagePayload);

                            // Buffer messages so we can resend them to clients that connect later
                            // or when a client requests data for a different device

                            // Lock to guard against concurrent reads from client resend
                            // Note that the Add operations are not contentious with each other
                            // because EH processor host serializes per partition, and we use one buffer per partition
                            lock (this.sortedDataBuffer)
                            {
                                if (!sortedDataBuffer.ContainsKey(messageTimeStamp))
                                {
                                    this.sortedDataBuffer.Add(messageTimeStamp, messagePayload);
                                }
                            }
                        }
                    }
                }

                //Call checkpoint every minute
                if (this.checkpointStopWatch.Elapsed > TimeSpan.FromMinutes(1))
                {
                    await context.CheckpointAsync();

                    lock (this)
                    {
                        this.checkpointStopWatch.Reset();
                    }

                    // trim data buffer to keep only last 10 minutes of data
                    lock (this.sortedDataBuffer)
                    {
                        SortedList <DateTime, IDictionary <string, object> > tempBuffer = new SortedList <DateTime, IDictionary <string, object> >();
                        foreach (var item in this.sortedDataBuffer)
                        {
                            if (item.Key + bufferTimeInterval >= now)
                            {
                                tempBuffer.Add(item.Key, item.Value);
                            }
                        }

                        this.sortedDataBuffer = tempBuffer;
                    }
                }
            }
            catch (Exception e)
            {
                Trace.TraceError("Error processing events in EH {0}, partition {1}: {0}",
                                 context.EventHubPath, context.Lease.PartitionId, e.Message);
            }
        }
예제 #49
0
        public async Task ProcessEventsAsync(PartitionContext context, IEnumerable <EventData> messages)
        {
            foreach (var eventData in messages)
            {
                var reqTime = DateTime.UtcNow;

                var data = Encoding.UTF8.GetString(eventData.Body.Array, eventData.Body.Offset, eventData.Body.Count);
                _logger.LogInformation($"Message received. Partition: '{context.PartitionId}', Data: '{data}'");

                var hitmsg = JsonConvert.DeserializeObject <HitCountMessage>(data);
                var devid  = eventData.Properties["iothub-connection-device-id"].ToString();

                //bool hasDevice;
                //try
                //{
                //    // Check the device exist
                //    var device = await iotRegManager.GetDeviceAsync(devid);
                //    hasDevice = (device != null ? true : false);
                //}
                //catch
                //{
                //    hasDevice = false;
                //}

                //bool ehResult = true;
                //if (hasDevice)
                //{
                //    try
                //    {
                //        // invoke direct method
                //        var method = new CloudToDeviceMethod("ControlMethod");
                //        method.SetPayloadJson(data);

                //        await serviceClient.InvokeDeviceMethodAsync(devid, method);
                //        ehResult = true;
                //    }
                //    catch (Exception ex)
                //    {
                //        _logger.LogError(ex.ToString());
                //        ehResult = false;
                //    }
                //}
                //else
                //{
                //    _logger.LogError("Device not found. No method call.");
                //}

                bool ehResult;
                try
                {
                    // invoke direct method
                    var method = new CloudToDeviceMethod("ControlMethod");
                    method.SetPayloadJson(data);

                    await serviceClient.InvokeDeviceMethodAsync(devid, method);

                    ehResult = true;
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex.ToString());
                    ehResult = false;
                }

                var reqid = Guid.NewGuid().ToString();

                //var duration = reqTime.Subtract(DateTimeOffset.Parse(eventData.Properties["ruleset-request-time"].ToString()));
                var duration = reqTime.Subtract(eventData.SystemProperties.EnqueuedTimeUtc);

                var dependencyTelemetry = new DependencyTelemetry
                {
                    Id        = reqid,
                    Duration  = duration,
                    Target    = "IoT Hub",
                    Success   = ehResult,
                    Name      = "MessageService processing",
                    Timestamp = reqTime
                };
                dependencyTelemetry.Context.Operation.Id       = hitmsg.corellationId;
                dependencyTelemetry.Context.Operation.ParentId = (eventData.Properties.ContainsKey("ruleset-request-id") ? eventData.Properties["ruleset-request-id"]?.ToString() : "");

                dependencyTelemetry.Context.Cloud.RoleName     = "MessageService";
                dependencyTelemetry.Context.Cloud.RoleInstance = Environment.MachineName;

                dependencyTelemetry.Properties["device-id"] = devid;

                _telemetryClient.TrackDependency(dependencyTelemetry);
                _telemetryClient.Flush();
            }

            await context.CheckpointAsync();
        }