protected override void ProcessRecord() { this.WriteObject(string.Format( "Note:Adding transport behavior causes reliability issues on the cluster.\n" + "Note: The behavior {0} is applied on the node until it is removed with Remove-ServiceFabricTransportBehavior cmdlet.", BehaviorName)); if (this.ShouldProcess(this.NodeName)) { if (this.Force || this.ShouldContinue(string.Empty, string.Empty)) { try { if (this.GetClusterConnection() == null) { throw new Exception("Connection to Cluster is null, Connect to Cluster before invoking the cmdlet"); } Microsoft.ServiceFabric.Powershell.InternalClusterConnection clusterConnection = new Microsoft.ServiceFabric.Powershell.InternalClusterConnection(this.GetClusterConnection()); ValidateParams(); TimeSpan delayInSeconds = string.IsNullOrEmpty(DelayInSeconds) ? TimeSpan.MaxValue : TimeSpan.FromSeconds(int.Parse(DelayInSeconds)); TimeSpan delaySpanInSeconds = string.IsNullOrEmpty(DelaySpanInSeconds) ? TimeSpan.Zero : TimeSpan.FromSeconds(int.Parse(DelaySpanInSeconds)); UnreliableTransportBehavior behavior = new UnreliableTransportBehavior( Destination, BehaviorName, double.Parse(ProbabilityToApply), delayInSeconds, delaySpanInSeconds, int.Parse(Priority), int.Parse(ApplyCount)); clusterConnection.AddUnreliableTransportAsync( NodeName, BehaviorName, behavior, this.GetTimeout(), this.GetCancellationToken()).Wait(); // localization of string not needed, since this cmdlet is an internal use. this.WriteObject(string.Format( "Added Unreliable transport for behavior: {0}.\n" + "Note: The behavior is applied on the node until it is removed with Remove-UnreliableTransport cmdlet.", BehaviorName)); } catch (AggregateException aggregateException) { aggregateException.Handle((ae) => { this.ThrowTerminatingError( ae, ConstantsInternal.AddUnreliableTransportId, this.GetClusterConnection()); return(true); }); } } } }
public static async Task RemoveUTAsync(FabricClient fabricClient, ActionStateBase state, TimeSpan requestTimeout, TimeSpan operationTimeout, CancellationToken cancellationToken) { InvokeQuorumLossState invokeQuorumLossState = Convert(state); Guid partitionId = invokeQuorumLossState.Info.PartitionId; List <Task> tasks = new List <Task>(); if (invokeQuorumLossState.Info.UnreliableTransportInfo != null) { foreach (Tuple <string, string> info in invokeQuorumLossState.Info.UnreliableTransportInfo) { UnreliableTransportBehavior behavior = new UnreliableTransportBehavior("*", "StatefulServiceReopen"); behavior.AddFilterForPartitionId(partitionId); string nodeName = info.Item1; string behaviorName = info.Item2; TestabilityTrace.TraceSource.WriteInfo(StepBase.TraceType, "{0} - Cleaning up behavior={1}", state.OperationId, behaviorName); Task task = FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync( () => fabricClient.TestManager.RemoveUnreliableTransportBehaviorAsync( nodeName, behaviorName, requestTimeout, cancellationToken), FabricClientRetryErrors.RemoveUnreliableTransportBehaviorErrors.Value, operationTimeout, cancellationToken); tasks.Add(task); } await Task.WhenAll(tasks).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); } }
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); }
internal Task AddUnreliableTransportAsync( string source, string behaviorName, UnreliableTransportBehavior behavior, TimeSpan timeout, CancellationToken cancellationToken) { return(this.connection.FabricClient.TestManager.AddUnreliableTransportAsync( source, behaviorName, behavior, timeout, cancellationToken)); }