From 857699d3ba322cef7bd007127508f510dc914f07 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Date: Tue, 20 Dec 2022 18:02:24 -0800 Subject: [PATCH] Zip element template (#83) Zip element template --- pom.xml | 2 +- .../cherry/admin/RunnerRestController.java | 464 +++++++++--------- .../io/camunda/cherry/admin/ZipOperation.java | 52 ++ .../cherry/files/LoadFileFromDiskWorker.java | 12 +- .../camunda/cherry/files/PurgeFileWorker.java | 20 +- .../cherry/files/SaveFileToDiskWorker.java | 4 +- .../io/camunda/cherry/ping/PingConnector.java | 7 +- .../cherry/ping/PingConnectorOutput.java | 70 +-- .../connectorworker/PingObjectConnector.bpmn | 20 +- 9 files changed, 372 insertions(+), 279 deletions(-) create mode 100644 src/main/java/io/camunda/cherry/admin/ZipOperation.java diff --git a/pom.xml b/pom.xml index 259f7ca..9511cc6 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.camunda.community zeebe-cherry-framework - 2.1.0 + 2.2.0 17 diff --git a/src/main/java/io/camunda/cherry/admin/RunnerRestController.java b/src/main/java/io/camunda/cherry/admin/RunnerRestController.java index 3563bcc..1ae4075 100644 --- a/src/main/java/io/camunda/cherry/admin/RunnerRestController.java +++ b/src/main/java/io/camunda/cherry/admin/RunnerRestController.java @@ -16,20 +16,21 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.io.Resource; import org.springframework.core.io.ByteArrayResource; import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.*; import org.springframework.web.server.ResponseStatusException; import java.io.IOException; -import java.nio.charset.Charset; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; @@ -38,237 +39,260 @@ @RequestMapping("cherry") public class RunnerRestController { - - Logger logger = LoggerFactory.getLogger(RunnerRestController.class.getName()); - @Autowired - CherryJobRunnerFactory cherryJobRunnerFactory; - - @Autowired - CherryHistoricFactory cherryHistoricFactory; - - /** - * Spring populate the list of all workers - */ - @Autowired - private List listRunners; - - /** - * Spring populate this list with runner marked at Framework - */ - @Autowired - private List listFrameworkRunners; - - - /** - * Get list of worker. Multiple result is possibles - * /api/runner/list?logo=true&stats=true&delaysstatsinhour=24 - * - * @param logo if true, logo is returned - * @param stats if true, execution on statistics is returned - * @param delayStatsInHours give the delay in hour to collect data - * @return - */ - @GetMapping(value = "/api/runner/list", produces = "application/json") - public List getWorkersList(@RequestParam(name = "logo", required = false) Boolean logo, - @RequestParam(name = "stats", required = false) Boolean stats, - @RequestParam(name = "delaystatsinhours", required = false) Integer delayStatsInHours) { - - return listRunners.stream() - .map(RunnerInformation::getRunnerInformation) - .map(w -> { - return this.completeRunnerInformation(w, - logo == null || logo, - stats == null ? false : stats, - delayStatsInHours == null ? Integer.valueOf(24) : delayStatsInHours); - }) - .toList(); + Logger logger = LoggerFactory.getLogger(RunnerRestController.class.getName()); + @Autowired + CherryJobRunnerFactory cherryJobRunnerFactory; + + @Autowired + CherryHistoricFactory cherryHistoricFactory; + + /** + * Spring populate the list of all workers + */ + @Autowired + private List listRunners; + + /** + * Spring populate this list with runner marked at Framework + */ + @Autowired + private List listFrameworkRunners; + + /** + * Get list of worker. Multiple result is possibles + * /api/runner/list?logo=true&stats=true&delaysstatsinhour=24 + * + * @param logo if true, logo is returned + * @param stats if true, execution on statistics is returned + * @param delayStatsInHours give the delay in hour to collect data + * @return a list of information on runner + */ + @GetMapping(value = "/api/runner/list", produces = "application/json") + public List getWorkersList(@RequestParam(name = "logo", required = false) Boolean logo, + @RequestParam(name = "stats", required = false) Boolean stats, + @RequestParam(name = "delaystatsinhours", required = false) Integer delayStatsInHours) { + + return listRunners.stream().map(RunnerInformation::getRunnerInformation).map(w -> { + return this.completeRunnerInformation(w, logo == null || logo, stats == null ? false : stats, + delayStatsInHours == null ? Integer.valueOf(24) : delayStatsInHours); + }).toList(); + } + + @GetMapping(value = "/api/runner/detail", produces = "application/json") + public Optional getWorker(@RequestParam(name = "name") String runnerName, + @RequestParam(name = "logo", required = false) Boolean logo, + @RequestParam(name = "stats", required = false) Boolean stats, + @RequestParam(name = "delaystatsinhours", required = false) Integer delayStatsInHours) { + return listRunners.stream() + .filter(worker -> worker.getIdentification().equals(runnerName)) + .map(RunnerInformation::getRunnerInformation) + .map(w -> this.completeRunnerInformation(w, logo == null || logo, stats == null ? false : stats, + delayStatsInHours)) + .findFirst(); + } + + /** + * Ask to stop a specific worker + * + * @param runnerName worker to stop + * @return NOTFOUND or the worker information on this worker + */ + @PutMapping(value = "/api/runner/stop", produces = "application/json") + public RunnerInformation stopWorker(@RequestParam(name = "name") String runnerName) { + logger.info("Stop requested for [" + runnerName + "]"); + try { + boolean isStopped = cherryJobRunnerFactory.stopRunner(runnerName); + logger.info("Stop executed for [" + runnerName + "]: " + isStopped); + AbstractRunner runner = getRunnerByName(runnerName); + RunnerInformation runnerInfo = RunnerInformation.getRunnerInformation(runner); + return completeRunnerInformation(runnerInfo, false, false, null); + } catch (CherryJobRunnerFactory.OperationException e) { + if (CherryJobRunnerFactory.RUNNER_NOT_FOUND.equals(e.getExceptionCode())) + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "WorkerName [" + runnerName + "] not found"); + throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "WorkerName [" + runnerName + "] error " + e); } - - @GetMapping(value = "/api/runner/detail", produces = "application/json") - public Optional getWorker(@RequestParam(name = "name") String runnerName, - @RequestParam(name = "logo", required = false) Boolean logo, - @RequestParam(name = "stats", required = false) Boolean stats, - @RequestParam(name = "delaystatsinhours", required = false) Integer delayStatsInHours) { - return listRunners.stream() - .filter(worker -> worker.getIdentification().equals(runnerName)) - .map(RunnerInformation::getRunnerInformation) - .map(w -> this.completeRunnerInformation(w, - logo == null || logo, - stats == null ? false : stats, - delayStatsInHours) - ) - .findFirst(); - } - - /** - * Ask to stop a specific worker - * - * @param runnerName worker to stop - * @return NOTFOUND or the worker information on this worker - */ - @PutMapping(value = "/api/runner/stop", produces = "application/json") - public RunnerInformation stopWorker(@RequestParam(name = "name") String runnerName) { - logger.info("Stop requested for [" + runnerName + "]"); - try { - boolean isStopped = cherryJobRunnerFactory.stopRunner(runnerName); - logger.info("Stop executed for [" + runnerName + "]: " + isStopped); - AbstractRunner runner = getRunnerByName(runnerName); - RunnerInformation runnerInfo = RunnerInformation.getRunnerInformation(runner); - return completeRunnerInformation(runnerInfo, false, false, null); - } catch (CherryJobRunnerFactory.OperationException e) { - if (CherryJobRunnerFactory.RUNNER_NOT_FOUND.equals(e.getExceptionCode())) - throw new ResponseStatusException(HttpStatus.NOT_FOUND, "WorkerName [" + runnerName + "] not found"); - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "WorkerName [" + runnerName + "] error " + e); - } + } + + /** + * Ask to start a specific worker + * + * @param runnerName worker to start + * @return NOTFOUND or the worker information on this worker + */ + @PutMapping(value = "/api/runner/start", produces = "application/json") + public RunnerInformation startWorker(@RequestParam(name = "name") String runnerName) { + logger.info("Start requested for [" + runnerName + "]"); + try { + boolean isStarted = cherryJobRunnerFactory.startRunner(runnerName); + logger.info("Start executed for [" + runnerName + "]: " + isStarted); + AbstractRunner runner = getRunnerByName(runnerName); + RunnerInformation runnerInfo = RunnerInformation.getRunnerInformation(runner); + return completeRunnerInformation(runnerInfo, false, false, null); + } catch (CherryJobRunnerFactory.OperationException e) { + if (CherryJobRunnerFactory.RUNNER_NOT_FOUND.equals(e.getExceptionCode())) + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "WorkerName [" + runnerName + "] not found"); + throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "WorkerName [" + runnerName + "] error " + e); } - - /** - * Ask to start a specific worker - * - * @param runnerName worker to start - * @return NOTFOUND or the worker information on this worker - */ - @PutMapping(value = "/api/runner/start", produces = "application/json") - public RunnerInformation startWorker(@RequestParam(name = "name") String runnerName) { - logger.info("Start requested for [" + runnerName + "]"); - try { - boolean isStarted = cherryJobRunnerFactory.startRunner(runnerName); - logger.info("Start executed for [" + runnerName + "]: " + isStarted); - AbstractRunner runner = getRunnerByName(runnerName); - RunnerInformation runnerInfo = RunnerInformation.getRunnerInformation(runner); - return completeRunnerInformation(runnerInfo, false, false, null); - } catch (CherryJobRunnerFactory.OperationException e) { - if (CherryJobRunnerFactory.RUNNER_NOT_FOUND.equals(e.getExceptionCode())) - throw new ResponseStatusException(HttpStatus.NOT_FOUND, "WorkerName [" + runnerName + "] not found"); - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "WorkerName [" + runnerName + "] error " + e); - } + } + + /** + * Download the Template for a runner + * + * @param runnerName worker to start. If not present, all runners are part of the result + * @param withFrameworkRunners if true, then runners from the framework are included. In general we don't want, else these runners will be present in each collection, and Modeler will throw a duplicate errors + * @return NOTFOUND or the worker information on this worker + */ + @GetMapping(value = "/api/runner/template", produces = "application/json") + public String getTemplate(@RequestParam(name = "name", required = false) String runnerName, + @RequestParam(name = "withframeworkrunners", required = false) Boolean withFrameworkRunners) { + boolean withFrameworkRunnersIncluded = (withFrameworkRunners != null && withFrameworkRunners); + logger.info( + "Download template requested for " + (runnerName == null ? "Complete collection" : "[" + runnerName + "]") + + " FrameworkIncluded[" + withFrameworkRunnersIncluded + "]"); + if (runnerName == null) { + // generate for ALL runners + List> listTemplate = getListRunners(withFrameworkRunnersIncluded).stream() + .map(runner -> new RunnerDecorationTemplate(runner).getTemplate()) + .toList(); + return RunnerDecorationTemplate.getJsonFromList(listTemplate); } - /** - * Download the Template for a runner - * - * @param runnerName worker to start. If not present, all runners are part of the result - * @param withFrameworkRunners if true, then runners from the framework are included. In general we don't want, else these runners will be present in each collection, and Modeler will throw a duplicate errors - * @return NOTFOUND or the worker information on this worker - */ - @GetMapping(value = "/api/runner/template", produces = "application/json") - public String getTemplate(@RequestParam(name = "name", required = false) String runnerName, @RequestParam(name = "withframeworkrunners", required = false) Boolean withFrameworkRunners) { - boolean withFrameworkRunnersIncluded = (withFrameworkRunners != null && withFrameworkRunners); - logger.info("Download template requested for " + (runnerName == null ? "Complete collection" : "[" + runnerName + "]") + " FrameworkIncluded[" + withFrameworkRunnersIncluded + "]"); - if (runnerName == null) { - // generate for ALL runners - List> listTemplate = getListRunners(withFrameworkRunnersIncluded).stream() - .map(runner -> new RunnerDecorationTemplate(runner).getTemplate()) - .toList(); - return RunnerDecorationTemplate.getJsonFromList(listTemplate); - } - + AbstractRunner runner = getRunnerByName(runnerName); + if (runner == null) + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "WorkerName [" + runnerName + "] not found"); + Map templateContent = new RunnerDecorationTemplate(runner).getTemplate(); + return RunnerDecorationTemplate.getJsonFromList(List.of(templateContent)); + } + + /** + * @param runnerName worker to start. If not present, all runners are part of the result + * @param withFrameworkRunners if true, then runners from the framework are included. In general we don't want, else these runners will be present in each collection, and Modeler will throw a duplicate errors + * @param separateTemplate if true, the ZIP file contains one file per runner + * @return a File to download + * @throws IOException can't write the content to the HTTP response + */ + @GetMapping(value = "/api/runner/templatefile", produces = MediaType.TEXT_PLAIN_VALUE) + public @ResponseBody + ResponseEntity downloadTemplate(@RequestParam(name = "name", required = false) String runnerName, + @RequestParam(name = "withframeworkrunners", required = false) Boolean withFrameworkRunners, + @RequestParam(name = "separatetemplate", required = false) Boolean separateTemplate) + throws IOException { + boolean withFrameworkRunnersIncluded = (withFrameworkRunners != null && withFrameworkRunners); + logger.info( + "Download template requested for " + (runnerName == null ? "Complete collection" : "[" + runnerName + "]") + + " FrameworkIncluded[" + withFrameworkRunnersIncluded + "]"); + try { + + Map mapContent = new HashMap<>(); + + String collectionName = null; + if (runnerName != null) { AbstractRunner runner = getRunnerByName(runnerName); if (runner == null) - throw new ResponseStatusException(HttpStatus.NOT_FOUND, "WorkerName [" + runnerName + "] not found"); - Map templateContent = new RunnerDecorationTemplate(runner).getTemplate(); - return RunnerDecorationTemplate.getJsonFromList(List.of(templateContent)); - } - - /** - * @param runnerName worker to start. If not present, all runners are part of the result - * @param withFrameworkRunners if true, then runners from the framework are included. In general we don't want, else these runners will be present in each collection, and Modeler will throw a duplicate errors - * @return a File to download - * @throws IOException can't write the content to the HTTP response - */ - @GetMapping(value = "/api/runner/templatefile", - produces = MediaType.TEXT_PLAIN_VALUE) - public @ResponseBody - ResponseEntity downloadTemplate(@RequestParam(name = "name", required = false) String runnerName, - @RequestParam(name = "withframeworkrunners", required = false) Boolean withFrameworkRunners) throws IOException { - boolean withFrameworkRunnersIncluded = (withFrameworkRunners != null && withFrameworkRunners); - logger.info("Download template requested for " + (runnerName == null ? "Complete collection" : "[" + runnerName + "]") + " FrameworkIncluded[" + withFrameworkRunnersIncluded + "]"); - try { - String content = "Cherry"; - String collectionName = null; - if (runnerName == null) { - List listRunners = getListRunners(withFrameworkRunnersIncluded); - // generate for ALL runners - List> listTemplate = listRunners.stream() - .map(runner -> new RunnerDecorationTemplate(runner).getTemplate()) - .toList(); - content = RunnerDecorationTemplate.getJsonFromList(listTemplate); - Optional collectionNameOp = listRunners.stream().findFirst().map(AbstractRunner::getCollectionName); - collectionName = collectionNameOp.isPresent() ? collectionNameOp.get() : "Cherry"; - - } else { - AbstractRunner runner = getRunnerByName(runnerName); - if (runner == null) - throw new ResponseStatusException(HttpStatus.NOT_FOUND, "WorkerName [" + runnerName + "] not found"); - collectionName = runner.getName(); - content = RunnerDecorationTemplate.getJsonFromList(List.of(new RunnerDecorationTemplate(runner).getTemplate())); - } - byte[] contentBytes = content.getBytes(Charset.defaultCharset()); - HttpHeaders header = new HttpHeaders(); - header.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + collectionName + "Template.json"); - header.add("Cache-Control", "no-cache, no-store, must-revalidate"); - header.add("Pragma", "no-cache"); - header.add("Expires", "0"); - - ByteArrayResource resource = new ByteArrayResource(contentBytes); - - return ResponseEntity.ok() - .headers(header) - .contentLength(contentBytes.length) - .contentType(MediaType.parseMediaType("application/json")) - .body(resource); + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "WorkerName [" + runnerName + "] not found"); + collectionName = runner.getName(); + mapContent.put(collectionName, + RunnerDecorationTemplate.getJsonFromList(List.of(new RunnerDecorationTemplate(runner).getTemplate()))); + + } else if (Boolean.TRUE.equals(separateTemplate) || separateTemplate == null) { + // one file per runner + for (AbstractRunner runner : getListRunners(withFrameworkRunnersIncluded)) { + Map templateContent = new RunnerDecorationTemplate(runner).getTemplate(); + mapContent.put(runner.getName(), RunnerDecorationTemplate.getJsonFromList(List.of(templateContent))); + if (collectionName==null) + collectionName=runner.getCollectionName(); } - catch(Exception e ){ - logger.error("Download template error for " + (runnerName == null ? "Complete collection" : "[" + runnerName + "]") + " FrameworkIncluded[" - + withFrameworkRunnersIncluded - + "] :" +e ); - return ResponseEntity.internalServerError().body(null); - + } else { + // one file with all runner + + List listRunners = getListRunners(withFrameworkRunnersIncluded); + // generate for ALL runners + List> listTemplate = listRunners.stream() + .map(runner -> new RunnerDecorationTemplate(runner).getTemplate()) + .toList(); + Optional collectionNameOp = listRunners.stream().findFirst().map(AbstractRunner::getCollectionName); + collectionName = collectionNameOp.isPresent() ? collectionNameOp.get() : "Cherry"; + mapContent.put(collectionName, RunnerDecorationTemplate.getJsonFromList(listTemplate)); + } + + // zip the result + ZipOperation zipOperation = new ZipOperation("element-template"); + try { + for (Map.Entry template : mapContent.entrySet()) { + zipOperation.addZipContent(template.getKey()+".json", template.getValue()); } + zipOperation.close(); + } catch (IOException e) { + throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Zip operation failed"); + } + + byte[] contentBytes = zipOperation.getBytes(); + HttpHeaders header = new HttpHeaders(); + header.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + collectionName + "Template.zip"); + header.add("Cache-Control", "no-cache, no-store, must-revalidate"); + header.add("Pragma", "no-cache"); + header.add("Expires", "0"); + + ByteArrayResource resource = new ByteArrayResource(contentBytes); + + return ResponseEntity.ok() + .headers(header) + .contentLength(contentBytes.length) + .contentType(MediaType.parseMediaType("application/json")) + .body(resource); + } catch (Exception e) { + logger.error( + "Download template error for " + (runnerName == null ? "Complete collection" : "[" + runnerName + "]") + + " FrameworkIncluded[" + withFrameworkRunnersIncluded + "] :" + e); + return ResponseEntity.internalServerError().body(null); } - - private AbstractRunner getRunnerByName(String runnerName) { - List listFiltered = listRunners.stream().filter(w -> w.getIdentification().equals(runnerName)).toList(); - if (listFiltered.size() != 1) - return null; - return listFiltered.get(0); - - } - - private RunnerInformation completeRunnerInformation(RunnerInformation runnerInformation, boolean withLogo, boolean withStats, Integer delayStatInHour) { - try { - runnerInformation.setActive(cherryJobRunnerFactory.isRunnerActive(runnerInformation.getName())); - runnerInformation.setDisplayLogo(withLogo); - - if (withStats) { - runnerInformation.setStatistic(cherryHistoricFactory.getStatistic(runnerInformation.getName(), delayStatInHour)); - runnerInformation.setPerformance(cherryHistoricFactory.getPerformance(runnerInformation.getName(), delayStatInHour)); - } - - - } catch (CherryJobRunnerFactory.OperationException e) { - // definitively not expected - } - return runnerInformation; + } + + private AbstractRunner getRunnerByName(String runnerName) { + List listFiltered = listRunners.stream() + .filter(w -> w.getIdentification().equals(runnerName)) + .toList(); + if (listFiltered.size() != 1) + return null; + return listFiltered.get(0); + + } + + private RunnerInformation completeRunnerInformation(RunnerInformation runnerInformation, + boolean withLogo, + boolean withStats, + Integer delayStatInHour) { + try { + runnerInformation.setActive(cherryJobRunnerFactory.isRunnerActive(runnerInformation.getName())); + runnerInformation.setDisplayLogo(withLogo); + + if (withStats) { + runnerInformation.setStatistic( + cherryHistoricFactory.getStatistic(runnerInformation.getName(), delayStatInHour)); + runnerInformation.setPerformance( + cherryHistoricFactory.getPerformance(runnerInformation.getName(), delayStatInHour)); + } + + } catch (CherryJobRunnerFactory.OperationException e) { + // definitively not expected } + return runnerInformation; + } + private List getListRunners(boolean withFrameworkRunnersIncluded) { + // get the list of running, with the framework runner or not. - private List getListRunners(boolean withFrameworkRunnersIncluded) { - // get the list of running, with the framework runner or not. - - // If runners contains ONLY framework runners, then this application is the Cherry framework, and we will return it - if (listRunners.size() == listFrameworkRunners.size()) - return listRunners; + // If runners contains ONLY framework runners, then this application is the Cherry framework, and we will return it + if (listRunners.size() == listFrameworkRunners.size()) + return listRunners; - if (withFrameworkRunnersIncluded) - return listRunners; + if (withFrameworkRunnersIncluded) + return listRunners; - // listRunnersWithoutFramework - return listRunners.stream() - .filter(runner -> !listFrameworkRunners.contains(runner)) - .toList(); - } + // listRunnersWithoutFramework + return listRunners.stream().filter(runner -> !listFrameworkRunners.contains(runner)).toList(); + } } diff --git a/src/main/java/io/camunda/cherry/admin/ZipOperation.java b/src/main/java/io/camunda/cherry/admin/ZipOperation.java new file mode 100644 index 0000000..c5dcad8 --- /dev/null +++ b/src/main/java/io/camunda/cherry/admin/ZipOperation.java @@ -0,0 +1,52 @@ +package io.camunda.cherry.admin; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +public class ZipOperation { + + ByteArrayOutputStream zipContent; + ZipOutputStream zipOut; +String fileName; + + public ZipOperation(String zipFileName) { + zipContent = new ByteArrayOutputStream(); + zipOut = new ZipOutputStream(zipContent); + fileName = zipFileName; + } + + /** + * Add a file in the Zip + * @param fileName file name + * @param content content to add + * @throws IOException in case of error + */ + public void addZipContent(String fileName, String content) throws IOException { + ZipEntry zipEntry = new ZipEntry(fileName); + zipOut.putNextEntry(zipEntry); + byte[] contentByte = content.getBytes(StandardCharsets.UTF_8); + + zipOut.write(contentByte, 0, contentByte.length); + } + + public void close() throws IOException { + zipOut.close(); + } + + public InputStream getInputStream() { + return new ByteArrayInputStream(zipContent.toByteArray()); + } + + public byte[] getBytes() { + return zipContent.toByteArray(); + } + + public String getFileName() { + return fileName; + } +} diff --git a/src/main/java/io/camunda/cherry/files/LoadFileFromDiskWorker.java b/src/main/java/io/camunda/cherry/files/LoadFileFromDiskWorker.java index 5427c5a..8df5b8d 100644 --- a/src/main/java/io/camunda/cherry/files/LoadFileFromDiskWorker.java +++ b/src/main/java/io/camunda/cherry/files/LoadFileFromDiskWorker.java @@ -8,22 +8,20 @@ /* ******************************************************************** */ package io.camunda.cherry.files; +import io.camunda.cherry.definition.AbstractWorker; +import io.camunda.cherry.definition.BpmnError; +import io.camunda.cherry.definition.IntFrameworkRunner; +import io.camunda.cherry.definition.RunnerParameter; import io.camunda.file.storage.FileVariable; import io.camunda.file.storage.StorageDefinition; import io.camunda.file.storage.cmis.CmisParameters; import io.camunda.zeebe.client.api.response.ActivatedJob; import io.camunda.zeebe.client.api.worker.JobClient; import io.camunda.zeebe.spring.client.exception.ZeebeBpmnError; -import io.camunda.cherry.definition.AbstractWorker; -import io.camunda.cherry.definition.BpmnError; -import io.camunda.cherry.definition.IntFrameworkRunner; -import io.camunda.cherry.definition.RunnerParameter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -146,7 +144,7 @@ public boolean isFrameworkRunner() { @Override public String getName() { - return "CherryLoadFileFromDisk"; + return "FileStorageLoadFileFromDisk"; } @Override diff --git a/src/main/java/io/camunda/cherry/files/PurgeFileWorker.java b/src/main/java/io/camunda/cherry/files/PurgeFileWorker.java index 20770bb..bd35126 100644 --- a/src/main/java/io/camunda/cherry/files/PurgeFileWorker.java +++ b/src/main/java/io/camunda/cherry/files/PurgeFileWorker.java @@ -6,20 +6,20 @@ /* ******************************************************************** */ package io.camunda.cherry.files; +import io.camunda.cherry.definition.AbstractWorker; +import io.camunda.cherry.definition.BpmnError; +import io.camunda.cherry.definition.IntFrameworkRunner; +import io.camunda.cherry.definition.RunnerParameter; import io.camunda.file.storage.FileRepoFactory; import io.camunda.file.storage.FileVariableReference; import io.camunda.file.storage.StorageDefinition; import io.camunda.zeebe.client.api.response.ActivatedJob; import io.camunda.zeebe.client.api.worker.JobClient; import io.camunda.zeebe.spring.client.exception.ZeebeBpmnError; -import io.camunda.cherry.definition.AbstractWorker; -import io.camunda.cherry.definition.BpmnError; -import io.camunda.cherry.definition.IntFrameworkRunner; -import io.camunda.cherry.definition.RunnerParameter; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.Arrays; +import java.util.Collections; @Component public class PurgeFileWorker extends AbstractWorker implements IntFrameworkRunner { @@ -31,20 +31,20 @@ public class PurgeFileWorker extends AbstractWorker implements IntFrameworkRunne public PurgeFileWorker() { super("c-files-purge", - Arrays.asList( + Collections.singletonList( RunnerParameter.getInstance(INPUT_SOURCE_FILE, "Source file", Object.class, RunnerParameter.Level.REQUIRED, "FileVariable used to save") ), - Arrays.asList( + Collections.singletonList( RunnerParameter.getInstance(OUTPUT_FILE_IS_PURGED, "File is purged", Object.class, RunnerParameter.Level.REQUIRED, "True if the file is purged correctly") ), - Arrays.asList( + Collections.singletonList( BpmnError.getInstance(StorageDefinition.ERROR_INCORRECT_STORAGEDEFINITION, "Incorrect storage definition"))); } /** * mark this worker as a Framework runner * - * @return + * @return true if the runner is part of the framework */ @Override public boolean isFrameworkRunner() { @@ -53,7 +53,7 @@ public boolean isFrameworkRunner() { @Override public String getName() { - return "CherryPurgeFile"; + return "FileStoragePurgeFile"; } @Override diff --git a/src/main/java/io/camunda/cherry/files/SaveFileToDiskWorker.java b/src/main/java/io/camunda/cherry/files/SaveFileToDiskWorker.java index ffbecaf..d9e00ba 100644 --- a/src/main/java/io/camunda/cherry/files/SaveFileToDiskWorker.java +++ b/src/main/java/io/camunda/cherry/files/SaveFileToDiskWorker.java @@ -72,7 +72,7 @@ public boolean isFrameworkRunner() { @Override public String getName() { - return "CherrySaveFileToDisk"; + return "FileStorageSaveFileToDisk"; } @Override @@ -82,7 +82,7 @@ public String getLabel() { @Override public String getDescription() { - return "Save a file in a storage definition a disk"; + return "Save a file from a storage definition to a disk"; } @Override diff --git a/src/main/java/io/camunda/cherry/ping/PingConnector.java b/src/main/java/io/camunda/cherry/ping/PingConnector.java index 9da5421..f0b26de 100644 --- a/src/main/java/io/camunda/cherry/ping/PingConnector.java +++ b/src/main/java/io/camunda/cherry/ping/PingConnector.java @@ -16,6 +16,7 @@ import java.net.InetAddress; import java.util.Collections; +import java.util.Map; /* ------------------------------------------------------------------- */ @@ -61,9 +62,11 @@ public Object execute(OutboundConnectorContext context) throws Exception { // context.validate(pingConnectorInput); Thread.sleep( pingConnectorInput.getDelay()); - InetAddress IP=InetAddress.getLocalHost(); + InetAddress ipAddress=InetAddress.getLocalHost(); - return new PingConnectorOutput(System.currentTimeMillis(), IP.getHostAddress()); + return new PingConnectorOutput(System.currentTimeMillis(), + ipAddress.getHostAddress(), + Map.of("JDK", System.getProperty("java.version"))); } } diff --git a/src/main/java/io/camunda/cherry/ping/PingConnectorOutput.java b/src/main/java/io/camunda/cherry/ping/PingConnectorOutput.java index 29c311b..e65e1cd 100644 --- a/src/main/java/io/camunda/cherry/ping/PingConnectorOutput.java +++ b/src/main/java/io/camunda/cherry/ping/PingConnectorOutput.java @@ -16,37 +16,49 @@ import java.util.Arrays; import java.util.List; +import java.util.Map; public class PingConnectorOutput extends AbstractConnectorOutput { - private long internalTimeStampMS; - private String internalIpAddress; - - public PingConnectorOutput() { - super(); - } - - public PingConnectorOutput(long currentTimestamp, String ipAddress) { - super(); - this.internalTimeStampMS = currentTimestamp; - this.internalIpAddress = ipAddress; - } - - @Override - public List getOutputParameters() { - return Arrays.asList( - RunnerParameter.getInstance("timeStampMS", "Time stamp", Long.class, RunnerParameter.Level.REQUIRED, "Produce a timestamp"), - RunnerParameter.getInstance("ipAddress", "Ip Address", String.class, RunnerParameter.Level.REQUIRED, "Returm the IpAddress") - ); - } - - /* The getter must start by a lower case */ - public long gettimeStampMS() { - return internalTimeStampMS; - } - /* The getter must start by a lower case */ - public String getipAddress() { - return internalIpAddress; - } + private long internalTimeStampMS; + private String internalIpAddress; + private Map parameters; + + public PingConnectorOutput() { + super(); + } + + public PingConnectorOutput(long currentTimestamp, String ipAddress, Map parameters) { + super(); + this.internalTimeStampMS = currentTimestamp; + this.internalIpAddress = ipAddress; + this.parameters = parameters; + } + + @Override + public List getOutputParameters() { + return Arrays.asList( + RunnerParameter.getInstance("timeStampMS", "Time stamp", Long.class, RunnerParameter.Level.REQUIRED, + "Produce a timestamp"), + RunnerParameter.getInstance("ipAddress", "Ip Address", String.class, RunnerParameter.Level.REQUIRED, + "Returm the IpAddress"), + RunnerParameter.getInstance("parameters", "Parameters", Map.class, RunnerParameter.Level.REQUIRED, + "Returm parameters")); + } + + /* The getter must start by a lower case */ + public long gettimeStampMS() { + return internalTimeStampMS; + } + + /* The getter must start by a lower case */ + public String getipAddress() { + return internalIpAddress; + } + + public Map getparameters() { + return parameters; + } } + diff --git a/src/test/resources/connectorworker/PingObjectConnector.bpmn b/src/test/resources/connectorworker/PingObjectConnector.bpmn index c3f8bd3..dfd748f 100644 --- a/src/test/resources/connectorworker/PingObjectConnector.bpmn +++ b/src/test/resources/connectorworker/PingObjectConnector.bpmn @@ -1,5 +1,5 @@ - + Flow_00mgsl9 @@ -24,15 +24,19 @@ - + - + + + + + - + Flow_00mgsl9 @@ -41,6 +45,9 @@ + + + @@ -50,12 +57,9 @@ - + - - -