public SubscriptionDescription CreateSubscription(SubscriptionDescription description, Filter filter) { SqlFilter sf = filter as SqlFilter; var value = sf.SqlExpression; //we must parse on the first ' and then go to the end of the string -1 char var index = value.IndexOf('\''); var typeName = value.Substring(index + 1); typeName = typeName.Substring(0, typeName.Length - 1).Replace("_", "."); //NOTE Limit is test class must exist in this assembly for now. var theType = this.GetType().Assembly.GetType(typeName); _subscriptions.Add(new SubscriptionDescriptionState() { Description = description, Type = theType }); ServiceBusEnpointData endpoint = null; if (_endpointMap.TryGetValue(description, out endpoint)) { receiver.CreateSubscription(endpoint); } else { throw new Exception("Endpoint error"); } return(description); }
/// <summary> /// Create a new Subscription. /// </summary> /// <param name="value">The data used to create the subscription</param> public void CreateSubscription(ServiceBusEnpointData value) { Guard.ArgumentNotNull(value, "value"); //TODO determine how we can change the filters for an existing registered item //ServiceBusNamespaceClient lock (lockObject) { logger.Info("CreateSubscription {0} Declared {1} MessageTytpe {2}, IsReusable {3} Custom Attribute {4}", value.SubscriptionName, value.DeclaredType.ToString(), value.MessageType.ToString(), value.IsReusable, value.AttributeData != null ? value.AttributeData.ToString() : string.Empty); var helper = new AzureReceiverHelper(defaultTopic, configurationFactory, configuration, serializer, verifyRetryPolicy, retryPolicy, value); mappings.Add(helper); //helper.ProcessMessagesForSubscription(); //TODO make a config setting to allow us to run subscriptions on different threads or not. //create a new thread for processing of the messages. var t = new Thread(helper.ProcessMessagesForSubscription); t.Name = value.SubscriptionName; t.IsBackground = false; t.Start(); } //lock end }
/// <summary> /// Cancel a subscription /// </summary> /// <param name="value">The data used to cancel the subscription</param> public void CancelSubscription(ServiceBusEnpointData value) { Guard.ArgumentNotNull(value, "value"); logger.Info("CancelSubscription {0} Declared {1} MessageTytpe {2}, IsReusable {3}", value.SubscriptionName, value.DeclaredType.ToString(), value.MessageType.ToString(), value.IsReusable); var subscription = mappings.FirstOrDefault(item => item.Data.EndPointData.SubscriptionName.Equals(value.SubscriptionName, StringComparison.OrdinalIgnoreCase)); if (subscription == null) { logger.Info("CancelSubscription Does not exist {0}", value.SubscriptionNameDebug); return; } subscription.Data.Cancel(); Task t = Task.Factory.StartNew(() => { //HACK find better way to wait for a cancel request so we are not blocking. logger.Info("CancelSubscription Deleting {0}", value.SubscriptionNameDebug); for (int i = 0; i < 100; i++) { if (!subscription.Data.Cancelled) { Thread.Sleep(1000); } else { break; } } if (configurationFactory.NamespaceManager.SubscriptionExists(defaultTopic.Path, value.SubscriptionName)) { var filter = new SqlFilter(string.Format(TYPE_HEADER_NAME + " = '{0}'", value.MessageType.FullName.Replace('.', '_'))); retryPolicy.ExecuteAction(() => configurationFactory.NamespaceManager.DeleteSubscription(defaultTopic.Path, value.SubscriptionName)); logger.Info("CancelSubscription Deleted {0}", value.SubscriptionNameDebug); } }); try { Task.WaitAny(t); } catch (Exception ex) { if (ex is AggregateException) { //do nothing } else { throw; } } }
internal static void SubscribeOrUnsubscribeType(Action <string> logInfo, Type type, IBusConfiguration config, Action <ServiceBusEnpointData> callback) { Guard.ArgumentNotNull(type, "type"); Guard.ArgumentNotNull(callback, "callback"); logInfo(string.Format("SubscribeOrUnsubscribeType={0}", type.FullName)); var interfaces = type.GetInterfaces() .Where(i => i.IsGenericType && (i.GetGenericTypeDefinition() == typeof(IHandleMessages <>) || i.GetGenericTypeDefinition() == typeof(IHandleCompetingMessages <>))) .ToList(); if (interfaces.Count == 0) { throw new ApplicationException(string.Format("Type {0} does not implement IHandleMessages or IHandleCompetingMessages", type.FullName)); } //for each interface we find, we need to register it with the bus. foreach (var foundInterface in interfaces) { var implementedMessageType = foundInterface.GetGenericArguments()[0]; //due to the limits of 50 chars we will take the name and a MD5 for the name. var hashName = implementedMessageType.FullName + "|" + type.FullName; var hash = MD5Helper.CalculateMD5(hashName); var fullName = (IsCompetingHandler(foundInterface) ? "C_" : config.ServiceBusApplicationId + "_") + hash; var info = new ServiceBusEnpointData() { AttributeData = type.GetCustomAttributes(typeof(MessageHandlerConfigurationAttribute), false).FirstOrDefault() as MessageHandlerConfigurationAttribute, DeclaredType = type, MessageType = implementedMessageType, SubscriptionName = fullName, ServiceType = foundInterface }; if (!config.Container.IsRegistered(type)) { if (info.IsReusable) { config.Container.Register(type, type); } else { config.Container.Register(type, type, true); } } callback(info); } config.Container.Build(); }
public AzureReceiverHelper(TopicDescription topic, IServiceBusConfigurationFactory configurationFactory, IBusConfiguration config, IServiceBusSerializer serializer, RetryPolicy verifyRetryPolicy, RetryPolicy retryPolicy, ServiceBusEnpointData endpoint) { Guard.ArgumentNotNull(topic, "topic"); Guard.ArgumentNotNull(configurationFactory, "configurationFactory"); Guard.ArgumentNotNull(config, "config"); Guard.ArgumentNotNull(serializer, "serializer"); Guard.ArgumentNotNull(retryPolicy, "retryPolicy"); Guard.ArgumentNotNull(endpoint, "endpoint"); this.topic = topic; this.configurationFactory = configurationFactory; this.config = config; this.serializer = serializer; this.verifyRetryPolicy = verifyRetryPolicy; this.retryPolicy = retryPolicy; this.endpoint = endpoint; Configure(endpoint); }
internal static void SubscribeOrUnsubscribeType(Action<string> logInfo, Type type, IBusConfiguration config, Action<ServiceBusEnpointData> callback) { Guard.ArgumentNotNull(type, "type"); Guard.ArgumentNotNull(callback, "callback"); logInfo(string.Format("SubscribeOrUnsubscribeType={0}", type.FullName)); var interfaces = type.GetInterfaces() .Where(i => i.IsGenericType && (i.GetGenericTypeDefinition() == typeof(IHandleMessages<>) || i.GetGenericTypeDefinition() == typeof(IHandleCompetingMessages<>))) .ToList(); if (interfaces.Count == 0) { throw new ApplicationException(string.Format("Type {0} does not implement IHandleMessages or IHandleCompetingMessages", type.FullName)); } //for each interface we find, we need to register it with the bus. foreach (var foundInterface in interfaces) { var implementedMessageType = foundInterface.GetGenericArguments()[0]; //due to the limits of 50 chars we will take the name and a MD5 for the name. var hashName = implementedMessageType.FullName + "|" + type.FullName; var hash = MD5Helper.CalculateMD5(hashName); var fullName = (IsCompetingHandler(foundInterface) ? "C_" : config.ServiceBusApplicationId + "_") + hash; var info = new ServiceBusEnpointData() { AttributeData = type.GetCustomAttributes(typeof(MessageHandlerConfigurationAttribute), false).FirstOrDefault() as MessageHandlerConfigurationAttribute, DeclaredType = type, MessageType = implementedMessageType, SubscriptionName = fullName, ServiceType = foundInterface }; if (!config.Container.IsRegistered(type)) { if (info.IsReusable) { config.Container.Register(type, type); } else { config.Container.Register(type, type, true); } } callback(info); } config.Container.Build(); }
void Configure(ServiceBusEnpointData value) { SubscriptionDescription desc = null; bool createNew = false; try { logger.Info("CreateSubscription Try {0} ", value.SubscriptionNameDebug); // First, let's see if a item with the specified name already exists. verifyRetryPolicy.ExecuteAction(() => { desc = configurationFactory.NamespaceManager.GetSubscription(topic.Path, value.SubscriptionName); }); createNew = (desc == null); } catch (MessagingEntityNotFoundException) { logger.Info("CreateSubscription Does Not Exist {0} ", value.SubscriptionNameDebug); // Looks like the item does not exist. We should create a new one. createNew = true; } // If a item with the specified name doesn't exist, it will be auto-created. if (createNew) { var descriptionToCreate = new SubscriptionDescription(topic.Path, value.SubscriptionName); if (value.AttributeData != null) { var attr = value.AttributeData; if (attr.DefaultMessageTimeToLiveSet()) { descriptionToCreate.DefaultMessageTimeToLive = new TimeSpan(0, 0, attr.DefaultMessageTimeToLive); } descriptionToCreate.EnableBatchedOperations = attr.EnableBatchedOperations; descriptionToCreate.EnableDeadLetteringOnMessageExpiration = attr.EnableDeadLetteringOnMessageExpiration; if (attr.LockDurationSet()) { descriptionToCreate.LockDuration = new TimeSpan(0, 0, attr.LockDuration); } } try { logger.Info("CreateSubscription {0} ", value.SubscriptionNameDebug); var filter = new SqlFilter(string.Format(AzureSenderReceiverBase.TYPE_HEADER_NAME + " = '{0}'", value.MessageType.FullName.Replace('.', '_'))); retryPolicy.ExecuteAction(() => { desc = configurationFactory.NamespaceManager.CreateSubscription(descriptionToCreate, filter); }); } catch (MessagingEntityAlreadyExistsException) { logger.Info("CreateSubscription {0} ", value.SubscriptionNameDebug); // A item under the same name was already created by someone else, perhaps by another instance. Let's just use it. retryPolicy.ExecuteAction(() => { desc = configurationFactory.NamespaceManager.GetSubscription(topic.Path, value.SubscriptionName); }); } } ISubscriptionClient subscriptionClient = null; var rm = ReceiveMode.PeekLock; if (value.AttributeData != null) { rm = value.AttributeData.ReceiveMode; } retryPolicy.ExecuteAction(() => { subscriptionClient = configurationFactory.MessageFactory.CreateSubscriptionClient(topic.Path, value.SubscriptionName, rm); }); if (value.AttributeData != null && value.AttributeData.PrefetchCountSet()) { subscriptionClient.PrefetchCount = value.AttributeData.PrefetchCount; } if (data == null) { data = new AzureBusReceiverState() { EndPointData = value, Client = subscriptionClient }; } else { //we need to clean up the deleted subscription var oldClient = this.data.Client; data.Client = subscriptionClient; //now lets dispose the client. ExtensionMethods.ExecuteAndReturn(() => { if (oldClient != null) { oldClient.Close(); } }); } }
void Configure(ServiceBusEnpointData value) { SubscriptionDescription desc = null; bool createNew = false; try { logger.Info("CreateSubscription Try {0} ", value.SubscriptionNameDebug); // First, let's see if a item with the specified name already exists. verifyRetryPolicy.ExecuteAction(() => { desc = configurationFactory.NamespaceManager.GetSubscription(topic.Path, value.SubscriptionName); }); createNew = (desc == null); } catch (MessagingEntityNotFoundException) { logger.Info("CreateSubscription Does Not Exist {0} ", value.SubscriptionNameDebug); // Looks like the item does not exist. We should create a new one. createNew = true; } // If a item with the specified name doesn't exist, it will be auto-created. if (createNew) { var descriptionToCreate = new SubscriptionDescription(topic.Path, value.SubscriptionName); if (value.AttributeData != null) { var attr = value.AttributeData; if (attr.DefaultMessageTimeToLiveSet()) { descriptionToCreate.DefaultMessageTimeToLive = new TimeSpan(0, 0, attr.DefaultMessageTimeToLive); } descriptionToCreate.EnableBatchedOperations = attr.EnableBatchedOperations; descriptionToCreate.EnableDeadLetteringOnMessageExpiration = attr.EnableDeadLetteringOnMessageExpiration; if (attr.LockDurationSet()) { descriptionToCreate.LockDuration = new TimeSpan(0, 0, attr.LockDuration); } } try { logger.Info("CreateSubscription {0} ", value.SubscriptionNameDebug); var filter = new SqlFilter(string.Format(AzureSenderReceiverBase.TYPE_HEADER_NAME + " = '{0}'", value.MessageType.FullName.Replace('.', '_'))); retryPolicy.ExecuteAction(() => { desc = configurationFactory.NamespaceManager.CreateSubscription(descriptionToCreate, filter); }); } catch (MessagingEntityAlreadyExistsException) { logger.Info("CreateSubscription {0} ", value.SubscriptionNameDebug); // A item under the same name was already created by someone else, perhaps by another instance. Let's just use it. retryPolicy.ExecuteAction(() => { desc = configurationFactory.NamespaceManager.GetSubscription(topic.Path, value.SubscriptionName); }); } } ISubscriptionClient subscriptionClient = null; var rm = ReceiveMode.PeekLock; if (value.AttributeData != null) { rm = value.AttributeData.ReceiveMode; } retryPolicy.ExecuteAction(() => { subscriptionClient = configurationFactory.MessageFactory.CreateSubscriptionClient(topic.Path, value.SubscriptionName, rm); }); if (value.AttributeData != null && value.AttributeData.PrefetchCountSet()) { subscriptionClient.PrefetchCount = value.AttributeData.PrefetchCount; } if (data == null) { data = new AzureBusReceiverState() { EndPointData = value, Client = subscriptionClient }; } else { //we need to clean up the deleted subscription var oldClient = data.Client; data.Client = subscriptionClient; //now lets dispose the client. ExtensionMethods.ExecuteAndReturn(() => { if (oldClient != null) { if (!oldClient.IsClosed) { oldClient.Close(); } } }); } }