예제 #1
0
        private static async Task GetMetaDataForTemplate(
            this DocumentGenerationClient documentGenerationClient,
            Guid configurationId,
            DocumentGenerationTemplate template,
            string hierarchyPath)
        {
            try
            {
                var stream =
                    await documentGenerationClient.GetMetadata(
                        configurationId,
                        template.TemplateId,
                        template.Languages?.FirstOrDefault() ?? string.Empty,
                        hierarchyPath).ConfigureAwait(false);

                if (stream != Stream.Null)
                {
                    var metadataFilename =
                        GetTempFilename("Metadata_for_" + template.TemplateId, "json");
                    await using var fs = new FileStream(metadataFilename, FileMode.Create, FileAccess.Write, FileShare.None);
                    await stream.CopyToAsync(fs).ConfigureAwait(false);

                    DiagnosticLog(
                        $"Metadata for {template.TemplateId} written to {metadataFilename}");
                }
            }
            catch (DocumentGenerationException d)
            {
                DiagnosticLog($"No template metadata available: {d.Message}");
            }
        }
예제 #2
0
        private static async Task Run(AppConfiguration configuration)
        {
            var validator = new ConfigurationValidator(configuration);

            if (!validator.Validate())
            {
                return;
            }

            using (var httpClient = new HttpClient())
                using (var tokenProviderFactory = new LogicTokenProviderFactory(configuration.TokenProvider))
                {
                    var documentGenerationClient = new DocumentGenerationClient(httpClient, tokenProviderFactory, configuration.DocumentGeneration);

                    var configurationId = configuration.GenerationSample.ConfigurationId ?? throw new Exception("Validation should have reported no ConfigurationId set");
                    var hierarchyPath   = configuration.GenerationSample.HierarchyPath;
                    var subject         = configuration.GenerationSample.Subject;
                    var mergeData       = JObject.Parse(File.ReadAllText($"values/{CustomerDataFileName}"));

                    try
                    {
                        var templates =
                            (await documentGenerationClient.GetTemplates(configurationId, hierarchyPath, subject)
                             .ConfigureAwait(false))
                            .ToDictionary(t => t.TemplateId, t => t);
                        var allFormats = Enum.GetValues(typeof(DocumentFormat)).Cast <DocumentFormat>().ToArray();

                        var documentDetailsList = new List <DocumentDetails>();

                        foreach (var templateId in new[] { BasicWordTemplateId, WordWithPartialTemplateId, WordToSaveAsTxtTemplateId })
                        {
                            if (!templates.TryGetValue(templateId, out var template))
                            {
                                DiagnosticLog($"Unable to find {templateId} in the template storage area");
                                continue;
                            }

                            await GetMetaDataForTemplate(documentGenerationClient, configurationId, template, hierarchyPath).ConfigureAwait(false);

                            foreach (var format in allFormats)
                            {
                                var documentDetails = new GeneratedDocumentDetails
                                {
                                    ConfigurationId = configurationId,
                                    HierarchyPath   = hierarchyPath,
                                    Template        = template,
                                    MergeData       = mergeData,
                                    DocumentFormat  = format,
                                    Description     = $"Generated from {template.TemplateId} to {format}",
                                };
                                await documentGenerationClient.GenerateDocumentFromTemplate(documentDetails)
                                .ConfigureAwait(false);

                                if (documentDetails.AnchorDetails != null)
                                {
                                    documentDetailsList.Add(documentDetails);
                                    if (documentDetails.AnchorDetails.Href != null)
                                    {
                                        var convertedDocumentDetails = new ConvertedDocumentDetails
                                        {
                                            ConfigurationId      = configurationId,
                                            SourceDocumentUrl    = documentDetails.AnchorDetails.Href,
                                            SourceDocumentFormat = format,
                                            DocumentFormat       = DocumentFormat.Pdf,
                                            Description          = $"Rendered from ({documentDetails.Description})",
                                        };
                                        await documentGenerationClient.RenderPdfAFromDocumentLink(convertedDocumentDetails)
                                        .ConfigureAwait(false);

                                        if (convertedDocumentDetails.AnchorDetails != null)
                                        {
                                            documentDetailsList.Add(convertedDocumentDetails);
                                        }
                                    }
                                }
                            }
                        }

                        GeneratePageWithDocumentLinks(documentDetailsList);
                    }
                    catch (Exception e)
                    {
                        DiagnosticLog($"{e.Message}/{e.StackTrace}");
                    }
                }
        }
예제 #3
0
        private static async Task GenerateDocumentFromTemplate(this DocumentGenerationClient documentGenerationClient, GeneratedDocumentDetails documentDetails)
        {
            try
            {
                DiagnosticLog($"Requesting document generation from template {documentDetails.Template.TemplateId}");
                var documentGenerationProgress =
                    await documentGenerationClient.RequestDocumentGeneration(
                        documentDetails.ConfigurationId,
                        new DocumentGenerationRequestDetails(
                            documentDetails.HierarchyPath,
                            documentDetails.Template.TemplateId,
                            documentDetails.Template.Languages.FirstOrDefault() ?? string.Empty,
                            documentDetails.DocumentFormat,
                            documentDetails.MergeData,
                            null,
                            false,
                            new Guid("11111111-1111-1111-1111-111111111111")))
                    .ConfigureAwait(false);

                const int secondsToTimesUp = 30;
                var       stopWatch        = Stopwatch.StartNew();
                while (stopWatch.Elapsed.TotalSeconds < secondsToTimesUp)
                {
                    var generationProgress =
                        await documentGenerationClient.GetDocumentGenerationProgress(documentGenerationProgress.Id)
                        .ConfigureAwait(false);

                    switch (generationProgress.State)
                    {
                    case DocumentGenerationState.Failed:
                        DiagnosticLog(
                            $"Document generation failed for template: {documentDetails.Template.TemplateId}: {generationProgress.FailReason}");
                        throw new Exception("Document generation failed for template: ");

                    case DocumentGenerationState.Requested:
                        DiagnosticLog($"{documentDetails.Template.TemplateId}: document not yet ready.");
                        Thread.Sleep(300);
                        continue;

                    case DocumentGenerationState.Completed:
                        break;
                    }

                    var documentUri =
                        await documentGenerationClient.GetDocumentGenerationUri(documentGenerationProgress.Id)
                        .ConfigureAwait(false);

                    if (documentUri?.Uri != null)
                    {
                        var filename =
                            GetTempFilename(documentDetails.Template.TemplateId, documentDetails.DocumentFormat.Ext());
                        await using (var fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None))
                        {
                            var response = await new HttpClient().GetAsync(documentUri.Uri).ConfigureAwait(false);
                            await response.Content.CopyToAsync(fs).ConfigureAwait(false);
                        }

                        DiagnosticLog(
                            $"{documentDetails.Template.TemplateId}: Generated document written to {filename}");
                        documentDetails.LocalDownloadPath = filename;
                        documentDetails.FileSize          = new FileInfo(filename).Length;

                        documentDetails.AnchorDetails = new AnchorDetails
                        {
                            Href     = documentUri.Uri,
                            Expiry   = documentUri.UriExpiryTime,
                            LinkText = $"download.{documentDetails.DocumentFormat.Ext()}",
                        };
                    }

                    return;
                }

                DiagnosticLog($"{documentDetails.Template.TemplateId}: Gave up after {secondsToTimesUp} seconds.");
            }
            catch (Exception e)
            {
                DiagnosticLog($"{e.Message}/{e.StackTrace}");
            }
        }
예제 #4
0
        private static async Task RenderPdfAFromDocumentLink(this DocumentGenerationClient documentGenerationClient, ConvertedDocumentDetails convertedDocumentDetails)
        {
            var ext = convertedDocumentDetails.DocumentFormat;

            try
            {
                DiagnosticLog($"Requesting document conversion from url {convertedDocumentDetails.Description}");
                var documentGenerationProgress =
                    await documentGenerationClient.RequestDocumentConversionToPdfA(
                        convertedDocumentDetails.ConfigurationId,
                        new DocumentConversionToPdfARequestDetails(
                            convertedDocumentDetails.SourceDocumentUrl,
                            convertedDocumentDetails.SourceDocumentFormat))
                    .ConfigureAwait(false);

                const int secondsToTimesUp = 30;
                var       stopWatch        = Stopwatch.StartNew();
                while (stopWatch.Elapsed.TotalSeconds < secondsToTimesUp)
                {
                    var documentGenerationRequestStatusCheck =
                        await documentGenerationClient.GetDocumentGenerationProgress(documentGenerationProgress.Id)
                        .ConfigureAwait(false);

                    switch (documentGenerationRequestStatusCheck.State)
                    {
                    case DocumentGenerationState.Failed:
                        DiagnosticLog(
                            $"Document conversion failed for {convertedDocumentDetails.Description}: {documentGenerationRequestStatusCheck.FailReason}");
                        throw new Exception("Document generation failed for template: ");

                    case DocumentGenerationState.Requested:
                        DiagnosticLog($"{convertedDocumentDetails.Description}: document not yet ready.");
                        Thread.Sleep(300);
                        continue;

                    case DocumentGenerationState.Completed:
                        break;
                    }

                    var documentUri =
                        await documentGenerationClient.GetDocumentGenerationUri(documentGenerationProgress.Id)
                        .ConfigureAwait(false);

                    if (documentUri?.Uri != null)
                    {
                        var filename =
                            GetTempFilename(convertedDocumentDetails.Description, ext.Ext());
                        await using (var fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None))
                        {
                            var response = await new HttpClient().GetAsync(documentUri.Uri).ConfigureAwait(false);
                            await response.Content.CopyToAsync(fs).ConfigureAwait(false);
                        }

                        DiagnosticLog(
                            $"{convertedDocumentDetails.Description}: Rendered document written to {filename}");
                        convertedDocumentDetails.LocalDownloadPath = filename;
                        convertedDocumentDetails.FileSize          = new FileInfo(filename).Length;

                        convertedDocumentDetails.AnchorDetails = new AnchorDetails
                        {
                            Href     = documentUri.Uri,
                            Expiry   = documentUri.UriExpiryTime,
                            LinkText = $"download.{ext.Ext()}",
                        };
                    }

                    return;
                }

                DiagnosticLog($"{convertedDocumentDetails.Description}: Gave up after {secondsToTimesUp} seconds.");
            }
            catch (Exception e)
            {
                DiagnosticLog($"{e.Message}/{e.StackTrace}");
            }
        }
예제 #5
0
        private static async Task Run(AppConfiguration configuration)
        {
            var validator = new ConfigurationValidator(configuration);

            if (!validator.Validate())
            {
                return;
            }

            using (var httpClient = new HttpClient())
                using (var tokenProviderFactory = new LogicTokenProviderFactory(configuration.TokenProvider))
                {
                    var documentGenerationClient = new DocumentGenerationClient(httpClient, tokenProviderFactory, configuration.DocumentGeneration);

                    var subject   = string.Empty;
                    var mergeData = JObject.Parse(File.ReadAllText($"values/{CustomerDataFileName}"));

                    ITemplateStorageConfiguration sampleTemplateStorageConfiguration;
                    if (configuration.ConfigurationSample.UseAzureBlob)
                    {
                        sampleTemplateStorageConfiguration = new AzureBlobTemplateStorage(
                            configuration.AzureBlobSample.StorageConnectionString,
                            configuration.AzureBlobSample.ContainerName,
                            configuration.AzureBlobSample.BlobPrefix);
                    }
                    else
                    {
                        sampleTemplateStorageConfiguration = new SharePointOnlineTemplateStorage(
                            configuration.SharePointOnlineSample.ClientId,
                            configuration.SharePointOnlineSample.TenantId,
                            configuration.SharePointOnlineSample.ClientSecret,
                            configuration.SharePointOnlineSample.GroupName);
                    }

                    var configurationId = configuration.ConfigurationSample.ConfigurationId ?? throw new Exception("Configuration Id not configured");

                    // Get an existing document generation configuration of template storage directories
                    DiagnosticLog("Getting a document generation template storage configuration.");
                    var documentGenerationConfiguration =
                        await documentGenerationClient.GetDocumentGenerationConfiguration(configurationId).ConfigureAwait(false);

                    // Update the existing configuration
                    documentGenerationConfiguration.Name       = "ConfigurationSample Name";
                    documentGenerationConfiguration.LevelNames = new[] { "one", "two" };
                    documentGenerationConfiguration.MetadataFilenameExtension = "json";

                    // Create a root directory for this configuration
                    var rootTemplateStorageDirectory =
                        documentGenerationConfiguration.SetRootTemplateStorageDirectory(
                            "Root directory",
                            sampleTemplateStorageConfiguration);

                    // Create a hierarchy of sub directories.
                    // In this case each sub directory is really the Logic template storage area for this subscription,
                    // so they'll all resolve to the same place server side.
                    foreach (var childKey in new[] { "schoolone", "schooltwo" })
                    {
                        var childEntry =
                            rootTemplateStorageDirectory.AddChild(
                                documentGenerationConfiguration.CreateDocumentGenerationTemplateStorageDirectory(
                                    childKey,
                                    $"school {childKey}",
                                    sampleTemplateStorageConfiguration));
                        foreach (var grandChildKey in new[] { "A", "B", "C" })
                        {
                            childEntry.AddChild(
                                grandChildKey,
                                $"dept {grandChildKey}",
                                sampleTemplateStorageConfiguration);
                        }
                    }

                    // Save the created configuration to the Logic server
                    {
                        DiagnosticLog("Saving the rebuilt document generation template storage configuration.");
                        await documentGenerationConfiguration.Save().ConfigureAwait(false);

                        DiagnosticLog("Document generation template storage configuration uploaded.");
                    }

                    // For the sake of the sample, load the configuration from the sever.
                    // This is not really required to proceed.
                    {
                        DiagnosticLog("Downloading the saved document generation template storage configuration.");
                        documentGenerationConfiguration =
                            await documentGenerationClient.GetDocumentGenerationConfiguration(documentGenerationConfiguration.Id).ConfigureAwait(false);

                        DiagnosticLog($"Document generation template storage configuration \"{documentGenerationConfiguration.Name}\" downloaded.");
                    }

                    // For the sake of the sample, modify the configuration and upload again.
                    // This is not required to proceed.
                    {
                        DiagnosticLog("Modifying and uploading the document generation template storage configuration.");
                        var modifyThisTemplateDirectory =
                            documentGenerationConfiguration.FindDirectoryByPath(new HierarchyPath(new[] { string.Empty, "schooltwo", "B" }));
                        modifyThisTemplateDirectory.Key = "BModified";
                        await documentGenerationConfiguration.Save().ConfigureAwait(false);

                        DiagnosticLog($"Document generation template storage configuration \"{documentGenerationConfiguration.Name}\" modified and uploaded.");
                    }

                    // Choose an arbitrary template directory
                    var hierarchyPath     = new HierarchyPath(new[] { string.Empty, "schooltwo", "BModified" });
                    var templateDirectory = documentGenerationConfiguration.FindDirectoryByPath(hierarchyPath);

                    try
                    {
                        // Get all the templates relative to that template directory and ancestor directories
                        var templates =
                            (await templateDirectory.GetTemplates(subject).ConfigureAwait(false))
                            .ToDictionary(t => t.TemplateId, t => t);

                        // If the template we're interested in hasn't been uploaded to the storage area, don't continue.
                        if (!templates.TryGetValue(BasicWordTemplateId, out var template))
                        {
                            DiagnosticLog($"Unable to find {BasicWordTemplateId} in the template storage area");
                            throw new Exception("Finishing prematurely");
                        }

                        var language = template.Languages.FirstOrDefault() ?? string.Empty;

                        // Get the template metadata if it exists
                        try
                        {
                            var metadataStream =
                                await templateDirectory.GetMetadata(BasicWordTemplateId, language)
                                .ConfigureAwait(false);

                            var metadataFilename = GetTempFilename("Metadata_for_" + BasicWordTemplateId, "json");
                            await using (var fs = new FileStream(metadataFilename, FileMode.Create, FileAccess.Write, FileShare.None))
                            {
                                await metadataStream.CopyToAsync(fs).ConfigureAwait(false);
                            }

                            DiagnosticLog($"Template metadata written to {metadataFilename}");
                        }
                        catch (DocumentGenerationException d)
                        {
                            DiagnosticLog($"Unable to get template metadata: {d.Message}");
                        }

                        // Request a document be generated using a template found in the templateDirectory or in ancestor directories
                        DiagnosticLog($"Requesting a document be generated using template {BasicWordTemplateId} found in {hierarchyPath} or in ancestor directories");
                        var documentGenerationProgress =
                            await templateDirectory.RequestDocumentGeneration(
                                template.TemplateId,
                                language,
                                DocumentFormat.Docx,
                                mergeData,
                                null,
                                false,
                                new Guid("11111111-1111-1111-1111-111111111111"))
                            .ConfigureAwait(false);

                        var documentGenerationRequestId = documentGenerationProgress?.Id;

                        Uri downloadLink;

                        if (documentGenerationRequestId == null)
                        {
                            DiagnosticLog($"Unable to request document generation");
                            throw new Exception("Finishing prematurely");
                        }

                        try
                        {
                            downloadLink = await PollForProgress(documentGenerationConfiguration, documentGenerationRequestId.Value).ConfigureAwait(false);
                        }
                        catch (Exception e)
                        {
                            throw new Exception($"Generation failed for {template.TemplateId}. Finishing prematurely", e);
                        }

                        if (downloadLink == null)
                        {
                            DiagnosticLog($"Generation took too long. Finishing prematurely");
                            return;
                        }

                        DiagnosticLog($"{template.TemplateId}: secure download link found: {downloadLink}");
                        var filename = GetTempFilename(template.TemplateId, DocumentFormat.Docx.ToString().ToLower());
                        await DownloadToFilesystem(downloadLink, filename, $"Generated {template.TemplateId}").ConfigureAwait(false);

                        // Request the new document be converted to Pdf/A
                        DiagnosticLog($"Requesting the generated document be converted to Pdf/A");
                        var conversionProgress =
                            await documentGenerationConfiguration.RequestDocumentConversionToPdfA(
                                new DocumentConversionToPdfARequestDetails(
                                    downloadLink,
                                    DocumentFormat.Docx))
                            .ConfigureAwait(false);

                        var conversionProgressId = conversionProgress?.Id;

                        Uri convertedDocumentDownloadLink;

                        if (conversionProgressId == null)
                        {
                            DiagnosticLog($"Unable to request document conversion");
                            throw new Exception("Finishing prematurely");
                        }
                        else
                        {
                            try
                            {
                                convertedDocumentDownloadLink =
                                    await PollForProgress(documentGenerationConfiguration, conversionProgressId.Value)
                                    .ConfigureAwait(false);
                            }
                            catch (Exception e)
                            {
                                throw new Exception($"Conversion to Pdf/A failed for {template.TemplateId}. Finishing prematurely", e);
                            }
                        }

                        if (convertedDocumentDownloadLink == null)
                        {
                            DiagnosticLog($"Conversion took too long. Finishing prematurely");
                            return;
                        }

                        DiagnosticLog($"{template.TemplateId}: secure download link to rendered document found: {convertedDocumentDownloadLink}");
                        var convertedDocumentFilename = GetTempFilename(template.TemplateId, DocumentFormat.Pdf.ToString().ToLower());
                        await DownloadToFilesystem(convertedDocumentDownloadLink, convertedDocumentFilename, $"Rendered {template.TemplateId}").ConfigureAwait(false);
                    }
                    catch (Exception e)
                    {
                        DiagnosticLog($"{e.Message}/{e.StackTrace}");
                    }
                }
        }