public void Route(IIntegrationMessage integrationMessage) { if ((object)integrationMessage == null) throw new ArgumentNullException("integrationMessage"); this.CoreRoute(integrationMessage); }
public async Task HandleAsync_LogWarning_WarningIsLogged( IIntegrationMessage message, string expectedValidationMessage) { var endpoint = TestProducerEndpoint.GetDefault(); endpoint.MessageValidationMode = MessageValidationMode.LogWarning; var envelope = new OutboundEnvelope(message, null, endpoint); IOutboundEnvelope?result = null; await new ValidatorProducerBehavior(_outboundLogger).HandleAsync( new ProducerPipelineContext( envelope, Substitute.For <IProducer>(), Substitute.For <IServiceProvider>()), context => { result = context.Envelope; return(Task.CompletedTask); }); result.Should().NotBeNull(); result !.Message.Should().NotBeNull(); _loggerSubstitute.Received(LogLevel.Warning, null, expectedValidationMessage, 1079); }
public async Task Handle_MultipleMessages_CorrectlyRoutedToEndpoint(IIntegrationMessage message, string[] expectedEndpointNames) { _routingConfiguration.Add <IIntegrationMessage>(new TestEndpoint("allMessages"), null); _routingConfiguration.Add <IIntegrationEvent>(new TestEndpoint("allEvents"), null); _routingConfiguration.Add <TestEventOne>(new TestEndpoint("eventOne"), null); _routingConfiguration.Add <TestEventTwo>(new TestEndpoint("eventTwo"), null); await _behavior.Handle(new[] { message }, Task.FromResult); await _outboundQueue.Commit(); var queued = await _outboundQueue.Dequeue(100); foreach (var expectedEndpointName in expectedEndpointNames) { queued.Count(x => x.Endpoint.Name == expectedEndpointName).Should().Be(1); } var notExpectedEndpointNames = _routingConfiguration .Routes.Select(r => r.DestinationEndpoint.Name) .Where(r => !expectedEndpointNames.Contains(r)); foreach (var notExpectedEndpointName in notExpectedEndpointNames) { queued.Count(x => x.Endpoint.Name == notExpectedEndpointName).Should().Be(0); } }
public static byte[] Serialize(IIntegrationMessage message) { string messageBody = JsonConvert.SerializeObject(message); var messageBytes = Encoding.UTF8.GetBytes(messageBody); return(messageBytes); }
public async Task HandleAsync_LogWarning_WarningIsLogged( IIntegrationMessage message, string expectedValidationMessage) { var endpoint = TestConsumerEndpoint.GetDefault(); endpoint.MessageValidationMode = MessageValidationMode.LogWarning; var envelope = new InboundEnvelope( message, null, null, new TestOffset(), endpoint, "source-endpoint"); IRawInboundEnvelope?result = null; await new ValidatorConsumerBehavior(_inboundLogger).HandleAsync( ConsumerPipelineContextHelper.CreateSubstitute(envelope, _serviceProvider), context => { result = context.Envelope; return(Task.CompletedTask); }); result.Should().NotBeNull(); _loggerSubstitute.Received(LogLevel.Warning, null, expectedValidationMessage, 1080); }
public virtual void MarkMessage(IIntegrationMessage integrationMessage, Guid messageStateId) { if ((object)integrationMessage == null) throw new ArgumentNullException("integrationMessage"); this.MarkMessageInternal(integrationMessage, messageStateId); }
public async Task HandleAsync_Message_CorrectlyRoutedToStaticEndpoint( IIntegrationMessage message, string[] expectedEndpointNames) { _routingConfiguration.Add <IIntegrationMessage>( _ => new StaticOutboundRouter(new TestProducerEndpoint("allMessages"))); _routingConfiguration.Add <IIntegrationEvent>( _ => new StaticOutboundRouter(new TestProducerEndpoint("allEvents"))); _routingConfiguration.Add <TestEventOne>( _ => new StaticOutboundRouter(new TestProducerEndpoint("eventOne"))); _routingConfiguration.Add <TestEventTwo>( _ => new StaticOutboundRouter(new TestProducerEndpoint("eventTwo"))); await _behavior.HandleAsync( message, nextMessage => Task.FromResult(new[] { nextMessage }.AsReadOnlyCollection()) !); foreach (var expectedEndpointName in expectedEndpointNames) { _broker.ProducedMessages.Count(envelope => envelope.Endpoint.Name == expectedEndpointName) .Should() .Be(1); } var notExpectedEndpointNames = _routingConfiguration .Routes.Select(route => route.GetOutboundRouter(_serviceProvider).Endpoints.First().Name) .Where(r => !expectedEndpointNames.Contains(r)); foreach (var notExpectedEndpointName in notExpectedEndpointNames) { _broker.ProducedMessages.Count(envelope => envelope.Endpoint.Name == notExpectedEndpointName) .Should() .Be(0); } }
public virtual void DropMessage(IIntegrationMessage integrationMessage) { if ((object)integrationMessage == null) throw new ArgumentNullException("integrationMessage"); this.DropMessageInternal(integrationMessage); }
public Task Dispatch(IIntegrationMessage message, MessageMetaData metaData = null, IOutboxSession outbox = null) { var endpoint = MessagingMap.FindEndpoint(message) ?? throw new ApplicationException($"Unable to dispatch message. Type: {message.GetType()} Message Type: {message.MessageType}"); return(Dispatch(message, metaData, endpoint, outbox)); }
protected override void DropMessageInternal(IIntegrationMessage integrationMessage) { DateTime nowUtc = DateTime.UtcNow; StreamReader streamReader; dynamic expando; IDictionary<string, object> associative; MongoCollection<BsonDocument> collection; expando = new ExpandoObject(); associative = new ExpandoObject(); streamReader = new StreamReader(integrationMessage.DataStream); foreach (KeyValuePair<string, object> metadata in integrationMessage.Metadata) associative.Add(metadata.Key, metadata.Value.SafeToString(null, null)); expando.Id = integrationMessage.RunTimeId; expando.CreationTimestamp = nowUtc; expando.ModificationTimestamp = nowUtc; expando.Charset = integrationMessage.ContentEncoding = streamReader.CurrentEncoding.WebName; expando.ContentType = integrationMessage.ContentType; expando.MessageClass = "unknown"; expando.MessageStateId = new Guid(MessageStateConstants.MESSAGE_STATE_CREATED); expando.MessageText = streamReader.ReadToEnd(); // TODO: inefficient buffered approach expando.Metadata = (IDictionary<string, object>)associative; expando = new BsonDocument((IDictionary<string, object>)expando); collection = this.AquireMessageCollection(); collection.Insert(expando); }
public IntegrationMessageFilterContext(IIntegrationMessage message, MessageMetaData meta, IEndpoint endpoint, FilterDirection direction, MessageTypeProperties props) { Message = message; MessageMetaData = meta; Endpoint = endpoint; Direction = direction; Props = props; }
private static IntegrationMessageDispatcherHandler GetHandler(IIntegrationMessage message) { var genericDispatcherType = typeof(IntegrationMessageDispatcherHandler <>) .MakeGenericType(message.GetType()); return((IntegrationMessageDispatcherHandler) Activator.CreateInstance(genericDispatcherType)); }
public InboundMessageEventArgs(IntegrationEndpoint integrationEndpoint, IIntegrationMessage integrationMessage) { if ((object)integrationEndpoint == null) throw new ArgumentNullException("integrationEndpoint"); if ((object)integrationMessage == null) throw new ArgumentNullException("integrationMessage"); this.integrationEndpoint = integrationEndpoint; this.integrationMessage = integrationMessage; }
public IEnumerable<IIntegrationMessage> Execute(IPipeliningContext pipeliningContext, IIntegrationMessage integrationMessage) { IReceiveStage receiveStage; IEnumerable<IIntegrationMessage> stagedIntegrationMessages; IEnumerable<IIntegrationMessage> splitIntegrationMessages; List<IIntegrationMessage> accumulatedIntegrationMessages; this.WriteLogSynchronized("PIPELINE: Excuting receive pipeline on thread '{0}'.", Thread.CurrentThread.ManagedThreadId); if ((object)pipeliningContext == null) throw new ArgumentNullException("pipeliningContext"); if ((object)integrationMessage == null) throw new ArgumentNullException("integrationMessage"); accumulatedIntegrationMessages = new List<IIntegrationMessage>(); stagedIntegrationMessages = new IIntegrationMessage[] { integrationMessage }; foreach (Type receiveStageType in this.GetStageTypes().Values) { receiveStage = Activator.CreateInstance(receiveStageType, true) as IReceiveStage; if ((object)receiveStage == null) throw new InvalidOperationException("Bad receive stage type."); this.TrackStageInstance(receiveStage); try { receiveStage.Initialize(); receiveStage.Freeze(); accumulatedIntegrationMessages.Clear(); foreach (IIntegrationMessage stagedIntegrationMessage in stagedIntegrationMessages) { splitIntegrationMessages = receiveStage.Execute(pipeliningContext, stagedIntegrationMessage); accumulatedIntegrationMessages.AddRange(splitIntegrationMessages); } } finally { receiveStage.Terminate(); // dispose } } return accumulatedIntegrationMessages; }
public Task Dispatch(IIntegrationMessage message, MessageMetaData metaData, IEndpoint endpoint, IOutboxSession outboxSession = null) { if (message == null) { throw new ArgumentNullException(nameof(message)); } if (endpoint == null) { throw new ArgumentNullException(nameof(endpoint)); } OutboundMessagePipeline messagePipeline = null; if (_endpointOutboundPipeline.ContainsKey(endpoint)) { messagePipeline = _endpointOutboundPipeline[endpoint]; } else { messagePipeline = new OutboundMessagePipeline(endpoint.Settings.OutboundIntegrationFilters, endpoint.Settings.OutboundTransportFilters); _endpointOutboundPipeline[endpoint] = messagePipeline; } var resultContext = messagePipeline.Process(new IntegrationMessageFilterContext(message, metaData, endpoint, FilterDirection.Outbound, null)); if (outboxSession != null)//dispatch through the outbox { OutboxDispatchOptions options = new OutboxDispatchOptions() { }; if (metaData != null) { if (metaData.DispatchDelay.HasValue && !endpoint.SupportsDelayedDispatch) { options.Delay = metaData.DispatchDelay; options.SkipTransientDispatch = true; // for safety because we set delay } else { options.SkipTransientDispatch = metaData.SkipTransientDispatch; } options.ExpiresAtUtc = metaData.ExpiresAtUtc; } return(outboxSession.Dispatch(message.MessageType, resultContext.TransportMessage.Data, resultContext.TransportMessage.MetaData, endpoint, options)); } //dispatch to the endpoint return(DispatchCore(message.MessageType, resultContext.TransportMessage.Data, resultContext.TransportMessage.MetaData, endpoint)); }
public IntegrationMessageFilterContext Process(TransportMessageFilterContext context) { string messageType = context.TransportMessage.MetaData.MessageType; if (String.IsNullOrEmpty(messageType)) { throw new InvalidMessageTypeException(messageType); } var metaData = context.TransportMessage.MetaData; var messageProps = MessagingMap.GetProps(messageType) ?? throw new UnknownMessageTypeException(messageType); IIntegrationMessage message = _extractMessage(context.TransportMessage.Data, messageProps); return(new IntegrationMessageFilterContext(message, context.TransportMessage.MetaData, context.Endpoint, FilterDirection.Inbound, messageProps)); }
public static IEndpoint FindEndpoint(IIntegrationMessage message) { IEndpoint endpoint = null; if (_messageTypeIdentifierRouteToEndpointMap.TryGetValue(message.MessageType, out endpoint)) { return(endpoint); } else if (message is IIntegrationEvent) { //check for a default route for events and adding to the route map if (_defaultPublishToEndpoint != null) { _messageTypeIdentifierRouteToEndpointMap.Add(message.MessageType, _defaultPublishToEndpoint); return(_defaultPublishToEndpoint); } } throw new EndpointNotFoundException(message.MessageType); }
public Task Handle(IIntegrationMessage message, MessageContext context) { var messageType = message.GetType(); if (_currentHandlers == null) { throw new InvalidMessageForStateException(null, messageType); } var handler = _currentHandlers.GetHandler(messageType); if (handler == null) { return(Unhandled(message, context)); } else { return(handler.Invoke(message, context)); } }
protected async Task <bool> ExecuteAsync(IServiceProvider serviceProvider, CancellationToken cancellationToken) { using (var scope = serviceProvider.CreateScope()) { var provider = scope.ServiceProvider; var dbContext = provider.GetRequiredService <IUserDbContext>(); var outboxMessageRepository = dbContext.OutboxMessageRepository; var integrationMessageBroker = provider.GetRequiredService <IIntegrationMessageBroker>(); (string, IIntegrationMessage)? resultTuple = await outboxMessageRepository.SetFirstWaitingMessageInProgressAsync(cancellationToken); if (resultTuple == null) { return(false); } string messageId = resultTuple.Value.Item1; IIntegrationMessage integrationMessage = resultTuple.Value.Item2; if (integrationMessage == null) { throw new ArgumentNullException(nameof(integrationMessage)); } try { integrationMessageBroker.Add(integrationMessage); await integrationMessageBroker.DistributeAsync(cancellationToken); await outboxMessageRepository.SetCompletedAsync(messageId, cancellationToken); } catch (Exception e) { await outboxMessageRepository.SetFailedAsync(messageId, e.ToString(), cancellationToken); } return(true); } }
public virtual void SetNextOutboundMessage(IIntegrationMessage integrationMessage) { if ((object)integrationMessage == null) throw new ArgumentNullException("integrationMessage"); this.AssertReady(); this.WriteLogSynchronized("OUTBOUND: Set next outbound message on thread '{0}'.", Thread.CurrentThread.ManagedThreadId); lock (this.SyncLock) // TODO: change this to reader/writer lock this.OutboundMessageQueue.Enqueue(integrationMessage); }
public override IEnumerable<IIntegrationMessage> Execute(IPipeliningContext pipeliningContext, IIntegrationMessage integrationMessage) { //return new IIntegrationMessage[] { }; return new IIntegrationMessage[] { integrationMessage }; }
protected void PostInboundMessage(IntegrationEndpoint integrationEndpoint, IIntegrationMessage integrationMessage) { if ((object)integrationEndpoint == null) throw new ArgumentNullException("integrationEndpoint"); if ((object)integrationMessage == null) throw new ArgumentNullException("integrationMessage"); this.AssertReady(); this.WriteLogSynchronized("INBOUND: Post inbound message on thread '{0}'.", Thread.CurrentThread.ManagedThreadId); this.InboundMessageQueue.Add(new Tuple<IntegrationEndpoint, IIntegrationMessage>(integrationEndpoint, integrationMessage)); }
protected abstract void DropMessageInternal(IIntegrationMessage integrationMessage);
public async Task AddAsync(IIntegrationMessage integrationMessage, CancellationToken cancellationToken = default) { var outboxMessage = new OutboxMessage(integrationMessage); await _dbContext.AddAsync(outboxMessage, cancellationToken); }
protected override void EnqueueOutboundMessageInternal(IIntegrationMessage integrationMessage) { if ((object)integrationMessage == null) throw new ArgumentNullException("integrationMessage"); this.WriteLogSynchronized("OUTBOUND: Integration message ID '{0}' enqueued on thread '{1}'.", integrationMessage.RunTimeId, Thread.CurrentThread.ManagedThreadId); // TODO: HACK -- manual trigger should be timer based this.FileSystemDumpsters.Values.ToList().ForEach(fsd => fsd.Trigger()); }
protected abstract void CoreRoute(IIntegrationMessage integrationMessage);
protected override void CoreRoute(IIntegrationMessage integrationMessage) { }
public async Task Dispatch(IIntegrationMessage message, MessageContext context) { var handler = GetHandler(message); await handler.Handle(message, context, _handlerFactory); }
protected virtual Task Unhandled(IIntegrationMessage message, MessageContext context) { throw new InvalidMessageForStateException(_currentHandlers.StateName, message.GetType()); }
protected override void MarkMessageInternal(IIntegrationMessage integrationMessage, Guid messageStateId) { /*IDropbox dropbox, prototype; IRepository repository; if ((object)integrationMessage == null) throw new ArgumentNullException("integrationMessage"); this.WriteLogSynchronized("SQLDBMESSAGESTORE: marking message on thread '{0}'.", Thread.CurrentThread.ManagedThreadId); repository = new Repository(); using (var scope = new AmbientUnitOfWorkScope(repository)) { prototype = repository.CreateModel<IDropbox>(m => { m.DropboxId = (Guid)integrationMessage.RunTimeId; }); dropbox = repository.Load<IDropbox>(prototype); if ((object)dropbox == null) throw new InvalidOperationException("not found"); dropbox.IsNew = false; dropbox.MessageStateId = messageStateId; repository.Save<IDropbox>(dropbox); scope.ScopeComplete(); }*/ }
public abstract Task Handle(IIntegrationMessage message, MessageContext context, IServiceFactory handlerFactory);
public void AddMessage(IIntegrationMessage integrationMessage) { _messages.Enqueue(integrationMessage); }
protected abstract void EnqueueOutboundMessageInternal(IIntegrationMessage integrationMessage);
protected abstract void MarkMessageInternal(IIntegrationMessage integrationMessage, Guid messageStateId);
public abstract IEnumerable<IIntegrationMessage> Execute(IPipeliningContext pipeliningContext, IIntegrationMessage integrationMessage);
object ISaga.FindKey(IIntegrationMessage message, MessageMetaData meta) => FindKey(message, meta);
protected override void DropMessageInternal(IIntegrationMessage integrationMessage) { /*IDropbox dropbox; IDropboxMetadata dropboxMetadata; IRepository repository; DateTime nowUtc = DateTime.UtcNow; StreamReader streamReader; if ((object)integrationMessage == null) throw new ArgumentNullException("integrationMessage"); this.WriteLogSynchronized("SQLDBMESSAGESTORE: dropping message on thread '{0}'.", Thread.CurrentThread.ManagedThreadId); repository = new Repository(); using (var scope = new AmbientUnitOfWorkScope(repository)) { streamReader = new StreamReader(integrationMessage.DataStream); dropbox = repository.CreateModel<IDropbox>(m => { m.DropboxId = integrationMessage.RunTimeId; m.CreationTimestamp = nowUtc; m.ModificationTimestamp = nowUtc; m.IsNew = true; m.LogicalDelete = false; m.ContentEncoding = integrationMessage.ContentEncoding = streamReader.CurrentEncoding.WebName; m.ContentLanguage = ""; m.ContentLength = integrationMessage.DataStream.Length; m.ContentLocation = ""; m.ContentHash = ""; m.ContentDisposition = ""; m.ContentRange = ""; m.ContentType = integrationMessage.ContentType; m.MessageSchemaId = new Guid(MessageStateConstants.MESSAGE_SCHEMA_UNKNOWN); m.MessageStateId = new Guid(MessageStateConstants.MESSAGE_STATE_CREATED); m.MessageText = streamReader.ReadToEnd(); // TODO: inefficient buffered approach }); repository.Save<IDropbox>(dropbox); foreach (KeyValuePair<string, object> metadata in integrationMessage.Metadata) { dropboxMetadata = repository.CreateModel<IDropboxMetadata>(m => { m.DropboxId = integrationMessage.RunTimeId; m.IsNew = true; m.MetadataKey = metadata.Key; m.MetadataOrdinal = 0; m.MetadataValue = metadata.Value.SafeToString(null, null); }); repository.Save<IDropboxMetadata>(dropboxMetadata); } scope.ScopeComplete(); }*/ }
protected override void MarkMessageInternal(IIntegrationMessage integrationMessage, Guid messageStateId) { // TODO }
public K FindKey(IIntegrationMessage message, MessageMetaData meta) { return(_keyMappers[message.GetType()].Invoke(message, meta)); }