Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Export jobs ui #733

Merged
merged 13 commits into from
Feb 13, 2018
Merged
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.marklogic.hub.job;

public class JobExportResponse {
public long totalJobs = 0;
public long totalTraces = 0;
public String fullPath = "";
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
Expand All @@ -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 {
Expand All @@ -165,6 +171,7 @@ public void exportJobs(Path exportFilePath, String jobIds) {
zipFile.delete();
}

return response;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,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());

Expand All @@ -229,7 +230,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());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import java.nio.file.Path

class ExportJobsTask extends HubTask {
@Input
public String jobIds
public String[] jobIds
public String filename

@TaskAction
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.marklogic.quickstart.model;

public class JobExport {
public String[] jobIds;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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) {

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@

import com.marklogic.hub.job.JobDeleteResponse;
import com.marklogic.quickstart.EnvironmentAware;
import com.marklogic.quickstart.model.EnvironmentConfig;
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;
Expand All @@ -31,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 {
Expand All @@ -56,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;
}

}
5 changes: 4 additions & 1 deletion quick-start/src/main/ui/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand All @@ -77,6 +78,7 @@ import { SelectKeyValuesComponent } from './select-key-values/select-key-values.
EntityModelerComponent,
ExternalDefDialogComponent,
JobsComponent,
JobExportDialogComponent,
JobOutputComponent,
LoginComponent,
MlcpUiComponent,
Expand Down Expand Up @@ -110,7 +112,8 @@ import { SelectKeyValuesComponent } from './select-key-values/select-key-values.
EntityEditorComponent,
NewEntityComponent,
NewFlowComponent,
JobOutputComponent
JobOutputComponent,
JobExportDialogComponent
],
imports: [
BrowserModule,
Expand Down
1 change: 1 addition & 0 deletions quick-start/src/main/ui/app/jobs/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './jobs.component';
export * from './job-output.component';
export * from './job-export.component';
10 changes: 10 additions & 0 deletions quick-start/src/main/ui/app/jobs/job-export.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<div>
<h3 class="mdl-dialog__title">Export Jobs and Traces</h3>
<div class="mdl-dialog__content">
<label>{{question}}</label>
</div>
<div class="mdl-dialog__actions">
<button mdl-button (click)="export()" mdl-button-type="raised" mdl-colored="primary" mdl-ripple>Export</button>
<button mdl-button (click)="this.dialog.hide()" mdl-colored="primary" mdl-ripple>Cancel</button>
</div>
</div>
58 changes: 58 additions & 0 deletions quick-start/src/main/ui/app/jobs/job-export.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import {Component, HostListener, Inject, Input} from '@angular/core';
import {MdlDialogReference, MdlDialogService} from '@angular-mdl/core';
import {JobService} from "./jobs.service";

@Component({
selector: 'job-export-dialog',
templateUrl: 'job-export.component.html'
})
export class JobExportDialogComponent {

jobIds: string[];
question: string;

constructor(
public dialog: MdlDialogReference,
private dialogService: MdlDialogService,
private jobService: JobService,
@Inject('jobIds') jobIds: string[]
) {

this.jobIds = jobIds;
this.question = "Export and download ";
if (jobIds.length === 0) {
this.question += "all jobs and their traces?";
} else if (this.jobIds.length === 1) {
this.question += "1 job and its traces?";
} else {
this.question += this.jobIds.length + " jobs and their traces?";
}
}

public export() {
this.dialog.hide();
this.jobService.exportJobs(this.jobIds)
.subscribe(response => {
let body = response['_body'];

// Create a download anchor tag and click it.
var blob = new Blob([body], {type: 'application/zip'});
let a = document.createElement("a");
a.style.display = "none";
document.body.appendChild(a);
let url = window.URL.createObjectURL(blob);
a.href = url;
a.download = 'jobexport.zip';
a.click();
window.URL.revokeObjectURL(url);
},
() => {
this.dialogService.alert("Unable to export jobs");
});
}

@HostListener('keydown.esc')
public onEsc(): void {
this.dialog.hide();
}
}
11 changes: 7 additions & 4 deletions quick-start/src/main/ui/app/jobs/jobs.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,13 @@ <h1>Jobs</h1>
<th class="mdl-data-table__cell--non-numeric">Duration</th>
<th class="mdl-data-table__cell--non-numeric">Output</th>
<th class="mdl-data-table__cell--non-numeric"></th>
<th class="mdl-data-table__cell--non-numeric">
<mdl-button class="delete-jobs"
mdl-tooltip="Delete selected jobs and associated traces"
(click)="deleteJobs()"><i class="fa fa-trash-o"></i></mdl-button>
<th class="mdl-data-table__cell--non-numeric job-actions">
<button mdl-button #btn1="mdlButton" (click)="m1.toggle($event, btn1)" mdl-ripple>Action
<i class="material-icons">keyboard_arrow_down</i></button>
<mdl-menu #m1="mdlMenu" mdl-menu-position="bottom-left">
<mdl-menu-item mdl-ripple (click)="exportJobs()">Export Jobs and Traces</mdl-menu-item>
<mdl-menu-item mdl-ripple (click)="deleteJobs()">Delete Jobs and Traces</mdl-menu-item>
</mdl-menu>
</th>
</tr>
</thead>
Expand Down
9 changes: 4 additions & 5 deletions quick-start/src/main/ui/app/jobs/jobs.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,13 @@ input[type="search"] {
th {
padding: 12px 8px 12px 8px;
color: white;
}

&:last-of-type {
padding-right: 0px;
th.job-actions {
button {
color: white;
}
}
th .delete-jobs {
color: white;
}
}
}

Expand Down
Loading