diff --git a/src/main/java/it/gov/pagopa/atmlayer/service/model/dto/DeployedProcessInfoDto.java b/src/main/java/it/gov/pagopa/atmlayer/service/model/dto/DeployedProcessInfoDto.java index ea80b5cb..60bd7f0e 100644 --- a/src/main/java/it/gov/pagopa/atmlayer/service/model/dto/DeployedProcessInfoDto.java +++ b/src/main/java/it/gov/pagopa/atmlayer/service/model/dto/DeployedProcessInfoDto.java @@ -17,7 +17,7 @@ public class DeployedProcessInfoDto { private String category; private String description; private String name; - private Long version; + private Integer version; private String resource; private UUID deploymentId; private String diagram; diff --git a/src/main/java/it/gov/pagopa/atmlayer/service/model/resource/BpmnResource.java b/src/main/java/it/gov/pagopa/atmlayer/service/model/resource/BpmnResource.java index 523fc827..1a71d3f5 100644 --- a/src/main/java/it/gov/pagopa/atmlayer/service/model/resource/BpmnResource.java +++ b/src/main/java/it/gov/pagopa/atmlayer/service/model/resource/BpmnResource.java @@ -5,6 +5,7 @@ import it.gov.pagopa.atmlayer.service.model.client.ProcessClient; import it.gov.pagopa.atmlayer.service.model.dto.BpmnAssociationDto; import it.gov.pagopa.atmlayer.service.model.dto.BpmnCreationDto; +import it.gov.pagopa.atmlayer.service.model.dto.DeployResponseDto; import it.gov.pagopa.atmlayer.service.model.entity.BpmnBankConfig; import it.gov.pagopa.atmlayer.service.model.entity.BpmnVersion; import it.gov.pagopa.atmlayer.service.model.entity.BpmnVersionPK; @@ -47,13 +48,14 @@ @Tag(name = "BPMN", description = "BPMN operations") @Slf4j public class BpmnResource { - @Inject - BpmnVersionService bpmnVersionService; - @Inject - BpmnEntityValidator bpmnEntityValidator; - @Inject - @RestClient - ProcessClient processClient; + + @Inject + BpmnVersionService bpmnVersionService; + @Inject + BpmnEntityValidator bpmnEntityValidator; + @Inject + @RestClient + ProcessClient processClient; // @GET // @Consumes(MediaType.APPLICATION_JSON) // @Produces(MediaType.TEXT_PLAIN) @@ -63,70 +65,76 @@ public class BpmnResource { // return "String file: " + xml; // } - @GET - @Path("/{bpmnId}/version/{version}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - public Uni getEncodedFile(@PathParam("bpmnId") UUID bpmnId, - @PathParam("version") Long version) { - BpmnVersionPK key = BpmnVersionPK.builder() - .bpmnId(bpmnId) - .modelVersion(version) - .build(); - return this.bpmnVersionService.findByPk(key) - .onItem() - .transform(Unchecked.function(x -> { - if (x.isEmpty()) { - throw new AtmLayerException(Response.Status.NOT_FOUND, BPMN_FILE_DOES_NOT_EXIST); - } - return x.get(); - })); - } + @GET + @Path("/{bpmnId}/version/{version}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Uni getEncodedFile(@PathParam("bpmnId") UUID bpmnId, + @PathParam("version") Long version) { + BpmnVersionPK key = BpmnVersionPK.builder() + .bpmnId(bpmnId) + .modelVersion(version) + .build(); + return this.bpmnVersionService.findByPk(key) + .onItem() + .transform(Unchecked.function(x -> { + if (x.isEmpty()) { + throw new AtmLayerException(Response.Status.NOT_FOUND, BPMN_FILE_DOES_NOT_EXIST); + } + return x.get(); + })); + } - @PUT - @Path("/bank/{acquirerId}/associations/function/{functionType}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - public Uni> associateBPMN(@PathParam("acquirerId") String acquirerId, - @PathParam("functionType") FunctionTypeEnum functionTypeEnum, - @RequestBody(required = true) @Valid BpmnAssociationDto bpmnAssociationDto) throws NoSuchAlgorithmException, IOException { - List configs = getAcquirerConfigs(bpmnAssociationDto, acquirerId, functionTypeEnum); - Set bpmnIds = BpmnUtils.extractBpmnUUIDFromAssociations(configs); - return bpmnEntityValidator.validateExistenceAndStatus(bpmnIds) - .onItem().transformToUni(x -> this.bpmnVersionService.putAssociations(acquirerId, functionTypeEnum, configs)); - } + @PUT + @Path("/bank/{acquirerId}/associations/function/{functionType}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Uni> associateBPMN(@PathParam("acquirerId") String acquirerId, + @PathParam("functionType") FunctionTypeEnum functionTypeEnum, + @RequestBody(required = true) @Valid BpmnAssociationDto bpmnAssociationDto) + throws NoSuchAlgorithmException, IOException { + List configs = getAcquirerConfigs(bpmnAssociationDto, acquirerId, + functionTypeEnum); + Set bpmnIds = BpmnUtils.extractBpmnUUIDFromAssociations(configs); + return bpmnEntityValidator.validateExistenceAndStatus(bpmnIds) + .onItem().transformToUni( + x -> this.bpmnVersionService.putAssociations(acquirerId, functionTypeEnum, configs)); + } - @POST - @Consumes(MediaType.MULTIPART_FORM_DATA) - @Produces(MediaType.APPLICATION_JSON) - public Uni createBPMN(@RequestBody(required = true) @Valid BpmnCreationDto bpmnCreationDto) throws NoSuchAlgorithmException, IOException { - BpmnVersion bpmnVersion = BpmnDtoMapper.toBpmnVersion(bpmnCreationDto); - return bpmnVersionService.save(bpmnVersion); - } + @POST + @Consumes(MediaType.MULTIPART_FORM_DATA) + @Produces(MediaType.APPLICATION_JSON) + public Uni createBPMN( + @RequestBody(required = true) @Valid BpmnCreationDto bpmnCreationDto) + throws NoSuchAlgorithmException, IOException { + BpmnVersion bpmnVersion = BpmnDtoMapper.toBpmnVersion(bpmnCreationDto); + return bpmnVersionService.save(bpmnVersion); + } - @POST - @Path("/deploy/{uuid}/version/{version}") - @Produces(MediaType.APPLICATION_JSON) - public Uni deployBPMN(@PathParam("uuid") UUID uuid, - @PathParam("version") Long version) { - return bpmnVersionService.checkBpmnFileExistence(uuid, version) - .onItem() - .transformToUni(x -> { - if (!x) { - String errorMessage = "The referenced BPMN file can not be deployed"; - throw new AtmLayerException(errorMessage, Response.Status.BAD_REQUEST, AppErrorCodeEnum.BPMN_FILE_CANNOT_BE_DEPLOYED); - } - return bpmnVersionService.setBpmnVersionStatus(uuid, version, StatusEnum.WAITING_DEPLOY); - }) - .onItem() - .transformToUni(bpmnWaiting -> { - try { - processClient.deploy("url"); - return bpmnVersionService.setBpmnVersionStatus(uuid, version, StatusEnum.DEPLOYED); - } catch (Exception e) { - bpmnVersionService.setBpmnVersionStatus(uuid, version, StatusEnum.DEPLOY_ERROR); - throw new RuntimeException("deploy failed"); - } - }); - } + @POST + @Path("/deploy/{uuid}/version/{version}") + @Produces(MediaType.APPLICATION_JSON) + public Uni deployBPMN(@PathParam("uuid") UUID uuid, + @PathParam("version") Long version) { + return bpmnVersionService.checkBpmnFileExistence(uuid, version) + .onItem() + .transformToUni(x -> { + if (!x) { + String errorMessage = "The referenced BPMN file can not be deployed"; + throw new AtmLayerException(errorMessage, Response.Status.BAD_REQUEST, + AppErrorCodeEnum.BPMN_FILE_CANNOT_BE_DEPLOYED); + } + return bpmnVersionService.setBpmnVersionStatus(uuid, version, StatusEnum.WAITING_DEPLOY); + }) + .onItem() + .transformToUni(bpmnWaiting -> { + return processClient.deploy("url") + .onItem() + .transformToUni(response -> bpmnVersionService.setDeployInfo(uuid, version, response)) + .onItem() + .transformToUni(bpmnUpdated -> bpmnVersionService.setBpmnVersionStatus(uuid, version, + StatusEnum.DEPLOYED)); + // return bpmnVersionService.setBpmnVersionStatus(uuid, version, StatusEnum.DEPLOYED); + }); + } } diff --git a/src/main/java/it/gov/pagopa/atmlayer/service/model/service/BpmnVersionService.java b/src/main/java/it/gov/pagopa/atmlayer/service/model/service/BpmnVersionService.java index ee89a98c..7db3e56f 100644 --- a/src/main/java/it/gov/pagopa/atmlayer/service/model/service/BpmnVersionService.java +++ b/src/main/java/it/gov/pagopa/atmlayer/service/model/service/BpmnVersionService.java @@ -1,6 +1,7 @@ package it.gov.pagopa.atmlayer.service.model.service; import io.smallrye.mutiny.Uni; +import it.gov.pagopa.atmlayer.service.model.dto.DeployResponseDto; import it.gov.pagopa.atmlayer.service.model.entity.BpmnBankConfig; import it.gov.pagopa.atmlayer.service.model.entity.BpmnVersion; import it.gov.pagopa.atmlayer.service.model.entity.BpmnVersionPK; @@ -16,21 +17,25 @@ import java.util.UUID; public interface BpmnVersionService { - String decodeBase64(String s) throws IOException; - Uni> findByPKSet(Set bpmnVersionPKSet); + String decodeBase64(String s) throws IOException; - String calculateSHA256(File file) throws NoSuchAlgorithmException, IOException; + Uni> findByPKSet(Set bpmnVersionPKSet); - Uni save(BpmnVersion bpmnVersion); + String calculateSHA256(File file) throws NoSuchAlgorithmException, IOException; - public Uni> findBySHA256(String sha256); + Uni save(BpmnVersion bpmnVersion); - Uni> findByPk(BpmnVersionPK bpmnVersionPK); + public Uni> findBySHA256(String sha256); - Uni> putAssociations(String acquirerId, FunctionTypeEnum functionTypeEnum, List bpmnBankConfigs); + Uni> findByPk(BpmnVersionPK bpmnVersionPK); - Uni setBpmnVersionStatus(UUID id, Long modelVersion, StatusEnum status); + Uni> putAssociations(String acquirerId, FunctionTypeEnum functionTypeEnum, + List bpmnBankConfigs); - public Uni checkBpmnFileExistence(UUID id, Long modelVersion); + Uni setBpmnVersionStatus(UUID id, Long modelVersion, StatusEnum status); + + public Uni checkBpmnFileExistence(UUID id, Long modelVersion); + + public Uni setDeployInfo(UUID id, Long modelVersion, DeployResponseDto response); } diff --git a/src/main/java/it/gov/pagopa/atmlayer/service/model/service/impl/BpmnVersionImpl.java b/src/main/java/it/gov/pagopa/atmlayer/service/model/service/impl/BpmnVersionImpl.java index 25aa3e53..df8fe9f4 100644 --- a/src/main/java/it/gov/pagopa/atmlayer/service/model/service/impl/BpmnVersionImpl.java +++ b/src/main/java/it/gov/pagopa/atmlayer/service/model/service/impl/BpmnVersionImpl.java @@ -5,6 +5,8 @@ import io.smallrye.mutiny.Multi; import io.smallrye.mutiny.Uni; import io.smallrye.mutiny.unchecked.Unchecked; +import it.gov.pagopa.atmlayer.service.model.dto.DeployResponseDto; +import it.gov.pagopa.atmlayer.service.model.dto.DeployedProcessInfoDto; import it.gov.pagopa.atmlayer.service.model.entity.BpmnBankConfig; import it.gov.pagopa.atmlayer.service.model.entity.BpmnVersion; import it.gov.pagopa.atmlayer.service.model.entity.BpmnVersionPK; @@ -24,6 +26,7 @@ import java.io.IOException; import java.security.NoSuchAlgorithmException; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.UUID; @@ -33,104 +36,148 @@ @ApplicationScoped @Slf4j public class BpmnVersionImpl implements BpmnVersionService { - @Inject - BpmnVersionRepository bpmnVersionRepository; - @Inject - BpmnBankConfigService bpmnBankConfigService; - - @Override - public String decodeBase64(String s) { - byte[] array = BpmnUtils.base64ToByteArray(s); - return BpmnUtils.byteArrayToString(array); - } - - @Override - public Uni> findByPKSet(Set bpmnVersionPKSet) { - return this.bpmnVersionRepository.findByIds(bpmnVersionPKSet); - } - - @Override - public String calculateSHA256(File file) throws NoSuchAlgorithmException, IOException { - //TODO: Controllare che il file sia un xml .bpmn - byte[] array = BpmnUtils.toSha256ByteArray(file); - return BpmnUtils.toHexString(array); - } - - @Override - @WithTransaction - public Uni save(BpmnVersion bpmnVersion) { - return this.findBySHA256(bpmnVersion.getSha256()) - .onItem().transform(Unchecked.function(x -> { - if (x.isPresent()) { - throw new AtmLayerException("A BPMN file with the same content already exists", Response.Status.BAD_REQUEST, BPMN_FILE_WITH_SAME_CONTENT_ALREADY_EXIST); - } - return x; - })) - .onItem().transformToUni(t -> this.bpmnVersionRepository.persist(bpmnVersion)); - } - - @Override - @WithSession - public Uni> findBySHA256(String sha256) { - return this.bpmnVersionRepository.findBySHA256(sha256) - .onItem().transformToUni(x -> Uni.createFrom().item(Optional.ofNullable(x))); - } - - @Override - @WithSession - public Uni> findByPk(BpmnVersionPK bpmnVersionPK) { - return bpmnVersionRepository.findById(bpmnVersionPK).onItem().transformToUni(bpmnVersion -> Uni.createFrom().item(Optional.ofNullable(bpmnVersion))); - } - - @Override - @WithTransaction - public Uni> putAssociations(String acquirerId, FunctionTypeEnum functionType, List bpmnBankConfigs) { - Uni deleteExistingUni = this.bpmnBankConfigService.deleteByAcquirerIdAndFunctionType(acquirerId, functionType); - return deleteExistingUni - .onItem() - .transformToUni(x -> this.bpmnBankConfigService.saveList(bpmnBankConfigs)) - .onItem() - .transformToUni(y -> this.bpmnBankConfigService.findByAcquirerIdAndFunctionType(acquirerId, functionType)); - } - - private static Uni> addFunctionTypeToAssociations(List bpmnBankConfigs, FunctionTypeEnum functionType) { - return Multi.createFrom().items(bpmnBankConfigs.stream()).onItem().transform(bpmnBankConfig -> { - bpmnBankConfig.setFunctionType(functionType); - return bpmnBankConfig; - }).collect().asList(); - } - - @Override - @WithTransaction - public Uni setBpmnVersionStatus(UUID id, Long modelVersion, StatusEnum status) { - BpmnVersionPK key = new BpmnVersionPK(id, modelVersion); - return this.findByPk(key) - .onItem() - .transformToUni(optionalBpmn -> { - if (optionalBpmn.isEmpty()) { - String errorMessage = String.format("One or some of the referenced BPMN files do not exists: %s", key); - throw new AtmLayerException(errorMessage, Response.Status.BAD_REQUEST, AppErrorCodeEnum.BPMN_FILE_DOES_NOT_EXIST); - } - BpmnVersion bpmnToDeploy = optionalBpmn.get(); - bpmnToDeploy.setStatus(status); - return this.bpmnVersionRepository.persist(bpmnToDeploy); - } - ); - } - - @Override - public Uni checkBpmnFileExistence(UUID id, Long modelVersion) { - BpmnVersionPK key = new BpmnVersionPK(id, modelVersion); - return this.findByPk(key) - .onItem() - .transform(optionalBpmn -> { - if (optionalBpmn.isEmpty()) { - String errorMessage = String.format("One or some of the referenced BPMN files do not exists: %s", key); - throw new AtmLayerException(errorMessage, Response.Status.BAD_REQUEST, AppErrorCodeEnum.BPMN_FILE_DOES_NOT_EXIST); - } - BpmnVersion bpmnVersion = optionalBpmn.get(); - return bpmnVersion.getStatus().equals(StatusEnum.CREATED) || bpmnVersion.getStatus().equals(StatusEnum.DEPLOY_ERROR); - } - ); - } + + @Inject + BpmnVersionRepository bpmnVersionRepository; + @Inject + BpmnBankConfigService bpmnBankConfigService; + + @Override + public String decodeBase64(String s) { + byte[] array = BpmnUtils.base64ToByteArray(s); + return BpmnUtils.byteArrayToString(array); + } + + @Override + public Uni> findByPKSet(Set bpmnVersionPKSet) { + return this.bpmnVersionRepository.findByIds(bpmnVersionPKSet); + } + + @Override + public String calculateSHA256(File file) throws NoSuchAlgorithmException, IOException { + //TODO: Controllare che il file sia un xml .bpmn + byte[] array = BpmnUtils.toSha256ByteArray(file); + return BpmnUtils.toHexString(array); + } + + @Override + @WithTransaction + public Uni save(BpmnVersion bpmnVersion) { + return this.findBySHA256(bpmnVersion.getSha256()) + .onItem().transform(Unchecked.function(x -> { + if (x.isPresent()) { + throw new AtmLayerException("A BPMN file with the same content already exists", + Response.Status.BAD_REQUEST, BPMN_FILE_WITH_SAME_CONTENT_ALREADY_EXIST); + } + return x; + })) + .onItem().transformToUni(t -> this.bpmnVersionRepository.persist(bpmnVersion)); + } + + @Override + @WithSession + public Uni> findBySHA256(String sha256) { + return this.bpmnVersionRepository.findBySHA256(sha256) + .onItem().transformToUni(x -> Uni.createFrom().item(Optional.ofNullable(x))); + } + + @Override + @WithSession + public Uni> findByPk(BpmnVersionPK bpmnVersionPK) { + return bpmnVersionRepository.findById(bpmnVersionPK).onItem() + .transformToUni(bpmnVersion -> Uni.createFrom().item(Optional.ofNullable(bpmnVersion))); + } + + @Override + @WithTransaction + public Uni> putAssociations(String acquirerId, FunctionTypeEnum functionType, + List bpmnBankConfigs) { + Uni deleteExistingUni = this.bpmnBankConfigService.deleteByAcquirerIdAndFunctionType( + acquirerId, functionType); + return deleteExistingUni + .onItem() + .transformToUni(x -> this.bpmnBankConfigService.saveList(bpmnBankConfigs)) + .onItem() + .transformToUni(y -> this.bpmnBankConfigService.findByAcquirerIdAndFunctionType(acquirerId, + functionType)); + } + + private static Uni> addFunctionTypeToAssociations( + List bpmnBankConfigs, FunctionTypeEnum functionType) { + return Multi.createFrom().items(bpmnBankConfigs.stream()).onItem().transform(bpmnBankConfig -> { + bpmnBankConfig.setFunctionType(functionType); + return bpmnBankConfig; + }).collect().asList(); + } + + @Override + @WithTransaction + public Uni setBpmnVersionStatus(UUID id, Long modelVersion, StatusEnum status) { + BpmnVersionPK key = new BpmnVersionPK(id, modelVersion); + return this.findByPk(key) + .onItem() + .transformToUni(optionalBpmn -> { + if (optionalBpmn.isEmpty()) { + String errorMessage = String.format( + "One or some of the referenced BPMN files do not exists: %s", key); + throw new AtmLayerException(errorMessage, Response.Status.BAD_REQUEST, + AppErrorCodeEnum.BPMN_FILE_DOES_NOT_EXIST); + } + BpmnVersion bpmnToDeploy = optionalBpmn.get(); + bpmnToDeploy.setStatus(status); + return this.bpmnVersionRepository.persist(bpmnToDeploy); + } + ); + } + + @Override + public Uni checkBpmnFileExistence(UUID id, Long modelVersion) { + BpmnVersionPK key = new BpmnVersionPK(id, modelVersion); + return this.findByPk(key) + .onItem() + .transform(optionalBpmn -> { + if (optionalBpmn.isEmpty()) { + String errorMessage = String.format( + "One or some of the referenced BPMN files do not exists: %s", key); + throw new AtmLayerException(errorMessage, Response.Status.BAD_REQUEST, + AppErrorCodeEnum.BPMN_FILE_DOES_NOT_EXIST); + } + BpmnVersion bpmnVersion = optionalBpmn.get(); + return bpmnVersion.getStatus().equals(StatusEnum.CREATED) || bpmnVersion.getStatus() + .equals(StatusEnum.DEPLOY_ERROR); + } + ); + } + + @Override + @WithTransaction + public Uni setDeployInfo(UUID id, Long modelVersion, DeployResponseDto response) { + BpmnVersionPK key = new BpmnVersionPK(id, modelVersion); + return this.findByPk(key) + .onItem() + .transformToUni(optionalBpmn -> { + if (optionalBpmn.isEmpty()) { + String errorMessage = String.format( + "One or some of the referenced BPMN files do not exists: %s", key); + throw new AtmLayerException(errorMessage, Response.Status.BAD_REQUEST, + AppErrorCodeEnum.BPMN_FILE_DOES_NOT_EXIST); + } + BpmnVersion bpmnVersion = optionalBpmn.get(); + Map deployedProcessDefinitions = response.getDeployedProcessDefinitions(); + Optional optionalDeployedProcessInfo = deployedProcessDefinitions.values() + .stream().findFirst(); + if (optionalDeployedProcessInfo.isEmpty()) { + throw new RuntimeException("empty process info"); + } + DeployedProcessInfoDto deployedProcessInfo = optionalDeployedProcessInfo.get(); + bpmnVersion.setDefinitionVersionCamunda(deployedProcessInfo.getVersion()); + bpmnVersion.setDeploymentId(deployedProcessInfo.getDeploymentId()); + bpmnVersion.setCamundaDefinitionId(deployedProcessInfo.getId()); + bpmnVersion.setDefinitionKey(deployedProcessInfo.getKey()); + bpmnVersion.setDeployedFileName(deployedProcessInfo.getName()); + bpmnVersion.setDescription(deployedProcessInfo.getDescription()); + bpmnVersion.setResource(deployedProcessInfo.getResource()); + return this.bpmnVersionRepository.persist(bpmnVersion); + }); + } } diff --git a/src/main/resources/application-local.properties b/src/main/resources/application-local.properties index dd8df8db..931ee47f 100644 --- a/src/main/resources/application-local.properties +++ b/src/main/resources/application-local.properties @@ -3,7 +3,7 @@ quarkus.http.port=${SERVER_PORT:8080} quarkus.datasource.db-kind=${MODEL_DB_TYPE:postgresql} quarkus.datasource.username=${MODEL_DB_USERNAME:postgres} quarkus.datasource.password=${MODEL_DB_PASSWORD:password} -quarkus.datasource.reactive.url=${MODEL_DB_URL:postgresql://localhost:5432/postgres?search_path=atm-layer-model} +quarkus.datasource.reactive.url=${MODEL_DB_URL:postgresql://localhost:5432/postgres?search_path=atm_layer_model} quarkus.hibernate-orm.database.generation=drop-and-create quarkus.hibernate-orm.physical-naming-strategy=org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy quarkus.rest-client.process-deploy.url=http://localhost:3001