public override async Task <IOperationStatus> CreateOperationStatusAsync(IOperationDescription operationDescription, IOperationContext context)
        {
            context.ThrowIfNull(nameof(context));

            ClusterOperationDescription description = operationDescription == null ? null : operationDescription as ClusterOperationDescription;

            Trace.WriteInfo(TraceType, "CreateOperationStatusAsync: begin");
            IOperationStatus status = null;

            try
            {
                Trace.WriteInfo(TraceType, "CreateOperationStatusAsync: performing operation");
                var errorDetails = await DoOperation(description, context);

                Trace.WriteInfo(TraceType, "CreateOperationStatusAsync: building status");
                status = await BuildStatusAsync(description, context, errorDetails);
            }
            catch (Exception ex)
            {
                Trace.WriteError(this.TraceType, $"CreateOperationStatusAsync: Exception encountered: {ex}");
            }

            Trace.WriteInfo(TraceType, "CreateOperationStatusAsync: end");
            return(status);
        }
示例#2
0
        public override async Task CreateAsync(IOperationDescription description, IOperationContext context)
        {
            Trace.WriteInfo(TraceType, "CreateAsync called");
            description.ThrowIfNull(nameof(description));
            context.ThrowIfNull(nameof(context));

            string errorMessage;

            if (!this.ValidObjectType <ServiceOperationDescription>(description, out errorMessage))
            {
                throw new InvalidCastException(errorMessage);
            }

            var serviceOperationDescription = (ServiceOperationDescription)description;

            serviceOperationDescription.ApplicationName.ThrowIfNull(nameof(serviceOperationDescription.ApplicationName));
            serviceOperationDescription.ServiceName.ThrowIfNull(nameof(serviceOperationDescription.ServiceName));
            serviceOperationDescription.ServiceTypeName.ThrowIfNullOrWhiteSpace(nameof(serviceOperationDescription.ServiceTypeName));
            serviceOperationDescription.PartitionDescription.ThrowIfNull(nameof(serviceOperationDescription.PartitionDescription));
            Trace.WriteInfo(
                TraceType,
                "CreateAsync: Creating service. Name: {0}. Kind: {1}. Timeout: {2}",
                serviceOperationDescription.ServiceName,
                serviceOperationDescription.ServiceKind,
                context.OperationTimeout);
            await this.fabricClient.ServiceManager.CreateServiceAsync(
                this.CreateServiceDescription(serviceOperationDescription),
                context.OperationTimeout,
                context.CancellationToken);

            Trace.WriteInfo(TraceType, "CreateAsync: Create service call accepted");
        }
示例#3
0
        /// <summary>
        /// Executes the operation's logic.
        /// </summary>
        /// <param name="context">The execution context for this operation.</param>
        protected override void Execute(IOperationContext context)
        {
            context.ThrowIfNull(nameof(context));

            if (!typeof(IElevatedOperationContext).IsAssignableFrom(context.GetType()))
            {
                throw new ArgumentException($"{nameof(context)} must be an {nameof(IElevatedOperationContext)}.");
            }

            this.Execute(context as IElevatedOperationContext);
        }
示例#4
0
        /// <summary>
        /// Attempts to add content to the first possible parent container that accepts it, on a chain of parent containers.
        /// </summary>
        /// <param name="context">A reference to the operation context.</param>
        /// <param name="thingContainer">The first thing container to add to.</param>
        /// <param name="remainder">The remainder content to add, which overflows to the next container in the chain.</param>
        /// <param name="addIndex">The index at which to attempt to add, only for the first attempted container.</param>
        /// <param name="includeTileAsFallback">Optional. A value for whether to include tiles in the fallback chain.</param>
        /// <param name="requestorCreature">Optional. The creature requesting the addition of content.</param>
        /// <returns>True if the content was successfully added, false otherwise.</returns>
        protected bool AddContentToContainerOrFallback(IOperationContext context, IThingContainer thingContainer, ref IThing remainder, byte addIndex = byte.MaxValue, bool includeTileAsFallback = true, ICreature requestorCreature = null)
        {
            context.ThrowIfNull(nameof(context));
            thingContainer.ThrowIfNull(nameof(thingContainer));

            const byte FallbackIndex = byte.MaxValue;

            bool success      = false;
            bool firstAttempt = true;

            foreach (var targetContainer in thingContainer.GetParentContainerHierarchy(includeTileAsFallback))
            {
                IThing lastAddedThing = remainder;

                if (!success)
                {
                    (success, remainder) = targetContainer.AddContent(context.ItemFactory, remainder, firstAttempt ? addIndex : FallbackIndex);
                }
                else if (remainder != null)
                {
                    (success, remainder) = targetContainer.AddContent(context.ItemFactory, remainder);
                }

                firstAttempt = false;

                if (success)
                {
                    if (targetContainer is ITile targetTile)
                    {
                        this.SendNotification(
                            context,
                            new TileUpdatedNotification(
                                () => context.Map.PlayersThatCanSee(targetTile.Location),
                                targetTile.Location,
                                context.MapDescriptor.DescribeTile));

                        // context.EventRulesApi.EvaluateRules(this, EventRuleType.Collision, new CollisionEventRuleArguments(targetContainer.Location, lastAddedThing, requestorCreature));
                    }

                    // context.EventRulesApi.EvaluateRules(this, EventRuleType.Movement, new MovementEventRuleArguments(lastAddedThing, requestorCreature));
                }

                if (success && remainder == null)
                {
                    break;
                }
            }

            return(success);
        }
示例#5
0
        public override async Task <IList <IOperationStatus> > ProcessAsync(
            IList <IOperationDescription> descriptions,
            IOperationContext context)
        {
            descriptions.ThrowIfNull(nameof(descriptions));
            context.ThrowIfNull(nameof(context));

            // TODO: ContinuationToken support
            var operationContext =
                new OperationContext(
                    context.CancellationToken,
                    context.GetRemainingTimeOrThrow(),
                    string.Empty);

            return(await base.ProcessAsync(descriptions, operationContext));
        }
示例#6
0
        public override async Task DeleteAsync(IOperationDescription description, IOperationContext context)
        {
            Trace.WriteInfo(TraceType, "DeleteAsync called");
            description.ThrowIfNull(nameof(description));
            context.ThrowIfNull(nameof(context));

            string errorMessage;

            if (!this.ValidObjectType <ApplicationTypeVersionOperationDescription>(description, out errorMessage))
            {
                throw new InvalidCastException(errorMessage);
            }

            var appTypeDescription = (ApplicationTypeVersionOperationDescription)description;

            try
            {
                Trace.WriteInfo(
                    TraceType,
                    "DeleteAsync: Unprovisioning application type. Name: {0}. Version: {1}. Timeout: {2}",
                    appTypeDescription.TypeName,
                    appTypeDescription.TypeVersion,
                    context.OperationTimeout);
                await this.fabricClient.ApplicationManager.UnprovisionApplicationAsync(
                    appTypeDescription.TypeName,
                    appTypeDescription.TypeVersion,
                    context.OperationTimeout,
                    context.CancellationToken);

                Trace.WriteInfo(TraceType, "DeleteAsync: Unprovisioning call accepted");
            }
            catch (FabricElementNotFoundException nfe)
            {
                if (nfe.ErrorCode == FabricErrorCode.ApplicationTypeNotFound)
                {
                    Trace.WriteInfo(
                        TraceType,
                        "DeleteAsync: Application type not found. Name: {0}. Version: {1}",
                        appTypeDescription.TypeName,
                        appTypeDescription.TypeVersion);
                    return;
                }

                throw;
            }
        }
示例#7
0
        public override async Task CreateAsync(IOperationDescription description, IOperationContext context)
        {
            Trace.WriteInfo(TraceType, "CreateAsync called");
            description.ThrowIfNull(nameof(description));
            context.ThrowIfNull(nameof(context));

            string errorMessage;

            if (!this.ValidObjectType <ApplicationTypeVersionOperationDescription>(description, out errorMessage))
            {
                throw new InvalidCastException(errorMessage);
            }

            var appTypeDescription = (ApplicationTypeVersionOperationDescription)description;

            appTypeDescription.TypeName.ThrowIfNullOrWhiteSpace(nameof(appTypeDescription.TypeName));
            appTypeDescription.TypeVersion.ThrowIfNullOrWhiteSpace(nameof(appTypeDescription.TypeVersion));
            appTypeDescription.AppPackageUrl.ThrowIfNullOrWhiteSpace(nameof(appTypeDescription.AppPackageUrl));

            Uri appPackageUri;

            if (!Uri.TryCreate(appTypeDescription.AppPackageUrl, UriKind.Absolute, out appPackageUri))
            {
                throw new InvalidOperationException($"{nameof(appTypeDescription.AppPackageUrl)} must have an absolute Uri value.");
            }

            Trace.WriteInfo(
                TraceType,
                "CreateAsync: Provisioning application package. Uri: {0}. Timeout: {1}",
                appPackageUri,
                context.OperationTimeout);
            await this.fabricClient.ApplicationManager.ProvisionApplicationAsync(
                new ExternalStoreProvisionApplicationTypeDescription(
                    appPackageUri,
                    appTypeDescription.TypeName,
                    appTypeDescription.TypeVersion)
                { Async = true },
                context.OperationTimeout,
                context.CancellationToken);

            Trace.WriteInfo(TraceType, "CreateAsync: Provisioning call accepted");
        }
示例#8
0
        public override async Task DeleteAsync(IOperationDescription description, IOperationContext context)
        {
            Trace.WriteInfo(TraceType, "DeleteAsync called");
            description.ThrowIfNull(nameof(description));
            context.ThrowIfNull(nameof(context));

            string errorMessage;

            if (!this.ValidObjectType <ServiceOperationDescription>(description, out errorMessage))
            {
                throw new InvalidCastException(errorMessage);
            }

            var serviceOperationDescription = (ServiceOperationDescription)description;

            try
            {
                Trace.WriteInfo(
                    TraceType,
                    "DeleteAsync: Deleting service. Name: {0}. Timeout: {1}",
                    serviceOperationDescription.ServiceName,
                    context.OperationTimeout);
                await this.fabricClient.ServiceManager.DeleteServiceAsync(
                    new DeleteServiceDescription(serviceOperationDescription.ServiceName),
                    context.OperationTimeout,
                    context.CancellationToken);

                Trace.WriteInfo(TraceType, "DeleteAsync: Delete service call accepted");
            }
            catch (FabricServiceNotFoundException)
            {
                Trace.WriteInfo(
                    TraceType,
                    "DeleteAsync: Service not found. Name: {0}",
                    serviceOperationDescription.ServiceName);
            }
        }
示例#9
0
        public override async Task UpdateAsync(IOperationDescription description, IFabricOperationResult result, IOperationContext context)
        {
            Trace.WriteInfo(TraceType, "UpdateAsync called");
            description.ThrowIfNull(nameof(description));
            result.ThrowIfNull(nameof(result));
            result.OperationStatus.ThrowIfNull(nameof(result.OperationStatus));
            result.QueryResult.ThrowIfNull(nameof(result.QueryResult));
            context.ThrowIfNull(nameof(context));

            string errorMessage;

            if (!this.ValidObjectType <ServiceOperationDescription>(description, out errorMessage))
            {
                throw new InvalidCastException(errorMessage);
            }

            if (!this.ValidObjectType <ServiceClientFabricQueryResult>(result.QueryResult, out errorMessage))
            {
                throw new InvalidCastException(errorMessage);
            }

            var serviceOperationDescription = (ServiceOperationDescription)description;

            serviceOperationDescription.ServiceName.ThrowIfNull(nameof(serviceOperationDescription.ServiceName));
            Trace.WriteInfo(
                TraceType,
                "UpdateAsync: Updating service. Name: {0}. Timeout: {1}",
                serviceOperationDescription.ServiceName,
                context.OperationTimeout);
            await this.fabricClient.ServiceManager.UpdateServiceAsync(
                serviceOperationDescription.ServiceName,
                this.CreateServiceUpdateDescription(serviceOperationDescription),
                context.OperationTimeout,
                context.CancellationToken);

            Trace.WriteInfo(TraceType, "UpdateAsync: Service update call accepted");
        }
示例#10
0
        public override async Task <IOperationStatus> CreateOperationStatusAsync(
            IOperationDescription description,
            IOperationContext context)
        {
            description.ThrowIfNull(nameof(description));
            context.ThrowIfNull(nameof(context));

            Trace.WriteInfo(TraceType, "CreateOperationStatusAsync called");
            IOperationStatus status = null;

            try
            {
                IFabricOperationResult result = null;
                if (!this.Operations.OperationExists(description))
                {
                    result = await this.fabricClient.GetAsync(description, context);

                    status = result?.OperationStatus;
                    var operationContext =
                        new OperationContext(
                            context.CancellationToken,
                            Constants.MaxOperationTimeout,
                            context.ContinuationToken);
                    switch (description.OperationType)
                    {
                    case OperationType.CreateOrUpdate:
                        if (null == status)
                        {
                            try
                            {
                                await this.fabricClient.CreateAsync(
                                    description,
                                    operationContext);
                            }
                            catch (Exception e)
                            {
                                return(this.HandleOperationFailedStatus(
                                           description,
                                           nameof(this.fabricClient.CreateAsync),
                                           e));
                            }
                        }

                        break;

                    case OperationType.Delete:
                        try
                        {
                            await this.fabricClient.DeleteAsync(
                                description,
                                operationContext);
                        }
                        catch (Exception e)
                        {
                            return(this.HandleOperationFailedStatus(
                                       description,
                                       nameof(this.fabricClient.DeleteAsync),
                                       e));
                        }

                        break;

                    default:
                        Trace.WriteError(this.TraceType, "Unhandled operation type: {0}", description.OperationType);
                        break;
                    }

                    Trace.WriteInfo(
                        this.TraceType,
                        this.Operations.TryAdd(description)
                            ? "CreateOperationStatusAsync: Operation started for resource. OperationId: {0}. ResourceId: {1}."
                            : "CreateOperationStatusAsync: Failed to track operation for resource. OperationId: {0}. ResourceId: {1}.",
                        description.OperationSequenceNumber,
                        description.ResourceId);
                }

                result = await this.fabricClient.GetAsync(description, context);

                status = result?.OperationStatus;
            }
            catch (Exception e)
            {
                ResourceCommandProcessor.HandleException("CreateOperationStatusAsync", e, this.TraceType);
            }

            Trace.WriteInfo(
                TraceType,
                "CreateOperationStatusAsync: completed {0}",
                status.ToFormattedString());
            return(status);
        }
示例#11
0
        public override async Task<IFabricOperationResult> GetAsync(IOperationDescription description, IOperationContext context)
        {
            Trace.WriteInfo(TraceType, "GetAsync called");
            description.ThrowIfNull(nameof(description));
            context.ThrowIfNull(nameof(context));

            string errorMessage;
            if (!this.ValidObjectType<ApplicationOperationDescription>(description, out errorMessage))
            {
                throw new InvalidCastException(errorMessage);
            }

            var appDescription = (ApplicationOperationDescription)description;
            Application clusterApp = (await this.fabricClient.QueryManager.GetApplicationListAsync(
                appDescription.ApplicationUri,
                context.ContinuationToken,
                context.GetRemainingTimeOrThrow(),
                context.CancellationToken)).FirstOrDefault();

            var result = new FabricOperationResult()
            {
                OperationStatus = null,
                QueryResult = new ApplicationFabricQueryResult(clusterApp)
            };

            Trace.WriteInfo(
                TraceType,
                null == clusterApp
                    ? "GetAsync: Application not found. Name: {0}."
                    : "GetAsync: Application exists. Name: {0}.",
                appDescription.ApplicationUri);

            if (null == clusterApp)
            {
                if (description.OperationType == OperationType.Delete)
                {
                    result.OperationStatus =
                        new ApplicationOperationStatus(appDescription)
                        {
                            Status = ResultStatus.Succeeded,
                            Progress = new JObject(),
                            ErrorDetails = new JObject()
                        };

                    return result;
                }

                return null;
            }

            var status = GetResultStatus(clusterApp.ApplicationStatus);
            var progress = new JObject();
            var errorDetails = new JObject();
            if ((clusterApp.ApplicationStatus == ApplicationStatus.Ready && !appDescription.TypeVersion.Equals(clusterApp.ApplicationTypeVersion)) ||
                clusterApp.ApplicationStatus == ApplicationStatus.Upgrading ||
                clusterApp.ApplicationStatus == ApplicationStatus.Failed)
            {
                // TODO: Can deletions end up in a failed state?
                ApplicationUpgradeProgress upgradingApp =
                    await this.fabricClient.ApplicationManager.GetApplicationUpgradeProgressAsync(
                        appDescription.ApplicationUri,
                        context.OperationTimeout,
                        context.CancellationToken);

                if (upgradingApp.UpgradeState == ApplicationUpgradeState.RollingBackCompleted)
                {
                    // clusterApp.ApplicationStatus == ApplicationStatus.Ready

                    status = ResultStatus.Failed;
                    errorDetails = JObject.FromObject(
                        new
                        {
                            FailureReason = upgradingApp.FailureReason.HasValue ? upgradingApp.FailureReason.ToString() : string.Empty,
                            Details = upgradingApp.UpgradeStatusDetails
                        });
                }
                else if (upgradingApp.UpgradeState == ApplicationUpgradeState.RollingForwardCompleted)
                {
                    // clusterApp.ApplicationStatus == ApplicationStatus.Ready

                    status = ResultStatus.Failed;
                    errorDetails = JObject.FromObject(new { Details = $"Deployment completed with {clusterApp.ApplicationTypeVersion} version. Deployment goal was overriden through SF native APIs." });
                }
                else if (upgradingApp.UpgradeState == ApplicationUpgradeState.RollingBackInProgress ||
                         upgradingApp.UpgradeState == ApplicationUpgradeState.RollingForwardInProgress ||
                         upgradingApp.UpgradeState == ApplicationUpgradeState.RollingForwardPending)
                {
                    // clusterApp.ApplicationStatus == ApplicationStatus.Upgrading

                    status = ResultStatus.InProgress;
                    progress = JObject.FromObject(upgradingApp.CurrentUpgradeDomainProgress);
                }
                else if (upgradingApp.UpgradeState == ApplicationUpgradeState.Failed)
                {
                    // clusterApp.ApplicationStatus == ApplicationStatus.Failed

                    status = ResultStatus.Failed;
                    errorDetails = JObject.FromObject(
                        new
                        {
                            FailureReason = upgradingApp.FailureReason.HasValue ? upgradingApp.FailureReason.ToString() : string.Empty,
                            Details = upgradingApp.UpgradeStatusDetails
                        });
                }
            }

            result.OperationStatus = 
                new ApplicationOperationStatus(appDescription)
                {
                    Status = status,
                    Progress = progress,
                    ErrorDetails = errorDetails
                };

            return result;
        }
示例#12
0
        public override async Task UpdateAsync(IOperationDescription description, IFabricOperationResult result, IOperationContext context)
        {
            Trace.WriteInfo(TraceType, "UpdateAsync called");
            description.ThrowIfNull(nameof(description));
            result.ThrowIfNull(nameof(result));
            result.OperationStatus.ThrowIfNull(nameof(result.OperationStatus));
            result.QueryResult.ThrowIfNull(nameof(result.QueryResult));
            context.ThrowIfNull(nameof(context));

            string errorMessage;
            if (!this.ValidObjectType<ApplicationOperationDescription>(description, out errorMessage))
            {
                throw new InvalidCastException(errorMessage);
            }

            if (!this.ValidObjectType<ApplicationFabricQueryResult>(result.QueryResult, out errorMessage))
            {
                throw new InvalidCastException(errorMessage);
            }

            var appDescription = (ApplicationOperationDescription)description;
            appDescription.TypeVersion.ThrowIfNullOrWhiteSpace(nameof(appDescription.TypeVersion));
            appDescription.ApplicationUri.ThrowIfNull(nameof(appDescription.ApplicationUri));
            var appResult = (ApplicationFabricQueryResult)result.QueryResult;

            var healthPolicy = new ApplicationHealthPolicy();
            var defaultServiceTypeHealthPolicy = new ServiceTypeHealthPolicy();
            if (appDescription.UpgradePolicy?.ApplicationHealthPolicy != null)
            {
                healthPolicy.ConsiderWarningAsError =
                    appDescription.UpgradePolicy.ApplicationHealthPolicy.ConsiderWarningAsError;
                healthPolicy.MaxPercentUnhealthyDeployedApplications =
                    appDescription.UpgradePolicy.ApplicationHealthPolicy.MaxPercentUnhealthyDeployedApplications;

                if (appDescription.UpgradePolicy.ApplicationHealthPolicy.DefaultServiceTypeHealthPolicy != null)
                {
                    defaultServiceTypeHealthPolicy.MaxPercentUnhealthyPartitionsPerService =
                        appDescription.UpgradePolicy.ApplicationHealthPolicy.DefaultServiceTypeHealthPolicy
                            .MaxPercentUnhealthyPartitionsPerService;
                    defaultServiceTypeHealthPolicy.MaxPercentUnhealthyReplicasPerPartition =
                        appDescription.UpgradePolicy.ApplicationHealthPolicy.DefaultServiceTypeHealthPolicy
                            .MaxPercentUnhealthyReplicasPerPartition;
                    defaultServiceTypeHealthPolicy.MaxPercentUnhealthyServices =
                        appDescription.UpgradePolicy.ApplicationHealthPolicy.DefaultServiceTypeHealthPolicy
                            .MaxPercentUnhealthyServices;
                    healthPolicy.DefaultServiceTypeHealthPolicy = defaultServiceTypeHealthPolicy;
                }
            }

            var monitoringPolicy = new RollingUpgradeMonitoringPolicy();
            if (appDescription.UpgradePolicy?.RollingUpgradeMonitoringPolicy != null)
            {
                monitoringPolicy.FailureAction =
                    (UpgradeFailureAction) Enum.Parse(
                        typeof (UpgradeFailureAction),
                        appDescription.UpgradePolicy.RollingUpgradeMonitoringPolicy.FailureAction.ToString(),
                        true);
                monitoringPolicy.HealthCheckRetryTimeout =
                    appDescription.UpgradePolicy.RollingUpgradeMonitoringPolicy.HealthCheckRetryTimeout;
                monitoringPolicy.HealthCheckStableDuration =
                    appDescription.UpgradePolicy.RollingUpgradeMonitoringPolicy.HealthCheckStableDuration;
                monitoringPolicy.HealthCheckWaitDuration =
                    appDescription.UpgradePolicy.RollingUpgradeMonitoringPolicy.HealthCheckWaitDuration;
                monitoringPolicy.UpgradeDomainTimeout =
                    appDescription.UpgradePolicy.RollingUpgradeMonitoringPolicy.UpgradeDomainTimeout;
                monitoringPolicy.UpgradeTimeout = appDescription.UpgradePolicy.RollingUpgradeMonitoringPolicy.UpgradeTimeout;
            }

            var policyDescription = new MonitoredRollingApplicationUpgradePolicyDescription()
            {
                UpgradeMode = RollingUpgradeMode.Monitored,
                HealthPolicy = healthPolicy,
                MonitoringPolicy = monitoringPolicy
            };

            if (appDescription.UpgradePolicy != null)
            {
                if (appDescription.UpgradePolicy.ForceRestart.HasValue)
                {
                    policyDescription.ForceRestart = appDescription.UpgradePolicy.ForceRestart.Value;
                }

                if (appDescription.UpgradePolicy.UpgradeReplicaSetCheckTimeout.HasValue)
                {
                    policyDescription.UpgradeReplicaSetCheckTimeout = appDescription.UpgradePolicy.UpgradeReplicaSetCheckTimeout.Value;
                }
            }

            // Update
            var updateDescription = new ApplicationUpdateDescription(appDescription.ApplicationUri)
            {
                RemoveApplicationCapacity = appDescription.RemoveApplicationCapacity
            };

            if (appDescription.MinimumNodes.HasValue)
            {
                updateDescription.MinimumNodes = appDescription.MinimumNodes.Value;
            }

            if (appDescription.MaximumNodes.HasValue)
            {
                updateDescription.MaximumNodes = appDescription.MaximumNodes.Value;
            }

            if (appDescription.Metrics != null && appDescription.Metrics.Any())
            {
                updateDescription.Metrics = new List<ApplicationMetricDescription>();
                foreach (var metric in appDescription.Metrics)
                {
                    updateDescription.Metrics.Add(
                        new ApplicationMetricDescription()
                        {
                            Name = metric.Name,
                            MaximumNodeCapacity = metric.MaximumCapacity,
                            NodeReservationCapacity = metric.ReservationCapacity,
                            TotalApplicationCapacity = metric.TotalApplicationCapacity
                        });
                }
            }

            Trace.WriteInfo(
                TraceType,
                "UpdateAsync: Updating application. Name: {0}. Timeout: {1}",
                updateDescription.ApplicationName,
                context.OperationTimeout);
            await this.fabricClient.ApplicationManager.UpdateApplicationAsync(
                updateDescription,
                context.OperationTimeout,
                context.CancellationToken);
            Trace.WriteInfo(TraceType, "UpdateAsync: Application update call accepted");

            // Upgrade
            var upgradeDescription = new ApplicationUpgradeDescription()
            {
                ApplicationName = appDescription.ApplicationUri,
                TargetApplicationTypeVersion = appDescription.TypeVersion,
                UpgradePolicyDescription = policyDescription
            };

            if (appDescription.Parameters != null)
            {
                upgradeDescription.ApplicationParameters.Add(appDescription.Parameters.ToNameValueCollection());
            }

            try
            {
                Trace.WriteInfo(
                    TraceType,
                    "UpdateAsync: Upgrading application. Name: {0}. Version: {1}. TargetVersion: {2}. Timeout: {3}",
                    upgradeDescription.ApplicationName,
                    appResult.Application.ApplicationTypeVersion,
                    upgradeDescription.TargetApplicationTypeVersion,
                    context.OperationTimeout);
                await this.fabricClient.ApplicationManager.UpgradeApplicationAsync(
                    upgradeDescription,
                    context.OperationTimeout,
                    context.CancellationToken);
                Trace.WriteInfo(TraceType, "UpdateAsync: Application upgrade call accepted");
            }
            catch (FabricException fe)
            {
                if (fe.ErrorCode == FabricErrorCode.ApplicationAlreadyInTargetVersion)
                {
                    Trace.WriteInfo(TraceType, "UpdateAsync: Application already in target version: {0}.", upgradeDescription.TargetApplicationTypeVersion);
                    return;
                }

                if (fe.ErrorCode == FabricErrorCode.ApplicationUpgradeInProgress)
                {
                    Trace.WriteInfo(TraceType, "UpdateAsync: Application upgrade in progress with same version: {0}", upgradeDescription.TargetApplicationTypeVersion);                 
                }
                else
                {
                    Trace.WriteError(TraceType, "UpdateAsync: Application upgrade encountered an exception: {0}", fe);
                    throw;
                }                
            }
            catch (Exception e)
            {
                Trace.WriteInfo(TraceType, "UpdateAsync: Application upgrade encountered an exception: {0}", e);
                throw;
            }

            // UpgradeUpdate
            ApplicationUpgradeProgress upgradeProgress = null;
            try
            {
                upgradeProgress = await this.fabricClient.ApplicationManager.GetApplicationUpgradeProgressAsync(
                        appDescription.ApplicationUri,
                        context.OperationTimeout,
                        context.CancellationToken);
            }
            catch (Exception)
            {
                Trace.WriteWarning(
                    TraceType,
                    "UpdateAsync: Failed to get the application upgrade progress to determine the parameters for upgrade update. Need to retry the operation. Application Name: {0}",
                    appDescription.ApplicationUri);

                throw new FabricTransientException();
            }
                       
            ApplicationUpgradeUpdateDescription upgradeUpdateDescription;
            if (upgradeProgress.UpgradeState == ApplicationUpgradeState.RollingBackInProgress)
            {
                // During rollback we can only change below properties
                upgradeUpdateDescription = new ApplicationUpgradeUpdateDescription()
                {
                    ApplicationName = appDescription.ApplicationUri,
                    UpgradeReplicaSetCheckTimeout = appDescription.UpgradePolicy.UpgradeReplicaSetCheckTimeout,
                    ForceRestart = appDescription.UpgradePolicy.ForceRestart
                };
            }
            else
            {
                upgradeUpdateDescription = new ApplicationUpgradeUpdateDescription()
                {
                    ApplicationName = appDescription.ApplicationUri,
                    UpgradeDomainTimeout = monitoringPolicy.UpgradeDomainTimeout,
                    UpgradeTimeout = monitoringPolicy.UpgradeTimeout,
                    HealthCheckRetryTimeout = monitoringPolicy.HealthCheckRetryTimeout,
                    HealthCheckWaitDuration = monitoringPolicy.HealthCheckWaitDuration,
                    HealthCheckStableDuration = monitoringPolicy.HealthCheckStableDuration,
                    UpgradeReplicaSetCheckTimeout = policyDescription.UpgradeReplicaSetCheckTimeout,
                    ForceRestart = policyDescription.ForceRestart,
                    FailureAction = monitoringPolicy.FailureAction,
                    HealthPolicy = healthPolicy
                };
            }

            try
            {               

                Trace.WriteInfo(
                    TraceType,
                    "UpdateAsync: Updating application upgrade in progress. Name: {0}. Timeout: {1}",
                    upgradeUpdateDescription.ApplicationName,
                    context.OperationTimeout);
                await this.fabricClient.ApplicationManager.UpdateApplicationUpgradeAsync(
                    upgradeUpdateDescription,
                    context.OperationTimeout,
                    context.CancellationToken);
                Trace.WriteInfo(TraceType, "UpdateAsync: Update application upgrade call accepted");
            }
            catch (FabricException fe)
            {
                if (fe.ErrorCode == FabricErrorCode.ApplicationNotUpgrading)
                {
                    Trace.WriteInfo(TraceType, "UpdateAsync: No application upgrade in progress");
                    return;
                }
            }
            catch (Exception e)
            {
                Trace.WriteInfo(TraceType, "UpdateAsync: Update application upgrade encountered an exception: {0}", e);
                throw;
            }
        }
示例#13
0
        public override async Task CreateAsync(IOperationDescription description, IOperationContext context)
        {
            Trace.WriteInfo(TraceType, "CreateAsync called");
            description.ThrowIfNull(nameof(description));
            context.ThrowIfNull(nameof(context));
            
            string errorMessage;
            if (!this.ValidObjectType<ApplicationOperationDescription>(description, out errorMessage))
            {
                throw new InvalidCastException(errorMessage);
            }

            var appDescription = (ApplicationOperationDescription)description;
            appDescription.ApplicationUri.ThrowIfNull(nameof(appDescription.ApplicationUri));
            appDescription.TypeName.ThrowIfNullOrWhiteSpace(nameof(appDescription.TypeName));
            appDescription.TypeVersion.ThrowIfNullOrWhiteSpace(nameof(appDescription.TypeVersion));

            var createDescription = new ApplicationDescription(
                appDescription.ApplicationUri,
                appDescription.TypeName,
                appDescription.TypeVersion,
                appDescription.Parameters?.ToNameValueCollection());
            if (appDescription.MinimumNodes.HasValue)
            {
                createDescription.MinimumNodes = appDescription.MinimumNodes.Value;
            }

            if (appDescription.MaximumNodes.HasValue)
            {
                createDescription.MaximumNodes = appDescription.MaximumNodes.Value;
            }

            if (appDescription.Metrics != null && appDescription.Metrics.Any())
            {
                createDescription.Metrics = new List<ApplicationMetricDescription>();
                foreach (var metric in appDescription.Metrics)
                {
                    createDescription.Metrics.Add(
                        new ApplicationMetricDescription()
                        {
                            Name = metric.Name,
                            MaximumNodeCapacity = metric.MaximumCapacity,
                            NodeReservationCapacity = metric.ReservationCapacity,
                            TotalApplicationCapacity = metric.TotalApplicationCapacity
                        });
                }
            }

            Trace.WriteInfo(
                TraceType,
                "CreateAsync: Creating application. Name: {0}. TypeName: {1}. TypeVersion: {2}. Timeout: {3}",
                appDescription.ApplicationUri,
                appDescription.TypeName,
                appDescription.TypeVersion,
                context.OperationTimeout);
            await this.fabricClient.ApplicationManager.CreateApplicationAsync(
                createDescription,
                context.OperationTimeout,
                context.CancellationToken);
            Trace.WriteInfo(TraceType, "CreateAsync: Create application call accepted");
        }
        public virtual async Task <IList <IOperationStatus> > ProcessAsync(
            IList <IOperationDescription> operations,
            IOperationContext context)
        {
            operations.ThrowIfNull(nameof(operations));
            context.ThrowIfNull(nameof(context));

            Trace.WriteInfo(TraceType, "ProcessAsync called");
            if (!operations.Any())
            {
                return(new List <IOperationStatus>());
            }

            var taskList = new List <Task <IOperationStatus> >();
            Task <IOperationStatus[]> operationTask = null;

            try
            {
                Trace.WriteInfo(TraceType, "ProcessAsync: processing {0} items", operations.Count);
                foreach (var operation in operations)
                {
                    taskList.Add(
                        this.CreateOperationStatusAsync(
                            operation,
                            new OperationContext(
                                context.CancellationToken,
                                context.GetRemainingTimeOrThrow(),
                                context.ContinuationToken)));
                }

                await Task.WhenAll(taskList);
            }
            catch (Exception e)
            {
                HandleException("ProcessAsync", e, this.TraceType);
                if (operationTask?.Exception != null)
                {
                    HandleException("ProcessAsync", operationTask.Exception, this.TraceType);
                }
            }

            var statuses = new List <IOperationStatus>();

            foreach (var t in taskList)
            {
                if (t.Status == TaskStatus.RanToCompletion && t.Result != null)
                {
                    statuses.Add(t.Result);
                    if (t.Result.Status != ResultStatus.InProgress)
                    {
                        Trace.WriteInfo(
                            this.TraceType,
                            this.Operations.TryRemove(t.Result)
                                ? "ProcessAsync: Operation completed for resource. OperationId: {0}. ResourceId: {1}."
                                : "ProcessAsync: Failed to remove completed operation for resource. OperationId: {0}. ResourceId: {1}.",
                            t.Result.OperationSequenceNumber,
                            t.Result.ResourceId);
                    }
                }
            }

            Trace.WriteInfo(TraceType, "ProcessAsync: {0} items processed successfully", statuses.Count);

            return(statuses);
        }
示例#15
0
        public override async Task <IFabricOperationResult> GetAsync(IOperationDescription description, IOperationContext context)
        {
            Trace.WriteInfo(TraceType, "GetAsync called");
            description.ThrowIfNull(nameof(description));
            context.ThrowIfNull(nameof(context));

            string errorMessage;

            if (!this.ValidObjectType <ServiceOperationDescription>(description, out errorMessage))
            {
                throw new InvalidCastException(errorMessage);
            }

            var     serviceOperationDescription = (ServiceOperationDescription)description;
            Service clusterService = (await this.fabricClient.QueryManager.GetServiceListAsync(
                                          serviceOperationDescription.ApplicationName,
                                          serviceOperationDescription.ServiceName,
                                          context.ContinuationToken,
                                          context.GetRemainingTimeOrThrow(),
                                          context.CancellationToken)).FirstOrDefault();

            var result = new FabricOperationResult()
            {
                OperationStatus = null,
                QueryResult     = new ServiceClientFabricQueryResult(clusterService)
            };

            Trace.WriteInfo(
                TraceType,
                null == clusterService
                    ? "GetAsync: Service not found. Name: {0}."
                    : "GetAsync: Service exists. Name: {0}.",
                serviceOperationDescription.ServiceName);

            if (null == clusterService)
            {
                if (description.OperationType == OperationType.Delete)
                {
                    result.OperationStatus =
                        new ServiceOperationStatus(serviceOperationDescription)
                    {
                        Status       = ResultStatus.Succeeded,
                        Progress     = new JObject(),
                        ErrorDetails = new JObject()
                    };

                    return(result);
                }

                return(null);
            }

            var status       = GetResultStatus(clusterService.ServiceStatus);
            var progress     = new JObject();
            var errorDetails = new JObject(); //TODO: How to get the error details?

            result.OperationStatus =
                new ServiceOperationStatus(serviceOperationDescription)
            {
                Status       = status,
                Progress     = progress,
                ErrorDetails = errorDetails
            };

            return(result);
        }
示例#16
0
        public override async Task <IFabricOperationResult> GetAsync(IOperationDescription description, IOperationContext context)
        {
            Trace.WriteInfo(TraceType, "GetAsync called");
            description.ThrowIfNull(nameof(description));
            context.ThrowIfNull(nameof(context));

            string errorMessage;

            if (!this.ValidObjectType <ApplicationTypeVersionOperationDescription>(description, out errorMessage))
            {
                throw new InvalidCastException(errorMessage);
            }

            var appTypeDescription = (ApplicationTypeVersionOperationDescription)description;
            var clusterAppTypes    = await this.fabricClient.QueryManager.GetApplicationTypeListAsync(
                appTypeDescription.TypeName,
                context.GetRemainingTimeOrThrow(),
                context.CancellationToken);

            var clusterAppType = clusterAppTypes
                                 .FirstOrDefault(a => a.ApplicationTypeVersion == appTypeDescription.TypeVersion);

            var result = new FabricOperationResult()
            {
                OperationStatus = null,
                QueryResult     = new ApplicationTypeFabricQueryResult(clusterAppType)
            };

            Trace.WriteInfo(
                TraceType,
                null == clusterAppType
                    ? "GetAsync: Application type not found. Name: {0}. Version: {1}"
                    : "GetAsync: Application type exists. Name: {0}. Version: {1}",
                appTypeDescription.TypeName,
                appTypeDescription.TypeVersion);

            if (null == clusterAppType)
            {
                if (description.OperationType == OperationType.Delete)
                {
                    result.OperationStatus =
                        new ApplicationTypeVersionOperationStatus(appTypeDescription)
                    {
                        Status       = ResultStatus.Succeeded,
                        Progress     = new JObject(),
                        ErrorDetails = new JObject()
                    };

                    return(result);
                }

                return(null);
            }

            var status       = GetResultStatus(clusterAppType.Status);
            var progress     = JObject.FromObject(new { Details = clusterAppType.StatusDetails });
            var errorDetails = new JObject();

            if (status == ResultStatus.Failed)
            {
                errorDetails = JObject.FromObject(new { Details = clusterAppType.StatusDetails });
            }

            var applicationTypeOperationStatus =
                new ApplicationTypeVersionOperationStatus(appTypeDescription)
            {
                Status       = status,
                Progress     = progress,
                ErrorDetails = errorDetails
            };

            if (status == ResultStatus.Succeeded)
            {
                applicationTypeOperationStatus.DefaultParameterList =
                    new Dictionary <string, string>(clusterAppType.DefaultParameters.AsDictionary());
            }

            result.OperationStatus = applicationTypeOperationStatus;
            return(result);
        }