public WindowsUpdateServiceCoordinator(IConfigStore configStore, string configSection, KeyValueStoreReplica kvsReplica, IStatefulServicePartition partition, IExceptionHandlingPolicy exceptionPolicy)
        {
            configStore.ThrowIfNull("configStore");
            configSection.ThrowIfNullOrWhiteSpace("configSectionName");
            kvsReplica.ThrowIfNull("kvsReplica");
            partition.ThrowIfNull("partition");
            exceptionPolicy.ThrowIfNull("exceptionPolicy");

            this.commandProcessor  = new FabricClientWrapper();
            this.store             = kvsReplica;
            this.partition         = partition;
            this.packageRetriever  = new UpdatePackageRetriever();
            this.serviceName       = new Uri(Constants.SystemServicePrefix + configSection);
            this.configStore       = configStore;
            this.configSectionName = configSection;
            this.exceptionPolicy   = exceptionPolicy;

            // Read all the configuration values
            string coordinatorType = configStore.ReadUnencryptedString(configSection, Constants.ConfigurationSection.CoordinatorType);

            this.testMode   = false;
            this.testSrcDir = string.Empty;
            if (coordinatorType.Equals(Constants.ConfigurationSection.WUTestCoordinator))
            {
                this.testSrcDir = configStore.ReadUnencryptedString(configSection, Constants.WUSCoordinator.TestCabFolderParam);
                this.testMode   = true;
            }

            this.waitTimeBeforePolling   = TimeSpan.FromMinutes(Constants.WUSCoordinator.PollingIntervalInMinutesDefault);
            this.windowsUpdateApiTimeout = TimeSpan.FromMinutes(Constants.WUSCoordinator.WuApiTimeoutInMinutesDefault);
        }
예제 #2
0
        private void Initialize(
            IConfigStore configStore,
            string configSectionName,
            KeyValueStoreReplica kvsStore,
            IStatefulServicePartition partition)
        {
            var baseUrlStr       = configStore.ReadUnencryptedString(configSectionName, Constants.ConfigurationSection.BaseUrl);
            var clusterId        = configStore.ReadUnencryptedString(Constants.ConfigurationSection.PaasSectionName, Constants.ConfigurationSection.ClusterId);
            var primaryNodeTypes = GetPrimaryNodeTypes(configStore, configSectionName);

            // Error checking
            baseUrlStr.ThrowIfNullOrWhiteSpace("baseUrlStr");
            clusterId.ThrowIfNullOrWhiteSpace("clusterId");
            Uri baseUrl;

            if (!Uri.TryCreate(baseUrlStr, UriKind.Absolute, out baseUrl))
            {
                throw new ArgumentException("BaseUrl in clusterManifest is not of Uri type");
            }

            Trace.WriteNoise(TraceType, "BaseUrl: {0}", baseUrl);

            var wrpStreamChannelUrlStr = Path.Combine(baseUrlStr, clusterId);
            Uri wrpStreamChannelUri;

            if (!Uri.TryCreate(wrpStreamChannelUrlStr, UriKind.Absolute, out wrpStreamChannelUri))
            {
                throw new ArgumentException($"StreamChannel URL is not of Uri type: {wrpStreamChannelUrlStr}");
            }

            Trace.WriteInfo(TraceType, "StreamChannel URL: {0}", wrpStreamChannelUrlStr);

            var wrpPollUrlStr = $"{wrpStreamChannelUrlStr}?api-version={ApiVersion}";
            Uri wrpPollUri;

            if (!Uri.TryCreate(wrpPollUrlStr, UriKind.Absolute, out wrpPollUri))
            {
                throw new ArgumentException($"Poll URL is not of Uri type: {wrpPollUrlStr}");
            }
            Trace.WriteInfo(TraceType, "Poll URL: {0}", wrpPollUrlStr);

            var fabricClientWrapper = new FabricClientWrapper();

            var resourceCommandProcessors = new Dictionary <ResourceType, IResourceCommandProcessor>()
            {
                {
                    ResourceType.Cluster,
                    new ClusterCommandProcessor(
                        configStore,
                        configSectionName,
                        fabricClientWrapper,
                        new CommandParameterGenerator(fabricClientWrapper),
                        new NodeStatusManager(kvsStore, configStore, configSectionName),
                        JsonSerializer.Create(WrpGatewayClient.SerializerSettings),
                        primaryNodeTypes)
                },
                {
                    ResourceType.ApplicationType,
                    new ApplicationTypeCommandProcessor(
                        new ApplicationTypeClient(fabricClientWrapper.FabricClient, configStore, configSectionName))
                },
                {
                    ResourceType.Application,
                    new ApplicationCommandProcessor(
                        new ApplicationClient(fabricClientWrapper.FabricClient))
                },
                {
                    ResourceType.Service,
                    new ServiceCommandProcessor(
                        new ServiceClient(fabricClientWrapper.FabricClient))
                }
            };

            this.coordinators = new List <IUpgradeCoordinator>
            {
                new ResourceCoordinator(
                    kvsStore,
                    configStore,
                    configSectionName,
                    resourceCommandProcessors,
                    new WrpPackageRetriever(wrpPollUri, clusterId, configStore, configSectionName),
                    new ExceptionHandlingPolicy(Constants.PaasCoordinator.SFRPPollHealthProperty, ResourceCoordinator.TaskName, configStore, configSectionName, partition)),

                new StreamChannelCoordinator(
                    new WrpStreamChannel(wrpStreamChannelUri, clusterId, configStore, configSectionName),
                    new ExceptionHandlingPolicy(Constants.PaasCoordinator.SFRPStreamChannelHealthProperty, StreamChannelCoordinator.TaskName, configStore, configSectionName, partition))
            };
        }
        private async Task UpgradeClusterAsync(ClusterUpgradeCommandParameter upgradeCommandParameter, CancellationToken token)
        {
            if (upgradeCommandParameter == null)
            {
                Trace.WriteInfo(TraceType, "upgradeCommandParameter is null. No op.");
                return;
            }

            if (string.IsNullOrWhiteSpace(upgradeCommandParameter.ConfigFilePath) &&
                string.IsNullOrWhiteSpace(upgradeCommandParameter.CodeFilePath))
            {
                Trace.WriteInfo(TraceType, "upgradeCommandParameter .ConfigFilePath=null and .CodeFilePath=null. No op.");
                return;
            }

            Trace.WriteInfo(TraceType,
                            "Upgrade command parameters: CodePath: {0}, CodeVersion: {1}, ConfigPath: {2}, ConfigVersion: {3}",
                            upgradeCommandParameter.CodeFilePath, upgradeCommandParameter.CodeVersion,
                            upgradeCommandParameter.ConfigFilePath, upgradeCommandParameter.ConfigVersion);

            // Determine targetCodeVersion & targetConfigVersion
            var targetCodeVersion   = upgradeCommandParameter.CodeVersion;
            var targetConfigVersion = upgradeCommandParameter.ConfigVersion;

            if (!string.IsNullOrWhiteSpace(upgradeCommandParameter.ConfigFilePath) &&
                string.IsNullOrWhiteSpace(targetConfigVersion))
            {
                // If config version is not mentioned then read it from given manifest file
                targetConfigVersion = FabricClientWrapper.GetConfigVersion(upgradeCommandParameter.ConfigFilePath);
            }

            // Get root image store path
            var imageStorePath = GetImageStorePath(targetCodeVersion, targetConfigVersion);

            // Build cluster package file paths in image store
            var configFileName         = string.Empty;
            var codeFileName           = string.Empty;
            var configPathInImageStore = string.Empty;
            var codePathInImageStore   = string.Empty;

            if (!string.IsNullOrWhiteSpace(upgradeCommandParameter.ConfigFilePath))
            {
                configFileName         = Path.GetFileName(upgradeCommandParameter.ConfigFilePath);
                configPathInImageStore = Path.Combine(imageStorePath, configFileName);
            }

            if (!string.IsNullOrWhiteSpace(upgradeCommandParameter.CodeFilePath))
            {
                codeFileName         = Path.GetFileName(upgradeCommandParameter.CodeFilePath);
                codePathInImageStore = Path.Combine(imageStorePath, codeFileName);
            }

            // Determine cluster package content that needs to be published.
            var configFilePath = upgradeCommandParameter.ConfigFilePath;
            var codeFilePath   = upgradeCommandParameter.CodeFilePath;

            if (!string.IsNullOrWhiteSpace(targetCodeVersion))
            {
                var provisionedCodeList = await this.fabricClientWrapper.GetProvisionedFabricCodeVersionListAsync(targetCodeVersion, Constants.MaxOperationTimeout, token);

                if (provisionedCodeList.Count != 0)
                {
                    Trace.WriteInfo(TraceType, "Code Already provisioned: {0}", targetCodeVersion);
                    codePathInImageStore = null;
                    codeFilePath         = null;
                }
            }

            if (!string.IsNullOrWhiteSpace(targetConfigVersion))
            {
                var provisionedConfigList = await this.fabricClientWrapper.GetProvisionedFabricConfigVersionListAsync(targetConfigVersion, Constants.MaxOperationTimeout, token);

                if (provisionedConfigList.Count != 0)
                {
                    Trace.WriteInfo(TraceType, "Config Already provisioned: {0}", targetConfigVersion);
                    configPathInImageStore = null;
                    configFilePath         = null;
                }
            }

            if (string.IsNullOrWhiteSpace(configPathInImageStore) &&
                string.IsNullOrWhiteSpace(codePathInImageStore))
            {
                Trace.WriteInfo(TraceType, "Both code={0} and config={1} are already provisioned. No op.", targetCodeVersion, targetConfigVersion);
            }
            else
            {
                Trace.WriteInfo(
                    TraceType,
                    "UpgradeClusterAsync: CodePath {0}, CodeVersion {1}, ConfigPath {2}, ConfigVersion {3}",
                    codeFilePath ?? "null",
                    targetCodeVersion ?? "null",
                    configFilePath ?? "null",
                    targetConfigVersion ?? "null");

                var imageStoreConnectionString = this.configStore.ReadUnencryptedString(Constants.ManagementSection.ManagementSectionName, Constants.ManagementSection.ImageStoreConnectionString);

                var copyTimeout = this.configStore.ReadTimeSpan(this.configSectionName, Constants.ConfigurationSection.CopyClusterPackageTimeoutInSeconds, TimeSpan.FromSeconds(180));

                Trace.WriteInfo(
                    TraceType,
                    "UpgradeClusterAsync: CopyClusterPackageAsync: Config:{0}->{1} Code:{2}->{3} Timeout:{4}",
                    configFilePath ?? "null",
                    configPathInImageStore ?? "null",
                    codeFilePath ?? "null",
                    codePathInImageStore ?? "null",
                    copyTimeout);

                await this.fabricClientWrapper.CopyClusterPackageAsync(
                    imageStoreConnectionString,
                    configFilePath,
                    configPathInImageStore,
                    codeFilePath,
                    codePathInImageStore,
                    copyTimeout,
                    token);

                Trace.WriteInfo(
                    TraceType,
                    "UpgradeClusterAsync: CopyClusterPackageAsync - Completed");

                var provisionTimeout = this.configStore.ReadTimeSpan(this.configSectionName, Constants.ConfigurationSection.ProvisionClusterPackageTimeoutInSeconds, TimeSpan.FromSeconds(300));

                Trace.WriteInfo(
                    TraceType,
                    "UpgradeClusterAsync: ProvisionFabricAsync: Config:{0} Code:{1} Timeout:{2}",
                    configPathInImageStore ?? "null",
                    codePathInImageStore ?? "null",
                    provisionTimeout);

                try
                {
                    await this.fabricClientWrapper.ProvisionFabricAsync(
                        codePathInImageStore,
                        configPathInImageStore,
                        provisionTimeout,
                        token);

                    Trace.WriteInfo(
                        TraceType,
                        "UpgradeClusterAsync: ProvisionFabricAsync - Completed");
                }
                finally
                {
                    try
                    {
                        Trace.WriteInfo(
                            TraceType,
                            "UpgradeClusterAsync: RemoveClusterPackageAsync: Config:{0} Code:{1} Timeout:{2}",
                            configPathInImageStore ?? "null",
                            codePathInImageStore ?? "null",
                            copyTimeout);

                        await this.fabricClientWrapper.RemoveClusterPackageAsync(
                            imageStoreConnectionString,
                            codePathInImageStore,
                            configPathInImageStore,
                            copyTimeout,
                            token);

                        Trace.WriteInfo(
                            TraceType,
                            "UpgradeClusterAsync: RemoveClusterPackageAsync: Config:{0} Code:{1} - Completed",
                            configPathInImageStore ?? "null",
                            codePathInImageStore ?? "null");
                    }
                    catch (Exception ex)
                    {
                        Trace.WriteWarning(
                            TraceType,
                            "UpgradeClusterAsync: RemoveClusterPackageAsync: Config:{0} Code:{1}. Failed with exception: {2}",
                            configPathInImageStore ?? "null",
                            codePathInImageStore ?? "null",
                            ex);
                    }
                }
            }

            var startUpgradeTimeout = this.configStore.ReadTimeSpan(this.configSectionName, Constants.ConfigurationSection.StartClusterUpgradeTimeoutInSeconds, TimeSpan.FromSeconds(180));

            Trace.WriteInfo(
                TraceType,
                "UpgradeClusterAsync: CodeVersion:{0} ConfigVersion:{1} Timeout:{2}",
                targetCodeVersion ?? "null",
                targetConfigVersion ?? "null",
                startUpgradeTimeout);

            await this.fabricClientWrapper.UpgradeFabricAsync(upgradeCommandParameter.UpgradeDescription, targetCodeVersion, targetConfigVersion, startUpgradeTimeout, token);

            Trace.WriteInfo(
                TraceType,
                "UpgradeClusterAsync: CodeVersion:{0} ConfigVersion:{1} - Started",
                targetCodeVersion ?? "null",
                targetConfigVersion ?? "null");
        }