/// <summary> /// Constructor /// </summary> /// <param name="core">Reference to core service bus infrastructure</param> /// <param name="logger">Logger used for diagnostic purposes</param> /// <param name="messagingNotification">A reference to the messaging notification system</param> internal SynchronousMessageListener( ServiceBusCore core, ILogger logger, IMessagingNotification messagingNotification) : base(core, logger, messagingNotification) { ReadTimeout = Core.Settings.Synchronous.ReadTimeout; }
/// <summary> /// Constructor /// </summary> /// <param name="core">Reference to core service bus infrastructure</param> /// <param name="logger">Logger used for diagnostic purposes</param> /// <param name="messagingNotification">A reference to the messaging notification system</param> internal ErrorMessageListener( ServiceBusCore core, ILogger logger, IMessagingNotification messagingNotification) : base(core, logger, messagingNotification) { ReadTimeout = Core.Settings.Error.ReadTimeout; }
/// <summary> /// Constructor /// </summary> /// <param name="settings">Set of options to use</param> /// <param name="collaborationProtocolRegistry">Reference to the collaboration protocol registry</param> /// <param name="addressRegistry">Reference to the address registry</param> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentOutOfRangeException"></exception> protected MessagingCore( MessagingSettings settings, ICollaborationProtocolRegistry collaborationProtocolRegistry, IAddressRegistry addressRegistry) { if (settings == null) { throw new ArgumentNullException(nameof(settings)); } if (collaborationProtocolRegistry == null) { throw new ArgumentNullException(nameof(collaborationProtocolRegistry)); } if (addressRegistry == null) { throw new ArgumentNullException(nameof(addressRegistry)); } Settings = settings; CollaborationProtocolRegistry = collaborationProtocolRegistry; AddressRegistry = addressRegistry; DefaultCertificateValidator = new CertificateValidator(); DefaultMessageProtection = new SignThenEncryptMessageProtection(); ServiceBus = new ServiceBusCore(this); Settings.Validate(); }
/// <summary> /// Constructor /// </summary> /// <param name="core">Reference to core service bus infrastructure</param> /// <param name="logger">Logger used for diagnostics information</param> /// <param name="messagingNotification">A reference to the messaging notification system</param> protected MessageListener( ServiceBusCore core, ILogger logger, IMessagingNotification messagingNotification) { Logger = logger ?? throw new ArgumentNullException(nameof(logger)); Core = core ?? throw new ArgumentNullException(nameof(core)); MessagingNotification = messagingNotification; }
private void ReportErrorOnLocalCertificate(IMessagingMessage originalMessage, X509Certificate2 certificate, CertificateErrors error, bool removeMessage) { string description; EventId id; switch (error) { case CertificateErrors.None: return; // no error case CertificateErrors.StartDate: description = "Invalid start date"; id = EventIds.LocalCertificateStartDate; break; case CertificateErrors.EndDate: description = "Invalid end date"; id = EventIds.LocalCertificateEndDate; break; case CertificateErrors.Usage: description = "Invalid usage"; id = EventIds.LocalCertificateUsage; break; case CertificateErrors.Revoked: description = "Certificate has been revoked"; id = EventIds.LocalCertificateRevocation; break; case CertificateErrors.RevokedUnknown: description = "Unable to determine revocation status"; id = EventIds.LocalCertificateRevocation; break; case CertificateErrors.Missing: description = "Certificate is missing"; id = EventIds.LocalCertificate; break; default: // since the value is bitcoded description = "More than one error with certificate"; id = EventIds.LocalCertificate; break; } Logger.LogError(id, null, "Description: {Description} Subject: {Subject} Thumbprint: {Thumbprint}", description, certificate?.Subject, certificate?.Thumbprint); if (removeMessage) { ServiceBusCore.RemoveMessageFromQueueAfterError(Logger, originalMessage); } }
/// <summary> /// Constructor /// </summary> /// <param name="settings">Set of options to use</param> /// <param name="collaborationProtocolRegistry">Reference to the collaboration protocol registry</param> /// <param name="addressRegistry">Reference to the address registry</param> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentOutOfRangeException"></exception> protected MessagingCore( MessagingSettings settings, ICollaborationProtocolRegistry collaborationProtocolRegistry, IAddressRegistry addressRegistry) { Settings = settings ?? throw new ArgumentNullException(nameof(settings)); CollaborationProtocolRegistry = collaborationProtocolRegistry ?? throw new ArgumentNullException(nameof(collaborationProtocolRegistry)); AddressRegistry = addressRegistry ?? throw new ArgumentNullException(nameof(addressRegistry)); ServiceBus = new ServiceBusCore(this); Settings.Validate(); CertificateStore = GetDefaultCertificateStore(); CertificateValidator = GetDefaultCertificateValidator(); MessageProtection = GetDefaultMessageProtection(); }
/// <summary> /// Constructor /// </summary> /// <param name="settings">Set of options to use</param> /// <param name="collaborationProtocolRegistry">Reference to the collaboration protocol registry</param> /// <param name="addressRegistry">Reference to the address registry</param> /// <param name="certificateStore"> /// Reference to a custom implementation of <see cref="ICertificateStore"/>, if not set the library will default to Windows Certificate Store. /// Setting this argument to null must be done cautiously as the default implementation of <see cref="IMessageProtection"/> /// <see cref="SignThenEncryptMessageProtection"/> relies on an <see cref="ICertificateStore"/> implementation. /// </param> /// <param name="certificateValidator"> /// Reference to a custom implementation of <see cref="ICertificateValidator"/>, if not set the library will default to the standard implementation /// of <see cref="ICertificateValidator"/>. By setting this parameter to null you effectively disable certificate validation. /// </param> /// <param name="messageProtection"> /// Reference to custom implemenation of <see cref="IMessageProtection"/>, if not set the library will default to standard behavior which relies on /// certificates retrieved from <see cref="ICertificateStore"/>. Setting this parameter to null will throw an <see cref="ArgumentNullException"/>. /// </param> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentOutOfRangeException"></exception> protected MessagingCore( MessagingSettings settings, ICollaborationProtocolRegistry collaborationProtocolRegistry, IAddressRegistry addressRegistry, ICertificateStore certificateStore, ICertificateValidator certificateValidator, IMessageProtection messageProtection) { Settings = settings ?? throw new ArgumentNullException(nameof(settings)); CollaborationProtocolRegistry = collaborationProtocolRegistry ?? throw new ArgumentNullException(nameof(collaborationProtocolRegistry)); AddressRegistry = addressRegistry ?? throw new ArgumentNullException(nameof(addressRegistry)); ServiceBus = new ServiceBusCore(this); Settings.Validate(); CertificateStore = certificateStore; CertificateValidator = certificateValidator; MessageProtection = messageProtection ?? throw new ArgumentNullException(nameof(messageProtection)); }
public SynchronousSender(ServiceBusCore core) { _core = core; }
private async Task <IncomingMessage> HandleRawMessage(IMessagingMessage message, bool alwaysRemoveMessage) { if (message == null) { return(null); } Stream bodyStream = null; try { var incomingMessage = new IncomingMessage() { MessageFunction = message.MessageFunction, FromHerId = message.FromHerId, ToHerId = message.ToHerId, MessageId = message.MessageId, CorrelationId = message.CorrelationId, EnqueuedTimeUtc = message.EnqueuedTimeUtc, RenewLock = message.RenewLock, DeliveryCount = message.DeliveryCount }; NotifyMessageProcessingStarted(incomingMessage); Logger.LogStartReceive(QueueType, incomingMessage); // we cannot dispose of the stream before we have potentially cloned the message for error use bodyStream = message.GetBody(); ValidateMessageHeader(message); // we need the certificates for decryption and certificate use incomingMessage.CollaborationAgreement = await ResolveProfile(message).ConfigureAwait(false); var payload = HandlePayload(message, bodyStream, message.ContentType, incomingMessage, out bool contentWasSigned); incomingMessage.ContentWasSigned = contentWasSigned; if (payload != null) { if (Core.LogPayload) { Logger.LogDebug(payload.ToString()); } incomingMessage.Payload = payload; } NotifyMessageProcessingReady(message, incomingMessage); ServiceBusCore.RemoveProcessedMessageFromQueue(message); Logger.LogRemoveMessageFromQueueNormal(message, QueueName); NotifyMessageProcessingCompleted(incomingMessage); Logger.LogEndReceive(QueueType, incomingMessage); return(incomingMessage); } catch (SecurityException ex) { Core.ReportErrorToExternalSender(Logger, EventIds.RemoteCertificate, message, "transport:invalid-certificate", ex.Message, null, ex); MessagingNotification.NotifyHandledException(message, ex); } catch (HeaderValidationException ex) { Core.ReportErrorToExternalSender(Logger, EventIds.MissingField, message, "transport:invalid-field-value", ex.Message, ex.Fields); MessagingNotification.NotifyHandledException(message, ex); } catch (XmlSchemaValidationException ex) // reportable error from message handler (application) { Core.ReportErrorToExternalSender(Logger, EventIds.NotXml, message, "transport:not-well-formed-xml", ex.Message, null, ex); MessagingNotification.NotifyHandledException(message, ex); } catch (ReceivedDataMismatchException ex) // reportable error from message handler (application) { Core.ReportErrorToExternalSender(Logger, EventIds.DataMismatch, message, "transport:invalid-field-value", ex.Message, new[] { ex.ExpectedValue, ex.ReceivedValue }, ex); MessagingNotification.NotifyHandledException(message, ex); } catch (NotifySenderException ex) // reportable error from message handler (application) { Core.ReportErrorToExternalSender(Logger, EventIds.ApplicationReported, message, "transport:internal-error", ex.Message, null, ex); MessagingNotification.NotifyHandledException(message, ex); } catch (SenderHerIdMismatchException ex) // reportable error from message handler (application) { Core.ReportErrorToExternalSender(Logger, EventIds.DataMismatch, message, "abuse:spoofing-attack", ex.Message, null, ex); MessagingNotification.NotifyHandledException(message, ex); } catch (PayloadDeserializationException ex) // from parsing to XML, reportable exception { Core.ReportErrorToExternalSender(Logger, EventIds.ApplicationReported, message, "transport:not-well-formed-xml", ex.Message, null, ex); MessagingNotification.NotifyHandledException(message, ex); } catch (AggregateException ex) when(ex.InnerException is MessagingException && ((MessagingException)ex.InnerException).EventId.Id == EventIds.Send.Id) { Core.ReportErrorToExternalSender(Logger, EventIds.ApplicationReported, message, "transport:invalid-field-value", "Invalid value in field: 'ReplyTo'", null, ex); MessagingNotification.NotifyHandledException(message, ex); } catch (UnsupportedMessageException ex) // reportable error from message handler (application) { Core.ReportErrorToExternalSender(Logger, EventIds.ApplicationReported, message, "transport:unsupported-message", ex.Message, null, ex); MessagingNotification.NotifyHandledException(message, ex); } catch (Exception ex) // unknown error { message.AddDetailsToException(ex); Logger.LogError(EventIds.UnknownError, null, $"Message processing failed. Keeping lock until it times out and we can try again. Message expires at UTC {message.ExpiresAtUtc}"); Logger.LogException("Unknown error", ex); // if something unknown goes wrong, we want to retry the message after a delay // we don't call Complete() or Abandon() since that will cause the message to be availble again // chances are that the failure may still be around // the Defer() method requires us to store the sequence id, but we don't have a place to store it // the option then is to let the lock time-out. This will happen after a couple of minutes and the // message becomes available again. 10 retries = 10 timeouts before it gets added to DLQ if (alwaysRemoveMessage) { ServiceBusCore.RemoveMessageFromQueueAfterError(Logger, message); } MessagingNotification.NotifyUnhandledException(message, ex); } finally { bodyStream?.Dispose(); message.Dispose(); } return(null); }