public Task Handle(MyMessage message, IMessageHandlerContext context) { Context.UniqueMessageId = DeterministicGuid.MakeId(context.MessageId, Settings.EndpointName()).ToString(); throw new Exception("Simulated"); }
public static string UniqueId(this IReadOnlyDictionary <string, string> headers) { return(headers.TryGetValue("ServiceControl.Retry.UniqueMessageId", out var existingUniqueMessageId) ? existingUniqueMessageId : DeterministicGuid.MakeId(headers.MessageId(), headers.ProcessingEndpointName()).ToString()); }
public async Task Handle(ReportCustomCheckResult message, IMessageHandlerContext context) { if (string.IsNullOrEmpty(message.EndpointName)) { throw new Exception("Received an custom check message without proper initialization of the EndpointName in the schema"); } if (string.IsNullOrEmpty(message.Host)) { throw new Exception("Received an custom check message without proper initialization of the Host in the schema"); } if (message.HostId == Guid.Empty) { throw new Exception("Received an custom check message without proper initialization of the HostId in the schema"); } var publish = false; var id = DeterministicGuid.MakeId(message.EndpointName, message.HostId.ToString(), message.CustomCheckId); CustomCheck customCheck; using (var session = store.OpenAsyncSession()) { customCheck = await session.LoadAsync <CustomCheck>(id) .ConfigureAwait(false); if (customCheck == null || customCheck.Status == Status.Fail && !message.HasFailed || customCheck.Status == Status.Pass && message.HasFailed) { if (customCheck == null) { customCheck = new CustomCheck { Id = id }; } publish = true; } customCheck.CustomCheckId = message.CustomCheckId; customCheck.Category = message.Category; customCheck.Status = message.HasFailed ? Status.Fail : Status.Pass; customCheck.ReportedAt = message.ReportedAt; customCheck.FailureReason = message.FailureReason; customCheck.OriginatingEndpoint = new EndpointDetails { Host = message.Host, HostId = message.HostId, Name = message.EndpointName }; await session.StoreAsync(customCheck) .ConfigureAwait(false); await session.SaveChangesAsync() .ConfigureAwait(false); } if (publish) { if (message.HasFailed) { await domainEvents.Raise(new CustomCheckFailed { Id = id, CustomCheckId = message.CustomCheckId, Category = message.Category, FailedAt = message.ReportedAt, FailureReason = message.FailureReason, OriginatingEndpoint = customCheck.OriginatingEndpoint }).ConfigureAwait(false); } else { await domainEvents.Raise(new CustomCheckSucceeded { Id = id, CustomCheckId = message.CustomCheckId, Category = message.Category, SucceededAt = message.ReportedAt, OriginatingEndpoint = customCheck.OriginatingEndpoint }).ConfigureAwait(false); } } }
public void Handle(RegisterEndpoint message) { var id = message.EndpointInstanceId; //Injecting store in this class because we want to know about ConcurrencyExceptions so that EndpointsCache.MarkAsProcessed is not called if the save fails. using (var session = Store.OpenSession()) { session.Advanced.UseOptimisticConcurrency = true; KnownEndpoint knownEndpoint; if (id == Guid.Empty) { knownEndpoint = session.Query <KnownEndpoint, KnownEndpointIndex>().SingleOrDefault(e => e.EndpointDetails.Name == message.Endpoint.Name && e.EndpointDetails.Host == message.Endpoint.Host); } else { knownEndpoint = session.Load <KnownEndpoint>(id); if (knownEndpoint == null) { knownEndpoint = session.Query <KnownEndpoint, KnownEndpointIndex>().SingleOrDefault(e => e.HasTemporaryId && e.EndpointDetails.Name == message.Endpoint.Name && e.EndpointDetails.Host == message.Endpoint.Host); } } if (knownEndpoint == null) { //new endpoint Bus.Publish(new NewEndpointDetected { Endpoint = message.Endpoint, DetectedAt = message.DetectedAt }); knownEndpoint = new KnownEndpoint { EndpointDetails = message.Endpoint, HostDisplayName = message.Endpoint.Host, Monitored = message.EnableMonitoring }; if (id == Guid.Empty) { knownEndpoint.Id = DeterministicGuid.MakeId(message.Endpoint.Name, message.Endpoint.HostId.ToString()); knownEndpoint.HasTemporaryId = true; } else { knownEndpoint.Id = id; } session.Store(knownEndpoint); } else { if (knownEndpoint.HasTemporaryId && id != Guid.Empty) { session.Delete(knownEndpoint); session.Store(new KnownEndpoint { Id = id, EndpointDetails = message.Endpoint, HostDisplayName = message.Endpoint.Host, Monitored = knownEndpoint.Monitored || message.EnableMonitoring }); } knownEndpoint.Monitored |= message.EnableMonitoring; } session.SaveChanges(); } }
public static string FormatId(MessageType messageType) { var id = DeterministicGuid.Create(messageType.TypeName, "/", messageType.Version.Major); return(string.Format("Subscriptions/{0}", id)); }
public void Handle(EndpointHeartbeat message) { if (string.IsNullOrEmpty(message.EndpointName)) { throw new ArgumentException("Received an EndpointHeartbeat message without proper initialization of the EndpointName in the schema", "message.EndpointName"); } if (string.IsNullOrEmpty(message.Host)) { throw new ArgumentException("Received an EndpointHeartbeat message without proper initialization of the Host in the schema", "message.Host"); } if (message.HostId == Guid.Empty) { throw new ArgumentException("Received an EndpointHeartbeat message without proper initialization of the HostId in the schema", "message.HostId"); } var id = DeterministicGuid.MakeId(message.EndpointName, message.HostId.ToString()); var heartbeat = Session.Load <Heartbeat>(id); if (heartbeat != null) { if (heartbeat.Disabled) { return; } } var isNew = false; if (heartbeat == null) { isNew = true; heartbeat = new Heartbeat { Id = id, ReportedStatus = Status.Beating }; Session.Store(heartbeat); } if (message.ExecutedAt <= heartbeat.LastReportAt) { Logger.InfoFormat("Out of sync heartbeat received for endpoint {0}", message.EndpointName); return; } heartbeat.LastReportAt = message.ExecutedAt; heartbeat.EndpointDetails = new EndpointDetails { HostId = message.HostId, Host = message.Host, Name = message.EndpointName }; if (isNew) // New endpoint heartbeat { Bus.Publish(new HeartbeatingEndpointDetected { Endpoint = heartbeat.EndpointDetails, DetectedAt = heartbeat.LastReportAt, }); } if (heartbeat.ReportedStatus == Status.Dead) { heartbeat.ReportedStatus = Status.Beating; Bus.Publish(new EndpointHeartbeatRestored { Endpoint = heartbeat.EndpointDetails, RestoredAt = heartbeat.LastReportAt }); } HeartbeatStatusProvider.RegisterHeartbeatingEndpoint(heartbeat.EndpointDetails, heartbeat.LastReportAt); }
public async Task Should_be_grouped() { List <FailureGroupView> defaultGroups = null; List <FailureGroupView> exceptionTypeAndStackTraceGroups = null; List <FailureGroupView> messageTypeGroups = null; FailedMessage failedMessageA = null; FailedMessage failedMessageB = null; var context = await Define <MyContext>() .WithEndpoint <Receiver>(b => b.When(async bus => { await bus.SendLocal(new MyMessageA()) .ConfigureAwait(false); await bus.SendLocal(new MyMessageB()) .ConfigureAwait(false); }).DoNotFailOnErrorMessages()) .Done(async c => { if (c.MessageIdA == null || c.MessageIdB == null) { return(false); } var defaultGroupsResult = await this.TryGetMany <FailureGroupView>("/api/recoverability/groups/"); defaultGroups = defaultGroupsResult; if (!defaultGroupsResult) { return(false); } if (defaultGroups.Count != 2) { return(false); } messageTypeGroups = await this.TryGetMany <FailureGroupView>("/api/recoverability/groups/Message%20Type"); exceptionTypeAndStackTraceGroups = await this.TryGetMany <FailureGroupView>("/api/recoverability/groups/Exception%20Type%20and%20Stack%20Trace"); var failedMessageAResult = await this.TryGet <FailedMessage>($"/api/errors/{c.UniqueMessageIdA}", msg => msg.FailureGroups.Any()); failedMessageA = failedMessageAResult; var failedMessageBResult = await this.TryGet <FailedMessage>($"/api/errors/{c.UniqueMessageIdB}", msg => msg.FailureGroups.Any()); failedMessageB = failedMessageBResult; if (!failedMessageAResult || !failedMessageBResult) { return(false); } return(true); }) .Run(); Assert.AreEqual(2, exceptionTypeAndStackTraceGroups.Count, "There should be 2 Exception Type and Stack Trace Groups"); Assert.AreEqual(2, messageTypeGroups.Count, "There should be 2 Message Type Groups"); defaultGroups.ForEach(g => Console.WriteLine(JsonConvert.SerializeObject(g))); Assert.IsEmpty(exceptionTypeAndStackTraceGroups.Select(g => g.Id).Except(defaultGroups.Select(g => g.Id)), "/api/recoverability/groups did not retrieve Exception Type and Stack Trace Group"); Assert.Contains(DeterministicGuid.MakeId(MessageTypeFailureClassifier.Id, typeof(MyMessageA).FullName).ToString(), messageTypeGroups.Select(g => g.Id).ToArray()); Assert.Contains(DeterministicGuid.MakeId(MessageTypeFailureClassifier.Id, typeof(MyMessageB).FullName).ToString(), messageTypeGroups.Select(g => g.Id).ToArray()); Assert.AreEqual(context.UniqueMessageIdA, failedMessageA.UniqueMessageId); Assert.AreEqual(context.UniqueMessageIdB, failedMessageB.UniqueMessageId); Assert.IsNotEmpty(failedMessageA.FailureGroups, "MyMessageA should have failure groups"); Assert.IsNotEmpty(failedMessageB.FailureGroups, "MyMessageB should have failure groups"); Assert.AreEqual(1, failedMessageA.FailureGroups.Count(g => g.Type == ExceptionTypeAndStackTraceFailureClassifier.Id), $"{ExceptionTypeAndStackTraceFailureClassifier.Id} FailureGroup was not created"); Assert.AreEqual(1, failedMessageA.FailureGroups.Count(g => g.Type == MessageTypeFailureClassifier.Id), $"{MessageTypeFailureClassifier.Id} FailureGroup was not created"); Assert.AreEqual(1, failedMessageB.FailureGroups.Count(g => g.Type == ExceptionTypeAndStackTraceFailureClassifier.Id), $"{ExceptionTypeAndStackTraceFailureClassifier.Id} FailureGroup was not created"); Assert.AreEqual(1, failedMessageB.FailureGroups.Count(g => g.Type == MessageTypeFailureClassifier.Id), $"{MessageTypeFailureClassifier.Id} FailureGroup was not created"); }
public Task Handle(MessageToRetry message, IMessageHandlerContext context) { Context.FromAddress = Settings.LocalAddress(); Context.UniqueMessageId = DeterministicGuid.MakeId(context.MessageId.Replace(@"\", "-"), Settings.EndpointName()).ToString(); throw new Exception("Message Failed"); }
public void Handle(EndpointHeartbeat message) { if (string.IsNullOrEmpty(message.EndpointName)) { throw new Exception("Received an EndpointHeartbeat message without proper initialization of the EndpointName in the schema"); } if (string.IsNullOrEmpty(message.Host)) { throw new Exception("Received an EndpointHeartbeat message without proper initialization of the Host in the schema"); } if (message.HostId == Guid.Empty) { throw new Exception("Received an EndpointHeartbeat message without proper initialization of the HostId in the schema"); } var id = DeterministicGuid.MakeId(message.EndpointName, message.HostId.ToString()); var key = store.Conventions.DefaultFindFullDocumentKeyFromNonStringIdentifier(id, typeof(Heartbeat), false); var endpointDetails = new EndpointDetails { HostId = message.HostId, Host = message.Host, Name = message.EndpointName }; var patchResult = store.DatabaseCommands.Patch(key, new ScriptedPatchRequest { Script = @" if(new Date(lastReported) <= new Date(this.LastReportAt)) { return; } if(this.ReportedStatus === deadStatus) { output('wasDead'); } this.LastReportAt = lastReported; this.ReportedStatus = reportedStatus; ", Values = { { "lastReported", message.ExecutedAt }, { "reportedStatus", (int)Status.Beating }, { "deadStatus", (int)Status.Dead }, } }, new ScriptedPatchRequest { Script = @" this.LastReportAt = lastReported; this.ReportedStatus = reportedStatus; this.EndpointDetails = { 'Host': endpointDetails_Host, 'HostId': endpointDetails_HostId, 'Name': endpointDetails_Name }; this.Disabled = false; output('isNew'); ", Values = { { "lastReported", message.ExecutedAt }, { "reportedStatus", (int)Status.Beating }, { "endpointDetails_Host", endpointDetails.Host }, { "endpointDetails_HostId", endpointDetails.HostId.ToString() }, { "endpointDetails_Name", endpointDetails.Name } } }, RavenJObject.Parse($@" {{ ""Raven-Entity-Name"": ""{store.Conventions.GetTypeTagName(typeof(Heartbeat))}"", ""Raven-Clr-Type"": ""{typeof(Heartbeat).AssemblyQualifiedName}"" }}")); var debugStatements = patchResult.Value <RavenJArray>("Debug"); var ravenJToken = debugStatements.SingleOrDefault(); bool isNew = false, wasDead = false; if (ravenJToken != null) { var result = ravenJToken.Value <string>(); isNew = result == "isNew"; wasDead = result == "wasDead"; } if (isNew) // New endpoint heartbeat { bus.Publish(new HeartbeatingEndpointDetected { Endpoint = endpointDetails, DetectedAt = message.ExecutedAt }); } else if (wasDead) { bus.Publish(new EndpointHeartbeatRestored { Endpoint = endpointDetails, RestoredAt = message.ExecutedAt }); } statusProvider.RegisterHeartbeatingEndpoint(endpointDetails, message.ExecutedAt); }
public MessageRedirectsModule() { Post["/redirects", true] = async(parameters, token) => { var request = this.Bind <MessageRedirectRequest>(); if (string.IsNullOrWhiteSpace(request.fromphysicaladdress) || string.IsNullOrWhiteSpace(request.tophysicaladdress)) { return(HttpStatusCode.BadRequest); } var messageRedirect = new MessageRedirect { FromPhysicalAddress = request.fromphysicaladdress, ToPhysicalAddress = request.tophysicaladdress, LastModifiedTicks = DateTime.UtcNow.Ticks }; using (var session = Store.OpenAsyncSession()) { var collection = await MessageRedirectsCollection.GetOrCreate(session).ConfigureAwait(false); var existing = collection[messageRedirect.MessageRedirectId]; if (existing != null) { return(existing.ToPhysicalAddress == messageRedirect.ToPhysicalAddress ? Negotiate.WithModel(messageRedirect).WithStatusCode(HttpStatusCode.Created) : Negotiate.WithReasonPhrase("Duplicate").WithModel(existing).WithStatusCode(HttpStatusCode.Conflict)); } var dependents = collection.Redirects.Where(r => r.ToPhysicalAddress == request.fromphysicaladdress).ToList(); if (dependents.Any()) { return(Negotiate.WithReasonPhrase("Dependents").WithModel(dependents).WithStatusCode(HttpStatusCode.Conflict)); } collection.Redirects.Add(messageRedirect); await collection.Save(session).ConfigureAwait(false); } await DomainEvents.Raise(new MessageRedirectCreated { MessageRedirectId = messageRedirect.MessageRedirectId, FromPhysicalAddress = messageRedirect.FromPhysicalAddress, ToPhysicalAddress = messageRedirect.ToPhysicalAddress }).ConfigureAwait(false); if (request.retryexisting) { await Bus.SendLocal(new RetryPendingMessages { QueueAddress = messageRedirect.FromPhysicalAddress, PeriodFrom = DateTime.MinValue, PeriodTo = DateTime.UtcNow }).ConfigureAwait(false); } return(HttpStatusCode.Created); }; Put["/redirects/{messageredirectid:guid}/", true] = async(parameters, token) => { Guid messageRedirectId = parameters.messageredirectid; var request = this.Bind <MessageRedirectRequest>(); if (string.IsNullOrWhiteSpace(request.tophysicaladdress)) { return(HttpStatusCode.BadRequest); } using (var session = Store.OpenAsyncSession()) { var redirects = await MessageRedirectsCollection.GetOrCreate(session).ConfigureAwait(false); var messageRedirect = redirects[messageRedirectId]; if (messageRedirect == null) { return(HttpStatusCode.NotFound); } var toMessageRedirectId = DeterministicGuid.MakeId(request.tophysicaladdress); if (redirects[toMessageRedirectId] != null) { return(HttpStatusCode.Conflict); } var messageRedirectChanged = new MessageRedirectChanged { MessageRedirectId = messageRedirectId, PreviousToPhysicalAddress = messageRedirect.ToPhysicalAddress, FromPhysicalAddress = messageRedirect.FromPhysicalAddress, ToPhysicalAddress = messageRedirect.ToPhysicalAddress = request.tophysicaladdress }; messageRedirect.LastModifiedTicks = DateTime.UtcNow.Ticks; await redirects.Save(session).ConfigureAwait(false); await DomainEvents.Raise(messageRedirectChanged) .ConfigureAwait(false); return(HttpStatusCode.NoContent); } }; Delete["/redirects/{messageredirectid:guid}/", true] = async(parameters, token) => { Guid messageRedirectId = parameters.messageredirectid; using (var session = Store.OpenAsyncSession()) { var redirects = await MessageRedirectsCollection.GetOrCreate(session).ConfigureAwait(false); var messageRedirect = redirects[messageRedirectId]; if (messageRedirect == null) { return(HttpStatusCode.NoContent); } redirects.Redirects.Remove(messageRedirect); await redirects.Save(session).ConfigureAwait(false); await DomainEvents.Raise(new MessageRedirectRemoved { MessageRedirectId = messageRedirectId, FromPhysicalAddress = messageRedirect.FromPhysicalAddress, ToPhysicalAddress = messageRedirect.ToPhysicalAddress }).ConfigureAwait(false); } return(HttpStatusCode.NoContent); }; Head["/redirects", true] = async(parameters, token) => { using (var session = Store.OpenAsyncSession()) { var redirects = await MessageRedirectsCollection.GetOrCreate(session).ConfigureAwait(false); return(Negotiate .WithEtag(redirects.ETag) .WithTotalCount(redirects.Redirects.Count)); } }; Get["/redirects", true] = async(parameters, token) => { using (var session = Store.OpenAsyncSession()) { var redirects = await MessageRedirectsCollection.GetOrCreate(session).ConfigureAwait(false); var queryResult = redirects .Sort(Request) .Paging(Request) .Select(r => new { r.MessageRedirectId, r.FromPhysicalAddress, r.ToPhysicalAddress, LastModified = new DateTime(r.LastModifiedTicks) }); return(Negotiate .WithModel(queryResult) .WithEtag(redirects.ETag) .WithPagingLinksAndTotalCount(redirects.Redirects.Count, Request)); } }; }
async Task ProcessAuditMessage(MessageContext context) { if (!context.Headers.TryGetValue(Headers.MessageId, out var messageId)) { messageId = DeterministicGuid.MakeId(context.MessageId).ToString(); } try { var metadata = new ConcurrentDictionary <string, object> { ["MessageId"] = messageId, ["MessageIntent"] = context.Headers.MessageIntent() }; var commandsToEmit = new List <ICommand>(); var enricherContext = new AuditEnricherContext(context.Headers, commandsToEmit, metadata); // ReSharper disable once LoopCanBeConvertedToQuery foreach (var enricher in enrichers) { enricher.Enrich(enricherContext); } await bodyStorageEnricher.StoreAuditMessageBody(context.Body, context.Headers, metadata) .ConfigureAwait(false); var auditMessage = new ProcessedMessage(context.Headers, new Dictionary <string, object>(metadata)) { Id = $"ProcessedMessages/{context.Headers.ProcessingId()}" }; foreach (var commandToEmit in commandsToEmit) { await messageSession.Send(commandToEmit) .ConfigureAwait(false); } context.Extensions.Set(auditMessage); if (metadata.TryGetValue("SendingEndpoint", out var sendingEndpoint)) { context.Extensions.Set("SendingEndpoint", (EndpointDetails)sendingEndpoint); } if (metadata.TryGetValue("ReceivingEndpoint", out var receivingEndpoint)) { context.Extensions.Set("ReceivingEndpoint", (EndpointDetails)receivingEndpoint); } context.Extensions.Set("AuditType", "ProcessedMessage"); } catch (Exception e) { if (Logger.IsDebugEnabled) { Logger.Debug($"Processing of message '{messageId}' failed.", e); } context.GetTaskCompletionSource().TrySetException(e); } }
public async Task UpdateCustomCheckStatus(EndpointDetails originatingEndpoint, DateTime reportedAt, string customCheckId, string category, bool hasFailed, string failureReason) { var publish = false; var id = DeterministicGuid.MakeId(originatingEndpoint.Name, originatingEndpoint.HostId.ToString(), customCheckId); using (var session = store.OpenAsyncSession()) { var customCheck = await session.LoadAsync <CustomCheck>(id) .ConfigureAwait(false); if (customCheck == null || customCheck.Status == Status.Fail && !hasFailed || customCheck.Status == Status.Pass && hasFailed) { if (customCheck == null) { customCheck = new CustomCheck { Id = id }; } publish = true; } customCheck.CustomCheckId = customCheckId; customCheck.Category = category; customCheck.Status = hasFailed ? Status.Fail : Status.Pass; customCheck.ReportedAt = reportedAt; customCheck.FailureReason = failureReason; customCheck.OriginatingEndpoint = originatingEndpoint; await session.StoreAsync(customCheck) .ConfigureAwait(false); await session.SaveChangesAsync() .ConfigureAwait(false); } if (publish) { if (hasFailed) { await domainEvents.Raise(new CustomCheckFailed { Id = id, CustomCheckId = customCheckId, Category = category, FailedAt = reportedAt, FailureReason = failureReason, OriginatingEndpoint = originatingEndpoint }).ConfigureAwait(false); } else { await domainEvents.Raise(new CustomCheckSucceeded { Id = id, CustomCheckId = customCheckId, Category = category, SucceededAt = reportedAt, OriginatingEndpoint = originatingEndpoint }).ConfigureAwait(false); } } }
public void Handle(MessageToRetry message) { Context.FromAddress = Settings.LocalAddress().ToString(); Context.UniqueMessageId = DeterministicGuid.MakeId(Bus.CurrentMessageContext.Id.Replace(@"\", "-"), Settings.LocalAddress().Queue).ToString(); throw new Exception("Message Failed"); }
public void Handle(ReportCustomCheckResult message) { if (string.IsNullOrEmpty(message.EndpointName)) { throw new ArgumentException("Received an custom check message without proper initialization of the EndpointName in the schema", "message.EndpointName"); } if (string.IsNullOrEmpty(message.Host)) { throw new ArgumentException("Received an custom check message without proper initialization of the Host in the schema", "message.Host"); } if (message.HostId == Guid.Empty) { throw new ArgumentException("Received an custom check message without proper initialization of the HostId in the schema", "message.HostId"); } var publish = false; var id = DeterministicGuid.MakeId(message.EndpointName, message.HostId.ToString(), message.CustomCheckId); var customCheck = Session.Load <CustomCheck>(id); if (customCheck == null || (customCheck.Status == Status.Fail && !message.HasFailed) || (customCheck.Status == Status.Pass && message.HasFailed)) { if (customCheck == null) { customCheck = new CustomCheck { Id = id, }; Session.Store(customCheck); } publish = true; } customCheck.CustomCheckId = message.CustomCheckId; customCheck.Category = message.Category; customCheck.Status = message.HasFailed ? Status.Fail : Status.Pass; customCheck.ReportedAt = message.ReportedAt; customCheck.FailureReason = message.FailureReason; customCheck.OriginatingEndpoint = new EndpointDetails { Host = message.Host, HostId = message.HostId, Name = message.EndpointName }; Session.Store(customCheck); if (publish) { if (message.HasFailed) { Bus.Publish <CustomCheckFailed>(m => { m.Id = id; m.CustomCheckId = message.CustomCheckId; m.Category = message.Category; m.FailedAt = message.ReportedAt; m.FailureReason = message.FailureReason; m.OriginatingEndpoint = customCheck.OriginatingEndpoint; }); } else { Bus.Publish <CustomCheckSucceeded>(m => { m.Id = id; m.CustomCheckId = message.CustomCheckId; m.Category = message.Category; m.SucceededAt = message.ReportedAt; m.OriginatingEndpoint = customCheck.OriginatingEndpoint; }); } } }
public void Handle(ReportCustomCheckResult message) { if (string.IsNullOrEmpty(message.EndpointName)) { throw new Exception("Received an custom check message without proper initialization of the EndpointName in the schema"); } if (string.IsNullOrEmpty(message.Host)) { throw new Exception("Received an custom check message without proper initialization of the Host in the schema"); } if (message.HostId == Guid.Empty) { throw new Exception("Received an custom check message without proper initialization of the HostId in the schema"); } var publish = false; var id = DeterministicGuid.MakeId(message.EndpointName, message.HostId.ToString(), message.CustomCheckId); CustomCheck customCheck; using (var session = store.OpenSession()) { customCheck = session.Load <CustomCheck>(id); if (customCheck == null || (customCheck.Status == Status.Fail && !message.HasFailed) || (customCheck.Status == Status.Pass && message.HasFailed)) { if (customCheck == null) { customCheck = new CustomCheck { Id = id }; } publish = true; } customCheck.CustomCheckId = message.CustomCheckId; customCheck.Category = message.Category; customCheck.Status = message.HasFailed ? Status.Fail : Status.Pass; customCheck.ReportedAt = message.ReportedAt; customCheck.FailureReason = message.FailureReason; customCheck.OriginatingEndpoint = new EndpointDetails { Host = message.Host, HostId = message.HostId, Name = message.EndpointName }; session.Store(customCheck); session.SaveChanges(); } if (publish) { if (message.HasFailed) { bus.Publish(new CustomCheckFailed { Id = id, CustomCheckId = message.CustomCheckId, Category = message.Category, FailedAt = message.ReportedAt, FailureReason = message.FailureReason, OriginatingEndpoint = customCheck.OriginatingEndpoint }); } else { bus.Publish(new CustomCheckSucceeded { Id = id, CustomCheckId = message.CustomCheckId, Category = message.Category, SucceededAt = message.ReportedAt, OriginatingEndpoint = customCheck.OriginatingEndpoint }); } } }