コード例 #1
0
        public async Task ReceiveReminderAsync(string reminderName, byte[] context, TimeSpan dueTime, TimeSpan period)
        {
            if (reminderName.Equals(CheckProvision))
            {
                ServiceFabricEventSource.Current.ActorMessage(this, "Checking Provision");
                var        clusterKey = this.Id.GetStringId();//Subscription/ResourceGroup/clustername/nodename;
                ActorState State      = await StateManager.GetStateAsync <ActorState>(StateKey);

                var processorNode = await ClusterConfigStore.GetMessageClusterResourceAsync(clusterKey) as ClusterProcessorNode;


                if (!State.IsInitialized)
                {
                    if (processorNode != null)
                    {
                        var nodeName = processorNode.Name;



                        var config = this.GetConfigurationInfo();

                        var armClinet = new ArmClient(await config.GetAccessToken());

                        var vmss = await armClinet.GetAsync <VMSS>($"/subscriptions/{config.SubscriptionId}/resourceGroups/{config.ResourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/vm{nodeName.ToLower()}", "2016-03-30");

                        var fabric = await armClinet.GetAsync <JObject>($"/subscriptions/{config.SubscriptionId}/resourceGroups/{config.ResourceGroupName}/providers/Microsoft.ServiceFabric/clusters/{config.ClusterName}", "2016-03-01");

                        var primvmss = await armClinet.GetAsync <JObject>($"/subscriptions/{config.SubscriptionId}/resourceGroups/{config.ResourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{config.PrimaryScaleSetName}", "2016-03-30");

                        var parameters = new JObject(
                            ResourceManagerHelper.CreateValue("clusterName",
                                                              config.ClusterName),
                            ResourceManagerHelper.CreateValue("clusterLocation",
                                                              "West Europe"),
                            ResourceManagerHelper.CreateValue("nodeTypeName", nodeName),
                            ResourceManagerHelper.CreateValue("certificateThumbprint", fabric.SelectToken("properties.certificate.thumbprint").ToString()),
                            ResourceManagerHelper.CreateValue("adminPassword", "JgT5FFJK"),
                            ResourceManagerHelper.CreateValue("sourceVaultValue", primvmss.SelectToken("properties.virtualMachineProfile.osProfile.secrets[0].sourceVault.id").ToString()),
                            ResourceManagerHelper.CreateValue("certificateUrlValue", primvmss.SelectToken("properties.virtualMachineProfile.osProfile.secrets[0].vaultCertificates[0].certificateUrl").ToString())
                            );

                        var deployment = await ResourceManagerHelper.CreateTemplateDeploymentAsync(
                            new ApplicationCredentials
                        {
                            AccessToken    = await config.GetAccessToken(),
                            SubscriptionId = config.SubscriptionId,
                        },
                            config.ResourceGroupName,
                            $"vmss-{nodeName}",                     //-{DateTimeOffset.UtcNow.ToString("s").Replace(":", "-")}",
                            new VmssArmTemplate(processorNode.Properties, vmss?.Sku?.capacity ?? 0),
                            parameters,
                            false, appendTimestamp : true
                            );

                        if (deployment.Properties.ProvisioningState == "Succeeded")
                        {
                            State.IsInitialized  = true;
                            State.VMSSResourceId = (deployment.Properties.Outputs as JObject).SelectToken("vmssResourceId.value").ToString();
                            ServiceFabricEventSource.Current.ActorMessage(this, "Initialization Complated");
                        }
                    }
                }

                if (State.IsInitialized)
                {
                    ServiceFabricEventSource.Current.ActorMessage(this, "Validating node configuration with vmss");

                    var client = new ArmClient(await this.GetConfigurationInfo().GetAccessToken());
                    var vmms   = await client.GetAsync <JObject>(State.VMSSResourceId, "2016-03-30");

                    State.Capacity = vmms.SelectToken("sku.capacity").ToObject <int>();

                    var virtualMachines = await client.GetAsync <JObject>(State.VMSSResourceId + "/virtualMachines", "2016-03-30");

                    var deleting = virtualMachines.SelectTokens("$value[?(@.properties.provisioningState == 'Deleting')]");

                    var fabric = new FabricClient();

                    //Remove all nodes that are i teh deleting state of VMSS;
                    foreach (JObject delete in deleting)
                    {
                        var instanceId = delete.SelectToken("instanceId").ToString();
                        var name       = delete.SelectToken("name").ToString();
                        var node       = await fabric.QueryManager.GetNodeListAsync("_" + name);

                        if (node.Any())
                        {
                            ServiceFabricEventSource.Current.ActorMessage(this, $"Removing {node.First().NodeName} state due to vm being deleted");
                            await fabric.ClusterManager.RemoveNodeStateAsync(node.First().NodeName);
                        }
                    }

                    //Remove all nodes that are down and not in the virtualmachine list.

                    var nodes = await fabric.QueryManager.GetNodeListAsync();

                    foreach (var node in nodes.Where(n => n.NodeStatus == System.Fabric.Query.NodeStatus.Down &&
                                                     n.NodeName.StartsWith($"_vm{NodeTypeName}")))
                    {
                        if (!virtualMachines.SelectTokens($"$value[?(@.instanceId == '{node.NodeName.Split('_').Last()}')]").Any())
                        {
                            ServiceFabricEventSource.Current.ActorMessage(this, $"Removing {node.NodeName} state due to vm not existing");
                            await fabric.ClusterManager.RemoveNodeStateAsync(node.NodeName);
                        }
                    }

                    if (vmms.SelectToken("properties.provisioningState").ToString() == "Succeeded")
                    {
                        State.IsProvisioning = false;
                        await UnregisterReminderAsync(GetReminder(reminderName));
                    }
                }

                await StateManager.SetStateAsync(StateKey, State);
            }
        }