예제 #1
0
        public async Task ReceiveReminderAsync(string reminderName, byte[] context, TimeSpan dueTime, TimeSpan period)
        {
            if (reminderName.Equals(MonitoringReminderName))
            {
                try
                {
                    var nodeKey = this.Id.GetStringId();//Subscription/ResourceGroup/clustername/nodename;
                    var topic   = await ClusterConfigStore.GetMessageClusterResourceAsync(nodeKey) as TopicInfo;

                    if (!await IsInitializedAsync())
                    {
                        var client = new ArmClient(await this.GetConfigurationInfo().GetAccessToken());

                        var keysState = await StateManager.TryGetStateAsync <ServicebusAuthorizationKeys>("keys");

                        ServicebusAuthorizationKeys keys;

                        if (!keysState.HasValue || !keysState.Value.IsAccessible)
                        {
                            var authRuleResourceId = topic.Properties.ServiceBus.AuthRuleResourceId;

                            keys = await client.ListKeysAsync <ServicebusAuthorizationKeys>(authRuleResourceId, "2015-08-01");

                            await StateManager.SetStateAsync("keys", keys);
                        }
                        else
                        {
                            keys = keysState.Value;
                        }

                        if (!keys.IsAccessible)
                        {
                            Logger.Error("Servicebus keys  are not accessible");
                            return;
                        }


                        var ns = NamespaceManager.CreateFromConnectionString(keys.PrimaryConnectionString);

                        for (int i = 0, ii = topic.Properties.TopicScaleCount; i < ii; ++i)
                        {
                            var topicPath = topic.Name + i.ToString("D3");
                            if (!await ns.TopicExistsAsync(topicPath))
                            {
                                await ns.CreateTopicAsync(topicPath);
                            }
                        }

                        await StateManager.SetStateAsync("IsInitialized", true);
                        await UnregisterReminderAsync(GetReminder(reminderName));
                    }
                }
                catch (Exception ex)
                {
                    Logger.ErrorException("Reminder Error:", ex);
                    throw;
                }
            }
        }
        public async Task <CloudStorageAccount> GetApplicationStorageAccountAsync()
        {
            var client = new ArmClient(await AzureAD.GetAccessToken());
            var keys   = await client.ListKeysAsync <JObject>(StorageAccountId, "2016-01-01");

            var account = new CloudStorageAccount(new StorageCredentials(StorageAccountId.Substring(StorageAccountId.LastIndexOf("/") + 1), keys.SelectToken("keys[0].value").ToString()), true);

            return(account);
        }
        private static CloudStorageAccount ApplicationCloudStorageAccountFactory(IUnityContainer arg)
        {
            var configuration = arg.Resolve <ServiceFabricClusterConfiguration>();

            var client = new ArmClient(configuration.GetAccessToken().GetAwaiter().GetResult());
            var keys   = client.ListKeysAsync <JObject>($"/subscriptions/{configuration.SubscriptionId}/resourceGroups/{configuration.ResourceGroupName}/providers/Microsoft.Storage/storageAccounts/{configuration.StorageName}", "2016-01-01").GetAwaiter().GetResult();

            var account = new CloudStorageAccount(new StorageCredentials(configuration.StorageName, keys.SelectToken("keys[0].value").ToString()), true);

            account.CreateCloudBlobClient().GetContainerReference("clusters").CreateIfNotExists();
            return(account);
        }
예제 #4
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);
                }
            }
        }
        public async Task ReceiveReminderAsync(string reminderName, byte[] context, TimeSpan dueTime, TimeSpan period)
        {
            if (reminderName.Equals(CheckProvision))
            {
                var disPatcherId = this.Id.GetStringId();//Subscription/ResourceGroup/clustername/nodename;
                var dispatcher   = await ClusterConfigStore.GetMessageClusterResourceAsync(disPatcherId) as ClusterDispatcherInfo;

                ActorState State = await StateManager.GetStateAsync <ActorState>(StateKey);

                if (State.Keys == null || !State.Keys.IsAccessible)
                {
                    var authRuleResourceId = dispatcher.Properties.ServiceBus.AuthRuleResourceId;
                    var client             = new ArmClient(await this.GetConfigurationInfo().GetAccessToken());
                    State.Keys = await client.ListKeysAsync <ServicebusAuthorizationKeys>(authRuleResourceId, "2015-08-01");
                }

                if (!State.Keys.IsAccessible)
                {
                    Logger.Warn("Servicebus keys  are not accessible");
                    return;
                }

                Logger.Debug($"Setting up {dispatcher.Name}");
                var ns      = NamespaceManager.CreateFromConnectionString(State.Keys.PrimaryConnectionString);
                var filters = dispatcher.Properties.CorrelationFilters;
                for (int i = 0, ii = dispatcher.Properties.TopicScaleCount; i < ii; ++i)
                {
                    var topicPath = dispatcher.Name + i.ToString("D3");
                    if (!await ns.TopicExistsAsync(topicPath))
                    {
                        await ns.CreateTopicAsync(topicPath);
                    }

                    foreach (var correlationFilter in filters.Keys)
                    {
                        var queueId    = disPatcherId.Split('/'); queueId[queueId.Length - 1] = filters[correlationFilter];
                        var queueActor = ActorProxy.Create <IQueueManagerActor>(new ActorId(string.Join("/", queueId)));

                        var forwardPath = await queueActor.GetPathAsync();

                        var name = dispatcher.Name + "2" + forwardPath;

                        if (!await ns.SubscriptionExistsAsync(topicPath, name))
                        {
                            Logger.DebugFormat($"Creating Subscription for {name}");
                            await ns.CreateSubscriptionAsync(
                                new SubscriptionDescription(topicPath, name)
                            {
                                ForwardTo = forwardPath,
                            }, new CorrelationFilter(correlationFilter));
                        }
                        else
                        {
                            Logger.DebugFormat($"Subscription '{name}' already created");
                        }
                    }
                }

                State.IsInitialized = true;
                await StateManager.SetStateAsync(StateKey, State);
                await UnregisterReminderAsync(GetReminder(reminderName));
            }
        }