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;
 }
Exemplo n.º 3
0
        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);
                }
            }
        }