public async Task <string> ProcessSetUpgradeOrchestrationServiceStateAsync(string inputBlob, TimeSpan timeout, CancellationToken cancellationToken) { UpgradeOrchestrationTrace.TraceSource.WriteInfo(TraceType, "Entering ProcessSetUpgradeOrchestrationServiceStateAsync."); try { // data validation StandAloneCluster cluster = null; if (!string.IsNullOrWhiteSpace(inputBlob)) { JsonSerializerSettings settings = StandaloneUtility.GetStandAloneClusterDeserializerSettings(); cluster = JsonConvert.DeserializeObject <StandAloneCluster>( inputBlob, settings); } await this.storeManager.SetStorageObjectAsync(Constants.ClusterReliableDictionaryKey, inputBlob, this.cancellationToken).ConfigureAwait(false); FabricUpgradeOrchestrationServiceState result = UpgradeOrchestrationMessageProcessor.ConstructServiceStateFromCluster(cluster); return(JsonConvert.SerializeObject( result, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Serialize, NullValueHandling = NullValueHandling.Ignore, })); } catch (Exception e) { UpgradeOrchestrationTrace.TraceSource.WriteWarning(TraceType, "ProcessSetUpgradeOrchestrationServiceStateAsync exception: {0}", e); throw UpgradeOrchestrationMessageProcessor.ConvertToComException(e); } }
public async Task <string> CallSystemService(string action, string inputBlob, TimeSpan timeout, CancellationToken cancellationToken) { string outputBlob = null; try { UpgradeOrchestrationTrace.TraceSource.WriteInfo(TraceType, "Enter CallSystemService for {0}.", action); if (this.actionMapping.ContainsKey(action)) { outputBlob = await this.actionMapping[action](inputBlob, timeout, cancellationToken).ConfigureAwait(false); } else { throw UpgradeOrchestrationMessageProcessor.ConvertToComException(new NotImplementedException(action + "is not implemented")); } } catch (Exception e) { UpgradeOrchestrationTrace.TraceSource.WriteWarning(TraceType, "CallSystemService error: {0}", e); throw; } UpgradeOrchestrationTrace.TraceSource.WriteInfo(TraceType, "Exit CallSystemService for {0}.", action); return(outputBlob); }
public async Task <string> ProcessGetClusterConfigurationAsync(string apiVersion, TimeSpan timeout, CancellationToken cancellationToken) { UpgradeOrchestrationTrace.TraceSource.WriteInfo(TraceType, "Entering ProcessGetClusterConfigurationAsync."); try { UpgradeOrchestrationTrace.TraceSource.WriteInfo(TraceType, "Retrieve current cluster resource from StoreManager."); StandAloneCluster cluster = await this.storeManager.GetClusterResourceAsync( Constants.ClusterReliableDictionaryKey, this.cancellationToken).ConfigureAwait(false); if (cluster == null || cluster.Current == null) { // read from fabric data root string fabricDataRoot = FabricEnvironment.GetDataRoot(); string jsonConfigPath = Path.Combine(fabricDataRoot, System.Fabric.FabricDeployer.Constants.FileNames.BaselineJsonClusterConfig); // TODO: Needs to come from image store return(File.ReadAllText(jsonConfigPath)); } else { var nodesFromFM = new Dictionary <string, NodeDescription>(); NodeList nodes = await StandaloneUtility.GetNodesFromFMAsync(this.fabricClient, this.cancellationToken).ConfigureAwait(false); for (int i = 0; i < nodes.Count; ++i) { if (nodes[i].NodeStatus != System.Fabric.Query.NodeStatus.Invalid && !UpgradeOrchestrationMessageProcessor.IsGhostNode(nodes[i])) { NodeDescription nodeDesc = new NodeDescription() { FaultDomain = nodes[i].FaultDomain.ToString(), UpgradeDomain = nodes[i].UpgradeDomain, IPAddress = nodes[i].IpAddressOrFQDN, NodeTypeRef = nodes[i].NodeType, NodeName = nodes[i].NodeName }; nodesFromFM.Add(nodes[i].NodeName, nodeDesc); } } cluster.Topology.Nodes = nodesFromFM; UpgradeOrchestrationTrace.TraceSource.WriteInfo(TraceType, "Construct StandAloneJsonModel from current cluster resource."); var jsonModel = StandAloneInstallerJsonModelBase.ConstructByApiVersion(cluster.Current.CSMConfig, cluster.Topology, cluster.Current.CSMConfig.Version.Version, apiVersion); UpgradeOrchestrationTrace.TraceSource.WriteInfo(TraceType, "Serializing current json model."); var serializerSettings = new JsonSerializerSettings { Formatting = Formatting.Indented, NullValueHandling = NullValueHandling.Ignore, PreserveReferencesHandling = PreserveReferencesHandling.None }; serializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter()); return(JsonConvert.SerializeObject(jsonModel, serializerSettings)); } } catch (Exception e) { UpgradeOrchestrationTrace.TraceSource.WriteWarning(TraceType, "ProcessStartUpgradeAsync exception: {0}", e); throw UpgradeOrchestrationMessageProcessor.ConvertToComException(e); } }
public async Task <string> ProcessGetUpgradeOrchestrationServiceStateAsync(string inputBlob, TimeSpan timeout, CancellationToken cancellationToken) { UpgradeOrchestrationTrace.TraceSource.WriteInfo(TraceType, "Entering ProcessGetUpgradeOrchestrationServiceStateAsync."); try { UpgradeOrchestrationTrace.TraceSource.WriteInfo(TraceType, "Retrieve current cluster resource object from StoreManager."); return(await this.storeManager.GetStorageObjectAsync( Constants.ClusterReliableDictionaryKey, this.cancellationToken).ConfigureAwait(false)); } catch (Exception e) { UpgradeOrchestrationTrace.TraceSource.WriteWarning(TraceType, "ProcessGetUpgradeOrchestrationServiceStateAsync exception: {0}", e); throw UpgradeOrchestrationMessageProcessor.ConvertToComException(e); } }
public async Task ProcessStartClusterConfigurationUpgradeAsync(ConfigurationUpgradeDescription configUpgradeDesc, TimeSpan timeout, CancellationToken cancellationToken) { /* The cancellation token passed in this API call is not used (by design). This token corresponds to the client side call. * The global this.cancellationToken is initialised in RunAsync() and is honored in every API call. */ UpgradeOrchestrationTrace.TraceSource.WriteInfo(TraceType, "Entering ProcessStartUpgradeAsync."); try { UpgradeOrchestrationTrace.TraceSource.WriteInfo(TraceType, "Deserializing input json config string."); StandAloneInstallerJsonModelBase targetJsonConfig = StandAloneInstallerJsonModelBase.GetJsonConfigFromString(configUpgradeDesc.ClusterConfiguration); if (targetJsonConfig == null) { throw new ArgumentException("The input cluster configuration is not in a valid json format or supported apiVersion."); } UpgradeOrchestrationTrace.TraceSource.WriteInfo(TraceType, "Retrieve current cluster resource from StoreManager."); StandAloneCluster cluster = await this.storeManager.GetClusterResourceAsync( Constants.ClusterReliableDictionaryKey, this.cancellationToken).ConfigureAwait(false); bool isInDataLossState = await DatalossHelper.IsInDatalossStateAsync(this.cancellationToken).ConfigureAwait(false); if (!isInDataLossState) { if (cluster == null || cluster.Current == null) { UpgradeOrchestrationTrace.TraceSource.WriteWarning(TraceType, "Persisted cluster resource is not ready: {0}", cluster == null ? "null" : "current = null"); throw new FabricException("UpgradeOrchestrationService is not ready."); } UpgradeOrchestrationTrace.TraceSource.WriteInfo(TraceType, "Setting target config and topology based on new input json config."); if (cluster.Pending != null && !this.IsInterruptibleAsync(cluster.Pending).Result) { throw new FabricException(string.Format("Cluster configuration upgrade of type {0} is already in progress and cannot be interrupted.", cluster.Pending.GetType().Name)); } StandaloneSettingsValidator validator = new StandaloneSettingsValidator(targetJsonConfig); await UpgradeOrchestrationMessageProcessor.ValidateModel(targetJsonConfig, validator, cluster, true).ConfigureAwait(false); var removedNodes = validator.GetRemovedNodes(cluster.Topology); var addedNodes = validator.GetAddedNodes(cluster.Topology); if (addedNodes.Any() && StandaloneUtility.CheckFabricRunningAsGMSA(cluster.Current.CSMConfig)) { /* Need to resolve assembly so that FabricDeployer can load the right binaries from FabricCodePath since not all binaries required by FabricDeployer are present in UOS.Current folder.*/ AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(this.LoadFromFabricCodePath); try { await this.PerformAddNodeOperationGMSAAsync(addedNodes, this.fabricClient, validator.ClusterProperties.NodeTypes).ConfigureAwait(false); } catch (AggregateException ex) { UpgradeOrchestrationTrace.TraceSource.WriteError(TraceType, "Adding nodes for GMSA scenario failed with exception: {0}", ex); throw; } finally { AppDomain.CurrentDomain.AssemblyResolve -= new ResolveEventHandler(this.LoadFromFabricCodePath); } } if (addedNodes.Any()) { cluster.TargetNodeConfig = GetTargetNodeConfigAddNode(validator.Topology, cluster.Current.NodeConfig.Version); } if (removedNodes.Any()) { cluster.TargetNodeConfig = GetTargetNodeConfigRemoveNode(cluster.Topology, removedNodes, cluster.Current.NodeConfig.Version); } else { cluster.Topology = validator.Topology; } cluster.TargetCsmConfig = validator.ClusterProperties; // Cluster is updated above so persist it. await this.storeManager.PersistClusterResourceAsync(Constants.ClusterReliableDictionaryKey, cluster, cancellationToken).ConfigureAwait(false); await this.UpdatePersistedCodeUpgradePackage(validator).ConfigureAwait(false); UpgradeOrchestrationTrace.TraceSource.WriteInfo(TraceType, "Invoking Orchestrator"); await this.orchestrator.StartUpgradeAsync(cluster, this.cancellationToken, configUpgradeDesc).ContinueWith(t => { if (t.Exception != null) { UpgradeOrchestrationTrace.TraceSource.WriteWarning(TraceType, "Orchestrator completed with status: {0} exception: {1}", t.Status, t.Exception); } else { UpgradeOrchestrationTrace.TraceSource.WriteInfo(TraceType, "Orchestrator completed with status: {0}", t.Status); } }); } else { StandaloneSettingsValidator validator = new StandaloneSettingsValidator(targetJsonConfig); await UpgradeOrchestrationMessageProcessor.ValidateModel(targetJsonConfig, validator, cluster, false).ConfigureAwait(false); cluster = FabricUpgradeOrchestrationService.ConstructClusterFromJson(targetJsonConfig, FabricNativeConfigStore.FabricGetConfigStore()); DatalossHelper.DryRunConfigUpgrade(cluster); await this.storeManager.PersistClusterResourceAsync(Constants.ClusterReliableDictionaryKey, cluster, this.cancellationToken); await DatalossHelper.UpdateHeathStateAsync(isHealthy : true).ConfigureAwait(false); } } catch (Exception e) { UpgradeOrchestrationTrace.TraceSource.WriteWarning(TraceType, "ProcessStartUpgradeAsync exception: {0}", e); throw UpgradeOrchestrationMessageProcessor.ConvertToComException(e); } UpgradeOrchestrationTrace.TraceSource.WriteInfo(TraceType, "Exiting ProcessStartUpgradeAsync."); }