public MessageProcessor(IMessageValidator validator, IMessageMapper mapper, IIdDeDuplicator idDeDuplicator, MessageProcessorOptions options) { this.mapper = mapper; this.idDeDuplicator = idDeDuplicator; this.options = options; this.validator = validator; }
public MessageProcessorHostedService(ILogger <MessageProcessorHostedService> logger, MessageProcessorOptions options, IServiceProvider services) { _logger = logger; _options = options; _services = services; }
public async Task ReceiveReminderAsync(string reminderName, byte[] context, TimeSpan dueTime, TimeSpan period) { if (reminderName.Equals(CheckProvision)) { ActorState State = await StateManager.GetStateAsync <ActorState>(StateKey); try { var nodeKey = this.Id.GetStringId();//Subscription/ResourceGroup/clustername/nodename; var queue = await ClusterConfigStore.GetMessageClusterResourceAsync(nodeKey) as ClusterQueueInfo; if (!State.IsInitialized) { var client = new ArmClient(await this.GetConfigurationInfo().GetAccessToken()); if (State.Keys == null || !State.Keys.IsAccessible) { var authRuleResourceId = queue.Properties.ServiceBus.AuthRuleResourceId; State.Keys = await client.ListKeysAsync <ServicebusAuthorizationKeys>(authRuleResourceId, "2015-08-01"); State.Path = queue.Name; } if (!State.Keys.IsAccessible) { Logger.Error("Servicebus keys are not accessible"); return; } // queue.Properties.ServiceBus.ServicebusNamespaceId var ns = NamespaceManager.CreateFromConnectionString(State.Keys.PrimaryConnectionString); if (!await ns.QueueExistsAsync(queue.Name)) { var qd = queue.Properties.QueueDescription; if (qd == null) { Logger.Warn("Servicebus queue do not exist"); return; } var q = new QueueDescription(queue.Name); if (qd.AutoDeleteOnIdle.IsPresent()) { q.AutoDeleteOnIdle = XmlConvert.ToTimeSpan(qd.AutoDeleteOnIdle); } if (qd.DefaultMessageTimeToLive.IsPresent()) { q.DefaultMessageTimeToLive = XmlConvert.ToTimeSpan(qd.DefaultMessageTimeToLive); } if (qd.DuplicateDetectionHistoryTimeWindow.IsPresent()) { q.RequiresDuplicateDetection = true; q.DuplicateDetectionHistoryTimeWindow = XmlConvert.ToTimeSpan(qd.DuplicateDetectionHistoryTimeWindow); } q.EnableBatchedOperations = qd.EnableBatchedOperations; q.EnableDeadLetteringOnMessageExpiration = qd.EnableDeadLetteringOnMessageExpiration; q.EnableExpress = qd.EnableExpress; q.EnablePartitioning = qd.EnablePartitioning; if (qd.ForwardDeadLetteredMessagesTo.IsPresent()) { q.ForwardDeadLetteredMessagesTo = qd.ForwardDeadLetteredMessagesTo; } if (qd.ForwardTo.IsPresent()) { q.ForwardTo = qd.ForwardTo; } await ns.CreateQueueAsync(q); } State.IsInitialized = true; } if (State.IsInitialized) { var ns = NamespaceManager.CreateFromConnectionString(State.Keys.PrimaryConnectionString); var config = this.GetConfigurationInfo(); var sbQueue = await ns.GetQueueAsync(queue.Name); Logger.Info($"Checking Queue information for {sbQueue.Path}, {sbQueue.MessageCount}, {sbQueue.MessageCountDetails.ActiveMessageCount}, {sbQueue.MessageCountDetails.DeadLetterMessageCount}, {sbQueue.MessageCountDetails.ScheduledMessageCount}, {sbQueue.MessageCountDetails.TransferDeadLetterMessageCount}, {sbQueue.MessageCountDetails.TransferMessageCount}"); var parts = nodeKey.Split('/'); var applicationName = new Uri($"fabric:/{parts[parts.Length - 2]}"); var serviceName = new Uri($"fabric:/{parts[parts.Length - 2]}/{parts[parts.Length-1]}"); var vmssManager = ActorProxy.Create <IVmssManagerActor>(new ActorId(string.Join("/", parts.Take(parts.Length - 1)) + "/" + queue.Properties.ListenerDescription.ProcessorNode)); var fabricClient = GetFabricClient(); var primNodes = 0; if (queue.Properties.ListenerDescription.UsePrimaryNode) { var nodes = await fabricClient.QueryManager.GetNodeListAsync(); primNodes = nodes.Aggregate(0, (c, p) => c + (p.NodeType == config.PrimaryScaleSetName ? 1 : 0)); } await vmssManager.ReportQueueMessageCountAsync(Id.GetStringId(), sbQueue.MessageCountDetails.ActiveMessageCount, primNodes); if (sbQueue.MessageCountDetails.ActiveMessageCount > 0 || queue.Properties.ListenerDescription.AlwaysOn) { //Handle Listener Application Deployment var listenerDescription = queue.Properties.ListenerDescription; var apps = await fabricClient.QueryManager.GetApplicationListAsync(applicationName); if (!apps.Any()) { var appTypes = await fabricClient.QueryManager.GetApplicationTypeListAsync(listenerDescription.ApplicationTypeName); if (!appTypes.Any(a => a.ApplicationTypeVersion == listenerDescription.ApplicationTypeVersion)) { Logger.Error("The listener application was not registed with service fabric"); return; } await fabricClient.ApplicationManager.CreateApplicationAsync(new ApplicationDescription { ApplicationName = applicationName, ApplicationTypeName = listenerDescription.ApplicationTypeName, ApplicationTypeVersion = listenerDescription.ApplicationTypeVersion, }); } var registered = await fabricClient.QueryManager.GetServiceListAsync(applicationName, serviceName); if (!registered.Any()) { var serviceType = await fabricClient.QueryManager.GetServiceTypeListAsync(listenerDescription.ApplicationTypeName, listenerDescription.ApplicationTypeVersion, listenerDescription.ServiceTypeName); if (!serviceType.Any()) { Logger.Error("The listener application service type was not registed with service fabric"); return; } try { var listenerConfiguration = new MessageProcessorOptions { ConnectionString = State.Keys.PrimaryConnectionString, QueuePath = sbQueue.Path, }; var placementConstraints = $"NodeTypeName == {queue.Properties.ListenerDescription.ProcessorNode}"; if (queue.Properties.ListenerDescription.UsePrimaryNode) { placementConstraints += " || isPrimary == true"; } await fabricClient.ServiceManager.CreateServiceAsync(new StatelessServiceDescription { ServiceTypeName = listenerDescription.ServiceTypeName, //QueueListenerService.ServiceType, // ServiceFabricConstants.ActorServiceTypes.QueueListenerActorService, ServiceName = serviceName, PartitionSchemeDescription = new UniformInt64RangePartitionSchemeDescription { PartitionCount = queue.Properties.ListenerDescription.PartitionCount, LowKey = Int64.MinValue, HighKey = Int64.MaxValue }, InstanceCount = -1, //One for each node, PlacementConstraints = placementConstraints, // $"NodeTypeName == {queue.Properties.ListenerDescription.ProcessorNode}", ApplicationName = applicationName, InitializationData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(listenerConfiguration)), }); } catch (Exception ex) { Logger.ErrorException("Could not register service for queue", ex); throw; } } } else { if ((DateTimeOffset.UtcNow - (XmlConvert.ToTimeSpan(queue.Properties.ListenerDescription.IdleTimeout))) > sbQueue.AccessedAt) { // await vmssManager.SetCapacityAsync(0); var registered = await fabricClient.QueryManager.GetServiceListAsync(applicationName, serviceName); if (registered.Any()) { await fabricClient.ServiceManager.DeleteServiceAsync(new DeleteServiceDescription(serviceName) { }); } } } } } catch (Exception ex) { Logger.ErrorException("Reminder Error:", ex); throw; } finally { await StateManager.SetStateAsync(StateKey, State); } } }