示例#1
0
 /// <summary>
 /// Copy errorsink values to error collection in output
 /// </summary>
 /// <param name="errorSink"></param>
 /// <param name="result"></param>
 private void ReportErrors(PhpErrorSink errorSink, TransformationResult result, string code)
 {
     foreach (var error in errorSink.Errors)
     {
         var sourceLocation = new PhpSourceLocation(error.Span);
         result.Errors.Add(error.ToString() + " Location: " + sourceLocation.GetLocation(code));
     }
 }
        protected override TransformationResult TransformFunction(TransformationContext context, TranslatedFunction declaration)
        {
            TransformationResult result = declaration;

            if (declaration.Name == "DebugCheckVersionAndDataLayout")
            {
                if (IMGUI_VERSION is not null)
                {
                    result.Add(IMGUI_VERSION);
                }

                if (IMGUI_VERSION_NUM is not null)
                {
                    result.Add(IMGUI_VERSION_NUM);
                }
            }

            return(result);
        }
示例#3
0
        /// <summary>
        /// Perform some checks to determine if the transformation is valid
        /// </summary>
        /// <param name="transformations"></param>
        /// <returns></returns>
        private bool ValidateTransformations(TransformationResult transformations)
        {
            if (transformations.Errors.Count > 0)
            {
                WriteLine("Error(s) in transformation: ");
                foreach (var error in transformations.Errors)
                {
                    Console.WriteLine(error);
                }
                return(false);
            }

            if (transformations.InputChannels.Count == 0)
            {
                var text = "No input channels found that match the active policy.";
                transformations.Errors.Add(text);
                WriteLine(text);

                return(false);
            }

            if (transformations.OutputChannels.Count == 0)
            {
                var text = "No output channels found that match the active policy.";
                transformations.Errors.Add(text);
                WriteLine(text);
                return(false);
            }

            if (transformations.CodeTransformations.Count == 0)
            {
                var text = "No code transformations available.";
                transformations.Errors.Add(text);
                WriteLine(text);
                return(false);
            }
            return(true);
        }
示例#4
0
        public override object ResolveContents(
            Sitecore.Mvc.Presentation.Rendering rendering,
            IRenderingConfiguration renderingConfig)
        {
            RenderingItem renderingItem = rendering.RenderingItem;

            if (renderingItem == null)
            {
                return(addPlaceHolderPath(rendering, renderingConfig));
            }

            string str = renderingItem.InnerItem[Sitecore.JavaScriptServices.Core.FieldIDs.JsonRendering.GraphQLQuery];

            if (string.IsNullOrWhiteSpace(str))
            {
                return(addPlaceHolderPath(rendering, renderingConfig));
            }
            AppConfiguration appConfiguration = this._configurationResolver.ResolveForItem(Context.Item);

            if (appConfiguration == null)
            {
                this._log.Warn("[JSS] - Rendering " + renderingItem.InnerItem.Paths.FullPath + " defined a GraphQL query to resolve its data, but when rendered on item " + Context.Item.Paths.FullPath + " it was not within a known JSS app path. The GraphQL query will not be used.", (object)this);
                return(addPlaceHolderPath(rendering, renderingConfig));
            }
            if (string.IsNullOrWhiteSpace(appConfiguration.GraphQLEndpoint))
            {
                this._log.Error("[JSS] - The JSS app " + appConfiguration.Name + " did not have a graphQLEndpoint set, but rendering " + renderingItem.InnerItem.Paths.FullPath + " defined a GraphQL query to resolve its data. The GraphQL query will not be used until an endpoint is defined on the app config.", (object)this);
                return(addPlaceHolderPath(rendering, renderingConfig));
            }
            IGraphQLEndpoint graphQlEndpoint;

            if (!this._graphQLEndpoints.TryGetValue(appConfiguration.GraphQLEndpoint, out graphQlEndpoint))
            {
                this._log.Error("[JSS] - The JSS app " + appConfiguration.Name + " is set to use GraphQL endpoint " + appConfiguration.GraphQLEndpoint + ", but no GraphQL endpoint was registered with this URL. GraphQL resolution will not be used.", (object)this);
                return(addPlaceHolderPath(rendering, renderingConfig));
            }
            GraphQLAwareRenderingContentsResolver.LocalGraphQLRequest localGraphQlRequest1 = new GraphQLAwareRenderingContentsResolver.LocalGraphQLRequest();
            localGraphQlRequest1.Query = str;
            GraphQLAwareRenderingContentsResolver.LocalGraphQLRequest localGraphQlRequest2 = localGraphQlRequest1;
            localGraphQlRequest2.LocalVariables.Add("contextItem", (object)Context.Item.ID.Guid.ToString());
            localGraphQlRequest2.LocalVariables.Add("datasource", (object)rendering.DataSource);

            //TODO Replace with correct path - Example of getting rendering field items to get path of card ID's
            string getCardPath = rendering.Item.Fields["sample1"].ToString();

            try
            {
                string   cardIDList = HttpContext.Current.Request.QueryString["cardIDList"];
                string[] cardIDs    = cardIDList.Split(',');
                int      cardInt    = 1;
                foreach (var cardID in cardIDs)
                {
                    localGraphQlRequest2.LocalVariables.Add("cardID" + cardInt, getCardPath + cardID);
                    cardInt++;
                }
            }
            catch (Exception ex)
            {
                this._log.Error("[JSS] - Something went wrong parsing the comma delimited query string parameter for cardIDList - " + ex.Message.ToString(), (object)this);
            }

            IDocumentExecuter executor = graphQlEndpoint.CreateDocumentExecutor();
            ExecutionOptions  options  = graphQlEndpoint.CreateExecutionOptions((GraphQLRequest)localGraphQlRequest2, !HttpContext.Current.IsCustomErrorEnabled);

            if (options == null)
            {
                throw new ArgumentException("Endpoint returned null options.");
            }
            TransformationResult transformationResult = graphQlEndpoint.SchemaInfo.QueryTransformer.Transform((GraphQLRequest)localGraphQlRequest2);

            if (transformationResult.Errors != null)
            {
                return (object)new ExecutionResult()
                       {
                           Errors = transformationResult.Errors
                       }
            }
            ;
            options.Query    = transformationResult.Document.OriginalQuery;
            options.Document = transformationResult.Document;
            if (options.Document.Operations.Any <Operation>((Func <Operation, bool>)(op => (uint)op.OperationType > 0U)))
            {
                throw new InvalidOperationException("Cannot use mutations or subscriptions in a datasource query. Use queries only.");
            }
            using (QueryTracer queryTracer = graphQlEndpoint.Performance.TrackQuery((GraphQLRequest)localGraphQlRequest2, options))
            {
                ExecutionResult result = this._asyncHelpers.RunSyncWithThreadContext <ExecutionResult>((Func <Task <ExecutionResult> >)(() => executor.ExecuteAsync(options)));
                graphQlEndpoint.Performance.CollectMetrics(graphQlEndpoint.SchemaInfo.Schema, (IEnumerable <Operation>)options.Document.Operations, result);
                new QueryErrorLog((ILogger) new BaseLogAdapter(this._log)).RecordQueryErrors(result);
                queryTracer.Result = result;
                //return (object)this._documentWriter.ToJObject((object)result);
                var jsonResultToConvert = (object)this._documentWriter.ToJObject((object)result);
                var jsonResult          = (JObject)jsonResultToConvert;
                jsonResult[PlaceholderPathKey] = rendering.Placeholder;
                return(jsonResult);
            }
        }
示例#5
0
 public void Setup()
 {
     _transformationResult = new TransformationResult <Foo>();
 }
        public async Task <IHardwareDescription> Transform(IEnumerable <string> assemblyPaths, IHardwareGenerationConfiguration configuration)
        {
            var apiClient = ApiClientFactory.CreateApiClient(configuration.RemoteClientConfiguration());

            var assemblyContainers = assemblyPaths
                                     .Select(path => new AssemblyContainer
            {
                Name        = Path.GetFileNameWithoutExtension(path),
                FileContent = File.ReadAllBytes(path)
            });

            var apiConfiguration = new Bridge.Models.HardwareGenerationConfiguration
            {
                CustomConfiguration = configuration.CustomConfiguration,
                DeviceName          = configuration.DeviceName,
                HardwareEntryPointMemberFullNames    = configuration.HardwareEntryPointMemberFullNames,
                HardwareEntryPointMemberNamePrefixes = configuration.HardwareEntryPointMemberNamePrefixes
            };

            var transformationTicket = await apiClient
                                       .RequestTransformation(new TransformationRequest
            {
                Assemblies    = assemblyContainers,
                Configuration = apiConfiguration
            });


            TransformationResult transformationResult  = null;
            const int            maxResultAttemptCount = 100;
            var waitAttemptIndex = 0;
            var waitMilliseconds = 333;

            while (transformationResult == null && waitAttemptIndex < maxResultAttemptCount)
            {
                await Task.Delay(waitMilliseconds);

                var transformationResultResponse = await apiClient.GetTransformationResult(transformationTicket.Token);

                if (transformationResultResponse.ResponseMessage.IsSuccessStatusCode)
                {
                    transformationResult = transformationResultResponse.GetContent();
                }
                else if (transformationResultResponse.ResponseMessage.StatusCode != System.Net.HttpStatusCode.NotFound)
                {
                    transformationResultResponse.ResponseMessage.EnsureSuccessStatusCode();
                }

                if (++waitAttemptIndex % 10 == 0)
                {
                    waitMilliseconds *= 2;
                }
            }

            var exceptionMessageBase =
                "Transforming the following assemblies failed: " + string.Join(", ", assemblyPaths) + ". ";

            if (transformationResult == null)
            {
                throw new Exception(
                          exceptionMessageBase + "The remote Hastlayer service didn't produce a result in a timely manner. " +
                          "This could indicate a problem with the service or that the assemblies contained exceptionally complex code.");
            }

            if (transformationResult.Errors?.Any() == true)
            {
                throw new Exception(
                          exceptionMessageBase + "The following error(s) happened: " + Environment.NewLine +
                          string.Join(Environment.NewLine, transformationResult.Errors));
            }

            var hardwareDescription = transformationResult.HardwareDescription;

            return(new RemoteHardwareDescription
            {
                HardwareEntryPointNamesToMemberIdMappings = hardwareDescription.HardwareEntryPointNamesToMemberIdMappings,
                Language = hardwareDescription.Language,
                Source = hardwareDescription.Source,
                Warnings = hardwareDescription.Warnings.Select(warning =>
                                                               new Common.Models.TransformationWarning {
                    Code = warning.Code, Message = warning.Message
                })
            });
        }
        public async Task <IHardwareDescription> Transform(IEnumerable <string> assemblyPaths, IHardwareGenerationConfiguration configuration)
        {
            var apiClient = ApiClientFactory.CreateApiClient(configuration.RemoteClientConfiguration());

            var assemblyContainers = assemblyPaths
                                     .Select(path => new AssemblyContainer
            {
                Name        = Path.GetFileNameWithoutExtension(path),
                FileContent = File.ReadAllBytes(path)
            });

            var apiConfiguration = new Bridge.Models.HardwareGenerationConfiguration
            {
                CustomConfiguration = configuration.CustomConfiguration,
                DeviceName          = configuration.DeviceName,
                HardwareEntryPointMemberFullNames    = configuration.HardwareEntryPointMemberFullNames,
                HardwareEntryPointMemberNamePrefixes = configuration.HardwareEntryPointMemberNamePrefixes
            };

            try
            {
                var transformationTicket = await apiClient
                                           .RequestTransformation(new TransformationRequest
                {
                    Assemblies    = assemblyContainers,
                    Configuration = apiConfiguration
                });


                TransformationResult transformationResult  = null;
                const int            maxResultAttemptCount = 100;
                var waitAttemptIndex = 0;
                var waitMilliseconds = 333;
                while (transformationResult == null && waitAttemptIndex < maxResultAttemptCount)
                {
                    await Task.Delay(waitMilliseconds);

                    var transformationResultResponse = await apiClient.GetTransformationResult(transformationTicket.Token);

                    if (transformationResultResponse.ResponseMessage.IsSuccessStatusCode)
                    {
                        transformationResult = transformationResultResponse.GetContent();
                    }
                    else if (transformationResultResponse.ResponseMessage.StatusCode != System.Net.HttpStatusCode.NotFound)
                    {
                        transformationResultResponse.ResponseMessage.EnsureSuccessStatusCode();
                    }

                    if (++waitAttemptIndex % 10 == 0)
                    {
                        waitMilliseconds *= 2;
                    }
                }

                var exceptionMessageBase =
                    "Transforming the following assemblies failed: " + string.Join(", ", assemblyPaths) + ". ";
                if (transformationResult == null)
                {
                    throw new Exception(
                              exceptionMessageBase + "The remote Hastlayer service didn't produce a result in a timely manner. " +
                              "This could indicate a problem with the service or that the assemblies contained exceptionally complex code.");
                }

                if (transformationResult.Errors?.Any() == true)
                {
                    throw new Exception(
                              exceptionMessageBase + "The following error(s) happened: " + Environment.NewLine +
                              string.Join(Environment.NewLine, transformationResult.Errors));
                }

                var hardwareDescription = transformationResult.HardwareDescription;
                return(new RemoteHardwareDescription
                {
                    HardwareEntryPointNamesToMemberIdMappings = hardwareDescription.HardwareEntryPointNamesToMemberIdMappings,
                    Language = hardwareDescription.Language,
                    Source = hardwareDescription.Source,
                    Warnings = hardwareDescription.Warnings.Select(warning =>
                                                                   new Common.Models.TransformationWarning {
                        Code = warning.Code, Message = warning.Message
                    })
                });
            }
            catch (ApiException ex)
            {
                var message = "Remote transformation failed: ";

                if (ex.StatusCode == System.Net.HttpStatusCode.Unauthorized)
                {
                    message += "Authorizing with Hastlayer Remote Services failed. Maybe you mistyped your credentials?";
                }
                else
                {
                    message += $"The response code was {ex.StatusCode}. Most possibly there is some issue with Hastlayer Remote Services. If this error persists please get in touch with us under https://hastlayer.com/contact.";
                }

                throw new RemoteTransformationException(message, ex);
            }
            catch (JsonReaderException ex)
            {
                // This will happen also when authorization fails and Azure AD authentication takes over from the API,
                // and redirects the client to the Microsoft login screen (there doesn't seem to be a way to prevent
                // this).
                throw new RemoteTransformationException("Remote transformation failed because Hastlayer Remote Services returned an unexpected response. This might be because authorization failed (check if you mistyped your credentials) or because there is some issue with the service. If this error persists please get in touch with us under https://hastlayer.com/contact.", ex);
            }
        }
        private async Task <ExitCode> InternalDeployAsync(
            ImmutableArray <DeploymentExecutionDefinition> deploymentExecutionDefinitions,
            SemanticVersion explicitVersion,
            CancellationToken cancellationToken = default)
        {
            var tempDirectoriesToClean = new List <DirectoryInfo>();
            var tempFilesToClean       = new List <string>();

            try
            {
                _logger.Verbose("Executing deployment execution definitions [{Length}]: {Executions}",
                                deploymentExecutionDefinitions.Length,
                                string.Join($"{Environment.NewLine}\t", deploymentExecutionDefinitions.Select(_ => $"'{_}'")));

                foreach (DeploymentExecutionDefinition deploymentExecutionDefinition in deploymentExecutionDefinitions)
                {
                    if (string.IsNullOrWhiteSpace(deploymentExecutionDefinition.TargetDirectoryPath) &&
                        string.IsNullOrWhiteSpace(deploymentExecutionDefinition.PublishSettingsFile))
                    {
                        throw new InvalidOperationException($"{nameof(deploymentExecutionDefinition.TargetDirectoryPath)} and {nameof(deploymentExecutionDefinition.PublishSettingsFile)} are both not set");
                    }

                    string asJson = JsonConvert.SerializeObject(deploymentExecutionDefinition, Formatting.Indented);
                    _logger.Information("Executing deployment execution definition: '{DeploymentExecutionDefinition}'",
                                        asJson);

                    const string TempPrefix = "MD-";

                    string uniqueSuffix = DateTime.Now.ToString("MMddHHmmssfff", CultureInfo.InvariantCulture);

                    string tempPath = Path.Combine(
                        Path.GetTempPath(),
                        $"{TempPrefix}{uniqueSuffix}{Guid.NewGuid().ToString().Substring(0, 6)}");

                    var           tempWorkingDirectory        = new DirectoryInfo(tempPath);
                    DirectoryInfo packageInstallTempDirectory = tempWorkingDirectory;

                    tempDirectoriesToClean.Add(packageInstallTempDirectory);

                    MayBe <InstalledPackage> installedMainPackage =
                        await _packageInstaller.InstallPackageAsync(
                            deploymentExecutionDefinition,
                            packageInstallTempDirectory,
                            false,
                            explicitVersion,
                            cancellationToken).ConfigureAwait(false);

                    if (!installedMainPackage.HasValue)
                    {
                        _logger.Error(
                            "Could not install package defined in deployment execution definition {DeploymentExecutionDefinition}",
                            deploymentExecutionDefinition);
                        return(ExitCode.Failure);
                    }

                    InstalledPackage installedPackage = installedMainPackage.Value;

                    _logger.Information(
                        "Successfully installed NuGet package '{PackageId}' version '{Version}' to path '{NugetPackageFullPath}'",
                        installedPackage.PackageId,
                        installedPackage.Version.ToNormalizedString(),
                        installedPackage.NugetPackageFullPath);

                    tempWorkingDirectory.Refresh();

                    DirectoryInfo[] packagesDirectory = tempWorkingDirectory.GetDirectories();

                    DirectoryInfo packageDirectory =
                        packagesDirectory.Single(directory =>
                                                 directory.Name.Equals(installedPackage.PackageId, StringComparison.OrdinalIgnoreCase));

                    SemanticVersion version = explicitVersion ?? GetSemanticVersionFromDefinition(
                        deploymentExecutionDefinition,
                        packageDirectory,
                        installedPackage.Version);

                    _logger.Verbose("Package version is {Version}", version.ToNormalizedString());

                    var possibleXmlTransformations = new List <FileMatch>();
                    var replaceFiles = new List <FileMatch>();

                    var environmentPackageResult = new EnvironmentPackageResult(true);

                    var contentDirectory =
                        new DirectoryInfo(Path.Combine(packageDirectory.FullName, "Content"));

                    if (!contentDirectory.Exists)
                    {
                        _logger.Error("Content directory '{FullName}' does not exist", contentDirectory.FullName);
                        return(ExitCode.Failure);
                    }

                    FileInfo contentFilesJson = packageDirectory.GetFiles("contentFiles.json").SingleOrDefault();

                    if (contentFilesJson?.Exists == true)
                    {
                        ExitCode exitCode = VerifyFiles(contentFilesJson.FullName, contentDirectory);

                        if (!exitCode.IsSuccess)
                        {
                            return(exitCode);
                        }
                    }
                    else
                    {
                        _logger.Debug("No file contentFiles.json was found in package directory {PackageDirectory}",
                                      packageDirectory.FullName);
                    }

                    if (!string.IsNullOrWhiteSpace(deploymentExecutionDefinition.EnvironmentConfig))
                    {
                        _logger.Information(
                            "Fetching environment packages for package {Package} and environment {Environment}",
                            deploymentExecutionDefinition.PackageId, deploymentExecutionDefinition.EnvironmentConfig);

                        environmentPackageResult = await AddEnvironmentPackageAsync(deploymentExecutionDefinition,
                                                                                    packageInstallTempDirectory,
                                                                                    possibleXmlTransformations,
                                                                                    replaceFiles,
                                                                                    tempDirectoriesToClean,
                                                                                    version,
                                                                                    cancellationToken).ConfigureAwait(false);

                        if (!environmentPackageResult.IsSuccess)
                        {
                            return(ExitCode.Failure);
                        }

                        if (environmentPackageResult.Version != null)
                        {
                            _logger.Information("Installed environment package version {Version}",
                                                environmentPackageResult.Version.ToNormalizedString());
                        }
                        else
                        {
                            _logger.Information("No environment package was installed");
                        }
                    }
                    else
                    {
                        _logger.Debug("Definition has no environment configuration specified");
                    }

                    if (possibleXmlTransformations.Any())
                    {
                        _logger.Debug("Possible Xml transformation files {V}",
                                      string.Join(", ",
                                                  possibleXmlTransformations.Select(fileMatch =>
                                                                                    $"'{fileMatch.TargetName}' replaced by --> '{fileMatch.ActionFile.FullName}'")));
                    }

                    var xmlTransformedFiles = new List <string>();

                    foreach (FileMatch possibleXmlTransformation in possibleXmlTransformations)
                    {
                        TransformationResult result = _xmlTransformer.TransformMatch(possibleXmlTransformation,
                                                                                     contentDirectory);

                        if (!result.IsSuccess)
                        {
                            return(ExitCode.Failure);
                        }

                        xmlTransformedFiles.AddRange(result.TransformedFiles);
                    }

                    if (replaceFiles.Any())
                    {
                        _logger.Debug("Possible replacing files {Files}",
                                      string.Join(", ",
                                                  replaceFiles.Select(fileMatch =>
                                                                      $"'{fileMatch.TargetName}' replaced by --> '{fileMatch.ActionFile.FullName}'")));
                    }

                    var replacedFiles = new List <string>();

                    foreach (FileMatch replacement in replaceFiles)
                    {
                        ReplaceResult result = ReplaceFileIfMatchingFiles(replacement, contentDirectory);

                        if (!result.IsSuccess)
                        {
                            return(ExitCode.Failure);
                        }

                        replacedFiles.AddRange(result.ReplacedFiles);
                    }

                    if (!string.IsNullOrWhiteSpace(deploymentExecutionDefinition.WebConfigTransformFile))
                    {
                        DeploymentTransformation.Transform(deploymentExecutionDefinition, contentDirectory, _logger);
                    }

                    string uniqueTargetTempSuffix =
                        DateTime.Now.ToString("MMddHHmmssfff", CultureInfo.InvariantCulture);

                    string uniqueTargetTempPath = Path.Combine(
                        Path.GetTempPath(),
                        $"{TempPrefix}t{uniqueTargetTempSuffix}{Guid.NewGuid().ToString().Substring(0, 6)}");

                    var targetTempDirectoryInfo =
                        new DirectoryInfo(uniqueTargetTempPath);

                    if (!targetTempDirectoryInfo.Exists)
                    {
                        _logger.Debug("Creating temp target directory '{FullName}'",
                                      packageInstallTempDirectory.FullName);
                        targetTempDirectoryInfo.Create();
                    }

                    string wwwrootPath = Path.Combine(contentDirectory.FullName, "wwwroot");

                    var wwwRootDirectory = new DirectoryInfo(wwwrootPath);

                    DirectoryInfo applicationMetadataTargetDirectory =
                        wwwRootDirectory.Exists ? wwwRootDirectory : contentDirectory;

                    string versionFile = ApplicationMetadataCreator.SetVersionFile(
                        installedMainPackage.Value,
                        applicationMetadataTargetDirectory,
                        deploymentExecutionDefinition,
                        xmlTransformedFiles,
                        replacedFiles,
                        environmentPackageResult,
                        _logger);

                    _logger.Information("Successfully wrote metadata file {Path}", versionFile);

                    _logger.Verbose("Copying content files to '{FullName}'", targetTempDirectoryInfo.FullName);

                    bool usePublishSettingsFile =
                        !string.IsNullOrWhiteSpace(deploymentExecutionDefinition.PublishSettingsFile);

                    var targetAppOffline = new FileInfo(Path.Combine(targetTempDirectoryInfo.FullName,
                                                                     DeploymentConstants.AppOfflineHtm));

                    var ruleConfiguration = RuleConfiguration.Get(deploymentExecutionDefinition,
                                                                  DeployerConfiguration,
                                                                  _logger);

                    if (ruleConfiguration.AppOfflineEnabled && usePublishSettingsFile)
                    {
                        string sourceAppOffline =
                            Path.Combine(contentDirectory.FullName, DeploymentConstants.AppOfflineHtm);

                        if (!File.Exists(sourceAppOffline) && !targetAppOffline.Exists)
                        {
                            using var _ = File.Create(targetAppOffline.FullName);

                            _logger.Debug("Created offline file '{File}'", targetAppOffline.FullName);

                            if (DeployerConfiguration.DefaultWaitTimeAfterAppOffline > TimeSpan.Zero)
                            {
                                await Task.Delay(DeployerConfiguration.DefaultWaitTimeAfterAppOffline,
                                                 cancellationToken)
                                .ConfigureAwait(false);
                            }

                            tempFilesToClean.Add(targetAppOffline.FullName);
                        }
                    }

                    RecursiveIO.RecursiveCopy(contentDirectory,
                                              targetTempDirectoryInfo,
                                              _logger,
                                              deploymentExecutionDefinition.ExcludedFilePatterns);

                    tempDirectoriesToClean.Add(targetTempDirectoryInfo);

                    _logger.Debug("Copied content files from '{ContentDirectory}' to '{FullName}'",
                                  contentDirectory,
                                  targetTempDirectoryInfo.FullName);
                    tempDirectoriesToClean.Add(packageInstallTempDirectory);

                    bool hasPublishSettingsFile =
                        !string.IsNullOrWhiteSpace(deploymentExecutionDefinition.PublishSettingsFile) &&
                        File.Exists(deploymentExecutionDefinition.PublishSettingsFile);

                    if (hasPublishSettingsFile)
                    {
                        _logger.Debug("The publish settings file '{PublishSettingsFile}' exists",
                                      deploymentExecutionDefinition.PublishSettingsFile);
                    }
                    else
                    {
                        _logger.Debug("The deployment definition has no publish setting file");
                    }

                    if (deploymentExecutionDefinition.PublishType == PublishType.WebDeploy)
                    {
                        _webDeployHelper.DeploymentTraceEventHandler += (sender, args) =>
                        {
                            if (string.IsNullOrWhiteSpace(args.Message))
                            {
                                return;
                            }

                            if (args.EventLevel == TraceLevel.Verbose)
                            {
                                _logger.Verbose("{Message}", args.Message);
                                return;
                            }

                            _logger.Information("{Message}", args.Message);
                        };
                    }

                    bool hasIisSiteName = deploymentExecutionDefinition.IisSiteName.HasValue();
                    IDeploymentChangeSummary summary;

                    try
                    {
                        IIisManager?manager = default;

                        if (!string.IsNullOrWhiteSpace(deploymentExecutionDefinition.IisSiteName))
                        {
                            manager = _iisManager(deploymentExecutionDefinition);
                        }

                        if (hasIisSiteName && manager is {})
                        {
                            bool stopped = manager.StopSiteIfApplicable();

                            if (!stopped)
                            {
                                _logger.Error(
                                    "Could not stop IIS site for deployment execution definition {DeploymentExecutionDefinition}",
                                    deploymentExecutionDefinition);
                                return(ExitCode.Failure);
                            }
                        }

                        try
                        {
                            if (deploymentExecutionDefinition.PublishType == PublishType.WebDeploy)
                            {
                                _logger.Information("Deploying {Target} with WebDeploy",
                                                    deploymentExecutionDefinition.TargetDirectoryPath);
                                summary = await _webDeployHelper.DeployContentToOneSiteAsync(
                                    targetTempDirectoryInfo.FullName,
                                    deploymentExecutionDefinition.PublishSettingsFile,
                                    DeployerConfiguration.DefaultWaitTimeAfterAppOffline,
                                    doNotDelete : ruleConfiguration.DoNotDeleteEnabled,
                                    appOfflineEnabled : ruleConfiguration.AppOfflineEnabled,
                                    useChecksum : ruleConfiguration.UseChecksumEnabled,
                                    whatIf : ruleConfiguration.WhatIfEnabled,
                                    traceLevel : TraceLevel.Verbose,
                                    appDataSkipDirectiveEnabled : ruleConfiguration.AppDataSkipDirectiveEnabled,
                                    applicationInsightsProfiler2SkipDirectiveEnabled :
                                    ruleConfiguration.ApplicationInsightsProfiler2SkipDirectiveEnabled,
                                    logAction : message => _logger.Debug("{Message}", message),
                                    targetPath : hasPublishSettingsFile
                                    ?string.Empty
                                    : deploymentExecutionDefinition.TargetDirectoryPath
                                    ).ConfigureAwait(false);
                            }
                            else if (deploymentExecutionDefinition.PublishType.IsAnyFtpType)
                            {
                                var basePath = deploymentExecutionDefinition.FtpPath;

                                bool isSecure = deploymentExecutionDefinition.PublishType == PublishType.Ftps;

                                var ftpSettings = new FtpSettings(basePath, isSecure);

                                _logger.Information("Deploying {Target} with {PublishType}",
                                                    deploymentExecutionDefinition.FtpPath?.Path,
                                                    deploymentExecutionDefinition.PublishType);
                                string publishSettingsFile = deploymentExecutionDefinition.PublishSettingsFile;

                                if (string.IsNullOrWhiteSpace(publishSettingsFile))
                                {
                                    _logger.Error(
                                        "Deployment target type is set to {Type} but no publish file is set",
                                        deploymentExecutionDefinition.PublishTypeValue);
                                    return(ExitCode.Failure);
                                }

                                using IFtpHandler ftpHandler = await _ftpHandlerFactory.CreateWithPublishSettings(
                                          publishSettingsFile,
                                          ftpSettings,
                                          _logger, cancellationToken);

                                _logger.Verbose("Created FTP handler, starting publish");

                                summary = await ftpHandler.PublishAsync(
                                    ruleConfiguration,
                                    targetTempDirectoryInfo,
                                    cancellationToken);
                            }
                            else
                            {
                                throw new InvalidOperationException(
                                          $"Publish type {deploymentExecutionDefinition.PublishType} is not supported");
                            }
                        }
                        catch (Exception ex) when(!ex.IsFatal())
                        {
                            _logger.Error(ex,
                                          "Could not deploy site {DeploymentExecutionDefinition}",
                                          deploymentExecutionDefinition);

                            return(ExitCode.Failure);
                        }
                        finally
                        {
                            manager?.Dispose();
                        }
                    }
                    catch (Exception ex) when(!ex.IsFatal())
                    {
                        _logger.Error(ex,
                                      "Could not handle start/stop for iis site {Site}",
                                      deploymentExecutionDefinition.IisSiteName);

                        return(ExitCode.Failure);
                    }

                    _logger.Information("Summary: {Summary}", summary.ToDisplayValue());
                }
示例#9
0
        public TransformationResult Transform(string content, IPolicy policy)
        {
            var result = new TransformationResult();

            var sourceUnit   = new CodeSourceUnit(content, filename, System.Text.Encoding.UTF8, Lexer.LexicalStates.INITIAL, LanguageFeatures.Php71Set);
            var nodesFactory = new BasicNodesFactory(sourceUnit);
            var errors       = new PhpErrorSink();

            sourceUnit.Parse(nodesFactory, errors);
            GlobalCode ast = sourceUnit.Ast;

            if (errors.Count != 0)
            {
                ReportErrors(errors, result, content);
                return(result); // AST is null or invalid
            }

            //collect channel information from source code
            var provider          = SourceTokenProviderFactory.CreateEmptyProvider();
            var collectorComposer = new PhpTokenComposer(provider);
            var collector         = new PhpChannelCollector(policy, new TreeContext(ast), collectorComposer, provider);

            collector.VisitElement(ast);
            result.InputChannels.AddRange(collector.InputChannels);
            result.OutputChannels.AddRange(collector.OutputChannels);
            result.SanitizeChannels.AddRange(collector.SanitizeChannels);

            //if there are no output or input channels found in the code, it makes no sense to transform it
            if (result.OutputChannels.Count == 0 || result.InputChannels.Count == 0)
            {
                return(result);
            }

            var levels = collector.GetDistinctSecurityLevels().OrderByDescending(sl => sl.Level);

            //append a sanitize transformation if there are sanitize channels
            var lowestInputLevel = result.InputChannels.Min(sc => sc.Label.Level);

            if (result.SanitizeChannels.Any())
            {
                var sanSourceUnit   = new CodeSourceUnit(content, filename, System.Text.Encoding.UTF8, Lexer.LexicalStates.INITIAL, LanguageFeatures.Php71Set);
                var sanNodesFactory = new BasicNodesFactory(sourceUnit);
                var sanErrors       = new PhpErrorSink();
                sanSourceUnit.Parse(sanNodesFactory, sanErrors);
                GlobalCode sanAst = sanSourceUnit.Ast;
                if (sanErrors.Count != 0)
                {
                    return(result); // AST is null or invalid
                }

                var pSanitize = new CodeTransformation();
                pSanitize.Kind          = TransformationKind.Sanitize;
                pSanitize.SecurityLevel = new SecurityLevel()
                {
                    Level = lowestInputLevel - 1, Name = "PS"
                };
                var composer = new PhpTokenComposer(provider);
                var rewriter = new PhpChannelRewriter(new TreeContext(sanAst), composer, provider, nodesFactory, policy, collector.InputChannels, collector.OutputChannels, collector.SanitizeChannels, pSanitize.SecurityLevel);
                rewriter.VisitElement(sanAst);
                pSanitize.Code = composer.Code.ToString();

                result.CodeTransformations.Add(pSanitize);
            }

            //create code version for each security level
            foreach (var level in levels)
            {
                var levelSourceUnit   = new CodeSourceUnit(content, filename, System.Text.Encoding.UTF8, Lexer.LexicalStates.INITIAL, LanguageFeatures.Php71Set);
                var levelNodesFactory = new BasicNodesFactory(levelSourceUnit);
                var levelerrors       = new PhpErrorSink();
                levelSourceUnit.Parse(nodesFactory, levelerrors);
                GlobalCode levelAst = levelSourceUnit.Ast;
                if (levelerrors.Count != 0)
                {
                    return(result); // AST is null or invalid
                }


                var version = new CodeTransformation();
                version.Kind          = TransformationKind.Default;
                version.SecurityLevel = level;
                var composer = new PhpTokenComposer(provider);
                var rewriter = new PhpChannelRewriter(new TreeContext(levelAst), composer, provider, levelNodesFactory, policy, collector.InputChannels, collector.OutputChannels, collector.SanitizeChannels, level);
                rewriter.VisitElement(levelAst);
                version.Code = composer.Code.ToString();


                result.CodeTransformations.Add(version);
            }

            //create P version
            var poSourceUnit   = new CodeSourceUnit(content, filename, System.Text.Encoding.UTF8, Lexer.LexicalStates.INITIAL, LanguageFeatures.Php71Set);
            var poNodesFactory = new BasicNodesFactory(poSourceUnit);
            var poErrors       = new PhpErrorSink();

            poSourceUnit.Parse(poNodesFactory, poErrors);
            GlobalCode poAst = poSourceUnit.Ast;

            var po = new CodeTransformation();

            po.Kind = TransformationKind.Original;
            var poComposer = new PhpTokenComposer(provider);

            po.SecurityLevel = new SecurityLevel()
            {
                Level = lowestInputLevel, Name = "P'"
            };
            var poRewriter = new PhpChannelRewriter(new TreeContext(poAst), poComposer, provider, poNodesFactory, policy, collector.InputChannels, collector.OutputChannels, collector.SanitizeChannels, po.SecurityLevel, isOriginalProgram: true);

            poRewriter.VisitElement(poAst);
            po.Code = poComposer.Code.ToString();
            result.CodeTransformations.Add(po);

            return(result);
        }