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}"); } }
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}"); } } }
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}"); } }
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}"); } }
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}"); } } }