public IMessageSender CreateMessageSender(Type messageType) { MessageTypeMessagingEntityMappingDetails mappingDetails = GetMappingDetails(messageType, MessagingEntityType.Queue, MessagingEntityType.Topic); IMessageSender messageSender; if (mappingDetails != null) { messageSender = _messagingFactory.CreateMessageSender(messageType, mappingDetails.Path); } else { // TODO: log messageSender = new UnconfiguredMessageSender(messageType); } return(messageSender); }
public IMessageReceiver CreateMessageReceiver(Type messageType) { MessageTypeMessagingEntityMappingDetails mappingDetails = GetMappingDetails(messageType, MessagingEntityType.Queue, MessagingEntityType.Subscription); IMessageReceiver messageReceiver; if (mappingDetails != null) { messageReceiver = _messagingFactory.CreateMessageReceiver(messageType, mappingDetails.Path, mappingDetails.ReceiveMode); } else { // TODO: log messageReceiver = new UnconfiguredMessageReceiver(messageType); } return(messageReceiver); }
private MessageTypeMessagingEntityMappingDetails GetMappingDetails(Type messageType, params MessagingEntityType[] expectedEntityTypes) { // Start by reducing the set to only those that match the messaging entity types we're looking for IEnumerable <MessageTypeMessagingEntityMappingDetails> messageTypePathMappingDetailsForMessagingEntityTypes = (from mtpm in _messageTypePathMappings join eet in expectedEntityTypes on mtpm.MessagingEntityType equals eet select mtpm); MessageTypeMessagingEntityMappingDetails resolvedMessageTypePathMappingDetails = null; foreach (MessageTypeMessagingEntityMappingDetails messageTypePathMappingDetails in messageTypePathMappingDetailsForMessagingEntityTypes) { Type supportedMessageType = messageTypePathMappingDetails.MessageType; // If the type matches exactly, then that's the one we use and we can stop looking for anything else if (supportedMessageType == messageType) { resolvedMessageTypePathMappingDetails = messageTypePathMappingDetails; break; } else { // Check if the type of this mapping is assignable from the message type in question if (supportedMessageType.IsAssignableFrom(messageType)) { // If we already found a mapping which might have worked and now we found another, then // we must fail and report the ambiguity if (resolvedMessageTypePathMappingDetails != null) { throw new AmbiguosMessageTypeMappingException(messageType, expectedEntityTypes); } // Remember this mapping, but we will continue looking to make sure it is the only one // that works for the specified message type (could be more than one) resolvedMessageTypePathMappingDetails = messageTypePathMappingDetails; } } } return(resolvedMessageTypePathMappingDetails); }
private void EnsureMessagingEntityExists(MessageTypeMessagingEntityMappingDetails mappingDetails, IEnumerable <MessageTypeMessagingEntityMappingDetails> allMessageTypePathMappings) { MessagingEntityCreationOptions creationOptions = mappingDetails.CreationOptions; if (creationOptions != MessagingEntityCreationOptions.None && !_verifiedExistingMessagingEntities.Contains(mappingDetails)) { Func <bool> exists; Action create; Action delete; string path = mappingDetails.Path; switch (mappingDetails.MessagingEntityType) { case MessagingEntityType.Queue: exists = () => _namespaceManager.QueueExists(path); create = () => _namespaceManager.CreateQueue(path); delete = () => _namespaceManager.DeleteQueue(path); break; case MessagingEntityType.Topic: exists = () => _namespaceManager.TopicExists(path); create = () => _namespaceManager.CreateTopic(path); delete = () => _namespaceManager.DeleteTopic(path); break; case MessagingEntityType.Subscription: string[] parts = path.Split('/'); string topicPath = parts[0]; string subscriptionName = parts[2]; exists = () => _namespaceManager.SubscriptionExists(topicPath, subscriptionName); create = () => { MessageTypeMessagingEntityMappingDetails topicMessageTypePathMapping = allMessageTypePathMappings.FirstOrDefault(mtpmd => mtpmd.MessagingEntityType == MessagingEntityType.Topic && mtpmd.Path == topicPath); if (topicMessageTypePathMapping == null) { topicMessageTypePathMapping = new MessageTypeMessagingEntityMappingDetails(mappingDetails.MessageType, topicPath, MessagingEntityType.Topic, MessagingEntityCreationOptions.VerifyAlreadyExists); } EnsureMessagingEntityExists(topicMessageTypePathMapping, allMessageTypePathMappings); _namespaceManager.CreateSubscription(topicPath, subscriptionName); }; delete = () => _namespaceManager.DeleteSubscription(topicPath, subscriptionName); break; default: throw new NotSupportedException(string.Format("Unsupported messaging entity type, {0}, requested for creation (path {1}).", mappingDetails.MessagingEntityType, mappingDetails.Path)); } bool alreadyExists = exists(); if (alreadyExists) { if ((creationOptions & MessagingEntityCreationOptions.CreateAsTemporary) != 0) { if ((creationOptions & MessagingEntityCreationOptions.RecreateExistingTemporary) == 0) { throw new MessagingEntityAlreadyExistsException(mappingDetails.Path, mappingDetails.MessagingEntityType); } try { delete(); alreadyExists = false; } catch (UnauthorizedAccessException exception) { throw new UnauthorizedAccessException(string.Format("Unable to delete temporary messaging that already exists at path \"{0}\" due to insufficient access. Make sure the policy being used has 'Manage' permission for the namespace.", mappingDetails.Path), exception); } } } if (!alreadyExists) { if ((creationOptions & (MessagingEntityCreationOptions.CreateIfDoesntExist | MessagingEntityCreationOptions.CreateAsTemporary)) == 0) { throw new MessagingEntityDoesNotAlreadyExistException(mappingDetails.Path, mappingDetails.MessagingEntityType); } try { create(); } catch (UnauthorizedAccessException exception) { throw new UnauthorizedAccessException(string.Format("Unable to create messaging entity at path \"{0}\" due to insufficient access. Make sure the policy being used has 'Manage' permission for the namespace.", mappingDetails.Path), exception); } } _verifiedExistingMessagingEntities.Add(mappingDetails); } }