private List <string> GetPackagesPath(string localPath, StoreLayoutSpecification storeLayoutSpecification)
        {
            var packagesPath = new List <string>();
            var manifest     = ImageBuilderUtility.ReadXml <ServiceManifestType>(localPath);

            if (manifest.CodePackage != null)
            {
                foreach (var codePackage in manifest.CodePackage)
                {
                    string packagePath = storeLayoutSpecification.GetCodePackageFolder(this.ApplicationTypeName, manifest.Name, codePackage.Name, codePackage.Version);
                    packagesPath.Add(packagePath);
                }
            }

            if (manifest.ConfigPackage != null)
            {
                foreach (var configPackage in manifest.ConfigPackage)
                {
                    string packagePath = storeLayoutSpecification.GetConfigPackageFolder(this.ApplicationTypeName, manifest.Name, configPackage.Name, configPackage.Version);
                    packagesPath.Add(packagePath);
                }
            }

            if (manifest.DataPackage != null)
            {
                foreach (var dataPackage in manifest.DataPackage)
                {
                    string packagePath = storeLayoutSpecification.GetDataPackageFolder(this.ApplicationTypeName, manifest.Name, dataPackage.Name, dataPackage.Version);
                    packagesPath.Add(packagePath);
                }
            }

            return(packagesPath);
        }
        private async Task <ApplicationTypeContext> GetApplicationTypeContextAsync(TimeoutHelper timeoutHelper)
        {
            StoreLayoutSpecification storeLayoutSpecification = StoreLayoutSpecification.Create();

            // Read the the ApplicationManifest from the store
            string applicationManifestFile = storeLayoutSpecification.GetApplicationManifestFile(this.ApplicationTypeName, this.ApplicationTypeVersion);
            ApplicationManifestType applicationManifestType = await this.ImageStoreWrapper.GetFromStoreAsync <ApplicationManifestType>(applicationManifestFile, timeoutHelper.GetRemainingTime());

            ApplicationTypeContext applicationTypeContext = new ApplicationTypeContext(applicationManifestType, string.Empty);

            // Read the Collection of ServiceManifests associated with the ApplicationManifest from the store
            List <Task <ServiceManifest> > taskList = new List <Task <ServiceManifest> >();
            TimeSpan remainingTime = timeoutHelper.GetRemainingTime();

            foreach (ApplicationManifestTypeServiceManifestImport serviceManifestImport in applicationManifestType.ServiceManifestImport)
            {
                taskList.Add(this.GetServiceManifestAsync(serviceManifestImport, storeLayoutSpecification, remainingTime));
            }

            await Task.WhenAll(taskList);

            taskList.ForEach(task => applicationTypeContext.ServiceManifests.Add(task.Result));

            return(applicationTypeContext);
        }
        private void OutputImageStoreContent(
            List <ImageStoreFile> sourceFiles,
            List <ImageStoreFolder> sourceFolders,
            string version,
            IImageStore imageStore,
            StoreLayoutSpecification storeLayoutSpecification,
            IClusterConnection clusterConnection,
            TimeoutHelper helper)
        {
            var targetFiles   = new List <ImageStoreFile>();
            var targetFolders = new List <ImageStoreFolder>();

            this.GetImageStoreContentByAppVersionImpl(
                sourceFiles,
                sourceFolders,
                targetFiles,
                targetFolders,
                version,
                imageStore,
                storeLayoutSpecification,
                clusterConnection,
                helper);

            targetFiles.ForEach(file => { base.OutputStoreFileInfo(file); });
            targetFolders.ForEach(folder => { base.OutputStoreFolderInfo(folder); });
        }
        public async Task CreateInstanceAsync(string outputFolder, TimeSpan timeout, ApplicationTypeContext validatedApplicationTypeContext = null)
        {
            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);

            ImageBuilder.TraceSource.WriteInfo(
                TraceType,
                "Starting CreateInstance. ApplicationTypeName:{0}, ApplicationTypeVersion:{1}, ApplicationId:{2}, Timeout:{3}",
                this.ApplicationTypeName,
                this.ApplicationTypeVersion,
                this.ApplicationId,
                timeoutHelper.GetRemainingTime());

            ApplicationInstanceContext appInstanceContext = await base.CreateAndSortInstanceAsync(
                1 /*ApplicationInstace version starts at 1*/,
                nameUri,
                timeoutHelper,
                validatedApplicationTypeContext);

            this.ValidateApplicationInstance(appInstanceContext);

            if (validatedApplicationTypeContext == null)
            {
                timeoutHelper.ThrowIfExpired();

                StoreLayoutSpecification clusterManagerOutputSpecification = null;
                if (outputFolder != null)
                {
                    clusterManagerOutputSpecification = StoreLayoutSpecification.Create();
                    clusterManagerOutputSpecification.SetRoot(outputFolder);
                }

                await this.UploadInstanceAsync(
                    appInstanceContext.ApplicationInstance,
                    appInstanceContext.ApplicationPackage,
                    appInstanceContext.ServicePackages,
                    StoreLayoutSpecification.Create(),
                    clusterManagerOutputSpecification,
                    true,
                    timeoutHelper);
            }

            ImageBuilder.TraceSource.WriteInfo(
                TraceType,
                "Completed CreateInstance. ApplicationTypeName:{0}, ApplicationTypeVersion:{1}, ApplicationId:{2}",
                this.ApplicationTypeName,
                this.ApplicationTypeVersion,
                this.ApplicationId);
        }
        private async Task <DataPackage> GetDataPackageAsync(
            DataPackageType dataPackageType,
            ServiceManifest serviceManifest,
            StoreLayoutSpecification storeLayoutSpecification,
            TimeSpan timeout)
        {
            var checksumFile = storeLayoutSpecification.GetDataPackageChecksumFile(
                this.ApplicationTypeName,
                serviceManifest.ServiceManifestType.Name,
                dataPackageType.Name,
                dataPackageType.Version);
            var checksumTask = await this.ImageStoreWrapper.TryGetFromStoreAsync(checksumFile, timeout);

            return(new DataPackage(dataPackageType)
            {
                Checksum = checksumTask.Item1                                       /*checksumValue*/
            });
        }
Example #6
0
        public async Task UpgradeInstaceAsync(string outputFolder, TimeSpan timeout)
        {
            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);

            ImageBuilder.TraceSource.WriteInfo(
                TraceType,
                "Starting UpgradeInstace. ApplicationTypeName:{0}, TargetApplicationTypeVersion:{1}, CurrentApplicationInstance:{2}, ApplicationId:{3}, Timeout:{4}",
                this.ApplicationTypeName,
                this.ApplicationTypeVersion,
                this.currentApplicationInstanceVersion,
                this.ApplicationId,
                timeoutHelper.GetRemainingTime());

            StoreLayoutSpecification storeLayoutSpecification = StoreLayoutSpecification.Create();

            // Read the current ApplicationInstance and ApplicationPackage from the store
            string currentApplicationInstanceFile = storeLayoutSpecification.GetApplicationInstanceFile(this.ApplicationTypeName, this.ApplicationId, this.currentApplicationInstanceVersion.ToString(CultureInfo.InvariantCulture));
            ApplicationInstanceType currentApplicationInstanceType = this.ImageStoreWrapper.GetFromStore <ApplicationInstanceType>(currentApplicationInstanceFile, timeoutHelper.GetRemainingTime());

            string currentApplicationPackageFile = storeLayoutSpecification.GetApplicationPackageFile(this.ApplicationTypeName, this.ApplicationId, currentApplicationInstanceType.ApplicationPackageRef.RolloutVersion);
            ApplicationPackageType currentApplicationPackageType = this.ImageStoreWrapper.GetFromStore <ApplicationPackageType>(currentApplicationPackageFile, timeoutHelper.GetRemainingTime());

            // Read the current ServicePackages from the store
            List <Task <ServicePackageType> > getServicePackageTasks = new List <Task <ServicePackageType> >();
            TimeSpan remainingTime = timeoutHelper.GetRemainingTime();

            foreach (ApplicationInstanceTypeServicePackageRef servicePackageRef in currentApplicationInstanceType.ServicePackageRef)
            {
                string currentServicePackageFile = storeLayoutSpecification.GetServicePackageFile(
                    this.ApplicationTypeName,
                    this.ApplicationId,
                    servicePackageRef.Name,
                    servicePackageRef.RolloutVersion);
                var getServicePackageTask = this.ImageStoreWrapper.GetFromStoreAsync <ServicePackageType>(currentServicePackageFile, remainingTime);
                getServicePackageTasks.Add(getServicePackageTask);
            }

            await Task.WhenAll(getServicePackageTasks);

            Collection <ServicePackageType> currentServicePackages = new Collection <ServicePackageType>();

            getServicePackageTasks.ForEach(task => currentServicePackages.Add(task.Result));

            timeoutHelper.ThrowIfExpired();

            ApplicationInstanceContext targetAppInstanceContext = await base.CreateAndSortInstanceAsync(
                currentApplicationInstanceType.Version + 1,
                new Uri(currentApplicationPackageType.NameUri),
                timeoutHelper);

            // Validate the target ApplicationInstance and ServicePackages
            this.ValidateApplicationInstance(targetAppInstanceContext);

            // Update the Rollout version on the target ApplicationInstance
            this.UpdateTargetApplicationPackage(currentApplicationPackageType, targetAppInstanceContext.ApplicationPackage);
            targetAppInstanceContext.ApplicationInstance.ApplicationPackageRef.RolloutVersion = targetAppInstanceContext.ApplicationPackage.RolloutVersion;

            // Update the Rollout version on the target ServicePackages
            foreach (ServicePackageType targetServicePackage in targetAppInstanceContext.ServicePackages)
            {
                ServicePackageType matchingCurrentServicePackageType = currentServicePackages.FirstOrDefault(
                    currentServicePackage => ImageBuilderUtility.Equals(currentServicePackage.Name, targetServicePackage.Name));

                this.UpdateTargetServicePackage(matchingCurrentServicePackageType, targetServicePackage);

                ApplicationInstanceTypeServicePackageRef matchingServicePackageRef = targetAppInstanceContext.ApplicationInstance.ServicePackageRef.First(
                    servicePackageRef => ImageBuilderUtility.Equals(servicePackageRef.Name, targetServicePackage.Name));
                matchingServicePackageRef.RolloutVersion = targetServicePackage.RolloutVersion;
            }

            StoreLayoutSpecification clusterManagerOutputSpecification = null;

            if (outputFolder != null)
            {
                clusterManagerOutputSpecification = StoreLayoutSpecification.Create();
                clusterManagerOutputSpecification.SetRoot(outputFolder);
            }

            timeoutHelper.ThrowIfExpired();

            // Upload the target ApplicationInstance and ServicePackages to the store
            // Also, write the target ApplicationInstance and ServicePackages to the CM output folder
            await this.UploadInstanceAsync(
                targetAppInstanceContext.ApplicationInstance,
                targetAppInstanceContext.ApplicationPackage,
                targetAppInstanceContext.ServicePackages,
                storeLayoutSpecification,
                clusterManagerOutputSpecification,
                false,
                timeoutHelper);

            // Write the current ApplicationInstance and ServicePackages to the CM output folder
            await this.UploadInstanceAsync(
                currentApplicationInstanceType,
                currentApplicationPackageType,
                currentServicePackages,
                null /* Do not upload to store*/,
                clusterManagerOutputSpecification,
                true,
                timeoutHelper);

            ImageBuilder.TraceSource.WriteInfo(
                TraceType,
                "Completed UpgradeInstace. ApplicationTypeName:{0}, TargetApplicationTypeVersion:{1}, CurrentApplicationInstance:{2}, ApplicationId:{3}",
                this.ApplicationTypeName,
                this.ApplicationTypeVersion,
                this.currentApplicationInstanceVersion,
                this.ApplicationId);
        }
        protected async Task UploadInstanceAsync(
            ApplicationInstanceType applicationInstanceType,
            ApplicationPackageType applicationPackageType,
            IEnumerable <ServicePackageType> servicePackages,
            StoreLayoutSpecification storeLayoutSpecification /* If null, don't upload to store */,
            StoreLayoutSpecification clusterManagerOutputSpecification /* If null, dont write to output folder*/,
            bool shouldOverwrite,
            TimeoutHelper timeoutHelper)
        {
            List <Task> uploadTasks = new List <Task>();

            // Write ApplicationInstance to Store
            if (storeLayoutSpecification != null)
            {
                ImageBuilder.TraceSource.WriteInfo(
                    TraceType,
                    "Starting to upload the ApplicationInstance, ApplicationPackage, ServicePackage to the store. ApplicationTypeName:{0}, ApplicationTypeVersion:{1}.",
                    applicationInstanceType.ApplicationTypeName,
                    applicationInstanceType.ApplicationTypeVersion);

                string applicationInstanceLocation = storeLayoutSpecification.GetApplicationInstanceFile(
                    applicationInstanceType.ApplicationTypeName,
                    applicationInstanceType.ApplicationId,
                    applicationInstanceType.Version.ToString(CultureInfo.InvariantCulture));
                var uploadInstanceTask = this.ImageStoreWrapper.SetToStoreAsync <ApplicationInstanceType>(applicationInstanceLocation, applicationInstanceType, timeoutHelper.GetRemainingTime(), shouldOverwrite);

                uploadTasks.Add(uploadInstanceTask);

                string applicationPackageLocation = storeLayoutSpecification.GetApplicationPackageFile(
                    applicationPackageType.ApplicationTypeName,
                    applicationPackageType.ApplicationId,
                    applicationPackageType.RolloutVersion);
                var uploadApplicationPackageTask = this.ImageStoreWrapper.SetToStoreAsync <ApplicationPackageType>(applicationPackageLocation, applicationPackageType, timeoutHelper.GetRemainingTime(), shouldOverwrite);

                uploadTasks.Add(uploadApplicationPackageTask);
                TimeSpan remainingTime = timeoutHelper.GetRemainingTime();
                foreach (ServicePackageType servicePackage in servicePackages)
                {
                    // Write ServicePackage to Store
                    string servicePackageLocation = storeLayoutSpecification.GetServicePackageFile(
                        applicationInstanceType.ApplicationTypeName,
                        applicationInstanceType.ApplicationId,
                        servicePackage.Name,
                        servicePackage.RolloutVersion);
                    var uploadServicePackageTask = this.ImageStoreWrapper.SetToStoreAsync <ServicePackageType>(servicePackageLocation, servicePackage, remainingTime, shouldOverwrite);

                    uploadTasks.Add(uploadServicePackageTask);
                }

                await Task.WhenAll(uploadTasks);
            }

            // Write ApplicationInstance to the outputFolder for the CM
            if (clusterManagerOutputSpecification != null)
            {
                ImageBuilder.TraceSource.WriteInfo(
                    TraceType,
                    "Starting to write the ApplicationInstance, ApplicationPackage, ServicePackage to folder {0}. ApplicationTypeName:{1}, ApplicationTypeVersion:{2}.",
                    clusterManagerOutputSpecification.GetRoot(),
                    applicationInstanceType.ApplicationTypeName,
                    applicationInstanceType.ApplicationTypeVersion);

                string clusterManagerApplicationInstanceLocation = clusterManagerOutputSpecification.GetApplicationInstanceFile(
                    applicationInstanceType.ApplicationTypeName,
                    applicationInstanceType.ApplicationId,
                    applicationInstanceType.Version.ToString(CultureInfo.InvariantCulture));
                ImageBuilderUtility.WriteXml <ApplicationInstanceType>(clusterManagerApplicationInstanceLocation, applicationInstanceType);

                string clusterManagerApplicationPackageLocation = clusterManagerOutputSpecification.GetApplicationPackageFile(
                    applicationPackageType.ApplicationTypeName,
                    applicationPackageType.ApplicationId,
                    applicationPackageType.RolloutVersion);
                ImageBuilderUtility.WriteXml <ApplicationPackageType>(clusterManagerApplicationPackageLocation, applicationPackageType);

                foreach (ServicePackageType servicePackage in servicePackages)
                {
                    string clusterManagerServicePackageLocation = clusterManagerOutputSpecification.GetServicePackageFile(
                        applicationInstanceType.ApplicationTypeName,
                        applicationInstanceType.ApplicationId,
                        servicePackage.Name,
                        servicePackage.RolloutVersion);
                    ImageBuilderUtility.WriteXml <ServicePackageType>(clusterManagerServicePackageLocation, servicePackage);
                }
            }

            ImageBuilder.TraceSource.WriteInfo(
                TraceType,
                "Completed uploading/writing ApplicationInstance, ApplicationPackage, ServicePackage to the store/folder. ApplicationTypeName:{0}, ApplicationTypeVersion:{1}.",
                applicationInstanceType.ApplicationTypeName,
                applicationInstanceType.ApplicationTypeVersion);
        }
        private async Task <ServiceManifest> GetServiceManifestAsync(
            ApplicationManifestTypeServiceManifestImport serviceManifestImport,
            StoreLayoutSpecification storeLayoutSpecification,
            TimeSpan timeout)
        {
            TimeoutHelper timeoutHelper       = new TimeoutHelper(timeout);
            string        serviceManifestFile = storeLayoutSpecification.GetServiceManifestFile(
                this.ApplicationTypeName,
                serviceManifestImport.ServiceManifestRef.ServiceManifestName,
                serviceManifestImport.ServiceManifestRef.ServiceManifestVersion);

            string checksumFile = storeLayoutSpecification.GetServiceManifestChecksumFile(
                this.ApplicationTypeName,
                serviceManifestImport.ServiceManifestRef.ServiceManifestName,
                serviceManifestImport.ServiceManifestRef.ServiceManifestVersion);

            var getServiceManifestTask = this.ImageStoreWrapper.GetFromStoreAsync <ServiceManifestType>(serviceManifestFile, timeoutHelper.GetRemainingTime());
            var getChecksumTask        = this.ImageStoreWrapper.TryGetFromStoreAsync(checksumFile, timeoutHelper.GetRemainingTime());

            await Task.WhenAll(getServiceManifestTask, getChecksumTask);

            timeoutHelper.ThrowIfExpired();
            ServiceManifestType serviceManifestType = getServiceManifestTask.Result;
            string checksum = getChecksumTask.Result.Item1;

            ServiceManifest serviceManifest = new ServiceManifest(serviceManifestType)
            {
                Checksum = checksum
            };

            List <Task <CodePackage> > codePackageTaskList = new List <Task <CodePackage> >();
            TimeSpan remainingTime = timeoutHelper.GetRemainingTime();

            foreach (CodePackageType codePackageType in serviceManifestType.CodePackage)
            {
                codePackageTaskList.Add(this.GetCodePackageAsync(codePackageType, serviceManifest, storeLayoutSpecification, remainingTime));
            }

            List <Task <ConfigPackage> > configPackageTaskList = new List <Task <ConfigPackage> >();

            if (serviceManifestType.ConfigPackage != null)
            {
                foreach (ConfigPackageType configPackageType in serviceManifestType.ConfigPackage)
                {
                    configPackageTaskList.Add(this.GetConfigPackageAsync(configPackageType, serviceManifest, storeLayoutSpecification, remainingTime));
                }
            }

            List <Task <DataPackage> > dataPackageTaskList = new List <Task <DataPackage> >();

            if (serviceManifestType.DataPackage != null)
            {
                foreach (DataPackageType dataPackageType in serviceManifestType.DataPackage)
                {
                    dataPackageTaskList.Add(this.GetDataPackageAsync(dataPackageType, serviceManifest, storeLayoutSpecification, remainingTime));
                }
            }

            List <Task> packageTasks = new List <Task>();

            packageTasks.AddRange(codePackageTaskList);
            packageTasks.AddRange(configPackageTaskList);
            packageTasks.AddRange(dataPackageTaskList);

            await Task.WhenAll(packageTasks);

            codePackageTaskList.ForEach(task => serviceManifest.CodePackages.Add(task.Result));
            configPackageTaskList.ForEach(task => serviceManifest.ConfigPackages.Add(task.Result));
            dataPackageTaskList.ForEach(task => serviceManifest.DataPackages.Add(task.Result));

            return(serviceManifest);
        }
        protected override void ProcessRecord()
        {
            TimeSpan timeout = this.GetTimeout();
            string   workingImageStoreConnectionString = this.TryFetchImageStoreConnectionString(this.ImageStoreConnectionString, this.CertStoreLocation);
            var      imageStore = this.CreateImageStore(
                workingImageStoreConnectionString,
                System.IO.Path.GetTempPath());

            switch (this.ParameterSetName)
            {
            case "Path":
                this.RemoteRelativePath = string.IsNullOrEmpty(this.RemoteRelativePath) ? " " : this.RemoteRelativePath.Trim(new char[] { System.IO.Path.DirectorySeparatorChar, System.IO.Path.AltDirectorySeparatorChar, ' ', '\t' });
                if (workingImageStoreConnectionString.StartsWith(Constants.ImageStoreConnectionFabricType, StringComparison.OrdinalIgnoreCase))
                {
                    this.GetImageStorePagedContentByLocation(this.RemoteRelativePath, imageStore, timeout);
                }
                else
                {
                    this.GetImageStoreContentByLocation(this.RemoteRelativePath, imageStore, timeout);
                }

                break;

            case "Application":
                if (string.IsNullOrEmpty(this.ApplicationTypeName))
                {
                    this.WriteObject(StringResources.Error_ArgumentInvalid);
                    return;
                }

                TimeoutHelper helper = timeout == TimeSpan.MaxValue ? null : new TimeoutHelper(timeout);
                var           storeLayoutSpecification = StoreLayoutSpecification.Create();
                if (storeLayoutSpecification == null)
                {
                    throw new ArgumentException(StringResources.Error_storeLayoutSpecification_Init_Failed);
                }

                var           clusterConnection = this.GetClusterConnection();
                List <string> versions;
                if (this.ApplicationTypeVersion == null)
                {
                    versions = this.GetAppVersions(clusterConnection, this.ApplicationTypeName);
                    if (!versions.Any())
                    {
                        throw new ArgumentException(StringResources.Error_ApplicationTypeNotFound);
                    }
                }
                else
                {
                    if (!this.VerifyAppVersion(clusterConnection, this.ApplicationTypeName, this.ApplicationTypeVersion))
                    {
                        throw new ArgumentException(StringResources.Error_ApplicationTypeNotFound);
                    }
                    else
                    {
                        versions = new List <string>()
                        {
                            this.ApplicationTypeVersion
                        };
                    }
                }

                if (helper != null)
                {
                    helper.ThrowIfExpired();
                }

                if (workingImageStoreConnectionString.StartsWith(Constants.ImageStoreConnectionFabricType, StringComparison.OrdinalIgnoreCase))
                {
                    bool   morePages = true;
                    string currentContinuationToken = null;
                    while (morePages)
                    {
                        var content = imageStore.ListPagedContentWithDetailsAsync(
                            new ImageStoreListDescription(
                                System.IO.Path.Combine(ImaageStorePathPrefix, this.ApplicationTypeName),
                                currentContinuationToken,
                                false),
                            helper == null ? timeout : helper.GetRemainingTime()).Result;

                        if (content.Files == null && content.Folders == null && string.IsNullOrEmpty(currentContinuationToken))
                        {
                            throw new ArgumentException(StringResources.ImageStoreError_DoesNotExistError);
                        }

                        versions.ForEach(version =>
                        {
                            this.OutputImageStoreContent(
                                content.Files,
                                content.Folders,
                                version,
                                imageStore,
                                storeLayoutSpecification,
                                clusterConnection,
                                helper);
                        });

                        morePages = Helpers.ResultHasMorePages(this, content.ContinuationToken, out currentContinuationToken);
                        if (morePages)
                        {
                            this.WriteVerbose(string.Format("Continuation Token:{0}", currentContinuationToken));
                        }
                    }
                }
                else
                {
                    var content = imageStore.ListContentWithDetails(System.IO.Path.Combine(ImaageStorePathPrefix, this.ApplicationTypeName), false, helper == null ? timeout : helper.GetRemainingTime());

                    if (content.Files == null && content.Folders == null)
                    {
                        throw new ArgumentException(StringResources.ImageStoreError_DoesNotExistError);
                    }

                    versions.ForEach(version =>
                    {
                        this.OutputImageStoreContent(
                            content.Files,
                            content.Folders,
                            version,
                            imageStore,
                            storeLayoutSpecification,
                            clusterConnection,
                            helper);
                    });
                }

                break;
            }
        }
        private void GetImageStoreContentByAppVersionImpl(
            List <ImageStoreFile> sourceFiles,
            List <ImageStoreFolder> sourceFolders,
            List <ImageStoreFile> targetFiles,
            List <ImageStoreFolder> targetFolders,
            string version,
            IImageStore imageStore,
            StoreLayoutSpecification storeLayoutSpecification,
            IClusterConnection clusterConnection,
            TimeoutHelper helper)
        {
            Action <string, string, string, string, bool> updateStoreInfo = (string path, string serviceName, string serviceVersion, string appVersion, bool isFile) =>
            {
                if (isFile)
                {
                    var existingFile = (from file in targetFiles
                                        where string.Compare(file.StoreRelativePath, path, StringComparison.OrdinalIgnoreCase) == 0
                                        select file).FirstOrDefault();

                    if (existingFile != null)
                    {
                        existingFile.VersionInfo.ConfigVersionInfo(serviceName, serviceVersion, appVersion);
                    }
                    else
                    {
                        existingFile = (from file in sourceFiles
                                        where string.Compare(file.StoreRelativePath, path, StringComparison.OrdinalIgnoreCase) == 0
                                        select file).FirstOrDefault();

                        if (existingFile != null)
                        {
                            existingFile.VersionInfo.ConfigVersionInfo(serviceName, serviceVersion, appVersion);
                            targetFiles.Add(existingFile);
                        }
                        else
                        {
                            throw new ArgumentException(StringResources.Error_ImageStoreRelativePathNotExist);
                        }
                    }
                }
                else
                {
                    var existingFolder = (from folder in targetFolders
                                          where string.Compare(folder.StoreRelativePath, path, StringComparison.OrdinalIgnoreCase) == 0
                                          select folder).FirstOrDefault();

                    if (existingFolder != null)
                    {
                        existingFolder.VersionInfo.ConfigVersionInfo(serviceName, serviceVersion, appVersion);
                    }
                    else
                    {
                        existingFolder = (from folder in sourceFolders
                                          where string.Compare(folder.StoreRelativePath, path, StringComparison.OrdinalIgnoreCase) == 0
                                          select folder).FirstOrDefault();

                        if (existingFolder != null)
                        {
                            existingFolder.VersionInfo.ConfigVersionInfo(serviceName, serviceVersion, appVersion);
                            targetFolders.Add(existingFolder);
                        }
                        else
                        {
                            throw new ArgumentException(StringResources.Error_ImageStoreRelativePathNotExist);
                        }
                    }
                }
            };

            if (helper != null)
            {
                helper.ThrowIfExpired();
            }

            var    foldersPath             = new Dictionary <string, Tuple <string, string> >();
            string applicationManifestPath = storeLayoutSpecification.GetApplicationManifestFile(this.ApplicationTypeName, version);

            updateStoreInfo(applicationManifestPath, string.Empty, string.Empty, version, true);
            var serviceTypeList = clusterConnection.GetServiceTypeListAsync(this.ApplicationTypeName, version, null, this.GetTimeout(), this.GetCancellationToken()).Result;

            foreach (var serviceType in serviceTypeList)
            {
                if (helper != null)
                {
                    helper.ThrowIfExpired();
                }

                string serviceManifestPath = storeLayoutSpecification.GetServiceManifestFile(this.ApplicationTypeName, serviceType.ServiceManifestName, serviceType.ServiceManifestVersion);
                updateStoreInfo(serviceManifestPath, serviceType.ServiceManifestName, serviceType.ServiceManifestVersion, version, true);
                if (helper != null)
                {
                    helper.ThrowIfExpired();
                }

                string serviceManifestChecksumPath = storeLayoutSpecification.GetServiceManifestChecksumFile(this.ApplicationTypeName, serviceType.ServiceManifestName, serviceType.ServiceManifestVersion);
                updateStoreInfo(serviceManifestChecksumPath, serviceType.ServiceManifestName, serviceType.ServiceManifestVersion, version, true);
                string localPath = System.IO.Path.Combine(System.IO.Path.GetTempPath(), serviceManifestPath.Substring(serviceManifestPath.LastIndexOf(@"\") + 1));
                try
                {
                    if (helper != null)
                    {
                        helper.ThrowIfExpired();
                        imageStore.DownloadContent(serviceManifestPath, localPath, helper.GetRemainingTime(), CopyFlag.AtomicCopy);
                    }
                    else
                    {
                        imageStore.DownloadContent(serviceManifestPath, localPath, this.GetTimeout(), CopyFlag.AtomicCopy);
                    }

                    foreach (var packagePath in this.GetPackagesPath(localPath, storeLayoutSpecification))
                    {
                        updateStoreInfo(packagePath, serviceType.ServiceManifestName, serviceType.ServiceManifestVersion, version, false);
                        updateStoreInfo(string.Format("{0}.{1}", packagePath, ChecksumFileExtension), serviceType.ServiceManifestName, serviceType.ServiceManifestVersion, version, true);
                    }
                }
                catch (Exception exception)
                {
                    this.ThrowTerminatingError(exception, Constants.GetImageStoreContentErrorId, null);
                }
                finally
                {
                    File.Delete(localPath);
                }
            }
        }
        public void UpgradeWithSetting()
        {
            string currentExecutingDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
            string jsonFilePath    = Path.Combine(currentExecutingDirectory, "Application_No_Setting.json");
            string descriptionJson = File.ReadAllText(jsonFilePath);

            SingleInstance.Application application = JsonConvert.DeserializeObject <SingleInstance.Application>(descriptionJson);

            string applicationTypeName    = "MeshApplicationType";
            string applicationTypeVersion = "v1";
            Uri    applicationName        = new Uri("fabric:/myapp");
            string tempBuildPath          = Path.Combine(TestUtility.TestDirectory, Guid.NewGuid().ToString());
            string outputPath             = Path.Combine(TestUtility.TestDirectory, Guid.NewGuid().ToString());

            string applicationId = Guid.NewGuid().ToString();

            this.imageBuilder.BuildSingleInstanceApplication(
                application,
                applicationTypeName,
                applicationTypeVersion,
                applicationId,
                applicationName,
                true, //generateDNS
                TimeSpan.MaxValue,
                tempBuildPath,
                outputPath, // output pkg build path
                false,      //use open network
                false,      //use local nat network
                "C:\\",
                new SingleInstance.GenerationConfig());

            BuildLayoutInfo         buildLayoutInfo     = new BuildLayoutInfo(this.imageStore, tempBuildPath);
            ApplicationInstanceType applicationInstance = TestUtility.GetApplicationInstance(buildLayoutInfo, applicationId, 1);

            TestUtility.VerifyStoreLayout(buildLayoutInfo);

            StoreLayoutSpecification storeLayoutSpec = StoreLayoutSpecification.Create();

            storeLayoutSpec.SetRoot(outputPath);
            string servicePackageFile = storeLayoutSpec.GetServicePackageFile(applicationTypeName, applicationId, "myBackendServicePkg", applicationInstance.ServicePackageRef[0].RolloutVersion);
            var    servicepackage     = buildLayoutInfo.ImageStoreWrapper.GetFromStore <ServicePackageType>(servicePackageFile, TestUtility.ImageStoreDefaultTimeout);

            string rolloutVersion1 = servicepackage.RolloutVersion;

            // Test Case 1: Instance Count change
            string jsonFilePath2    = Path.Combine(currentExecutingDirectory, "Application_No_Setting2.json");
            string descriptionJson2 = File.ReadAllText(jsonFilePath2);

            SingleInstance.Application application2 = JsonConvert.DeserializeObject <SingleInstance.Application>(descriptionJson2);

            string applicationTypeVersion2 = "v2";

            this.imageBuilder.BuildSingleInstanceApplicationForUpgrade(
                application2,
                applicationTypeName,
                applicationTypeVersion,
                applicationTypeVersion2,
                applicationId,
                applicationInstance.Version,
                applicationName,
                true, //generateDNS
                TimeSpan.MaxValue,
                tempBuildPath,
                outputPath,
                false, //use open network
                false, //use local nat network
                "C:\\",
                new SingleInstance.GenerationConfig());

            ApplicationInstanceType applicationInstance2 = TestUtility.GetApplicationInstance(buildLayoutInfo, applicationId, 2);
            string servicePackageFile2 = storeLayoutSpec.GetServicePackageFile(applicationTypeName, applicationId, "myBackendServicePkg", applicationInstance2.ServicePackageRef[0].RolloutVersion);
            var    servicepackage2     = buildLayoutInfo.ImageStoreWrapper.GetFromStore <ServicePackageType>(servicePackageFile2, TestUtility.ImageStoreDefaultTimeout);

            Verify.AreEqual(servicepackage2.ManifestVersion, "v1");

            string rolloutVersion2 = servicepackage2.RolloutVersion;

            Verify.AreEqual(rolloutVersion1, rolloutVersion2);
            TestUtility.VerifyStoreLayout(buildLayoutInfo);

            // Test Case 2: Adding settings
            string jsonSettingFilePath1    = Path.Combine(currentExecutingDirectory, "Application_Setting1.json");
            string settingDescriptionJson1 = File.ReadAllText(jsonSettingFilePath1);

            SingleInstance.Application applicationWithSetting1 = JsonConvert.DeserializeObject <SingleInstance.Application>(settingDescriptionJson1);

            string applicationTypeVersion3 = "v3";

            this.imageBuilder.BuildSingleInstanceApplicationForUpgrade(
                applicationWithSetting1,
                applicationTypeName,
                applicationTypeVersion2,
                applicationTypeVersion3,
                applicationId,
                applicationInstance2.Version,
                applicationName,
                true, //generateDNS
                TimeSpan.MaxValue,
                tempBuildPath,
                outputPath,
                false, //use open network
                false, //use localnat network
                "C:\\",
                new SingleInstance.GenerationConfig());
            ApplicationInstanceType applicationInstance3 = TestUtility.GetApplicationInstance(buildLayoutInfo, applicationId, 3);
            string servicePackageFile3 = storeLayoutSpec.GetServicePackageFile(applicationTypeName, applicationId, "myBackendServicePkg", applicationInstance3.ServicePackageRef[0].RolloutVersion);
            var    servicepackage3     = buildLayoutInfo.ImageStoreWrapper.GetFromStore <ServicePackageType>(servicePackageFile3, TestUtility.ImageStoreDefaultTimeout);

            Verify.AreEqual(servicepackage3.ManifestVersion, applicationTypeVersion3);

            string rolloutVersion3 = servicepackage3.RolloutVersion;

            Verify.AreNotEqual(rolloutVersion2, rolloutVersion3);
            TestUtility.VerifyStoreLayout(buildLayoutInfo);

            // Test Case 3: Changing settings only
            string jsonSettingFilePath2    = Path.Combine(currentExecutingDirectory, "Application_Setting2.json");
            string settingDescriptionJson2 = File.ReadAllText(jsonSettingFilePath2);

            SingleInstance.Application applicationWithSetting2 = JsonConvert.DeserializeObject <SingleInstance.Application>(settingDescriptionJson2);

            string applicationTypeVersion4 = "v4";

            this.imageBuilder.BuildSingleInstanceApplicationForUpgrade(
                applicationWithSetting2,
                applicationTypeName,
                applicationTypeVersion3,
                applicationTypeVersion4,
                applicationId,
                applicationInstance3.Version,
                applicationName,
                true, //generateDNS
                TimeSpan.MaxValue,
                tempBuildPath,
                outputPath,
                false, //use open network
                false, //use localnat network
                "C:\\",
                new SingleInstance.GenerationConfig());
            ApplicationInstanceType applicationInstance4 = TestUtility.GetApplicationInstance(buildLayoutInfo, applicationId, 4);
            string servicePackageFile4 = storeLayoutSpec.GetServicePackageFile(applicationTypeName, applicationId, "myBackendServicePkg", applicationInstance4.ServicePackageRef[0].RolloutVersion);
            var    servicepackage4     = buildLayoutInfo.ImageStoreWrapper.GetFromStore <ServicePackageType>(servicePackageFile4, TestUtility.ImageStoreDefaultTimeout);

            Verify.AreEqual(servicepackage4.ManifestVersion, applicationTypeVersion4);

            // Code package version remains the same for settings upgrade
            foreach (var codePackage in servicepackage4.DigestedCodePackage)
            {
                Verify.AreEqual(applicationTypeVersion3, codePackage.CodePackage.Version);
            }
            // Config package version is set to target version for settings upgrade
            foreach (var configPackage in servicepackage4.DigestedConfigPackage)
            {
                Verify.AreEqual(applicationTypeVersion4, configPackage.ConfigPackage.Version);
            }

            string rolloutVersion4 = servicepackage4.RolloutVersion;

            Verify.AreNotEqual(rolloutVersion3, rolloutVersion4);
            TestUtility.VerifyStoreLayout(buildLayoutInfo);

            // Test Case 4: Keep settings
            string jsonSettingFilePath3    = Path.Combine(currentExecutingDirectory, "Application_Setting2InstanceCount.json");
            string settingDescriptionJson3 = File.ReadAllText(jsonSettingFilePath3);

            SingleInstance.Application applicationWithSetting3 = JsonConvert.DeserializeObject <SingleInstance.Application>(settingDescriptionJson3);

            string applicationTypeVersion5 = "v5";

            this.imageBuilder.BuildSingleInstanceApplicationForUpgrade(
                applicationWithSetting3,
                applicationTypeName,
                applicationTypeVersion4,
                applicationTypeVersion5,
                applicationId,
                applicationInstance4.Version,
                applicationName,
                true, //generateDNS
                TimeSpan.MaxValue,
                tempBuildPath,
                outputPath,
                false, //use open network
                false, //use localnat network
                "C:\\",
                new SingleInstance.GenerationConfig());
            ApplicationInstanceType applicationInstance5 = TestUtility.GetApplicationInstance(buildLayoutInfo, applicationId, 5);
            string servicePackageFile5 = storeLayoutSpec.GetServicePackageFile(applicationTypeName, applicationId, "myBackendServicePkg", applicationInstance5.ServicePackageRef[0].RolloutVersion);
            var    servicepackage5     = buildLayoutInfo.ImageStoreWrapper.GetFromStore <ServicePackageType>(servicePackageFile5, TestUtility.ImageStoreDefaultTimeout);

            // SP manifest version remains the same
            Verify.AreEqual(servicepackage5.ManifestVersion, applicationTypeVersion4);

            // SP rollout version remains the same
            string rolloutVersion5 = servicepackage5.RolloutVersion;

            Verify.AreEqual(rolloutVersion4, rolloutVersion5);
            TestUtility.VerifyStoreLayout(buildLayoutInfo);

            // Test Case 5: Autoscaling - Instance Count change
            string jsonSettingFilePath4    = Path.Combine(currentExecutingDirectory, "Application_Setting3Autoscaling.json");
            string settingDescriptionJson4 = File.ReadAllText(jsonSettingFilePath4);

            SingleInstance.Application applicationWithSetting4 = JsonConvert.DeserializeObject <SingleInstance.Application>(settingDescriptionJson4);

            string applicationTypeVersion6 = "v6";

            this.imageBuilder.BuildSingleInstanceApplicationForUpgrade(
                applicationWithSetting4,
                applicationTypeName,
                applicationTypeVersion5,
                applicationTypeVersion6,
                applicationId,
                applicationInstance5.Version,
                applicationName,
                true, //generateDNS
                TimeSpan.MaxValue,
                tempBuildPath,
                outputPath,
                false, //use open network
                false, //use localnat network
                "C:\\",
                new SingleInstance.GenerationConfig());

            ApplicationInstanceType applicationInstance6 = TestUtility.GetApplicationInstance(buildLayoutInfo, applicationId, 6);
            string servicePackageFile6 = storeLayoutSpec.GetServicePackageFile(applicationTypeName, applicationId, "myBackendServicePkg", applicationInstance6.ServicePackageRef[0].RolloutVersion);
            var    servicepackage6     = buildLayoutInfo.ImageStoreWrapper.GetFromStore <ServicePackageType>(servicePackageFile6, TestUtility.ImageStoreDefaultTimeout);

            Verify.AreEqual(servicepackage6.ManifestVersion, "v4");

            string rolloutVersion6 = servicepackage6.RolloutVersion;

            Verify.AreEqual(rolloutVersion5, rolloutVersion6);
            TestUtility.VerifyStoreLayout(buildLayoutInfo);

            // Test Case 6: Changing settings and image at the same time
            string jsonSettingFilePath5    = Path.Combine(currentExecutingDirectory, "Application_Setting3.json");
            string settingDescriptionJson5 = File.ReadAllText(jsonSettingFilePath5);

            SingleInstance.Application applicationWithSetting5 = JsonConvert.DeserializeObject <SingleInstance.Application>(settingDescriptionJson5);

            string applicationTypeVersion7 = "v7";

            this.imageBuilder.BuildSingleInstanceApplicationForUpgrade(
                applicationWithSetting5,
                applicationTypeName,
                applicationTypeVersion6,
                applicationTypeVersion7,
                applicationId,
                applicationInstance6.Version,
                applicationName,
                true, //generateDNS
                TimeSpan.MaxValue,
                tempBuildPath,
                outputPath,
                false, //use open network
                false, //use localnat network
                "C:\\",
                new SingleInstance.GenerationConfig());

            ApplicationInstanceType applicationInstance7 = TestUtility.GetApplicationInstance(buildLayoutInfo, applicationId, 7);
            string servicePackageFile7 = storeLayoutSpec.GetServicePackageFile(applicationTypeName, applicationId, "myBackendServicePkg", applicationInstance7.ServicePackageRef[0].RolloutVersion);
            var    servicepackage7     = buildLayoutInfo.ImageStoreWrapper.GetFromStore <ServicePackageType>(servicePackageFile7, TestUtility.ImageStoreDefaultTimeout);

            Verify.AreEqual(servicepackage7.ManifestVersion, applicationTypeVersion7);

            // Code package version and config package version are set to target version applicationTypeVersion7
            foreach (var codePackage in servicepackage7.DigestedCodePackage)
            {
                Verify.AreEqual(applicationTypeVersion7, codePackage.CodePackage.Version);
            }
            foreach (var configPackage in servicepackage7.DigestedConfigPackage)
            {
                Verify.AreEqual(applicationTypeVersion7, configPackage.ConfigPackage.Version);
            }

            string rolloutVersion7 = servicepackage7.RolloutVersion;

            Verify.AreNotEqual(rolloutVersion6, rolloutVersion7);
            TestUtility.VerifyStoreLayout(buildLayoutInfo);
        }