public override ServiceGroupDescription Build() { this.ServiceGroupDescription = new ServiceGroupDescription(); var statefulServiceDescription = new StatefulServiceDescription { HasPersistedState = this.HasPersistentState, TargetReplicaSetSize = this.TargetReplicaSetSize, MinReplicaSetSize = this.MinReplicaSetSize }; if (this.ReplicaRestartWaitDuration.HasValue) { statefulServiceDescription.ReplicaRestartWaitDuration = this.ReplicaRestartWaitDuration.Value; } if (this.QuorumLossWaitDuration.HasValue) { statefulServiceDescription.QuorumLossWaitDuration = this.QuorumLossWaitDuration.Value; } this.ServiceGroupDescription.ServiceDescription = statefulServiceDescription; if (this.Metrics != null) { foreach (var str in this.Metrics) { this.ServiceGroupDescription.ServiceDescription.Metrics.Add(ServiceCmdletBase.ParseStatefulMetric(str)); } } return(base.Build()); }
/// <summary> /// Provisions a new backend and name it uniquely according to the name in param /// </summary> /// <param name="backendName"></param> /// <returns></returns> public async Task ProvisionNewBackend(string backendName) { Uri serviceName = new Uri($"{m_appName}/{backendName}"); var applicationName = new Uri(m_appName); var payload = backendName; StatefulServiceDescription serviceDescription = new StatefulServiceDescription() { ApplicationName = applicationName, ServiceTypeName = "LogicEngineType", ServiceName = serviceName, PartitionSchemeDescription = new UniformInt64RangePartitionSchemeDescription(3, 0, 2),//TODO read from config ServicePackageActivationMode = ServicePackageActivationMode.ExclusiveProcess, HasPersistedState = true, MinReplicaSetSize = 1, TargetReplicaSetSize = 1 }; //launch service try { using (var fabricClient = new FabricClient()) { await fabricClient.ServiceManager.CreateServiceAsync(serviceDescription); } } catch (Exception e) { throw e; } }
public async Task WaitForStatefulService(Uri serviceInstanceUri) { StatefulServiceDescription description = await this.Client.ServiceManager.GetServiceDescriptionAsync(serviceInstanceUri) as StatefulServiceDescription; int targetTotalReplicas = description.TargetReplicaSetSize; if (description.PartitionSchemeDescription is UniformInt64RangePartitionSchemeDescription) { targetTotalReplicas *= ((UniformInt64RangePartitionSchemeDescription)description.PartitionSchemeDescription).PartitionCount; } ServicePartitionList partitions = await this.Client.QueryManager.GetPartitionListAsync(serviceInstanceUri); int replicaTotal = 0; while (replicaTotal < targetTotalReplicas) { await Task.Delay(this.interval); //ServiceEventSource.Current.ServiceMessage(this, "CountyService waiting for National Service to come up."); replicaTotal = 0; foreach (Partition partition in partitions) { ServiceReplicaList replicaList = await this.Client.QueryManager.GetReplicaListAsync(partition.PartitionInformation.Id); replicaTotal += replicaList.Count(x => x.ReplicaStatus == System.Fabric.Query.ServiceReplicaStatus.Ready); } } }
public async Task <IActionResult> Put(string name) { StatefulServiceDescription serviceDescription = new StatefulServiceDescription() { ApplicationName = new Uri(this.applicationName), MinReplicaSetSize = 3, TargetReplicaSetSize = 3, PartitionSchemeDescription = new SingletonPartitionSchemeDescription(), HasPersistedState = true, ServiceTypeName = Constants.TOPIC_SERVICE_TYPE_NAME, ServiceName = this.serviceContext.CreateTopicUri(name) }; try { await fabric.ServiceManager.CreateServiceAsync(serviceDescription); } catch (FabricElementAlreadyExistsException) { //idempotent so return 200 return(Ok()); } return(Ok()); }
public Task Post(string jobName, string parameters) { string applicationName = this.context.CodePackageActivationContext.ApplicationName; StatefulServiceDescription serviceDescription = new StatefulServiceDescription() { ApplicationName = new Uri(applicationName), MinReplicaSetSize = 3, TargetReplicaSetSize = 3, PartitionSchemeDescription = new UniformInt64RangePartitionSchemeDescription() { LowKey = 0, HighKey = 10, PartitionCount = 1 }, HasPersistedState = true, InitializationData = Encoding.UTF8.GetBytes(parameters), ServiceTypeName = "JobServiceType", ServiceName = new Uri($"{applicationName}/jobs/{jobName}") }; //try //{ return(fabricClient.ServiceManager.CreateServiceAsync(serviceDescription)); // return Task.FromResult(true); //} //catch(Exception e) //{ //return Task.FromResult(false); //} }
protected override void ProcessRecord() { PartitionSchemeDescription partitionSchemeDescription; ServiceDescription serviceDescription; var client = new ServiceFabricClientBuilder().ConnectAsync(ClusterEndPoint, ThumbPrint).Result; if (PartitionSchemeUniformInt64) { partitionSchemeDescription = new UniformInt64RangePartitionSchemeDescription(PartitionCount, LowKey.ToString(), HighKey.ToString()); } else if (PartitionSchemeNamed) { partitionSchemeDescription = new NamedPartitionSchemeDescription(PartitionCount, PartitionNames); } else { partitionSchemeDescription = new SingletonPartitionSchemeDescription(); } if (Stateless.IsPresent) { serviceDescription = new StatelessServiceDescription(new ServiceName(ServiceName), ServiceType, partitionSchemeDescription, InstanceCount, initializationData: InitializationData); } else { serviceDescription = new StatefulServiceDescription(new ServiceName(ServiceName), ServiceType, partitionSchemeDescription, TargetReplicaSetSize, MinReplicaSetSize, PersistedState, initializationData: InitializationData); } client.Services.CreateServiceAsync(ApplicationId, serviceDescription).Wait(); }
/// <summary> /// Provisions a new backend and name it uniquely according to the name in param /// </summary> /// <param name="backendName"></param> /// <returns></returns> public async Task ProvisionNewBackend(string backendName) { Uri serviceName = new Uri($"{m_appName}/{backendName}"); var applicationName = new Uri(m_appName); StatefulServiceDescription serviceDescription = new StatefulServiceDescription() { ApplicationName = applicationName, ServiceTypeName = "Stateful.BackendType", ServiceName = serviceName, PartitionSchemeDescription = new SingletonPartitionSchemeDescription(), HasPersistedState = true, MinReplicaSetSize = 3, TargetReplicaSetSize = 3, ServicePackageActivationMode = ServicePackageActivationMode.ExclusiveProcess }; //launch service try { using (var fabricClient = new FabricClient()) { await fabricClient.ServiceManager.CreateServiceAsync(serviceDescription); } } catch (Exception e) { throw e; } }
public async Task <IActionResult> Post(string reportName) { // Now create the data service in the new application instance. StatefulServiceDescription dataServiceDescription = new StatefulServiceDescription() { ApplicationName = new Uri(this.serviceContext.CodePackageActivationContext.ApplicationName), HasPersistedState = true, MinReplicaSetSize = 3, TargetReplicaSetSize = 3, PartitionSchemeDescription = new SingletonPartitionSchemeDescription(), ServiceName = this.GetServiceName(reportName), ServiceTypeName = ReportProcessingServiceTypeName, ServicePackageActivationMode = ServicePackageActivationMode.ExclusiveProcess }; try { await this.fabricClient.ServiceManager.CreateServiceAsync(dataServiceDescription, this.operationTimeout, this.appLifetime.ApplicationStopping); return(this.Ok()); } catch (FabricElementAlreadyExistsException) { return(new ContentResult() { StatusCode = 400, Content = $"Service for report '{reportName}' already exists." }); } }
internal StatefulServiceDescription GetStatefulDescription(Job j) { var ser = JsonSerializer.Create(); var sw = new StringWriter(); ser.Serialize(sw, j); var desc = new StatefulServiceDescription() { ApplicationName = new Uri("fabric:/Compute2"), DefaultMoveCost = MoveCost.High, ServiceName = new Uri(string.Format("fabric:/Compute2/ComputeInstance{0}", System.DateTime.Now.Ticks)), ServiceTypeName = "StatefulComputeServiceType", HasPersistedState = true, PartitionSchemeDescription = new SingletonPartitionSchemeDescription(), TargetReplicaSetSize = 3, MinReplicaSetSize = 2, InitializationData = Encoding.UTF8.GetBytes(sw.ToString()) }; var metric = new StatefulServiceLoadMetricDescription() { PrimaryDefaultLoad = 1, SecondaryDefaultLoad = 0, Name = "TCU", Weight = ServiceLoadMetricWeight.Medium }; desc.Metrics.Add(metric); return(desc); }
public async Task <IActionResult> Post(string reportName) { int power = this.random.Next(2, 7); int multiplier = (int)Math.Pow(2, power); // Now create the data service in the new application instance. StatefulServiceDescription dataServiceDescription = new StatefulServiceDescription() { ApplicationName = new Uri(this.serviceContext.CodePackageActivationContext.ApplicationName), HasPersistedState = true, MinReplicaSetSize = 3, TargetReplicaSetSize = 3, PartitionSchemeDescription = new SingletonPartitionSchemeDescription(), ServiceName = this.GetServiceName(reportName), ServiceTypeName = ReportProcessingServiceTypeName, ServicePackageActivationMode = ServicePackageActivationMode.ExclusiveProcess, InitializationData = BitConverter.GetBytes(multiplier) }; dataServiceDescription.Metrics.Add(new StatefulServiceLoadMetricDescription() { Name = "ProcessingCapacity", PrimaryDefaultLoad = multiplier, SecondaryDefaultLoad = multiplier, Weight = ServiceLoadMetricWeight.High }); dataServiceDescription.Metrics.Add(new StatefulServiceLoadMetricDescription() { Name = "CPU", PrimaryDefaultLoad = 0, SecondaryDefaultLoad = 0, Weight = ServiceLoadMetricWeight.Medium }); dataServiceDescription.Metrics.Add(new StatefulServiceLoadMetricDescription() { Name = "MemoryMB", PrimaryDefaultLoad = multiplier, SecondaryDefaultLoad = multiplier, Weight = ServiceLoadMetricWeight.Medium }); try { await this.fabricClient.ServiceManager.CreateServiceAsync(dataServiceDescription, this.operationTimeout, this.appLifetime.ApplicationStopping); return(this.Ok()); } catch (FabricElementAlreadyExistsException) { return(new ContentResult() { StatusCode = 400, Content = $"Service for report '{reportName}' already exists." }); } }
public async Task <IActionResult> Post([FromRoute] string name, [FromBody] EventsProcessorApplicationParams parameters) { // Determine the number of IoT Hub partitions. // The events processing service will be created with the same number of partitions. EventHubClient eventHubClient = EventHubClient.CreateFromConnectionString(parameters.IotHubConnectionString, "messages/events"); EventHubRuntimeInformation eventHubInfo = await eventHubClient.GetRuntimeInformationAsync(); // Application parameters are passed to the Events Processing application instance. NameValueCollection appInstanceParameters = new NameValueCollection(); appInstanceParameters["IotHubConnectionString"] = parameters.IotHubConnectionString; appInstanceParameters["IotHubProcessOnlyFutureEvents"] = parameters.IotHubProcessOnlyFutureEvents; appInstanceParameters["PublishDataServiceURLs"] = parameters.PublishDataServiceURLs; ApplicationDescription application = new ApplicationDescription( new Uri($"{Names.EventsProcessorApplicationPrefix}/{name}"), Names.EventsProcessorApplicationTypeName, parameters.Version, appInstanceParameters); // Create a named application instance await this.fabricClient.ApplicationManager.CreateApplicationAsync(application, this.operationTimeout, this.appLifetime.ApplicationStopping); // Next, create named instances of the services that run in the application. ServiceUriBuilder serviceNameUriBuilder = new ServiceUriBuilder(application.ApplicationName.ToString(), Names.EventsProcessorRouterServiceName); StatefulServiceDescription service = new StatefulServiceDescription() { ApplicationName = application.ApplicationName, HasPersistedState = true, MinReplicaSetSize = 3, TargetReplicaSetSize = 3, PartitionSchemeDescription = new UniformInt64RangePartitionSchemeDescription(eventHubInfo.PartitionCount, 0, eventHubInfo.PartitionCount - 1), ServiceName = serviceNameUriBuilder.Build(), ServiceTypeName = Names.EventsProcessorRouterServiceTypeName }; await this.fabricClient.ServiceManager.CreateServiceAsync(service, this.operationTimeout, this.appLifetime.ApplicationStopping); if (parameters.PublishDataServiceURLs != null && parameters.PublishDataServiceURLs.Length > 0) { // Next, create named instances of the services that run in the application. serviceNameUriBuilder = new ServiceUriBuilder(application.ApplicationName.ToString(), Names.EventsProcessorExtenderServiceName); StatelessServiceDescription extenderService = new StatelessServiceDescription() { ApplicationName = application.ApplicationName, InstanceCount = 1, PartitionSchemeDescription = new SingletonPartitionSchemeDescription(), ServiceName = serviceNameUriBuilder.Build(), ServiceTypeName = Names.EventsProcessorExtenderServiceTypeName }; await this.fabricClient.ServiceManager.CreateServiceAsync(extenderService, this.operationTimeout, this.appLifetime.ApplicationStopping); } return(this.Ok()); }
public Task <Job> DiagStateful(int replicas) { var j = new Job() { NodeName = "", // TODO Id = Guid.NewGuid().ToString(), Status = JobStatus.Waiting }; var ser = JsonSerializer.Create(); var sw = new StringWriter(); ser.Serialize(sw, j); StatefulServiceDescription desc = new StatefulServiceDescription(); try { FabricClient client = new FabricClient(); desc.ApplicationName = new Uri("fabric:/Compute2"); desc.DefaultMoveCost = MoveCost.High; desc.ServiceName = new Uri(string.Format("fabric:/Compute2/EmptyStatefulInstance{0}", System.DateTime.Now.Ticks)); desc.ServiceTypeName = "EmptyServiceType"; desc.PartitionSchemeDescription = new SingletonPartitionSchemeDescription(); desc.TargetReplicaSetSize = replicas; desc.MinReplicaSetSize = 1; desc.HasPersistedState = false; desc.InitializationData = Encoding.UTF8.GetBytes(sw.ToString()); var metric = new StatefulServiceLoadMetricDescription(); metric.PrimaryDefaultLoad = 1; metric.SecondaryDefaultLoad = 1; metric.Name = "calc"; metric.Weight = ServiceLoadMetricWeight.Medium; desc.Metrics.Add(metric); client.ServiceManager.CreateServiceAsync(desc).Wait(); //ServiceEventSource.Current.ServiceMessage(this, string.Format("created on svc {0}", desc.ServiceName)); } catch (Exception ex) { // CreateServiceAsync throws when there's no capacity for StatefulServices // Handle appropriately //ServiceEventSource.Current.ServiceMessage(this, string.Format("ERROR creating svc {0}, {1}", desc.ServiceName, ex.ToString())); Debug.WriteLine(ex.ToString()); return(Task.FromResult(RecordErrorStatus(j))); } return(Task.FromResult <Job>(j)); }
public static StatefulServiceDescription GetCloneStateful(this StatefulServiceDescription other) { StatefulServiceDescription clone = new StatefulServiceDescription() { HasPersistedState = other.HasPersistedState, MinReplicaSetSize = other.MinReplicaSetSize, TargetReplicaSetSize = other.TargetReplicaSetSize, }; clone.Metrics.AddRangeNullSafe(other.Metrics.Select(m => (m as StatefulServiceLoadMetricDescription).GetClone())); // Copy properties clone.CopyFrom(other); return(clone); }
private bool TryCreateStatefulServiceDescription(out StatefulServiceDescription sd) { sd = null; try { sd = new StatefulServiceDescription(); sd.ApplicationName = new Uri(this.control.Package.ApplicationAddress); sd.ServiceName = new Uri(this.control.Package.ServiceAddress); sd.ServiceTypeName = this.control.Package.ServiceType; int minRep; if (!this.TryGetData("ServiceStatefulMinReplica", out minRep)) { return(false); } sd.MinReplicaSetSize = minRep; int tgtSize; if (!this.TryGetData("ServiceStatefulTargetReplica", out tgtSize)) { return(false); } sd.TargetReplicaSetSize = tgtSize; sd.HasPersistedState = false; string hasPersistedValue; if (this.control.Package.Data.TryGetValue("ServiceStatefulPersisted", out hasPersistedValue)) { if (hasPersistedValue == "true") { sd.HasPersistedState = true; } } PartitionSchemeDescription psd; if (!this.TryCreatePartitionDescription(out psd)) { return(false); } sd.PartitionSchemeDescription = psd; return(true); } catch (Exception e) { log.Error("failed to create StatelessServiceDescription, exception={0}", e.Message); return(false); } }
public async Task <IActionResult> Post([FromRoute] string tenantName, [FromBody] InsightApplicationParams parameters) { // First create the application instance. // This won't actually create the services yet. ApplicationDescription application = new ApplicationDescription( new Uri($"{Names.InsightApplicationNamePrefix}/{tenantName}"), Names.InsightApplicationTypeName, parameters.Version); await this.fabricClient.ApplicationManager.CreateApplicationAsync(application, this.operationTimeout, this.appLifetime.ApplicationStopping); // Now create the data service in the new application instance. ServiceUriBuilder dataServiceNameUriBuilder = new ServiceUriBuilder(application.ApplicationName.ToString(), Names.InsightDataServiceName); StatefulServiceDescription dataServiceDescription = new StatefulServiceDescription() { ApplicationName = application.ApplicationName, HasPersistedState = true, MinReplicaSetSize = 3, TargetReplicaSetSize = 3, PartitionSchemeDescription = new UniformInt64RangePartitionSchemeDescription(parameters.DataPartitionCount, Int64.MinValue, Int64.MaxValue), ServiceName = dataServiceNameUriBuilder.Build(), ServiceTypeName = Names.InsightDataServiceTypeName }; await this.fabricClient.ServiceManager.CreateServiceAsync(dataServiceDescription, this.operationTimeout, this.appLifetime.ApplicationStopping); // And finally, create the web service in the new application instance. ServiceUriBuilder webServiceNameUriBuilder = new ServiceUriBuilder(application.ApplicationName.ToString(), Names.InsightWebServiceName); StatelessServiceDescription webServiceDescription = new StatelessServiceDescription() { ApplicationName = application.ApplicationName, InstanceCount = parameters.WebInstanceCount, PartitionSchemeDescription = new SingletonPartitionSchemeDescription(), ServiceName = webServiceNameUriBuilder.Build(), ServiceTypeName = Names.InsightWebServiceTypeName }; await this.fabricClient.ServiceManager.CreateServiceAsync(webServiceDescription, this.operationTimeout, this.appLifetime.ApplicationStopping); return(this.Ok()); }
public async Task<IActionResult> Post([FromRoute] string tenantName, [FromBody] TenantApplicationParams parameters) { // First create the application instance. // This won't actually create the services yet. ApplicationDescription application = new ApplicationDescription( new Uri($"{Names.TenantApplicationNamePrefix}/{tenantName}"), Names.TenantApplicationTypeName, parameters.Version); await this.fabricClient.ApplicationManager.CreateApplicationAsync(application, this.operationTimeout, this.serviceCancellationToken); // Now create the data service in the new application instance. ServiceUriBuilder dataServiceNameUriBuilder = new ServiceUriBuilder(application.ApplicationName.ToString(), Names.TenantDataServiceName); StatefulServiceDescription dataServiceDescription = new StatefulServiceDescription() { ApplicationName = application.ApplicationName, HasPersistedState = true, MinReplicaSetSize = 3, TargetReplicaSetSize = 3, PartitionSchemeDescription = new UniformInt64RangePartitionSchemeDescription(parameters.DataPartitionCount, Int64.MinValue, Int64.MaxValue), ServiceName = dataServiceNameUriBuilder.Build(), ServiceTypeName = Names.TenantDataServiceTypeName }; await this.fabricClient.ServiceManager.CreateServiceAsync(dataServiceDescription, this.operationTimeout, this.serviceCancellationToken); // And finally, create the web service in the new application instance. ServiceUriBuilder webServiceNameUriBuilder = new ServiceUriBuilder(application.ApplicationName.ToString(), Names.TenantWebServiceName); StatelessServiceDescription webServiceDescription = new StatelessServiceDescription() { ApplicationName = application.ApplicationName, InstanceCount = parameters.WebInstanceCount, PartitionSchemeDescription = new SingletonPartitionSchemeDescription(), ServiceName = webServiceNameUriBuilder.Build(), ServiceTypeName = Names.TenantWebServiceTypeName }; await this.fabricClient.ServiceManager.CreateServiceAsync(webServiceDescription, this.operationTimeout, this.serviceCancellationToken); return this.Ok(); }
private void TestHelper(Action <StatefulServiceDescription> setup) { var expected = HelperInstance.CreateDefaultDescription(); if (setup != null) { setup(expected); } using (var pc = new PinCollection()) { NativeTypes.FABRIC_SERVICE_DESCRIPTION_KIND kind; IntPtr native = expected.ToNative(pc, out kind); var actual = StatefulServiceDescription.CreateFromNative(native); Assert.AreEqual(NativeTypes.FABRIC_SERVICE_DESCRIPTION_KIND.FABRIC_SERVICE_DESCRIPTION_KIND_STATEFUL, kind); HelperInstance.Compare(expected, actual); } }
public async Task <string> ExecuteTaskAsync([FromBody] Dictionary <string, string> parameters) { try { // No error checking - just trusting the TaskExecutorClient :-) string taskAssemblyPath = parameters["taskAssemblyPath"]; string taskClassName = parameters["taskClassName"]; string taskParameters = parameters["taskParameters"]; // Generate unique service name based on the assembly directory. Uri serviceUri = GetServiceUri(Path.GetDirectoryName(taskAssemblyPath)); using (var client = new FabricClient()) { Service service = await FindExistingServiceAsync(client, serviceUri); if (service == null) { // Service not yet created - first request for a task from within the directory since the // service started. We now create a new service instance with the unique directory-based name. var description = new StatefulServiceDescription() { ApplicationName = GetApplicationUri(), ServiceName = serviceUri, ServiceTypeName = "TaskExecutorActorServiceType", HasPersistedState = true, PartitionSchemeDescription = new UniformInt64RangePartitionSchemeDescription() }; await client.ServiceManager.CreateServiceAsync(description); } } // Now delegate the execution to the service by calling the actor. var taskExecutorProxy = ActorProxy.Create <ITaskExecutorActor>(ActorId.CreateRandom(), serviceUri); return(await taskExecutorProxy.ExecuteTaskAsync(taskAssemblyPath, taskClassName, taskParameters)); } catch (Exception ex) { return(ex.ToString()); } }
public async Task <IActionResult> Put(string topicName, string name) { ServiceList services = await this.fabric.QueryManager.GetServiceListAsync(new Uri(applicationName)); try { Service topicService = services.Where(x => x.ServiceTypeName == Constants.TOPIC_SERVICE_TYPE_NAME && x.ServiceName.IsTopic(topicName)).Single(); } catch (InvalidOperationException) { //Topic is not availible return(NotFound($"No topic found with name '{topicName}'. Please create topic before adding subscription.")); } StatefulServiceDescription serviceDescription = new StatefulServiceDescription() { ApplicationName = new Uri(this.applicationName), MinReplicaSetSize = 3, TargetReplicaSetSize = 3, PartitionSchemeDescription = new SingletonPartitionSchemeDescription(), HasPersistedState = true, InitializationData = Encoding.UTF8.GetBytes(topicName), ServiceTypeName = Constants.SUBSCRIBER_SERVICE_TYPE_NAME, ServiceName = this.serviceContext.CreateSubscriptionUri(topicName, name) }; try { await fabric.ServiceManager.CreateServiceAsync(serviceDescription); } catch (FabricElementAlreadyExistsException) { //idempotent so return 200 return(Ok()); } return(Ok()); }
public async Task <IActionResult> Post([FromRoute] string name, [FromBody] IngestionApplicationParams parameters) { // Determine the number of IoT Hub partitions. // The ingestion service will be created with the same number of partitions. EventHubClient eventHubClient = EventHubClient.CreateFromConnectionString(parameters.IotHubConnectionString, "messages/events"); EventHubRuntimeInformation eventHubInfo = await eventHubClient.GetRuntimeInformationAsync(); // Application parameters are passed to the Ingestion application instance. NameValueCollection appInstanceParameters = new NameValueCollection(); appInstanceParameters["IotHubConnectionString"] = parameters.IotHubConnectionString; appInstanceParameters["ReplicaSetSize"] = parameters.ReplicaSetSize.ToString(); ApplicationDescription application = new ApplicationDescription( new Uri($"{Names.IngestionApplicationPrefix}/{name}"), Names.IngestionApplicationTypeName, parameters.Version, appInstanceParameters); // Create a named application instance await this.fabricClient.ApplicationManager.CreateApplicationAsync(application, this.operationTimeout, this.appLifetime.ApplicationStopping); // Next, create named instances of the services that run in the application. ServiceUriBuilder serviceNameUriBuilder = new ServiceUriBuilder(application.ApplicationName.ToString(), Names.IngestionRouterServiceName); StatefulServiceDescription service = new StatefulServiceDescription() { ApplicationName = application.ApplicationName, HasPersistedState = true, MinReplicaSetSize = parameters.ReplicaSetSize, // Previous 3 for 5 node cluster and 1 for 1 node cluster TargetReplicaSetSize = parameters.ReplicaSetSize, PartitionSchemeDescription = new UniformInt64RangePartitionSchemeDescription(eventHubInfo.PartitionCount, 0, eventHubInfo.PartitionCount - 1), ServiceName = serviceNameUriBuilder.Build(), ServiceTypeName = Names.IngestionRouterServiceTypeName }; await this.fabricClient.ServiceManager.CreateServiceAsync(service, this.operationTimeout, this.appLifetime.ApplicationStopping); return(this.Ok()); }
private async Task <ActorsCountInfo> CreateActor(int index) { var description = new StatefulServiceDescription() { HasPersistedState = true, ApplicationName = new Uri(this.context.CodePackageActivationContext.ApplicationName), ServiceName = new Uri($"{this.context.CodePackageActivationContext.ApplicationName}/SimulationActorService{GetSimulationActorNameSuffix(index)}"), ServiceTypeName = "SimulationActorServiceType", PartitionSchemeDescription = new UniformInt64RangePartitionSchemeDescription() { LowKey = -9223372036854775808, HighKey = 9223372036854775807, PartitionCount = 1, }, MinReplicaSetSize = 3, TargetReplicaSetSize = 3, }; await this.fabricClient.ServiceManager.CreateServiceAsync(description); return(PopulateActorInfo(index, poolInfo.pool)); }
internal static async Task <IGatewayMonitor> GetGatewaySupervisorServiceAsync(string nodeId, bool createIfnotExist) { var appName = "fabric:/DeviceMonitorApp"; var serviceName = $"{appName}/{nodeId}"; var fabricClient = new FabricClient(); var serviceAlreadyExists = false; try { var services = await fabricClient.QueryManager.GetServiceListAsync(new Uri(appName)); serviceAlreadyExists = services.Select(s => s.ServiceName).Contains(new Uri(serviceName)); } catch (FabricElementNotFoundException) { } if (!serviceAlreadyExists && createIfnotExist) { StatefulServiceDescription serviceDescription = new StatefulServiceDescription(); serviceDescription.ApplicationName = new Uri(appName); serviceDescription.PartitionSchemeDescription = new SingletonPartitionSchemeDescription(); serviceDescription.ServiceName = new Uri(serviceName); serviceDescription.ServiceTypeName = "GatewayMonitorServiceType"; serviceDescription.HasPersistedState = true; serviceDescription.MinReplicaSetSize = 3; serviceDescription.TargetReplicaSetSize = 3; await fabricClient.ServiceManager.CreateServiceAsync(serviceDescription); //TODO:Call GetService and then get partition instead of delay await Task.Delay(TimeSpan.FromSeconds(30)); } else if (!serviceAlreadyExists) { throw new ArgumentException("Invalid Arguments"); } return(ServiceProxy.Create <IGatewayMonitor>(new Uri(serviceName))); }
public async Task <IActionResult> Put(string name) { string applicationName = this.serviceContext.CodePackageActivationContext.ApplicationName; StatefulServiceDescription serviceDescription = new StatefulServiceDescription() { ApplicationName = new Uri(applicationName), MinReplicaSetSize = 3, TargetReplicaSetSize = 3, PartitionSchemeDescription = new UniformInt64RangePartitionSchemeDescription() { LowKey = 0, HighKey = 10, PartitionCount = 1 }, HasPersistedState = true, ServiceTypeName = TOPIC_SERVICE_NAME, ServiceName = CreateTopicUri(name) }; await fabric.ServiceManager.CreateServiceAsync(serviceDescription); return(Ok()); }
public override async Task <ActionStateBase> RunAsync(CancellationToken cancellationToken, ServiceInternalFaultInfo serviceInternalFaultInfo) { InvokeQuorumLossState state = Convert(this.State); // get info about the service so we can check type and trss ServiceDescription result = await FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync( () => this.FabricClient.ServiceManager.GetServiceDescriptionAsync( this.partitionSelector.ServiceName, this.RequestTimeout, cancellationToken), this.OperationTimeout, cancellationToken).ConfigureAwait(false); if (result.Kind != ServiceDescriptionKind.Stateful) { // The message in the first arg is only for debugging, it is not returned to the user. throw new FabricInvalidForStatelessServicesException("FabricInvalidForStatelessServicesException", FabricErrorCode.InvalidForStatelessServices); } StatefulServiceDescription statefulServiceDescription = result as StatefulServiceDescription; ReleaseAssert.AssertIf(statefulServiceDescription == null, string.Format(CultureInfo.InvariantCulture, "{0} - Service is not a stateful service", this.State.OperationId)); if (!statefulServiceDescription.HasPersistedState) { // The message in the first arg is only for debugging, it is not returned to the user. throw new FabricOnlyValidForStatefulPersistentServicesException("This is only valid for stateful persistent services", FabricErrorCode.OnlyValidForStatefulPersistentServices); } SelectedPartition targetPartition = await FaultAnalysisServiceUtility.GetSelectedPartitionStateAsync( this.FabricClient, this.partitionSelector, this.RequestTimeout, this.OperationTimeout, cancellationToken).ConfigureAwait(false); Guid partitionId = targetPartition.PartitionId; // get data about replicas in that partition ServiceReplicaList replicasResult = await FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync( () => this.FabricClient.QueryManager.GetReplicaListAsync( partitionId, 0, this.RequestTimeout, cancellationToken), this.OperationTimeout, cancellationToken).ConfigureAwait(false); List <StatefulServiceReplica> tempReplicas = new List <StatefulServiceReplica>(); foreach (var replica in replicasResult) { StatefulServiceReplica statefulReplica = replica as StatefulServiceReplica; ReleaseAssert.AssertIf(statefulReplica == null, "Expected stateful replica"); tempReplicas.Add(statefulReplica); } List <StatefulServiceReplica> targetReplicas = null; if (this.quorumLossMode == QuorumLossMode.AllReplicas) { targetReplicas = tempReplicas.Where(r => r.ReplicaRole == ReplicaRole.Primary || r.ReplicaRole == ReplicaRole.ActiveSecondary).ToList(); } else if (this.quorumLossMode == QuorumLossMode.QuorumReplicas) { targetReplicas = FaultAnalysisServiceUtility.GetReplicasForPartialLoss(state.OperationId, tempReplicas); } else { throw FaultAnalysisServiceUtility.CreateException(StepBase.TraceType, Interop.NativeTypes.FABRIC_ERROR_CODE.E_INVALIDARG, Strings.StringResources.Error_UnsupportedQuorumLossMode); } if (targetReplicas == null) { // This will cause the command to rollback and retry throw new FabricTransientException("The operation could not be performed, please retry", FabricErrorCode.NotReady); } List <string> targetNodes = new List <string>(); foreach (var replica in targetReplicas) { targetNodes.Add(replica.NodeName); } List <Tuple <string, string> > unreliableTransportInfoList = new List <Tuple <string, string> >(); foreach (string nodeName in targetNodes) { UnreliableTransportBehavior behavior = new UnreliableTransportBehavior("*", "StatefulServiceReopen"); behavior.AddFilterForPartitionId(partitionId); // ApplyingUnreliableTransport.BehaviorNamePrefix + nodeName; string behaviorName = this.CreateBehaviorName(nodeName); unreliableTransportInfoList.Add(new Tuple <string, string>(nodeName, behaviorName)); } state.StateProgress.Push(StepStateNames.PerformingActions); state.Info.PartitionId = partitionId; state.Info.ReplicaIds = targetReplicas.Select(r => r.Id).ToList(); state.Info.UnreliableTransportInfo = unreliableTransportInfoList; return(state); }
public override ServiceDescription Build() { var statefulDescription = new StatefulServiceDescription { HasPersistedState = this.HasPersistentState, TargetReplicaSetSize = this.TargetReplicaSetSize, MinReplicaSetSize = this.MinReplicaSetSize }; statefulDescription.ApplicationName = this.ApplicationName; statefulDescription.PartitionSchemeDescription = this.PartitionSchemeDescriptionBuilder.Build(); statefulDescription.ServiceName = this.ServiceName; statefulDescription.ServiceTypeName = this.ServiceTypeName; statefulDescription.PlacementConstraints = this.PlacementConstraints; statefulDescription.ServiceDnsName = this.ServiceDnsName; if (this.ReplicaRestartWaitDuration.HasValue) { statefulDescription.ReplicaRestartWaitDuration = this.ReplicaRestartWaitDuration.Value; } if (this.QuorumLossWaitDuration.HasValue) { statefulDescription.QuorumLossWaitDuration = this.QuorumLossWaitDuration.Value; } if (this.StandByReplicaKeepDuration.HasValue) { statefulDescription.StandByReplicaKeepDuration = this.StandByReplicaKeepDuration.Value; } if (this.Correlations != null) { foreach (var str in this.Correlations) { statefulDescription.Correlations.Add(ServiceCmdletBase.ParseCorrelation(str)); } } if (this.PlacementPolicies != null) { foreach (var str in this.PlacementPolicies) { statefulDescription.PlacementPolicies.Add(ServiceCmdletBase.ParsePlacementPolicy(str)); } } if (this.DefaultMoveCost != null) { statefulDescription.DefaultMoveCost = ServiceCmdletBase.ParseMoveCost(this.DefaultMoveCost); } statefulDescription.ServicePackageActivationMode = this.ServicePackageActivationMode; if (this.Metrics != null) { foreach (var str in this.Metrics) { statefulDescription.Metrics.Add(ServiceCmdletBase.ParseStatefulMetric(str)); } } if (this.ScalingPolicies != null) { foreach (var scale in this.ScalingPolicies) { statefulDescription.ScalingPolicies.Add(scale); } } return(statefulDescription); }
protected override object FormatOutput(object output) { var result = new PSObject(output); if (output is ServiceGroupDescription) { var serviceGroupDescription = output as ServiceGroupDescription; // Adding a helper toString method for printing IList<MemberDescription> var memberDescriptionsPSObj = new PSObject(serviceGroupDescription.MemberDescriptions); memberDescriptionsPSObj.Members.Add( new PSCodeMethod( Constants.ToStringMethodName, typeof(OutputFormatter).GetMethod(Constants.FormatObjectMethodName))); result.Properties.Add(new PSNoteProperty(Constants.MemberDescriptionsPropertyName, memberDescriptionsPSObj)); result.Properties.Add(new PSNoteProperty( Constants.ApplicationNamePropertyName, serviceGroupDescription.ServiceDescription.ApplicationName)); result.Properties.Add(new PSNoteProperty( Constants.ServiceNamePropertyName, serviceGroupDescription.ServiceDescription.ServiceName)); result.Properties.Add(new PSNoteProperty( Constants.ServiceTypeNamePropertyName, serviceGroupDescription.ServiceDescription.ServiceTypeName)); result.Properties.Add(new PSNoteProperty( Constants.ServiceKindPropertyName, serviceGroupDescription.ServiceDescription.Kind)); if (serviceGroupDescription.ServiceDescription is StatefulServiceDescription) { StatefulServiceDescription statefulServiceDescription = serviceGroupDescription.ServiceDescription as StatefulServiceDescription; result.Properties.Add(new PSNoteProperty( Constants.HasPersistedStatePropertyName, statefulServiceDescription.HasPersistedState)); result.Properties.Add(new PSNoteProperty( Constants.MinReplicaSetSizePropertyName, statefulServiceDescription.MinReplicaSetSize)); result.Properties.Add(new PSNoteProperty( Constants.TargetReplicaSetSizePropertyName, statefulServiceDescription.TargetReplicaSetSize)); if (statefulServiceDescription.HasPersistedState) { result.Properties.Add(new PSNoteProperty( Constants.ReplicaRestartWaitDurationPropertyName, statefulServiceDescription.ReplicaRestartWaitDuration)); result.Properties.Add(new PSNoteProperty( Constants.QuorumLossWaitDurationPropertyName, statefulServiceDescription.QuorumLossWaitDuration)); result.Properties.Add(new PSNoteProperty( Constants.StandByReplicaKeepDurationPropertyName, statefulServiceDescription.StandByReplicaKeepDuration)); } } else if (serviceGroupDescription.ServiceDescription is StatelessServiceDescription) { StatelessServiceDescription statelessServiceDescription = serviceGroupDescription.ServiceDescription as StatelessServiceDescription; result.Properties.Add(new PSNoteProperty( Constants.InstanceCountPropertyName, statelessServiceDescription.InstanceCount)); } result.Properties.Add( new PSNoteProperty( Constants.PartitionSchemePropertyName, serviceGroupDescription.ServiceDescription.PartitionSchemeDescription.Scheme)); result.Properties.Add( new PSNoteProperty( Constants.PlacementConstraintsPropertyName, string.IsNullOrEmpty(serviceGroupDescription.ServiceDescription.PlacementConstraints) ? Constants.NoneResultOutput : serviceGroupDescription.ServiceDescription.PlacementConstraints)); if (serviceGroupDescription.ServiceDescription.PartitionSchemeDescription.Scheme == PartitionScheme.UniformInt64Range) { var info = serviceGroupDescription.ServiceDescription.PartitionSchemeDescription as UniformInt64RangePartitionSchemeDescription; if (info != null) { result.Properties.Add(new PSNoteProperty(Constants.PartitionLowKeyPropertyName, info.LowKey)); result.Properties.Add(new PSNoteProperty(Constants.PartitionHighKeyPropertyName, info.HighKey)); result.Properties.Add(new PSNoteProperty(Constants.PartitionCountPropertyName, info.PartitionCount)); } } else if (serviceGroupDescription.ServiceDescription.PartitionSchemeDescription.Scheme == PartitionScheme.Named) { var info = serviceGroupDescription.ServiceDescription.PartitionSchemeDescription as NamedPartitionSchemeDescription; if (info != null) { var partitionNamesPropertyPSObj = new PSObject(info.PartitionNames); partitionNamesPropertyPSObj.Members.Add( new PSCodeMethod( Constants.ToStringMethodName, typeof(OutputFormatter).GetMethod(Constants.FormatObjectMethodName))); result.Properties.Add(new PSNoteProperty(Constants.PartitionNamesPropertyName, partitionNamesPropertyPSObj)); } } return(result); } return(base.FormatOutput(output)); }
/// <inheritdoc/> protected override void ProcessRecordInternal() { PartitionSchemeDescription partitionSchemeDescription = null; if (this.Named.IsPresent) { partitionSchemeDescription = new NamedPartitionSchemeDescription( count: this.Count, names: this.Names); } else if (this.Singleton.IsPresent) { partitionSchemeDescription = new SingletonPartitionSchemeDescription(); } else if (this.UniformInt64Range.IsPresent) { partitionSchemeDescription = new UniformInt64RangePartitionSchemeDescription( count: this.Count, lowKey: this.LowKey, highKey: this.HighKey); } ServiceDescription serviceDescription = null; if (this.Stateful.IsPresent) { serviceDescription = new StatefulServiceDescription( serviceName: this.ServiceName, serviceTypeName: this.ServiceTypeName, partitionDescription: partitionSchemeDescription, targetReplicaSetSize: this.TargetReplicaSetSize, minReplicaSetSize: this.MinReplicaSetSize, hasPersistedState: this.HasPersistedState, applicationName: this.ApplicationName, initializationData: this.InitializationData, placementConstraints: this.PlacementConstraints, correlationScheme: this.CorrelationScheme, serviceLoadMetrics: this.ServiceLoadMetrics, servicePlacementPolicies: this.ServicePlacementPolicies, defaultMoveCost: this.DefaultMoveCost, isDefaultMoveCostSpecified: this.IsDefaultMoveCostSpecified, servicePackageActivationMode: this.ServicePackageActivationMode, serviceDnsName: this.ServiceDnsName, scalingPolicies: this.ScalingPolicies, tagsRequiredToPlace: this.TagsRequiredToPlace, tagsRequiredToRun: this.TagsRequiredToRun, flags: this.Flags, replicaRestartWaitDurationSeconds: this.ReplicaRestartWaitDurationSeconds, quorumLossWaitDurationSeconds: this.QuorumLossWaitDurationSeconds, standByReplicaKeepDurationSeconds: this.StandByReplicaKeepDurationSeconds, servicePlacementTimeLimitSeconds: this.ServicePlacementTimeLimitSeconds, dropSourceReplicaOnMove: this.DropSourceReplicaOnMove, replicaLifecycleDescription: this.ReplicaLifecycleDescription, auxiliaryReplicaCount: this.AuxiliaryReplicaCount); } else if (this.Stateless.IsPresent) { serviceDescription = new StatelessServiceDescription( serviceName: this.ServiceName, serviceTypeName: this.ServiceTypeName, partitionDescription: partitionSchemeDescription, instanceCount: this.InstanceCount, applicationName: this.ApplicationName, initializationData: this.InitializationData, placementConstraints: this.PlacementConstraints, correlationScheme: this.CorrelationScheme, serviceLoadMetrics: this.ServiceLoadMetrics, servicePlacementPolicies: this.ServicePlacementPolicies, defaultMoveCost: this.DefaultMoveCost, isDefaultMoveCostSpecified: this.IsDefaultMoveCostSpecified, servicePackageActivationMode: this.ServicePackageActivationMode, serviceDnsName: this.ServiceDnsName, scalingPolicies: this.ScalingPolicies, tagsRequiredToPlace: this.TagsRequiredToPlace, tagsRequiredToRun: this.TagsRequiredToRun, minInstanceCount: this.MinInstanceCount, minInstancePercentage: this.MinInstancePercentage, flags: this.Flags, instanceCloseDelayDurationSeconds: this.InstanceCloseDelayDurationSeconds, instanceLifecycleDescription: this.InstanceLifecycleDescription, instanceRestartWaitDurationSeconds: this.InstanceRestartWaitDurationSeconds); } this.ServiceFabricClient.Services.CreateServiceAsync( applicationId: this.ApplicationId, serviceDescription: serviceDescription, serverTimeout: this.ServerTimeout, cancellationToken: this.CancellationToken).GetAwaiter().GetResult(); Console.WriteLine("Success!"); }
/// <summary> /// This API supports the Service Fabric platform and is not meant to be called from your code /// </summary> /// <param name="token">This API supports the Service Fabric platform and is not meant to be called from your code</param> /// <returns></returns> protected override async Task OnExecuteAsync(CancellationToken token) { this.serviceDescription = await FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync( () => this.FabricClient.ServiceManager.GetServiceDescriptionAsync( this.failoverTestScenarioParameters.PartitionSelector.ServiceName, this.failoverTestScenarioParameters.RequestTimeout, token), this.failoverTestScenarioParameters.OperationTimeout, token).ConfigureAwait(false); bool hasPersistedState = false; if (this.serviceDescription.IsStateful()) { StatefulServiceDescription statefulDescription = this.serviceDescription as StatefulServiceDescription; ReleaseAssert.AssertIf(statefulDescription == null, "Stateful service description is not WinFabricStatefulServiceDescription"); hasPersistedState = statefulDescription.HasPersistedState; } Log.WriteInfo(TraceType, "Validating Service health and availability"); await this.FabricClient.TestManager.ValidateServiceAsync( this.failoverTestScenarioParameters.PartitionSelector.ServiceName, this.failoverTestScenarioParameters.MaxServiceStabilizationTimeout, token); Log.WriteInfo(TraceType, "Getting Selected Partition"); var getPartitionStateAction = new GetSelectedPartitionStateAction(this.failoverTestScenarioParameters.PartitionSelector) { RequestTimeout = this.failoverTestScenarioParameters.RequestTimeout, ActionTimeout = this.failoverTestScenarioParameters.OperationTimeout }; await this.TestContext.ActionExecutor.RunAsync(getPartitionStateAction, token); Guid selectedPartitionId = getPartitionStateAction.Result.PartitionId; Log.WriteInfo(TraceType, "Running test for partition {0}", selectedPartitionId); this.ReportProgress("Selected partition {0} for testing failover", selectedPartitionId); PartitionSelector selectedPartition = PartitionSelector.PartitionIdOf(this.failoverTestScenarioParameters.PartitionSelector.ServiceName, selectedPartitionId); while (this.failoverTestScenarioParameters.TimeToRun - this.GetElapsedTime() > TimeSpan.Zero && !token.IsCancellationRequested) { if (this.serviceDescription.IsStateful()) { ReplicaSelector primaryReplicaSelector = ReplicaSelector.PrimaryOf(selectedPartition); ReplicaSelector secondaryReplicaSelector = ReplicaSelector.RandomSecondaryOf(selectedPartition); // Make Primary go through RemoveReplica, RestartReplica and RestartCodePackage await this.TestReplicaFaultsAsync(primaryReplicaSelector, "Primary", hasPersistedState, token); // Make Secondary go through RemoveReplica, RestartReplica and RestartCodePackage await this.TestReplicaFaultsAsync(secondaryReplicaSelector, "Secondary", hasPersistedState, token); } else { ReplicaSelector randomInstanceSelector = ReplicaSelector.RandomOf(selectedPartition); // Make Stateless Instance go through RemoveReplica, RestartReplica and RestartCodePackage await this.TestReplicaFaultsAsync(randomInstanceSelector, "Stateless Instance", hasPersistedState, token); } if (this.serviceDescription.IsStateful()) { // Restart all secondary replicas and make sure the replica set recovers await this.InvokeAndValidateFaultAsync( "Restarting all the secondary replicas", () => { #pragma warning disable 618 return(this.FabricClient.TestManager.RestartPartitionAsync( selectedPartition, RestartPartitionMode.OnlyActiveSecondaries, this.failoverTestScenarioParameters.OperationTimeout, token)); #pragma warning restore 618 }, token); // Restart all replicas if service is persisted if (hasPersistedState) { await this.InvokeAndValidateFaultAsync( "Restarting all replicas including Primary", () => { #pragma warning disable 618 return(this.FabricClient.TestManager.RestartPartitionAsync( selectedPartition, RestartPartitionMode.AllReplicasOrInstances, this.failoverTestScenarioParameters.OperationTimeout, token)); #pragma warning restore 618 }, token); } // Induce move and swap primary a few times await this.InvokeAndValidateFaultAsync( "Move Primary to a different node", () => { return(this.FabricClient.FaultManager.MovePrimaryAsync( string.Empty, selectedPartition, true, this.failoverTestScenarioParameters.OperationTimeout, token)); }, token); // Induce move secondary a few times await this.InvokeAndValidateFaultAsync( "Move Secondary to a different node", () => { return(this.FabricClient.FaultManager.MoveSecondaryAsync( string.Empty, string.Empty, selectedPartition, true, this.failoverTestScenarioParameters.OperationTimeout, token)); }, token); } else { // Restart all stateless instances await this.InvokeAndValidateFaultAsync( "Restarting all stateless instances for partition", () => { #pragma warning disable 618 return(this.FabricClient.TestManager.RestartPartitionAsync( selectedPartition, RestartPartitionMode.AllReplicasOrInstances, this.failoverTestScenarioParameters.OperationTimeout, token)); #pragma warning restore 618 }, token); } } }
private bool TryCreateStatefulServiceDescription(out StatefulServiceDescription sd) { sd = null; try { sd = new StatefulServiceDescription(); sd.ApplicationName = new Uri(this.control.Package.ApplicationAddress); sd.ServiceName = new Uri(this.control.Package.ServiceAddress); sd.ServiceTypeName = this.control.Package.ServiceType; int minRep; if (!this.TryGetData("ServiceStatefulMinReplica", out minRep)) { return false; } sd.MinReplicaSetSize = minRep; int tgtSize; if (!this.TryGetData("ServiceStatefulTargetReplica", out tgtSize)) { return false; } sd.TargetReplicaSetSize = tgtSize; sd.HasPersistedState = false; string hasPersistedValue; if (this.control.Package.Data.TryGetValue("ServiceStatefulPersisted", out hasPersistedValue)) { if (hasPersistedValue == "true") { sd.HasPersistedState = true; } } PartitionSchemeDescription psd; if (!this.TryCreatePartitionDescription(out psd)) { return false; } sd.PartitionSchemeDescription = psd; return true; } catch (Exception e) { log.Error("failed to create StatelessServiceDescription, exception={0}", e.Message); return false; } }
protected override async Task ExecuteActionAsync(FabricTestContext testContext, RestartPartitionAction action, CancellationToken cancellationToken) { ThrowIf.Null(action.PartitionSelector, "partitionSelector"); this.helper = new TimeoutHelper(action.ActionTimeout); // get service info so we can validate if the operation is valid ServiceDescription result = await FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync( () => testContext.FabricClient.ServiceManager.GetServiceDescriptionAsync( action.PartitionSelector.ServiceName, action.RequestTimeout, cancellationToken), this.helper.GetRemainingTime(), cancellationToken).ConfigureAwait(false); if (result.Kind != ServiceDescriptionKind.Stateful && action.RestartPartitionMode == RestartPartitionMode.OnlyActiveSecondaries) { throw new InvalidOperationException(StringHelper.Format(StringResources.Error_InvalidServiceTypeTestability, "RestartPartitionMode.OnlyActiveSecondaries", "Stateful", action.PartitionSelector.ServiceName, "Stateless")); } bool hasPersistedState = false; if (result.Kind == ServiceDescriptionKind.Stateful) { StatefulServiceDescription statefulDescription = result as StatefulServiceDescription; ReleaseAssert.AssertIf(statefulDescription == null, "Stateful service description is not WinFabricStatefulServiceDescription"); hasPersistedState = statefulDescription.HasPersistedState; } // now actually select a partition var getPartitionStateAction = new GetSelectedPartitionStateAction(action.PartitionSelector) { RequestTimeout = action.RequestTimeout, ActionTimeout = helper.GetRemainingTime() }; await testContext.ActionExecutor.RunAsync(getPartitionStateAction, cancellationToken); Guid partitionId = getPartitionStateAction.Result.PartitionId; // get replicas for target ServiceReplicaList replicasResult = await FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync( () => testContext.FabricClient.QueryManager.GetReplicaListAsync( partitionId, 0, action.RequestTimeout, cancellationToken), this.helper.GetRemainingTime(), cancellationToken).ConfigureAwait(false); // get replicas for fm in order to get the primary ServiceReplicaList fmReplicasResult = await FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync( () => testContext.FabricClient.QueryManager.GetReplicaListAsync( Constants.FmPartitionId, 0, action.RequestTimeout, cancellationToken), this.helper.GetRemainingTime(), cancellationToken).ConfigureAwait(false); string fmPrimaryNodeName = string.Empty; var readyFMReplicas = fmReplicasResult.Where(r => r.ReplicaStatus == ServiceReplicaStatus.Ready).ToArray(); foreach (var replica in readyFMReplicas) { StatefulServiceReplica statefulReplica = replica as StatefulServiceReplica; ReleaseAssert.AssertIf(statefulReplica == null, "FM Replica is not a stateful replica"); if (statefulReplica.ReplicaRole == ReplicaRole.Primary) { fmPrimaryNodeName = replica.NodeName; } } if (string.IsNullOrEmpty(fmPrimaryNodeName)) { throw new FabricException(StringHelper.Format(StringResources.Error_PartitionPrimaryNotReady, "FailoverManager"), FabricErrorCode.NotReady); } ////------------------------------------------------------ // target ut at the fm primary only UnreliableTransportBehavior behavior = new UnreliableTransportBehavior("*", "DoReconfiguration"); behavior.AddFilterForPartitionId(partitionId); string behaviorName = "BlockDoReconfiguration"; await FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync( () => testContext.FabricClient.TestManager.AddUnreliableTransportBehaviorAsync( fmPrimaryNodeName, behaviorName, behavior, action.RequestTimeout, cancellationToken), this.helper.GetRemainingTime(), cancellationToken).ConfigureAwait(false); // TODO: Wait for some time so that the unreliable transport behavior can be read from the files. // Bug#2271465 - Unreliable transport through API should return only once the behavior has been successfully applied await Task.Delay(TimeSpan.FromSeconds(5.0), cancellationToken).ConfigureAwait(false); bool triedToRemovedBehavior = false; // inspect the actual replicas to restart, only operate on stable ones try { var stableReplicasToRestart = replicasResult.Where(r => r.ReplicaStatus == ServiceReplicaStatus.Ready).ToArray(); foreach (var replica in stableReplicasToRestart) { var currentReplica = replica; if (action.RestartPartitionMode == RestartPartitionMode.OnlyActiveSecondaries) { StatefulServiceReplica statefulReplica = currentReplica as StatefulServiceReplica; ReleaseAssert.AssertIf(statefulReplica == null, "Stateful service replica is not StatefulServiceReplica"); if (statefulReplica.ReplicaRole == ReplicaRole.Primary) { continue; } } if (hasPersistedState) { await FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync( () => testContext.FabricClient.FaultManager.RestartReplicaAsync( currentReplica.NodeName, partitionId, currentReplica.Id, CompletionMode.DoNotVerify, action.RequestTimeout.TotalSeconds, cancellationToken), this.helper.GetRemainingTime(), cancellationToken).ConfigureAwait(false); } else { await FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync( () => testContext.FabricClient.FaultManager.RemoveReplicaAsync( currentReplica.NodeName, partitionId, currentReplica.Id, CompletionMode.DoNotVerify, false, /*force remove*/ action.RequestTimeout.TotalSeconds, cancellationToken), this.helper.GetRemainingTime(), cancellationToken).ConfigureAwait(false); } } triedToRemovedBehavior = true; await FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync( () => testContext.FabricClient.TestManager.RemoveUnreliableTransportBehaviorAsync( fmPrimaryNodeName, behaviorName, action.RequestTimeout, cancellationToken), FabricClientRetryErrors.RemoveUnreliableTransportBehaviorErrors.Value, this.helper.GetRemainingTime(), cancellationToken).ConfigureAwait(false); // TODO: Wait for some time so that the unreliable transport behavior can be read from the files. // Bug#2271465 - Unreliable transport through API should return only once the behavior has been successfully applied await Task.Delay(TimeSpan.FromSeconds(5.0)).ConfigureAwait(false); } finally { // TODO: Provide a way to clear all behaviors just in case. if (!triedToRemovedBehavior) { ActionTraceSource.WriteWarning(TraceType, "Exception after adding behavior to block messages. Removing behavior synchronously"); FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync( () => testContext.FabricClient.TestManager.RemoveUnreliableTransportBehaviorAsync( fmPrimaryNodeName, behaviorName, action.RequestTimeout, cancellationToken), FabricClientRetryErrors.RemoveUnreliableTransportBehaviorErrors.Value, this.helper.GetRemainingTime(), cancellationToken).GetAwaiter().GetResult(); // TODO: Wait for some time so that the unreliable transport behavior can be read from the files. // Bug#2271465 - Unreliable transport through API should return only once the behavior has been successfully applied Task.Delay(TimeSpan.FromSeconds(5.0)).GetAwaiter().GetResult(); } } // -- note there's no explict validation // action result action.Result = new RestartPartitionResult(getPartitionStateAction.Result); ResultTraceString = StringHelper.Format("RestartPartitionAction succeeded for {0} with RestartPartitionMode = {1}", partitionId, action.RestartPartitionMode); }
protected override async Task ExecuteActionAsync(FabricTestContext testContext, InvokeQuorumLossAction action, CancellationToken cancellationToken) { ThrowIf.Null(action.PartitionSelector, "PartitionSelector"); var helper = new TimeoutHelper(action.ActionTimeout); // get info about the service so we can check type and trss ServiceDescription result = await FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync( () => testContext.FabricClient.ServiceManager.GetServiceDescriptionAsync( action.PartitionSelector.ServiceName, action.RequestTimeout, cancellationToken), helper.GetRemainingTime(), cancellationToken).ConfigureAwait(false); if (result.Kind != ServiceDescriptionKind.Stateful) { throw new InvalidOperationException(StringHelper.Format(StringResources.Error_InvalidServiceTypeTestability, "QuorumLoss", "Stateful", action.PartitionSelector.ServiceName, "Stateless")); } StatefulServiceDescription statefulServiceDescription = result as StatefulServiceDescription; ReleaseAssert.AssertIf(statefulServiceDescription == null, "Service is not a stateful service"); if (!statefulServiceDescription.HasPersistedState) { throw new InvalidOperationException(StringHelper.Format(StringResources.Error_InvalidServiceTypeTestability, "QuorumLoss", "Stateful Persistent", action.PartitionSelector.ServiceName, "Stateful In-Memory Only")); } // figure out /which/ partition to select var getPartitionStateAction = new GetSelectedPartitionStateAction(action.PartitionSelector) { RequestTimeout = action.RequestTimeout, ActionTimeout = helper.GetRemainingTime() }; await testContext.ActionExecutor.RunAsync(getPartitionStateAction, cancellationToken); Guid partitionId = getPartitionStateAction.Result.PartitionId; // get data about replicas in that partition ServiceReplicaList replicasResult = await FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync( () => testContext.FabricClient.QueryManager.GetReplicaListAsync( partitionId, 0, action.RequestTimeout, cancellationToken), helper.GetRemainingTime(), cancellationToken).ConfigureAwait(false); var removeUTRequestList = new List <Tuple <string, string> >(); Dictionary <Tuple <string, string>, Task> removeUTTaskDictionary = new Dictionary <Tuple <string, string>, Task>(); try { var stableReplicas = replicasResult.Where(r => r.ReplicaStatus == ServiceReplicaStatus.Ready).ToArray(); var stableReplicasToRemove = new List <StatefulServiceReplica>(); long replicasToRestartWithoutPrimary = action.QuorumLossMode == QuorumLossMode.AllReplicas ? stableReplicas.Length - 1 : FabricCluster.GetWriteQuorumSize(replicasResult.Count); foreach (var replica in stableReplicas) { StatefulServiceReplica statefulReplica = replica as StatefulServiceReplica; ReleaseAssert.AssertIf(statefulReplica == null, "Service Replica is not of stateful type even though service is stateful"); if (statefulReplica.ReplicaRole != ReplicaRole.Primary) { replicasToRestartWithoutPrimary--; } if (replicasToRestartWithoutPrimary >= 0 || statefulReplica.ReplicaRole == ReplicaRole.Primary) { stableReplicasToRemove.Add(statefulReplica); } } // for selected replicas, block reopen so that when we restart the replica (NOT remove the replica) it doesn't come up var utTaskList = new List <Task>(); foreach (var statefulReplica in stableReplicasToRemove) { string nodeName = statefulReplica.NodeName; UnreliableTransportBehavior behavior = new UnreliableTransportBehavior("*", "StatefulServiceReopen"); behavior.AddFilterForPartitionId(partitionId); string behaviorName = "BlockStatefulServiceReopen_" + nodeName; removeUTRequestList.Add(new Tuple <string, string>(nodeName, behaviorName)); utTaskList.Add( FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync( () => testContext.FabricClient.TestManager.AddUnreliableTransportBehaviorAsync( nodeName, behaviorName, behavior, action.RequestTimeout, cancellationToken), helper.GetRemainingTime(), cancellationToken)); } await Task.WhenAll(utTaskList).ConfigureAwait(false); // TODO: Wait for some time so that the unreliable transport behavior can be read from the files. // Bug#2271465 - Unreliable transport through API should return only once the behavior has been successfully applied await Task.Delay(TimeSpan.FromSeconds(5.0), cancellationToken); var restartReplicaTaskList = new List <Task>(); foreach (var statefulReplica in stableReplicasToRemove) { ReplicaSelector replicaSelector = ReplicaSelector.ReplicaIdOf(PartitionSelector.PartitionIdOf(action.PartitionSelector.ServiceName, partitionId), statefulReplica.Id); var restartReplicaAction = new RestartReplicaAction(replicaSelector) { CompletionMode = CompletionMode.DoNotVerify, RequestTimeout = action.RequestTimeout, ActionTimeout = helper.GetRemainingTime() }; restartReplicaTaskList.Add(testContext.ActionExecutor.RunAsync(restartReplicaAction, cancellationToken)); } await Task.WhenAll(restartReplicaTaskList).ConfigureAwait(false); await AsyncWaiter.WaitAsync(action.QuorumLossDuration, cancellationToken).ConfigureAwait(false); // validate ServicePartitionList partitionsResult = await FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync( () => testContext.FabricClient.QueryManager.GetPartitionListAsync( action.PartitionSelector.ServiceName, null, action.RequestTimeout, cancellationToken), FabricClientRetryErrors.GetPartitionListFabricErrors.Value, helper.GetRemainingTime(), cancellationToken).ConfigureAwait(false); foreach (StatefulServicePartition partition in partitionsResult) { if (partition.PartitionInformation.Id == partitionId) { ReleaseAssert.AssertIf(partition.PartitionStatus != ServicePartitionStatus.InQuorumLoss, "Partition failed to be in Quorum Loss."); break; } } foreach (var removeUTParams in removeUTRequestList) { var currentParams = removeUTParams; Task task = FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync( () => testContext.FabricClient.TestManager.RemoveUnreliableTransportBehaviorAsync( currentParams.Item1, /*nodeName*/ currentParams.Item2, /*behaviorName*/ action.RequestTimeout, cancellationToken), FabricClientRetryErrors.RemoveUnreliableTransportBehaviorErrors.Value, helper.GetRemainingTime(), cancellationToken); removeUTTaskDictionary[currentParams] = task; } await Task.WhenAll(removeUTTaskDictionary.Values).ConfigureAwait(false); // TODO: Wait for some time so that the removal of this unreliable transport behavior can be read from the files. // Bug#2271465 - Unreliable transport through API should return only once the behavior has been successully applied await Task.Delay(TimeSpan.FromSeconds(5.0), cancellationToken); } finally { var removeUTTaskList = new List <Task>(); foreach (var removeUTRequest in removeUTTaskDictionary) { var currentRemoveUTRequest = removeUTRequest; if (currentRemoveUTRequest.Value == null || currentRemoveUTRequest.Value.IsFaulted) { removeUTTaskList.Add( FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync( () => testContext.FabricClient.TestManager.RemoveUnreliableTransportBehaviorAsync( currentRemoveUTRequest.Key.Item1, /*nodeName*/ currentRemoveUTRequest.Key.Item2, /*behaviorName*/ action.RequestTimeout, cancellationToken), FabricClientRetryErrors.RemoveUnreliableTransportBehaviorErrors.Value, helper.GetRemainingTime(), cancellationToken)); } } Task.WhenAll(removeUTTaskList).Wait(cancellationToken); // TODO: Wait for some time so that the removal of this unreliable transport behavior can be read from the files. // Bug#2271465 - Unreliable transport through API should return only once the behavior has been successully applied Task.Delay(TimeSpan.FromSeconds(5.0), cancellationToken).GetAwaiter().GetResult(); } action.Result = new InvokeQuorumLossResult(getPartitionStateAction.Result); this.ResultTraceString = StringHelper.Format("InvokeQuorumLossAction succeeded for {0} with QuorumLossMode = {1}", partitionId, action.QuorumLossMode); }
/// <summary> /// Serializes the object to JSON. /// </summary> /// <param name="writer">The <see cref="T: Newtonsoft.Json.JsonWriter" /> to write to.</param> /// <param name="obj">The object to serialize to JSON.</param> internal static void Serialize(JsonWriter writer, StatefulServiceDescription obj) { // Required properties are always serialized, optional properties are serialized when not null. writer.WriteStartObject(); writer.WriteProperty(obj.ServiceKind, "ServiceKind", ServiceKindConverter.Serialize); writer.WriteProperty(obj.ServiceName, "ServiceName", ServiceNameConverter.Serialize); writer.WriteProperty(obj.ServiceTypeName, "ServiceTypeName", JsonWriterExtensions.WriteStringValue); writer.WriteProperty(obj.PartitionDescription, "PartitionDescription", PartitionSchemeDescriptionConverter.Serialize); writer.WriteProperty(obj.TargetReplicaSetSize, "TargetReplicaSetSize", JsonWriterExtensions.WriteIntValue); writer.WriteProperty(obj.MinReplicaSetSize, "MinReplicaSetSize", JsonWriterExtensions.WriteIntValue); writer.WriteProperty(obj.HasPersistedState, "HasPersistedState", JsonWriterExtensions.WriteBoolValue); writer.WriteProperty(obj.DefaultMoveCost, "DefaultMoveCost", MoveCostConverter.Serialize); writer.WriteProperty(obj.ServicePackageActivationMode, "ServicePackageActivationMode", ServicePackageActivationModeConverter.Serialize); if (obj.ApplicationName != null) { writer.WriteProperty(obj.ApplicationName, "ApplicationName", ApplicationNameConverter.Serialize); } if (obj.InitializationData != null) { writer.WriteProperty(obj.InitializationData, "InitializationData", ByteArrayConverter.Serialize); } if (obj.PlacementConstraints != null) { writer.WriteProperty(obj.PlacementConstraints, "PlacementConstraints", JsonWriterExtensions.WriteStringValue); } if (obj.CorrelationScheme != null) { writer.WriteEnumerableProperty(obj.CorrelationScheme, "CorrelationScheme", ServiceCorrelationDescriptionConverter.Serialize); } if (obj.ServiceLoadMetrics != null) { writer.WriteEnumerableProperty(obj.ServiceLoadMetrics, "ServiceLoadMetrics", ServiceLoadMetricDescriptionConverter.Serialize); } if (obj.ServicePlacementPolicies != null) { writer.WriteEnumerableProperty(obj.ServicePlacementPolicies, "ServicePlacementPolicies", ServicePlacementPolicyDescriptionConverter.Serialize); } if (obj.IsDefaultMoveCostSpecified != null) { writer.WriteProperty(obj.IsDefaultMoveCostSpecified, "IsDefaultMoveCostSpecified", JsonWriterExtensions.WriteBoolValue); } if (obj.ServiceDnsName != null) { writer.WriteProperty(obj.ServiceDnsName, "ServiceDnsName", JsonWriterExtensions.WriteStringValue); } if (obj.ScalingPolicies != null) { writer.WriteEnumerableProperty(obj.ScalingPolicies, "ScalingPolicies", ScalingPolicyDescriptionConverter.Serialize); } if (obj.Flags != null) { writer.WriteProperty(obj.Flags, "Flags", JsonWriterExtensions.WriteIntValue); } if (obj.ReplicaRestartWaitDurationSeconds != null) { writer.WriteProperty(obj.ReplicaRestartWaitDurationSeconds, "ReplicaRestartWaitDurationSeconds", JsonWriterExtensions.WriteLongValue); } if (obj.QuorumLossWaitDurationSeconds != null) { writer.WriteProperty(obj.QuorumLossWaitDurationSeconds, "QuorumLossWaitDurationSeconds", JsonWriterExtensions.WriteLongValue); } if (obj.StandByReplicaKeepDurationSeconds != null) { writer.WriteProperty(obj.StandByReplicaKeepDurationSeconds, "StandByReplicaKeepDurationSeconds", JsonWriterExtensions.WriteLongValue); } if (obj.ServicePlacementTimeLimitSeconds != null) { writer.WriteProperty(obj.ServicePlacementTimeLimitSeconds, "ServicePlacementTimeLimitSeconds", JsonWriterExtensions.WriteLongValue); } if (obj.DropSourceReplicaOnMove != null) { writer.WriteProperty(obj.DropSourceReplicaOnMove, "DropSourceReplicaOnMove", JsonWriterExtensions.WriteBoolValue); } writer.WriteEndObject(); }