diff --git a/marklogic-data-hub/src/main/java/com/marklogic/hub/job/JobExportResponse.java b/marklogic-data-hub/src/main/java/com/marklogic/hub/job/JobExportResponse.java new file mode 100644 index 0000000000..05b3e2f417 --- /dev/null +++ b/marklogic-data-hub/src/main/java/com/marklogic/hub/job/JobExportResponse.java @@ -0,0 +1,7 @@ +package com.marklogic.hub.job; + +public class JobExportResponse { + public long totalJobs = 0; + public long totalTraces = 0; + public String fullPath = ""; +} diff --git a/marklogic-data-hub/src/main/java/com/marklogic/hub/job/JobManager.java b/marklogic-data-hub/src/main/java/com/marklogic/hub/job/JobManager.java index 2ec7eff1d1..7a007d41b3 100644 --- a/marklogic-data-hub/src/main/java/com/marklogic/hub/job/JobManager.java +++ b/marklogic-data-hub/src/main/java/com/marklogic/hub/job/JobManager.java @@ -107,12 +107,13 @@ public JobDeleteResponse deleteJobs(String jobIds) { * @param exportFilePath specifies where the zip file will be written * @param jobIds a comma-separated list of jobIds; if null, all will be exported */ - public void exportJobs(Path exportFilePath, String jobIds) { + public JobExportResponse exportJobs(Path exportFilePath, String[] jobIds) { + JobExportResponse response = new JobExportResponse(); + response.fullPath = exportFilePath.toAbsolutePath().toString(); + File zipFile = exportFilePath.toFile(); WriteToZipConsumer zipConsumer = new WriteToZipConsumer(zipFile); - String[] jobsArray = jobIds != null ? jobIds.split(",") : null; - QueryManager qm = jobClient.newQueryManager(); // Build a query that will match everything @@ -124,11 +125,11 @@ public void exportJobs(Path exportFilePath, String jobIds) { DataMovementManager dmm = jobClient.newDataMovementManager(); QueryBatcher batcher = null; StructuredQueryDefinition query = null; - if (jobsArray == null) { + if (jobIds == null) { batcher = dmm.newQueryBatcher(emptyQuery); } else { - batcher = dmm.newQueryBatcher(sqb.value(sqb.jsonProperty("jobId"), jobsArray)); + batcher = dmm.newQueryBatcher(sqb.value(sqb.jsonProperty("jobId"), jobIds)); } batcher.onUrisReady(new ExportListener().onDocumentReady(zipConsumer)); JobTicket jobTicket = dmm.startJob(batcher); @@ -139,24 +140,29 @@ public void exportJobs(Path exportFilePath, String jobIds) { JobReport report = dmm.getJobReport(jobTicket); long jobCount = report.getSuccessEventsCount(); + response.totalJobs = jobCount; if (jobCount > 0) { // Get the traces that go with the job(s) dmm = this.traceClient.newDataMovementManager(); - if (jobsArray == null) { + if (jobIds == null) { batcher = dmm.newQueryBatcher(emptyQuery); } else { - batcher = dmm.newQueryBatcher(sqb.value(sqb.element(new QName("jobId")), jobsArray)); + batcher = dmm.newQueryBatcher(sqb.value(sqb.element(new QName("jobId")), jobIds)); } batcher.onUrisReady(new ExportListener().onDocumentReady(zipConsumer)); - dmm.startJob(batcher); + jobTicket = dmm.startJob(batcher); batcher.awaitCompletion(); dmm.stopJob(batcher); dmm.release(); + report = dmm.getJobReport(jobTicket); + long traceCount = report.getSuccessEventsCount(); + response.totalTraces = traceCount; + zipConsumer.close(); } else { @@ -165,6 +171,7 @@ public void exportJobs(Path exportFilePath, String jobIds) { zipFile.delete(); } + return response; } /** diff --git a/marklogic-data-hub/src/test/java/com/marklogic/hub/job/JobManagerTest.java b/marklogic-data-hub/src/test/java/com/marklogic/hub/job/JobManagerTest.java index 5f61050a81..324de8b857 100644 --- a/marklogic-data-hub/src/test/java/com/marklogic/hub/job/JobManagerTest.java +++ b/marklogic-data-hub/src/test/java/com/marklogic/hub/job/JobManagerTest.java @@ -205,7 +205,8 @@ public void exportOneJob() throws IOException { File zipFile = exportPath.toFile(); assertFalse(zipFile.exists()); - manager.exportJobs(exportPath, jobIds.get(0)); + String[] jobs = { jobIds.get(0) }; + manager.exportJobs(exportPath, jobs); assertTrue(zipFile.exists()); @@ -227,7 +228,8 @@ public void exportMultipleJobs() throws IOException { File zipFile = exportPath.toFile(); assertFalse(zipFile.exists()); - manager.exportJobs(exportPath, new StringJoiner(",").add(jobIds.get(0)).add(jobIds.get(1)).toString()); + String[] jobs = { jobIds.get(0), jobIds.get(1) }; + manager.exportJobs(exportPath, jobs); assertTrue(zipFile.exists()); diff --git a/ml-data-hub-plugin/src/main/groovy/com/marklogic/gradle/task/ExportJobsTask.groovy b/ml-data-hub-plugin/src/main/groovy/com/marklogic/gradle/task/ExportJobsTask.groovy index d689377c5f..99b63891a4 100644 --- a/ml-data-hub-plugin/src/main/groovy/com/marklogic/gradle/task/ExportJobsTask.groovy +++ b/ml-data-hub-plugin/src/main/groovy/com/marklogic/gradle/task/ExportJobsTask.groovy @@ -7,7 +7,7 @@ import java.nio.file.Path class ExportJobsTask extends HubTask { @Input - public String jobIds + public String[] jobIds public String filename @TaskAction @@ -16,7 +16,9 @@ class ExportJobsTask extends HubTask { filename = project.hasProperty("filename") ? project.property("filename") : "jobexport.zip" } if (jobIds == null) { - jobIds = project.hasProperty("jobIds") ? project.property("jobIds") : null + if (project.hasProperty("jobIds")) { + jobIds = project.property("jobIds").split(",") + } } if (jobIds == null) { println("Exporting all jobs to " + filename) diff --git a/quick-start/src/main/java/com/marklogic/quickstart/model/JobExport.java b/quick-start/src/main/java/com/marklogic/quickstart/model/JobExport.java new file mode 100644 index 0000000000..11f12f5154 --- /dev/null +++ b/quick-start/src/main/java/com/marklogic/quickstart/model/JobExport.java @@ -0,0 +1,5 @@ +package com.marklogic.quickstart.model; + +public class JobExport { + public String[] jobIds; +} diff --git a/quick-start/src/main/java/com/marklogic/quickstart/service/JobService.java b/quick-start/src/main/java/com/marklogic/quickstart/service/JobService.java index 787abdc72e..f6022a817f 100644 --- a/quick-start/src/main/java/com/marklogic/quickstart/service/JobService.java +++ b/quick-start/src/main/java/com/marklogic/quickstart/service/JobService.java @@ -24,9 +24,14 @@ import com.marklogic.client.query.StructuredQueryBuilder; import com.marklogic.client.query.StructuredQueryDefinition; import com.marklogic.hub.job.JobDeleteResponse; +import com.marklogic.hub.job.JobExportResponse; import com.marklogic.hub.job.JobManager; import com.marklogic.quickstart.model.JobQuery; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; public class JobService extends SearchableService { @@ -89,6 +94,13 @@ public JobDeleteResponse deleteJobs(String jobIds) { return this.jobMgr.deleteJobs(jobIds); } + public File exportJobs(String[] jobIds) throws IOException { + Path exportPath = Files.createTempFile("jobexport", ".zip"); + JobExportResponse jobExportResponse = this.jobMgr.exportJobs(exportPath, jobIds); + File zipfile = new File(jobExportResponse.fullPath); + return zipfile; + } + public void cancelJob(long jobId) { } diff --git a/quick-start/src/main/java/com/marklogic/quickstart/web/JobsController.java b/quick-start/src/main/java/com/marklogic/quickstart/web/JobsController.java index 817147d159..7840e67df3 100644 --- a/quick-start/src/main/java/com/marklogic/quickstart/web/JobsController.java +++ b/quick-start/src/main/java/com/marklogic/quickstart/web/JobsController.java @@ -17,8 +17,11 @@ import com.marklogic.hub.job.JobDeleteResponse; import com.marklogic.quickstart.EnvironmentAware; +import com.marklogic.quickstart.exception.DataHubException; +import com.marklogic.quickstart.model.JobExport; import com.marklogic.quickstart.model.JobQuery; import com.marklogic.quickstart.service.JobService; +import org.apache.commons.io.IOUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Scope; @@ -30,6 +33,8 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; +import java.io.*; + @Controller @RequestMapping(value="/api/jobs") public class JobsController extends EnvironmentAware { @@ -55,4 +60,21 @@ public JobDeleteResponse deleteJobs(@RequestBody String jobIds) { return jobService.deleteJobs(jobIds); } + @RequestMapping(value = "/export", method = RequestMethod.POST) + @ResponseBody + public byte[] exportJobs(@RequestBody JobExport jobExport) { + byte[] response = null; + try { + File zipFile = jobService.exportJobs(jobExport.jobIds); + InputStream is = new FileInputStream(zipFile); + response = IOUtils.toByteArray(is); + } catch (FileNotFoundException e) { + throw new DataHubException(e.getMessage(), e); + } catch (IOException e) { + throw new DataHubException(e.getMessage(), e); + } + + return response; + } + } diff --git a/quick-start/src/main/ui/app/app.module.ts b/quick-start/src/main/ui/app/app.module.ts index b20aa83ba9..0a6f2a50bf 100644 --- a/quick-start/src/main/ui/app/app.module.ts +++ b/quick-start/src/main/ui/app/app.module.ts @@ -61,6 +61,7 @@ import { ObjectToArrayPipe } from './object-to-array.pipe'; import { DatePipeModule } from './date-pipe/date-pipe.module'; import { SelectKeyValuesComponent } from './select-key-values/select-key-values.component'; +import {JobExportDialogComponent} from "./jobs/job-export.component"; @NgModule({ @@ -77,6 +78,7 @@ import { SelectKeyValuesComponent } from './select-key-values/select-key-values. EntityModelerComponent, ExternalDefDialogComponent, JobsComponent, + JobExportDialogComponent, JobOutputComponent, LoginComponent, MlcpUiComponent, @@ -110,7 +112,8 @@ import { SelectKeyValuesComponent } from './select-key-values/select-key-values. EntityEditorComponent, NewEntityComponent, NewFlowComponent, - JobOutputComponent + JobOutputComponent, + JobExportDialogComponent ], imports: [ BrowserModule, diff --git a/quick-start/src/main/ui/app/jobs/index.ts b/quick-start/src/main/ui/app/jobs/index.ts index 77242a224a..94d475083f 100644 --- a/quick-start/src/main/ui/app/jobs/index.ts +++ b/quick-start/src/main/ui/app/jobs/index.ts @@ -1,2 +1,3 @@ export * from './jobs.component'; export * from './job-output.component'; +export * from './job-export.component'; diff --git a/quick-start/src/main/ui/app/jobs/job-export.component.html b/quick-start/src/main/ui/app/jobs/job-export.component.html new file mode 100644 index 0000000000..cc47f83498 --- /dev/null +++ b/quick-start/src/main/ui/app/jobs/job-export.component.html @@ -0,0 +1,10 @@ +