Beispiel #1
0
        private async Task <CollaborationProtocolProfile> FindProfile(ILogger logger, OutgoingMessage message)
        {
            var profile =
                await CollaborationProtocolRegistry.FindAgreementForCounterpartyAsync(logger, message.ToHerId).ConfigureAwait(false) ??
                await CollaborationProtocolRegistry.FindProtocolForCounterpartyAsync(logger, message.ToHerId).ConfigureAwait(false);

            return(profile);
        }
Beispiel #2
0
        private static void Configure(string profile, bool ignoreCertificateErrors, bool noProtection)
        {
            // read configuration values
            var builder = new Microsoft.Extensions.Configuration.ConfigurationBuilder()
                          .SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
                          .AddJsonFile("appsettings.json", false)
                          .AddJsonFile($"{profile}.json", false);
            var configurationRoot = builder.Build();

            // configure logging
            _loggerFactory = new LoggerFactory();
            _loggerFactory.AddConsole(configurationRoot.GetSection("Logging"));
            _logger = _loggerFactory.CreateLogger("TestClient");

            // configure caching
            var distributedCache = DistributedCacheFactory.Create();

            // set up address registry
            var addressRegistrySettings = new AddressRegistrySettings();

            configurationRoot.GetSection("AddressRegistrySettings").Bind(addressRegistrySettings);
            addressRegistrySettings.WcfConfiguration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            var addressRegistry = new AddressRegistry(addressRegistrySettings, distributedCache);

            // set up collaboration registry
            var collaborationProtocolRegistrySettings = new CollaborationProtocolRegistrySettings();

            configurationRoot.GetSection("CollaborationProtocolRegistrySettings").Bind(collaborationProtocolRegistrySettings);
            collaborationProtocolRegistrySettings.WcfConfiguration =
                ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

            var collaborationProtocolRegistry = new CollaborationProtocolRegistry(collaborationProtocolRegistrySettings,
                                                                                  distributedCache, addressRegistry);

            _clientSettings = new ClientSettings();
            configurationRoot.GetSection("ClientSettings").Bind(_clientSettings);

            // set up messaging
            var messagingSettings = new MessagingSettings();

            configurationRoot.GetSection("MessagingSettings").Bind(messagingSettings);

            messagingSettings.IgnoreCertificateErrorOnSend = ignoreCertificateErrors;
            messagingSettings.LogPayload = true;

            if (noProtection)
            {
                _messagingClient = new MessagingClient(messagingSettings, collaborationProtocolRegistry, addressRegistry, null, null, new NoMessageProtection());
            }
            else
            {
                _messagingClient = new MessagingClient(messagingSettings, collaborationProtocolRegistry, addressRegistry);
            }
        }
Beispiel #3
0
        private static void Configure(string profile)
        {
            // read configuration values
            var builder = new Microsoft.Extensions.Configuration.ConfigurationBuilder()
                          .SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
                          .AddJsonFile("appsettings.json", false)
                          .AddJsonFile($"{profile}.json", false);
            var configurationRoot = builder.Build();

            // configure logging
            _loggerFactory = new LoggerFactory();
            _loggerFactory.AddConsole(configurationRoot.GetSection("Logging"));
            _loggerFactory.AddNLog();

            LogManager.Configuration = new XmlLoggingConfiguration("nlog.config", true);

            _logger = _loggerFactory.CreateLogger("TestServer");

            // configure caching
            var distributedCache = DistributedCacheFactory.Create();

            // set up address registry
            var addressRegistrySettings = new AddressRegistrySettings();

            configurationRoot.GetSection("AddressRegistrySettings").Bind(addressRegistrySettings);
            addressRegistrySettings.WcfConfiguration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            var addressRegistry = new AddressRegistry(addressRegistrySettings, distributedCache);

            // set up collaboration registry
            var collaborationProtocolRegistrySettings = new CollaborationProtocolRegistrySettings();

            configurationRoot.GetSection("CollaborationProtocolRegistrySettings").Bind(collaborationProtocolRegistrySettings);
            collaborationProtocolRegistrySettings.WcfConfiguration =
                ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

            var collaborationProtocolRegistry = new CollaborationProtocolRegistry(collaborationProtocolRegistrySettings, distributedCache, addressRegistry);

            _serverSettings = new ServerSettings();
            configurationRoot.GetSection("ServerSettings").Bind(_serverSettings);

            // set up messaging
            var messagingSettings = new MessagingSettings();

            configurationRoot.GetSection("MessagingSettings").Bind(messagingSettings);

            messagingSettings.ServiceBus.Synchronous.ReplyQueueMapping.Add(Environment.MachineName, "DUMMY"); // we just need a value, it will never be used
            messagingSettings.LogPayload = true;

            _messagingServer = new MessagingServer(messagingSettings, _logger, _loggerFactory, collaborationProtocolRegistry, addressRegistry);

            _messagingServer.RegisterAsynchronousMessageReceivedStartingCallback((m) =>
            {
                MappedDiagnosticsLogicalContext.Set("correlationId", m.MessageId);
            });
            _messagingServer.RegisterAsynchronousMessageReceivedCallback((m) =>
            {
                if (m.Payload.ToString().Contains("ThrowException"))
                {
                    throw new InvalidOperationException();
                }

                var path = Path.Combine(_serverSettings.DestinationDirectory, "Asynchronous");
                if (Directory.Exists(path) == false)
                {
                    Directory.CreateDirectory(path);
                }
                var fileName = Path.Combine(path, m.MessageId + ".xml");
                using (var sw = File.CreateText(fileName))
                {
                    m.Payload.Save(sw);
                }
            });
            _messagingServer.RegisterAsynchronousMessageReceivedCompletedCallback((m) =>
            {
                MappedDiagnosticsLogicalContext.Set("correlationId", m.MessageId);
            });

            _messagingServer.RegisterSynchronousMessageReceivedStartingCallback((m) =>
            {
                MappedDiagnosticsLogicalContext.Set("correlationId", string.Empty);// reset correlation id
            });
            _messagingServer.RegisterSynchronousMessageReceivedCallback((m) =>
            {
                var path = Path.Combine(_serverSettings.DestinationDirectory, "Synchronous");
                if (Directory.Exists(path) == false)
                {
                    Directory.CreateDirectory(path);
                }
                var fileName = Path.Combine(path, m.MessageId + ".xml");
                using (var sw = File.CreateText(fileName))
                {
                    m.Payload.Save(sw);
                }
                return(new XDocument(new XElement("DummyResponse")));
            });
            _messagingServer.RegisterSynchronousMessageReceivedCompletedCallback((m) =>
            {
                MappedDiagnosticsLogicalContext.Set("correlationId", string.Empty); // reset correlation id
            });
        }
Beispiel #4
0
        /// <summary>
        /// Sends an outgoing message
        /// </summary>
        /// <param name="logger"></param>
        /// <param name="outgoingMessage">Information about the message to send</param>
        /// <param name="queueType">The type of queue that should be used</param>
        /// <param name="replyTo">An optional ReplyTo queue that should be used. Only relevant in synchronous messaging</param>
        /// <param name="correlationId">The correlation id to use when sending the message. Only relevant in synchronous messaging</param>
        /// <returns></returns>
        internal async Task Send(ILogger logger, OutgoingMessage outgoingMessage, QueueType queueType, string replyTo = null, string correlationId = null)
        {
            logger.LogDebug($"Start-ServiceBusCore::Send QueueType: {queueType} replyTo: {replyTo} correlationId: {correlationId}");

            if (outgoingMessage == null)
            {
                throw new ArgumentNullException(nameof(outgoingMessage));
            }
            if (string.IsNullOrEmpty(outgoingMessage.MessageId))
            {
                throw new ArgumentNullException(nameof(outgoingMessage.MessageId));
            }
            if (outgoingMessage.Payload == null)
            {
                throw new ArgumentNullException(nameof(outgoingMessage.Payload));
            }

            var hasAgreement = true;
            // first we try and find an agreement
            var profile = await CollaborationProtocolRegistry.FindAgreementForCounterpartyAsync(logger, outgoingMessage.ToHerId).ConfigureAwait(false);

            if (profile == null)
            {
                hasAgreement = false;                 // if we don't have an agreement, we try to find the specific profile
                profile      = await CollaborationProtocolRegistry.FindProtocolForCounterpartyAsync(logger, outgoingMessage.ToHerId).ConfigureAwait(false);
            }

            logger.LogDebug($"ServiceBusCore::Send - Start retrieving and valiating certificates - correlationId: {correlationId}");
            var signature  = Settings.SigningCertificate.Certificate;
            var encryption = profile.EncryptionCertificate;

            var validator        = Core.DefaultCertificateValidator;
            var encryptionStatus = validator.Validate(encryption, X509KeyUsageFlags.DataEncipherment);
            var signatureStatus  = validator.Validate(signature, X509KeyUsageFlags.NonRepudiation);

            // this is the other parties certificate that may be out of date, not something we can fix
            if (encryptionStatus != CertificateErrors.None)
            {
                if (Core.Settings.IgnoreCertificateErrorOnSend)
                {
                    logger.LogError(EventIds.RemoteCertificate, "Remote encryption certificate is not valid");
                }
                else
                {
                    throw new MessagingException("Remote encryption certificate is not valid")
                          {
                              EventId = EventIds.RemoteCertificate
                          };
                }
            }
            // this is our certificate, something we can fix
            if (signatureStatus != CertificateErrors.None)
            {
                if (Core.Settings.IgnoreCertificateErrorOnSend)
                {
                    logger.LogError(EventIds.LocalCertificate, "Locally installed signing certificate is not valid");
                }
                else
                {
                    throw new MessagingException("Locally installed signing certificate is not valid")
                          {
                              EventId = EventIds.LocalCertificate
                          };
                }
            }
            logger.LogDebug($"ServiceBusCore::Send - End retrieving and valiating certificates - correlationId: {correlationId}");

            logger.LogDebug($"ServiceBusCore::Send - Start encrypting message - correlationId: {correlationId}");
            var protection = Core.DefaultMessageProtection;
            var stream     = protection.Protect(outgoingMessage.Payload, encryption, signature);

            logger.LogDebug($"ServiceBusCore::Send - End encrypting message - correlationId: {correlationId}");

            logger.LogDebug($"ServiceBusCore::Send - Start Create and Initialize message - correlationId: {correlationId}");
            var messagingMessage = FactoryPool.CreateMessage(logger, stream, outgoingMessage);

            if (queueType != QueueType.SynchronousReply)
            {
                messagingMessage.ReplyTo =
                    replyTo ?? await ConstructQueueName(logger, Core.Settings.MyHerId, queueType).ConfigureAwait(false);
            }

            messagingMessage.ContentType = protection.ContentType;
            messagingMessage.MessageId   = outgoingMessage.MessageId;
            // when we are replying to a synchronous message, we need to use the replyto of the original message
            messagingMessage.To =
                (queueType == QueueType.SynchronousReply) ?
                replyTo :
                await ConstructQueueName(logger, outgoingMessage.ToHerId, queueType).ConfigureAwait(false);

            messagingMessage.MessageFunction = outgoingMessage.MessageFunction;
            messagingMessage.CorrelationId   = correlationId ?? outgoingMessage.MessageId;
            messagingMessage.TimeToLive      = (queueType == QueueType.Asynchronous)
                                ? Settings.Asynchronous.TimeToLive
                                : Settings.Synchronous.TimeToLive;
            messagingMessage.ScheduledEnqueueTimeUtc = outgoingMessage.ScheduledSendTimeUtc;
            messagingMessage.FromHerId            = Core.Settings.MyHerId;
            messagingMessage.ToHerId              = outgoingMessage.ToHerId;
            messagingMessage.ApplicationTimestamp = DateTime.Now;

            if (hasAgreement)
            {
                messagingMessage.CpaId = profile.CpaId.ToString("D");
            }
            logger.LogDebug($"ServiceBusCore::Send - End Create and Initialize message - correlationId: {correlationId}");

            await Send(logger, messagingMessage, queueType, outgoingMessage.PersonalId, (LogPayload)?outgoingMessage.Payload : null).ConfigureAwait(false);

            logger.LogDebug($"End-ServiceBusCore::Send QueueType: {queueType} replyTo: {replyTo} correlationId: {correlationId}");
        }
Beispiel #5
0
        /// <summary>
        /// Sends an outgoing message
        /// </summary>
        /// <param name="logger"></param>
        /// <param name="outgoingMessage">Information about the message to send</param>
        /// <param name="queueType">The type of queue that should be used</param>
        /// <param name="replyTo">An optional ReplyTo queue that should be used. Only relevant in synchronous messaging</param>
        /// <param name="correlationId">The correlation id to use when sending the message. Only relevant in synchronous messaging</param>
        /// <returns></returns>
        internal async Task Send(ILogger logger, OutgoingMessage outgoingMessage, QueueType queueType, string replyTo = null, string correlationId = null)
        {
            if (outgoingMessage == null)
            {
                throw new ArgumentNullException(nameof(outgoingMessage));
            }
            if (string.IsNullOrEmpty(outgoingMessage.MessageId))
            {
                throw new ArgumentNullException(nameof(outgoingMessage.MessageId));
            }
            if (outgoingMessage.Payload == null)
            {
                throw new ArgumentNullException(nameof(outgoingMessage.Payload));
            }

            logger.LogStartSend(queueType, outgoingMessage.MessageFunction, Core.Settings.MyHerId, outgoingMessage.ToHerId, outgoingMessage.MessageId, outgoingMessage.PersonalId, outgoingMessage.Payload);

            var hasAgreement = true;
            // first we try and find an agreement
            var profile = await CollaborationProtocolRegistry.FindAgreementForCounterpartyAsync(logger, outgoingMessage.ToHerId).ConfigureAwait(false);

            if (profile == null)
            {
                hasAgreement = false; // if we don't have an agreement, we try to find the specific profile
                profile      = await CollaborationProtocolRegistry.FindProtocolForCounterpartyAsync(logger, outgoingMessage.ToHerId).ConfigureAwait(false);
            }

            var contentType = Core.MessageProtection.ContentType;

            if (contentType.Equals(ContentType.SignedAndEnveloped, StringComparison.OrdinalIgnoreCase))
            {
                var validator = Core.CertificateValidator;
                // Validate external part's encryption certificate
                logger.LogBeforeValidatingCertificate(outgoingMessage.MessageFunction, profile.EncryptionCertificate.Thumbprint, profile.EncryptionCertificate.Subject, "DataEncipherment", outgoingMessage.ToHerId, outgoingMessage.MessageId);
                var encryptionStatus = validator == null
                    ? CertificateErrors.None
                    : validator.Validate(profile.EncryptionCertificate, X509KeyUsageFlags.DataEncipherment);
                logger.LogAfterValidatingCertificate(outgoingMessage.MessageFunction, profile.EncryptionCertificate.Thumbprint, profile.EncryptionCertificate.Subject, "DataEncipherment", outgoingMessage.ToHerId, outgoingMessage.MessageId);

                logger.LogBeforeValidatingCertificate(outgoingMessage.MessageFunction, Core.MessageProtection.SigningCertificate.Thumbprint, Core.MessageProtection.SigningCertificate.Subject, "NonRepudiation", Core.Settings.MyHerId, outgoingMessage.MessageId);
                // Validate "our" own signature certificate
                var signatureStatus = validator == null
                    ? CertificateErrors.None
                    : validator.Validate(Core.MessageProtection.SigningCertificate, X509KeyUsageFlags.NonRepudiation);
                logger.LogAfterValidatingCertificate(outgoingMessage.MessageFunction, Core.MessageProtection.SigningCertificate.Thumbprint, Core.MessageProtection.SigningCertificate.Subject, "NonRepudiation", Core.Settings.MyHerId, outgoingMessage.MessageId);

                // this is the other parties certificate that may be out of date, not something we can fix
                if (encryptionStatus != CertificateErrors.None)
                {
                    if (Core.Settings.IgnoreCertificateErrorOnSend)
                    {
                        logger.LogError(EventIds.RemoteCertificate, $"Remote encryption certificate {profile.EncryptionCertificate?.SerialNumber} for {outgoingMessage.ToHerId.ToString()} is not valid");
                    }
                    else
                    {
                        throw new MessagingException($"Remote encryption certificate {profile.EncryptionCertificate?.SerialNumber} for {outgoingMessage.ToHerId.ToString()} is not valid")
                              {
                                  EventId = EventIds.RemoteCertificate
                              };
                    }
                }
                // this is our certificate, something we can fix
                if (signatureStatus != CertificateErrors.None)
                {
                    if (Core.Settings.IgnoreCertificateErrorOnSend)
                    {
                        logger.LogError(EventIds.LocalCertificate, $"Locally installed signing certificate {Core.MessageProtection.SigningCertificate?.SerialNumber} is not valid.\nSerial Number: {Core.MessageProtection.SigningCertificate?.SerialNumber}\nThumbprint: {Core.MessageProtection.SigningCertificate?.Thumbprint}");
                    }
                    else
                    {
                        throw new MessagingException($"Locally installed signing certificate {Core.MessageProtection.SigningCertificate?.SerialNumber} is not valid.\nSerial Number: {Core.MessageProtection.SigningCertificate?.SerialNumber}\nThumbprint: {Core.MessageProtection.SigningCertificate?.Thumbprint}")
                              {
                                  EventId = EventIds.LocalCertificate
                              };
                    }
                }
            }
            logger.LogBeforeEncryptingPayload(outgoingMessage.MessageFunction, profile.EncryptionCertificate.Thumbprint, profile.EncryptionCertificate.Subject, Core.Settings.MyHerId, outgoingMessage.ToHerId, outgoingMessage.MessageId);
            // Encrypt the payload
            var stream = Core.MessageProtection.Protect(outgoingMessage.Payload?.ToStream(), profile.EncryptionCertificate);

            logger.LogAfterEncryptingPayload(outgoingMessage.MessageFunction, profile.EncryptionCertificate.Thumbprint, profile.EncryptionCertificate.Subject, Core.Settings.MyHerId, outgoingMessage.ToHerId, outgoingMessage.MessageId);

            logger.LogBeforeFactoryPoolCreateMessage(outgoingMessage.MessageFunction, Core.Settings.MyHerId, outgoingMessage.ToHerId, outgoingMessage.MessageId);
            // Create an empty message
            var messagingMessage = FactoryPool.CreateMessage(logger, stream, outgoingMessage);

            logger.LogAfterFactoryPoolCreateMessage(outgoingMessage.MessageFunction, Core.Settings.MyHerId, outgoingMessage.ToHerId, outgoingMessage.MessageId);

            if (queueType != QueueType.SynchronousReply)
            {
                messagingMessage.ReplyTo =
                    replyTo ?? await ConstructQueueName(logger, Core.Settings.MyHerId, queueType).ConfigureAwait(false);
            }
            messagingMessage.ContentType = Core.MessageProtection.ContentType;
            messagingMessage.MessageId   = outgoingMessage.MessageId;
            // when we are replying to a synchronous message, we need to use the replyto of the original message
            messagingMessage.To =
                (queueType == QueueType.SynchronousReply) ?
                replyTo :
                await ConstructQueueName(logger, outgoingMessage.ToHerId, queueType).ConfigureAwait(false);

            messagingMessage.MessageFunction = outgoingMessage.MessageFunction;
            messagingMessage.CorrelationId   = correlationId ?? outgoingMessage.MessageId;
            messagingMessage.TimeToLive      = (queueType == QueueType.Asynchronous)
                ? Settings.Asynchronous.TimeToLive
                : Settings.Synchronous.TimeToLive;
            messagingMessage.ScheduledEnqueueTimeUtc = outgoingMessage.ScheduledSendTimeUtc;
            messagingMessage.FromHerId            = Core.Settings.MyHerId;
            messagingMessage.ToHerId              = outgoingMessage.ToHerId;
            messagingMessage.ApplicationTimestamp = DateTime.Now;

            if (hasAgreement)
            {
                messagingMessage.CpaId = profile.CpaId.ToString("D");
            }
            await Send(logger, messagingMessage, queueType, outgoingMessage.PersonalId, (LogPayload)?outgoingMessage.Payload : null).ConfigureAwait(false);

            logger.LogEndSend(queueType, messagingMessage.MessageFunction, messagingMessage.FromHerId, messagingMessage.ToHerId, messagingMessage.MessageId, outgoingMessage.PersonalId);
        }