public async Task  OnGet([FromQuery] string issueId, [FromQuery] string issueKey
                          , [FromQuery] string xdm_e, [FromQuery] string xdm_c, [FromQuery] string cp, [FromQuery] string lic, [FromQuery] string cv, [FromQuery] string jwt
                          , [FromHeader(Name = "Referer")] string referer, [FromHeader(Name = "x-real-ip")] string realIp, [FromHeader(Name = "User-Agent")] string userAgent
                          , [FromHeader(Name = "x-forwarded-for")] string forwardedFor
                          )
 {
     Model.ClientRegistration registrationData = null;
     try
     {
         // check if middleware has problems with token validation
         if (null != _client.AuthException)
         {
             throw _client.AuthException;
         }
         ExportActionPath = Url.Action("ExportIssues", "JiraExporter");
         registrationData = _client.RegistrationData;
         ExportToken      = Utils.EncodeToken(registrationData.SharedSecret, registrationData.ClientKey,
                                              registrationData.Key, 15, "POST"
                                              , ExportActionPath, "");
         SingleIssueKey = issueKey;
         SingleMode     = (!string.IsNullOrEmpty(issueId));
         if (!string.IsNullOrEmpty(issueKey))
         {
             IssuesText = $"<b>{issueKey}</b>";
         }
     }
     catch (Exception exc)
     {
         ZipFileArchive archive = new ZipFileArchive().AddFile("010_ExporterContentPane_params.json", new
         {
             RequestId = _client.RequestId,
             IssueId   = issueId,
             IssueKey  = issueKey,
             ExportActionPath,
             ExportToken,
             registrationData,
             SingleIssueKey,
             SingleMode,
             IssuesText
         });
         // we cannot use exception middleware here, we have to handle errors in place
         (_, ErrorInfo) = await ReporterMiddleware.HandleError(_client
                                                               , new ControllerException($"Error initializing ExporterContentPane", innerException : exc, customData : await archive.Archive())
                                                               , HttpContext, _serviceProvider,
                                                               ReporterMiddleware.HandleReportError, _loggerFactory.CreateLogger <BaseExceptionHandlingMiddleware <IAppJiraCloudExporterCli> >());
     }
 }
示例#2
0
        public async Task <IActionResult> ExportIssues([FromForm(Name = "issues")] List <string> issuesList, [FromForm(Name = "includeqr")] bool includeQRCode
                                                       , [FromHeader(Name = "Referer")] string referer, [FromHeader(Name = "x-real-ip")] string realIp, [FromHeader(Name = "User-Agent")] string userAgent
                                                       , [FromHeader(Name = "x-forwarded-for")] string forwardedFor)
        {
            IActionResult result          = null;
            DateTime      requestDateTime = DateTime.Now;
            TaskMeasurer  taskMeasurer    = new TaskMeasurer();
            string        extension       = "pdf";

            Model.ClientRegistration registrationData = _client.RegistrationData;
            string fileId         = Guid.NewGuid().ToString();
            string reportFileName = $"{_configuration.GetValue<string>("Settings:StorageRoot", "clients_jiracloud")}/{registrationData.ClientKey}/{fileId}.{extension}";

            JArray  fields = null;
            JObject issues = null;
            Dictionary <string, JArray> epicStories = new Dictionary <string, JArray>();

            Report.Model.Document      document             = null;
            Model.ReportFile           reportFile           = null;
            ReportJiraCloudModel       reportJiraCloudModel = null;
            List <StatisticalDocument> statItems            = new List <StatisticalDocument>();

            try
            {
                _logger.LogInformation($"{requestDateTime} New job ClientKey {registrationData.ClientKey}, issues {String.Join(", ", issuesList)}");
                HttpClient httpCli = _clientFactory.CreateClient("jira_client");
                httpCli.BaseAddress = new Uri(registrationData.BaseUrl);
                RestApiClient cli = new RestApiClient(registrationData.Key, registrationData.SharedSecret, registrationData.ClientKey, httpCli);

                fields = (JArray)JsonConvert.DeserializeObject(await taskMeasurer.Run(() => cli.Get($"/rest/api/3/field"), "000_FetchFields"));
                var EpicNameField = getField(fields, "com.pyxis.greenhopper.jira:gh-epic-label");


                string[] responses = await taskMeasurer.Run(() => Task.WhenAll(issuesList.Select(i => cli.Get($"/rest/api/3/issue/{i}"))), "111_FetchIssuesData");

                PdfReport pdfReport = new PdfReport(filePath: reportFileName, storageName: _configuration.GetValue <string>("Settings:StorageName"), debug: _hostEnvironment.IsDevelopment());
                await pdfReport.Configure(_client.PdfApi, _client.BarcodeApi);

                issues = JToken.FromObject(new
                {
                    issues = responses.Select(JsonConvert.DeserializeObject).ToList()
                }) as JObject;

                // get stories for epics
                epicStories = new Dictionary <string, JArray>();
                if (!string.IsNullOrEmpty(EpicNameField))
                {
                    var issuesArr = await Task.WhenAll(issues["issues"]
                                                       .Where(i => !string.IsNullOrEmpty(i.SelectToken($"$.fields.{EpicNameField}")?.ToString()))
                                                       .Select(async i => KeyValuePair.Create(i.SelectToken($"$.key")?.ToString(), await getSubtasksForEpic(cli, i.SelectToken($"$.key")?.ToString()))
                                                               ));

                    epicStories = issuesArr.ToDictionary(t => t.Key, t => t.Value);
                }

                document = taskMeasurer.RunSync(() =>
                {
                    reportJiraCloudModel = new ReportJiraCloudModel(System.IO.File.ReadAllText(
                                                                        _configuration.GetValue("Templates:ReportIssuesModel",
                                                                                                "template/Report-Issues.Mustache")))
                    {
                        EpicLinkField  = getField(fields, "com.pyxis.greenhopper.jira:gh-epic-link"),
                        EpicNameField  = EpicNameField,
                        GenerateQRCode = includeQRCode
                    };
                    return(reportJiraCloudModel.CreateReportModel(reportJiraCloudModel.issuesModel(issues, epicStories)));
                }, "112_PrepareReportModel");

                if (null == document.Options)
                {
                    document.Options = new Report.Model.DocumentOptions();
                }
                await pdfReport.Report(document);


                DateTime current = DateTime.Now;
                reportFile = new Model.ReportFile
                {
                    UniqueId        = $"{Guid.NewGuid()}",
                    ReportType      = extension,
                    ContentType     = "application/pdf",
                    FileName        = issuesList.Count == 1 ? $"{issuesList.First()}.{extension}" : $"Issues.{extension}",
                    StorageFileName = reportFileName,
                    ClientId        = registrationData.Id,
                    Created         = current,
                    Expired         = current.AddHours(_configuration.GetValue("Settings:FileExpirationHours", 24)),
                };
                _dbContext.ReportFile.Add(reportFile);
                statItems = taskMeasurer.Stat.Concat(pdfReport.Stat).ToList();

                await _dbContext.SaveChangesAsync();

                _logger.LogInformation($"{current} Finished {registrationData.ClientKey} in {DateTime.Now - requestDateTime}");
                return(result = new OkObjectResult(new {
                    fileid = reportFile.UniqueId
                    , downloadlink = _basePathReplacement.ReplaceBaseUrl(Url.Link("GetDownload", new { id = reportFile.UniqueId }))
                    , expText = TimeSpan.FromHours(_configuration.GetValue("Settings:FileExpirationHours", 24)).ToReadableString()
                    , exp = reportFile.Expired
                }));
            }
            catch (Exception ex)
            {
                ZipFileArchive archive = new ZipFileArchive().AddFile("010_request_params.json", new
                {
                    RequestId = _client.RequestId,
                    FileId    = fileId,
                    FileName  = reportFileName,
                    includeQRCode, referer, realIp, userAgent, forwardedFor,
                    issues = issuesList
                });
                foreach (var f in new Dictionary <string, object> {
                    { "020_registration.json", registrationData },
                    { "030_fields.json", fields },
                    { "040_issues.json", issues },
                    { "050_epic_stories.json", epicStories },
                    { "051_RenderedDocument.yaml", reportJiraCloudModel?.RenderedYamlDocument },
                    { "052_RenderedJsonDocument.yaml", reportJiraCloudModel?.RenderedJsonDocument },
                    { "060_document.json", document },
                    { "070_report_file.json", reportFile },
                    { "080_result.json", result },
                }.ToArray())
                {
                    archive.AddFile(f.Key, f.Value);
                }
                throw new ControllerException($"Error generating {reportFileName}", innerException: ex, customData: await archive.Archive());
            }
            finally
            {
                _client.Stat = statItems;
            }
        }