From ee4ac671048087c30bae604fda675940403d7998 Mon Sep 17 00:00:00 2001 From: Angelo Caporaso <56113767+cap-ang@users.noreply.github.com> Date: Tue, 26 Nov 2024 17:28:27 +0100 Subject: [PATCH 01/19] feat: Add Support API --- .../upload/controller/SupportController.java | 30 ++++++++++++- .../gpd/upload/service/BlobService.java | 9 ++-- .../gpd/upload/service/RecoveryService.java | 42 ++++++++++++------- 3 files changed, 59 insertions(+), 22 deletions(-) diff --git a/src/main/java/it/gov/pagopa/gpd/upload/controller/SupportController.java b/src/main/java/it/gov/pagopa/gpd/upload/controller/SupportController.java index f1871e0..f8e0f55 100644 --- a/src/main/java/it/gov/pagopa/gpd/upload/controller/SupportController.java +++ b/src/main/java/it/gov/pagopa/gpd/upload/controller/SupportController.java @@ -45,7 +45,7 @@ public class SupportController { @ApiResponse(responseCode = "429", description = "Too many requests.", content = @Content(mediaType = MediaType.TEXT_JSON)), @ApiResponse(responseCode = "500", description = "Service unavailable", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = ProblemJson.class)))}) @Get(value = "brokers/{broker}/organizations/{organization}/{upload}/status/created/refresh") - public HttpResponse recoverStatus( + public HttpResponse recoverCreateOperationStatus( @Parameter(description = "The broker code", required = true) @NotBlank @PathVariable(name = "broker") String broker, @Parameter(description = "The organization fiscal code", required = true) @@ -53,7 +53,33 @@ public HttpResponse recoverStatus( @Parameter(description = "The unique identifier for file upload", required = true) @NotBlank @PathVariable(name = "upload") String upload ) { - recoveryService.recover(broker, organization, upload); + recoveryService.recoverCreated(broker, organization, upload); + log.info("[Support-API] Status {} recovered", upload); + UploadReport report = statusService.getReport(organization, upload); + + return HttpResponse.status(HttpStatus.OK) + .contentType(MediaType.APPLICATION_JSON) + .body(report); + } + + @Operation(summary = "Support API to recover status on CREATE operation", description = "Returns the debt positions upload report recovered.", tags = {"Support API"}) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "OK", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = AppInfo.class))), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = ProblemJson.class))), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(schema = @Schema())), + @ApiResponse(responseCode = "403", description = "Forbidden", content = @Content(schema = @Schema())), + @ApiResponse(responseCode = "429", description = "Too many requests.", content = @Content(mediaType = MediaType.TEXT_JSON)), + @ApiResponse(responseCode = "500", description = "Service unavailable", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = ProblemJson.class)))}) + @Get(value = "brokers/{broker}/organizations/{organization}/{upload}/status/deleted/refresh") + public HttpResponse recoverDeleteOperationStatus( + @Parameter(description = "The broker code", required = true) + @NotBlank @PathVariable(name = "broker") String broker, + @Parameter(description = "The organization fiscal code", required = true) + @NotBlank @PathVariable(name = "organization") String organization, + @Parameter(description = "The unique identifier for file upload", required = true) + @NotBlank @PathVariable(name = "upload") String upload + ) { + recoveryService.recoverDeleted(broker, organization, upload); log.info("[Support-API] Status {} recovered", upload); UploadReport report = statusService.getReport(organization, upload); diff --git a/src/main/java/it/gov/pagopa/gpd/upload/service/BlobService.java b/src/main/java/it/gov/pagopa/gpd/upload/service/BlobService.java index df9df29..9dbec50 100644 --- a/src/main/java/it/gov/pagopa/gpd/upload/service/BlobService.java +++ b/src/main/java/it/gov/pagopa/gpd/upload/service/BlobService.java @@ -70,17 +70,16 @@ public String upsert(String broker, String organizationFiscalCode, UploadOperati File file = this.unzip(fileUpload); if (null == file) throw new AppException(HttpStatus.BAD_REQUEST, "EMPTY FILE", "The JSON file is missing"); - log.debug("File with name " + file.getName() + " has been unzipped, upload operation: " + uploadOperation); + log.debug("File with name {} has been unzipped, upload operation: {}", file.getName(), uploadOperation); try { PaymentPositionsModel paymentPositionsModel = objectMapper.readValue(new FileInputStream(file), PaymentPositionsModel.class); if(!file.delete()) { - log.error(String.format("[Error][BlobService@upsert] The file %s was not deleted", file.getName())); + log.error("[Error][BlobService@upsert] The file {} was not deleted", file.getName()); } if (!paymentPositionsValidator.isValid(paymentPositionsModel)) { - log.error(String.format("[Error][BlobService@upload] Debt-Positions validation failed for upload from broker %s and organization %s", - broker, organizationFiscalCode)); + log.error("[Error][BlobService@upload] Debt-Positions validation failed for upload from broker {} and organization {}", broker, organizationFiscalCode); throw new AppException(HttpStatus.BAD_REQUEST, "INVALID DEBT POSITIONS", "The format of the debt positions in the uploaded file is invalid."); } @@ -94,7 +93,7 @@ public String upsert(String broker, String organizationFiscalCode, UploadOperati } catch (IOException e) { log.error("[Error][BlobService@upload] " + e.getMessage()); if(!file.delete()) - log.error(String.format("[Error][BlobService@upsert] The file %s was not deleted", file.getName())); + log.error("[Error][BlobService@upsert] The file {} was not deleted", file.getName()); if(e instanceof JsonMappingException) throw new AppException(HttpStatus.BAD_REQUEST, "INVALID JSON", "Given JSON is invalid for required API payload: " + e.getMessage()); diff --git a/src/main/java/it/gov/pagopa/gpd/upload/service/RecoveryService.java b/src/main/java/it/gov/pagopa/gpd/upload/service/RecoveryService.java index 439f1f2..4079db7 100644 --- a/src/main/java/it/gov/pagopa/gpd/upload/service/RecoveryService.java +++ b/src/main/java/it/gov/pagopa/gpd/upload/service/RecoveryService.java @@ -32,41 +32,53 @@ public RecoveryService(StatusService statusService, BlobService blobService, GPD this.gpdClient = gpdClient; } - public Status recover(String brokerId, String organizationFiscalCode, String uploadId) { - Status current = statusService.getStatus(organizationFiscalCode, uploadId); + public Status recoverCreated(String brokerId, String organizationFiscalCode, String uploadId) { UploadInput uploadInput = blobService.getUploadInput(brokerId, organizationFiscalCode, uploadId); - if(!uploadInput.getUploadOperation().equals(UploadOperation.CREATE)) throw new AppException(HttpStatus.NOT_FOUND, "Upload operation not processable", String.format("Not exists create operation with upload-id %s", uploadId)); + List inputIUPD = uploadInput.getPaymentPositionIUPDs(); + return this.recover(organizationFiscalCode, uploadId, inputIUPD, HttpStatus.OK, HttpStatus.CREATED); + } + + public Status recoverDeleted(String brokerId, String organizationFiscalCode, String uploadId) { + UploadInput uploadInput = blobService.getUploadInput(brokerId, organizationFiscalCode, uploadId); + if(!uploadInput.getUploadOperation().equals(UploadOperation.DELETE)) + throw new AppException(HttpStatus.NOT_FOUND, + "Upload operation not processable", String.format("Not exists delete operation with upload-id %s", uploadId)); + List inputIUPD = uploadInput.getPaymentPositionIUPDs(); + return this.recover(organizationFiscalCode, uploadId, inputIUPD, HttpStatus.NOT_FOUND, HttpStatus.NOT_FOUND); + } + + public Status recover(String organizationFiscalCode, String uploadId, List inputIUPD, HttpStatus statusToCheck, HttpStatus uploadStatus) { + Status current = statusService.getStatus(organizationFiscalCode, uploadId); + // check if upload is pending if(current.upload.getCurrent() >= current.upload.getTotal()) return current; // extract debt position id list - List inputIUPD = uploadInput.getPaymentPositions().stream() - .map(PaymentPositionModel::getIupd).toList(); List processedIUPD = new ArrayList<>(); current.upload.getResponses().forEach( res -> processedIUPD.addAll(res.getRequestIDs()) ); - // sync with core to check if debt positions are already created - List createdIUPD = getAlreadyCreatedIUPD(organizationFiscalCode, inputIUPD, processedIUPD); + // sync with core to check if debt positions are already processed (DELETED or CREATED -> NOT_EXISTS, EXISTS) + List deletedIUPD = getAlreadyIUPD(organizationFiscalCode, inputIUPD, processedIUPD, statusToCheck); // update status and save current.upload.addResponse(ResponseEntry.builder() - .requestIDs(createdIUPD) - .statusCode(HttpStatus.CREATED.getCode()) - .statusMessage(statusService.getDetail(HttpStatus.CREATED)) + .requestIDs(deletedIUPD) + .statusCode(uploadStatus.getCode()) + .statusMessage(statusService.getDetail(uploadStatus)) .build()); current.upload.setEnd(LocalDateTime.now()); return statusService.upsert(current); } - private List getAlreadyCreatedIUPD(String organizationFiscalCode, List inputIUPD, List processedIUPD) { + private List getAlreadyIUPD(String organizationFiscalCode, List inputIUPD, List processedIUPD, HttpStatus target) { Set inputIUPDSet = new HashSet<>(inputIUPD); Set processedIUPDSet = new HashSet<>(processedIUPD); @@ -74,16 +86,16 @@ private List getAlreadyCreatedIUPD(String organizationFiscalCode, List createdIUPD = new ArrayList<>(); + List alreadyIUPD = new ArrayList<>(); // for each check if position is processed inputIUPDSet.forEach(id -> { // request to GPD HttpStatus httpStatus = gpdClient.getDebtPosition(organizationFiscalCode, id).getStatus(); - if(httpStatus.equals(HttpStatus.OK)) { // if request was successful - createdIUPD.add(id); + if(httpStatus.equals(target)) { // if request was successful + alreadyIUPD.add(id); } }); - return createdIUPD; + return alreadyIUPD; } } \ No newline at end of file From 43fa6716a12005526ee48fca0124ab41123da401 Mon Sep 17 00:00:00 2001 From: pagopa-github-bot Date: Tue, 26 Nov 2024 16:31:06 +0000 Subject: [PATCH 02/19] Bump to version 0.1.32-1-recover-delete-operation-status --- helm/Chart.yaml | 4 ++-- helm/values-dev.yaml | 2 +- helm/values-prod.yaml | 2 +- helm/values-uat.yaml | 2 +- openapi/openapi.json | 2 +- pom.xml | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/helm/Chart.yaml b/helm/Chart.yaml index 1861ad5..06e20ac 100644 --- a/helm/Chart.yaml +++ b/helm/Chart.yaml @@ -2,8 +2,8 @@ apiVersion: v2 name: pagopa-gpd-upload description: Microservice that handles file upload of massive debt positions JSON object type: application -version: 0.106.0 -appVersion: 0.1.32 +version: 0.107.0 +appVersion: 0.1.32-1-recover-delete-operation-status dependencies: - name: microservice-chart version: 2.8.0 diff --git a/helm/values-dev.yaml b/helm/values-dev.yaml index a56e3d2..b9cb1fd 100644 --- a/helm/values-dev.yaml +++ b/helm/values-dev.yaml @@ -4,7 +4,7 @@ microservice-chart: fullnameOverride: "" image: repository: ghcr.io/pagopa/pagopa-gpd-upload - tag: "0.1.32" + tag: "0.1.32-1-recover-delete-operation-status" pullPolicy: Always livenessProbe: httpGet: diff --git a/helm/values-prod.yaml b/helm/values-prod.yaml index 7beea56..876d977 100644 --- a/helm/values-prod.yaml +++ b/helm/values-prod.yaml @@ -4,7 +4,7 @@ microservice-chart: fullnameOverride: "" image: repository: ghcr.io/pagopa/pagopa-gpd-upload - tag: "0.1.32" + tag: "0.1.32-1-recover-delete-operation-status" pullPolicy: Always livenessProbe: httpGet: diff --git a/helm/values-uat.yaml b/helm/values-uat.yaml index f4f12e3..9974a69 100644 --- a/helm/values-uat.yaml +++ b/helm/values-uat.yaml @@ -4,7 +4,7 @@ microservice-chart: fullnameOverride: "" image: repository: ghcr.io/pagopa/pagopa-gpd-upload - tag: "0.1.32" + tag: "0.1.32-1-recover-delete-operation-status" pullPolicy: Always livenessProbe: httpGet: diff --git a/openapi/openapi.json b/openapi/openapi.json index 095f46c..f8f635c 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -4,7 +4,7 @@ "title": "pagopa-gpd-upload", "description": "Microservice to manage PagoPA GPD Upload", "termsOfService": "https://www.pagopa.gov.it/", - "version": "0.1.32" + "version": "0.1.32-1-recover-delete-operation-status" }, "servers": [ { diff --git a/pom.xml b/pom.xml index 149c9a0..1b350a3 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 it.gov.pagopa.gpd.upload pagopa-gpd-upload - 0.1.32 + 0.1.32-1-recover-delete-operation-status ${packaging} From 0d7dc06d147f91ee8aaf02efbb35619a2cc520f3 Mon Sep 17 00:00:00 2001 From: Angelo Caporaso <56113767+cap-ang@users.noreply.github.com> Date: Thu, 28 Nov 2024 11:57:09 +0100 Subject: [PATCH 03/19] [PAGOPA-2426] refactoring: Update Support API --- openapi/openapi-support-internal.json | 837 +++++++++++ openapi/openapi.json | 1303 ++++++++--------- .../{ => support}/SupportController.java | 45 +- .../pagopa/gpd/upload/entity/MatchResult.java | 8 + .../gpd/upload/service/RecoveryService.java | 76 +- src/main/resources/application.properties | 11 + .../gpd/upload/OpenApiGenerationTest.java | 4 +- 7 files changed, 1512 insertions(+), 772 deletions(-) create mode 100644 openapi/openapi-support-internal.json rename src/main/java/it/gov/pagopa/gpd/upload/controller/{ => support}/SupportController.java (51%) create mode 100644 src/main/java/it/gov/pagopa/gpd/upload/entity/MatchResult.java diff --git a/openapi/openapi-support-internal.json b/openapi/openapi-support-internal.json new file mode 100644 index 0000000..6ed6089 --- /dev/null +++ b/openapi/openapi-support-internal.json @@ -0,0 +1,837 @@ +{ + "openapi" : "3.0.1", + "paths" : { + "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file" : { + "put" : { + "tags" : [ "Debt Positions CRUD via file upload API" ], + "summary" : "The Organization updates the debt positions listed in the file.", + "operationId" : "update-debt-positions-by-file-upload", + "parameters" : [ { + "name" : "broker-code", + "in" : "path", + "description" : "The broker code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + }, { + "name" : "organization-fiscal-code", + "in" : "path", + "description" : "The organization fiscal code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "multipart/form-data" : { + "schema" : { + "type" : "object", + "properties" : { + "file" : { + "type" : "string", + "description" : "File to be uploaded", + "format" : "binary" + } + } + }, + "encoding" : { + "file" : { + "contentType" : "application/octet-stream" + } + } + } + }, + "required" : true + }, + "responses" : { + "202" : { + "description" : "Request accepted." + }, + "400" : { + "description" : "Malformed request.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" + } + } + } + }, + "401" : { + "description" : "Wrong or missing function key.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" + } + } + } + }, + "403" : { + "description" : "Forbidden", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] + } + } + } + }, + "409" : { + "description" : "Conflict: duplicate file found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" + } + } + } + }, + "429" : { + "description" : "Too many requests.", + "content" : { + "text/json" : { } + } + }, + "500" : { + "description" : "Service unavailable.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" + } + } + } + } + }, + "security" : [ { + "ApiKey" : [ ] + }, { + "Authorization" : [ ] + } ] + }, + "post" : { + "tags" : [ "Debt Positions CRUD via file upload API" ], + "summary" : "The Organization creates the debt positions listed in the file.", + "operationId" : "create-debt-positions-by-file-upload", + "parameters" : [ { + "name" : "broker-code", + "in" : "path", + "description" : "The broker code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + }, { + "name" : "organization-fiscal-code", + "in" : "path", + "description" : "The organization fiscal code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "multipart/form-data" : { + "schema" : { + "type" : "object", + "properties" : { + "file" : { + "type" : "string", + "description" : "File to be uploaded", + "format" : "binary" + } + } + }, + "encoding" : { + "file" : { + "contentType" : "application/octet-stream" + } + } + } + }, + "required" : true + }, + "responses" : { + "202" : { + "description" : "Request accepted." + }, + "400" : { + "description" : "Malformed request.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" + } + } + } + }, + "401" : { + "description" : "Wrong or missing function key.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" + } + } + } + }, + "403" : { + "description" : "Forbidden", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] + } + } + } + }, + "409" : { + "description" : "Conflict: duplicate file found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" + } + } + } + }, + "429" : { + "description" : "Too many requests.", + "content" : { + "text/json" : { } + } + }, + "500" : { + "description" : "Service unavailable.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" + } + } + } + } + }, + "security" : [ { + "ApiKey" : [ ] + }, { + "Authorization" : [ ] + } ] + }, + "delete" : { + "tags" : [ "Debt Positions CRUD via file upload API" ], + "summary" : "The Organization deletes the debt positions based on IUPD listed in the file.", + "operationId" : "delete-debt-positions-by-file-upload", + "parameters" : [ { + "name" : "broker-code", + "in" : "path", + "description" : "The broker code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + }, { + "name" : "organization-fiscal-code", + "in" : "path", + "description" : "The organization fiscal code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "multipart/form-data" : { + "schema" : { + "type" : "object", + "properties" : { + "file" : { + "type" : "string", + "description" : "File to be uploaded", + "format" : "binary" + } + } + }, + "encoding" : { + "file" : { + "contentType" : "application/octet-stream" + } + } + } + }, + "required" : true + }, + "responses" : { + "202" : { + "description" : "Request accepted." + }, + "400" : { + "description" : "Malformed request.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" + } + } + } + }, + "401" : { + "description" : "Wrong or missing function key.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" + } + } + } + }, + "403" : { + "description" : "Forbidden", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] + } + } + } + }, + "409" : { + "description" : "Conflict: duplicate file found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" + } + } + } + }, + "429" : { + "description" : "Too many requests.", + "content" : { + "text/json" : { } + } + }, + "500" : { + "description" : "Service unavailable.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" + } + } + } + } + }, + "security" : [ { + "ApiKey" : [ ] + }, { + "Authorization" : [ ] + } ] + } + }, + "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/report" : { + "get" : { + "tags" : [ "Upload Status API" ], + "summary" : "Returns the debt positions upload report.", + "operationId" : "get-debt-positions-upload-report", + "parameters" : [ { + "name" : "broker-code", + "in" : "path", + "description" : "The broker code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + }, { + "name" : "organization-fiscal-code", + "in" : "path", + "description" : "The organization fiscal code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + }, { + "name" : "file-id", + "in" : "path", + "description" : "The unique identifier for file upload", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "Upload report found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UploadReport" + } + } + } + }, + "400" : { + "description" : "Malformed request.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" + } + } + } + }, + "401" : { + "description" : "Wrong or missing function key.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" + } + } + } + }, + "403" : { + "description" : "Forbidden", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] + } + } + } + }, + "404" : { + "description" : "Upload report not found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" + } + } + } + }, + "429" : { + "description" : "Too many requests.", + "content" : { + "text/json" : { } + } + }, + "500" : { + "description" : "Service unavailable.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" + } + } + } + } + }, + "security" : [ { + "ApiKey" : [ ] + }, { + "Authorization" : [ ] + } ] + } + }, + "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/status" : { + "get" : { + "tags" : [ "Upload Status API" ], + "summary" : "Returns the debt positions upload status.", + "operationId" : "get-debt-positions-upload-status", + "parameters" : [ { + "name" : "broker-code", + "in" : "path", + "description" : "The broker code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + }, { + "name" : "organization-fiscal-code", + "in" : "path", + "description" : "The organization fiscal code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + }, { + "name" : "file-id", + "in" : "path", + "description" : "The unique identifier for file upload", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "Upload found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UploadStatus" + } + } + } + }, + "400" : { + "description" : "Malformed request.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" + } + } + } + }, + "401" : { + "description" : "Wrong or missing function key.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" + } + } + } + }, + "403" : { + "description" : "Forbidden", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] + } + } + } + }, + "404" : { + "description" : "Upload not found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" + } + } + } + }, + "429" : { + "description" : "Too many requests.", + "content" : { + "text/json" : { } + } + }, + "500" : { + "description" : "Service unavailable.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" + } + } + } + } + }, + "security" : [ { + "ApiKey" : [ ] + }, { + "Authorization" : [ ] + } ] + } + }, + "/info" : { + "get" : { + "tags" : [ "Health check" ], + "summary" : "health check", + "description" : "Return OK if application is started", + "operationId" : "healthCheck", + "responses" : { + "200" : { + "description" : "OK", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/AppInfo" + } + } + } + }, + "400" : { + "description" : "Bad Request", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" + } + } + } + }, + "401" : { + "description" : "Unauthorized", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] + } + } + } + }, + "403" : { + "description" : "Forbidden", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] + } + } + } + }, + "429" : { + "description" : "Too many requests.", + "content" : { + "text/json" : { } + } + }, + "500" : { + "description" : "Service unavailable", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" + } + } + } + } + } + } + }, + "/support/uploads/{upload}/status/refresh" : { + "get" : { + "tags" : [ "Support API" ], + "summary" : "Support API to recover status on CREATE operation", + "description" : "Returns the debt positions upload report recovered.", + "operationId" : "recoverStatus", + "parameters" : [ { + "name" : "upload", + "in" : "path", + "description" : "The unique identifier for file upload", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "OK", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/AppInfo" + } + } + } + }, + "400" : { + "description" : "Bad Request", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" + } + } + } + }, + "401" : { + "description" : "Unauthorized", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] + } + } + } + }, + "403" : { + "description" : "Forbidden", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] + } + } + } + }, + "429" : { + "description" : "Too many requests.", + "content" : { + "text/json" : { } + } + }, + "500" : { + "description" : "Service unavailable", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" + } + } + } + } + } + } + } + }, + "components" : { + "schemas" : { + "AppInfo" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "version" : { + "type" : "string" + }, + "environment" : { + "type" : "string" + } + } + }, + "ProblemJson" : { + "type" : "object", + "properties" : { + "title" : { + "type" : "string", + "description" : "A short, summary of the problem type. Written in english and readable for engineers (usually not suited for non technical stakeholders and not localized); example: Service Unavailable" + }, + "status" : { + "type" : "integer", + "description" : "The HTTP status code generated by the origin server for this occurrence of the problem.", + "format" : "int32", + "example" : 200 + }, + "detail" : { + "type" : "string", + "description" : "A human readable explanation specific to this occurrence of the problem.", + "example" : "There was an error processing the request" + } + } + }, + "ResponseEntry" : { + "type" : "object", + "properties" : { + "statusCode" : { + "type" : "integer", + "format" : "int32", + "example" : 400 + }, + "statusMessage" : { + "type" : "string", + "example" : "Bad request caused by invalid email address" + }, + "requestIDs" : { + "type" : "array", + "items" : { + "type" : "string" + } + } + } + }, + "UploadReport" : { + "type" : "object", + "properties" : { + "uploadID" : { + "type" : "string" + }, + "processedItem" : { + "type" : "integer", + "format" : "int32" + }, + "submittedItem" : { + "type" : "integer", + "format" : "int32" + }, + "responses" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/ResponseEntry" + } + }, + "startTime" : { + "type" : "string", + "format" : "date-time", + "example" : "2024-10-08T14:55:16.302Z" + }, + "endTime" : { + "type" : "string", + "format" : "date-time", + "example" : "2024-10-08T14:55:16.302Z" + } + } + }, + "UploadStatus" : { + "type" : "object", + "properties" : { + "uploadID" : { + "type" : "string" + }, + "processedItem" : { + "type" : "integer", + "format" : "int32" + }, + "submittedItem" : { + "type" : "integer", + "format" : "int32" + }, + "startTime" : { + "type" : "string", + "format" : "date-time", + "example" : "2024-10-08T14:55:16.302Z" + } + } + } + }, + "securitySchemes" : { + "Ocp-Apim-Subscription-Key" : { + "type" : "apiKey", + "name" : "Ocp-Apim-Subscription-Key", + "in" : "header" + } + } + } +} \ No newline at end of file diff --git a/openapi/openapi.json b/openapi/openapi.json index f8f635c..6ed6089 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -1,707 +1,633 @@ { - "openapi": "3.0.1", - "info": { - "title": "pagopa-gpd-upload", - "description": "Microservice to manage PagoPA GPD Upload", - "termsOfService": "https://www.pagopa.gov.it/", - "version": "0.1.32-1-recover-delete-operation-status" - }, - "servers": [ - { - "url": "http://localhost:8080" - }, - { - "url": "https://{host}{basePath}", - "variables": { - "basePath": { - "default": "/upload/gpd/debt-positions-service/v1", - "enum": [ - "/upload/gpd/debt-positions-service/v1" - ] - }, - "host": { - "default": "api.dev.platform.pagopa.it", - "enum": [ - "api.dev.platform.pagopa.it", - "api.uat.platform.pagopa.it", - "api.platform.pagopa.it" - ] - } - } - } - ], - "paths": { - "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file": { - "put": { - "tags": [ - "Debt Positions CRUD via file upload API" - ], - "summary": "The Organization updates the debt positions listed in the file.", - "operationId": "update-debt-positions-by-file-upload", - "parameters": [ - { - "name": "broker-code", - "in": "path", - "description": "The broker code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - }, - { - "name": "organization-fiscal-code", - "in": "path", - "description": "The organization fiscal code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } + "openapi" : "3.0.1", + "paths" : { + "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file" : { + "put" : { + "tags" : [ "Debt Positions CRUD via file upload API" ], + "summary" : "The Organization updates the debt positions listed in the file.", + "operationId" : "update-debt-positions-by-file-upload", + "parameters" : [ { + "name" : "broker-code", + "in" : "path", + "description" : "The broker code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + }, { + "name" : "organization-fiscal-code", + "in" : "path", + "description" : "The organization fiscal code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" } - ], - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "file": { - "type": "string", - "description": "File to be uploaded", - "format": "binary" + } ], + "requestBody" : { + "content" : { + "multipart/form-data" : { + "schema" : { + "type" : "object", + "properties" : { + "file" : { + "type" : "string", + "description" : "File to be uploaded", + "format" : "binary" } } }, - "encoding": { - "file": { - "contentType": "application/octet-stream" + "encoding" : { + "file" : { + "contentType" : "application/octet-stream" } } } }, - "required": true + "required" : true }, - "responses": { - "202": { - "description": "Request accepted." + "responses" : { + "202" : { + "description" : "Request accepted." }, - "400": { - "description": "Malformed request.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "400" : { + "description" : "Malformed request.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "401": { - "description": "Wrong or missing function key.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "401" : { + "description" : "Wrong or missing function key.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "allOf": [], - "anyOf": [], - "oneOf": [] + "403" : { + "description" : "Forbidden", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] } } } }, - "409": { - "description": "Conflict: duplicate file found.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "409" : { + "description" : "Conflict: duplicate file found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "429": { - "description": "Too many requests.", - "content": { - "text/json": {} + "429" : { + "description" : "Too many requests.", + "content" : { + "text/json" : { } } }, - "500": { - "description": "Service unavailable.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "500" : { + "description" : "Service unavailable.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } } }, - "security": [ - { - "ApiKey": [] - }, - { - "Authorization": [] - } - ] + "security" : [ { + "ApiKey" : [ ] + }, { + "Authorization" : [ ] + } ] }, - "post": { - "tags": [ - "Debt Positions CRUD via file upload API" - ], - "summary": "The Organization creates the debt positions listed in the file.", - "operationId": "create-debt-positions-by-file-upload", - "parameters": [ - { - "name": "broker-code", - "in": "path", - "description": "The broker code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - }, - { - "name": "organization-fiscal-code", - "in": "path", - "description": "The organization fiscal code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } + "post" : { + "tags" : [ "Debt Positions CRUD via file upload API" ], + "summary" : "The Organization creates the debt positions listed in the file.", + "operationId" : "create-debt-positions-by-file-upload", + "parameters" : [ { + "name" : "broker-code", + "in" : "path", + "description" : "The broker code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + }, { + "name" : "organization-fiscal-code", + "in" : "path", + "description" : "The organization fiscal code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" } - ], - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "file": { - "type": "string", - "description": "File to be uploaded", - "format": "binary" + } ], + "requestBody" : { + "content" : { + "multipart/form-data" : { + "schema" : { + "type" : "object", + "properties" : { + "file" : { + "type" : "string", + "description" : "File to be uploaded", + "format" : "binary" } } }, - "encoding": { - "file": { - "contentType": "application/octet-stream" + "encoding" : { + "file" : { + "contentType" : "application/octet-stream" } } } }, - "required": true + "required" : true }, - "responses": { - "202": { - "description": "Request accepted." + "responses" : { + "202" : { + "description" : "Request accepted." }, - "400": { - "description": "Malformed request.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "400" : { + "description" : "Malformed request.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "401": { - "description": "Wrong or missing function key.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "401" : { + "description" : "Wrong or missing function key.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "allOf": [], - "anyOf": [], - "oneOf": [] + "403" : { + "description" : "Forbidden", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] } } } }, - "409": { - "description": "Conflict: duplicate file found.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "409" : { + "description" : "Conflict: duplicate file found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "429": { - "description": "Too many requests.", - "content": { - "text/json": {} + "429" : { + "description" : "Too many requests.", + "content" : { + "text/json" : { } } }, - "500": { - "description": "Service unavailable.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "500" : { + "description" : "Service unavailable.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } } }, - "security": [ - { - "ApiKey": [] - }, - { - "Authorization": [] - } - ] + "security" : [ { + "ApiKey" : [ ] + }, { + "Authorization" : [ ] + } ] }, - "delete": { - "tags": [ - "Debt Positions CRUD via file upload API" - ], - "summary": "The Organization deletes the debt positions based on IUPD listed in the file.", - "operationId": "delete-debt-positions-by-file-upload", - "parameters": [ - { - "name": "broker-code", - "in": "path", - "description": "The broker code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - }, - { - "name": "organization-fiscal-code", - "in": "path", - "description": "The organization fiscal code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } + "delete" : { + "tags" : [ "Debt Positions CRUD via file upload API" ], + "summary" : "The Organization deletes the debt positions based on IUPD listed in the file.", + "operationId" : "delete-debt-positions-by-file-upload", + "parameters" : [ { + "name" : "broker-code", + "in" : "path", + "description" : "The broker code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + }, { + "name" : "organization-fiscal-code", + "in" : "path", + "description" : "The organization fiscal code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" } - ], - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "file": { - "type": "string", - "description": "File to be uploaded", - "format": "binary" + } ], + "requestBody" : { + "content" : { + "multipart/form-data" : { + "schema" : { + "type" : "object", + "properties" : { + "file" : { + "type" : "string", + "description" : "File to be uploaded", + "format" : "binary" } } }, - "encoding": { - "file": { - "contentType": "application/octet-stream" + "encoding" : { + "file" : { + "contentType" : "application/octet-stream" } } } }, - "required": true + "required" : true }, - "responses": { - "202": { - "description": "Request accepted." + "responses" : { + "202" : { + "description" : "Request accepted." }, - "400": { - "description": "Malformed request.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "400" : { + "description" : "Malformed request.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "401": { - "description": "Wrong or missing function key.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "401" : { + "description" : "Wrong or missing function key.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "allOf": [], - "anyOf": [], - "oneOf": [] + "403" : { + "description" : "Forbidden", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] } } } }, - "409": { - "description": "Conflict: duplicate file found.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "409" : { + "description" : "Conflict: duplicate file found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "429": { - "description": "Too many requests.", - "content": { - "text/json": {} + "429" : { + "description" : "Too many requests.", + "content" : { + "text/json" : { } } }, - "500": { - "description": "Service unavailable.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "500" : { + "description" : "Service unavailable.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } } }, - "security": [ - { - "ApiKey": [] - }, - { - "Authorization": [] - } - ] + "security" : [ { + "ApiKey" : [ ] + }, { + "Authorization" : [ ] + } ] } }, - "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/report": { - "get": { - "tags": [ - "Upload Status API" - ], - "summary": "Returns the debt positions upload report.", - "operationId": "get-debt-positions-upload-report", - "parameters": [ - { - "name": "broker-code", - "in": "path", - "description": "The broker code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - }, - { - "name": "organization-fiscal-code", - "in": "path", - "description": "The organization fiscal code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - }, - { - "name": "file-id", - "in": "path", - "description": "The unique identifier for file upload", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } + "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/report" : { + "get" : { + "tags" : [ "Upload Status API" ], + "summary" : "Returns the debt positions upload report.", + "operationId" : "get-debt-positions-upload-report", + "parameters" : [ { + "name" : "broker-code", + "in" : "path", + "description" : "The broker code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + }, { + "name" : "organization-fiscal-code", + "in" : "path", + "description" : "The organization fiscal code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" } - ], - "responses": { - "200": { - "description": "Upload report found.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UploadReport" + }, { + "name" : "file-id", + "in" : "path", + "description" : "The unique identifier for file upload", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "Upload report found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UploadReport" } } } }, - "400": { - "description": "Malformed request.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "400" : { + "description" : "Malformed request.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "401": { - "description": "Wrong or missing function key.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "401" : { + "description" : "Wrong or missing function key.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "allOf": [], - "anyOf": [], - "oneOf": [] + "403" : { + "description" : "Forbidden", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] } } } }, - "404": { - "description": "Upload report not found.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "404" : { + "description" : "Upload report not found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "429": { - "description": "Too many requests.", - "content": { - "text/json": {} + "429" : { + "description" : "Too many requests.", + "content" : { + "text/json" : { } } }, - "500": { - "description": "Service unavailable.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "500" : { + "description" : "Service unavailable.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } } }, - "security": [ - { - "ApiKey": [] - }, - { - "Authorization": [] - } - ] + "security" : [ { + "ApiKey" : [ ] + }, { + "Authorization" : [ ] + } ] } }, - "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/status": { - "get": { - "tags": [ - "Upload Status API" - ], - "summary": "Returns the debt positions upload status.", - "operationId": "get-debt-positions-upload-status", - "parameters": [ - { - "name": "broker-code", - "in": "path", - "description": "The broker code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - }, - { - "name": "organization-fiscal-code", - "in": "path", - "description": "The organization fiscal code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - }, - { - "name": "file-id", - "in": "path", - "description": "The unique identifier for file upload", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } + "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/status" : { + "get" : { + "tags" : [ "Upload Status API" ], + "summary" : "Returns the debt positions upload status.", + "operationId" : "get-debt-positions-upload-status", + "parameters" : [ { + "name" : "broker-code", + "in" : "path", + "description" : "The broker code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" } - ], - "responses": { - "200": { - "description": "Upload found.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UploadStatus" + }, { + "name" : "organization-fiscal-code", + "in" : "path", + "description" : "The organization fiscal code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + }, { + "name" : "file-id", + "in" : "path", + "description" : "The unique identifier for file upload", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "Upload found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UploadStatus" } } } }, - "400": { - "description": "Malformed request.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "400" : { + "description" : "Malformed request.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "401": { - "description": "Wrong or missing function key.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "401" : { + "description" : "Wrong or missing function key.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "allOf": [], - "anyOf": [], - "oneOf": [] + "403" : { + "description" : "Forbidden", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] } } } }, - "404": { - "description": "Upload not found.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "404" : { + "description" : "Upload not found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "429": { - "description": "Too many requests.", - "content": { - "text/json": {} + "429" : { + "description" : "Too many requests.", + "content" : { + "text/json" : { } } }, - "500": { - "description": "Service unavailable.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "500" : { + "description" : "Service unavailable.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } } }, - "security": [ - { - "ApiKey": [] - }, - { - "Authorization": [] - } - ] + "security" : [ { + "ApiKey" : [ ] + }, { + "Authorization" : [ ] + } ] } }, - "/info": { - "get": { - "tags": [ - "Health check" - ], - "summary": "health check", - "description": "Return OK if application is started", - "operationId": "healthCheck", - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AppInfo" + "/info" : { + "get" : { + "tags" : [ "Health check" ], + "summary" : "health check", + "description" : "Return OK if application is started", + "operationId" : "healthCheck", + "responses" : { + "200" : { + "description" : "OK", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/AppInfo" } } } }, - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "400" : { + "description" : "Bad Request", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "allOf": [], - "anyOf": [], - "oneOf": [] + "401" : { + "description" : "Unauthorized", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] } } } }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "allOf": [], - "anyOf": [], - "oneOf": [] + "403" : { + "description" : "Forbidden", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] } } } }, - "429": { - "description": "Too many requests.", - "content": { - "text/json": {} + "429" : { + "description" : "Too many requests.", + "content" : { + "text/json" : { } } }, - "500": { - "description": "Service unavailable", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "500" : { + "description" : "Service unavailable", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } @@ -709,103 +635,79 @@ } } }, - "/support/brokers/{broker}/organizations/{organization}/{upload}/status/created/refresh": { - "get": { - "tags": [ - "Support API" - ], - "summary": "Support API to recover status on CREATE operation", - "description": "Returns the debt positions upload report recovered.", - "operationId": "recoverStatus", - "parameters": [ - { - "name": "broker", - "in": "path", - "description": "The broker code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - }, - { - "name": "organization", - "in": "path", - "description": "The organization fiscal code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - }, - { - "name": "upload", - "in": "path", - "description": "The unique identifier for file upload", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } + "/support/uploads/{upload}/status/refresh" : { + "get" : { + "tags" : [ "Support API" ], + "summary" : "Support API to recover status on CREATE operation", + "description" : "Returns the debt positions upload report recovered.", + "operationId" : "recoverStatus", + "parameters" : [ { + "name" : "upload", + "in" : "path", + "description" : "The unique identifier for file upload", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AppInfo" + } ], + "responses" : { + "200" : { + "description" : "OK", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/AppInfo" } } } }, - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "400" : { + "description" : "Bad Request", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "allOf": [], - "anyOf": [], - "oneOf": [] + "401" : { + "description" : "Unauthorized", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] } } } }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "allOf": [], - "anyOf": [], - "oneOf": [] + "403" : { + "description" : "Forbidden", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] } } } }, - "429": { - "description": "Too many requests.", - "content": { - "text/json": {} + "429" : { + "description" : "Too many requests.", + "content" : { + "text/json" : { } } }, - "500": { - "description": "Service unavailable", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "500" : { + "description" : "Service unavailable", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } @@ -814,123 +716,122 @@ } } }, - "components": { - "schemas": { - "AppInfo": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "version": { - "type": "string" - }, - "environment": { - "type": "string" + "components" : { + "schemas" : { + "AppInfo" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "version" : { + "type" : "string" + }, + "environment" : { + "type" : "string" } } }, - "ProblemJson": { - "type": "object", - "properties": { - "title": { - "type": "string", - "description": "A short, summary of the problem type. Written in english and readable for engineers (usually not suited for non technical stakeholders and not localized); example: Service Unavailable" - }, - "status": { - "type": "integer", - "description": "The HTTP status code generated by the origin server for this occurrence of the problem.", - "format": "int32", - "example": 200 - }, - "detail": { - "type": "string", - "description": "A human readable explanation specific to this occurrence of the problem.", - "example": "There was an error processing the request" + "ProblemJson" : { + "type" : "object", + "properties" : { + "title" : { + "type" : "string", + "description" : "A short, summary of the problem type. Written in english and readable for engineers (usually not suited for non technical stakeholders and not localized); example: Service Unavailable" + }, + "status" : { + "type" : "integer", + "description" : "The HTTP status code generated by the origin server for this occurrence of the problem.", + "format" : "int32", + "example" : 200 + }, + "detail" : { + "type" : "string", + "description" : "A human readable explanation specific to this occurrence of the problem.", + "example" : "There was an error processing the request" } - }, - "description": "Object returned as response in case of an error." + } }, - "ResponseEntry": { - "type": "object", - "properties": { - "statusCode": { - "type": "integer", - "format": "int32", - "example": 400 - }, - "statusMessage": { - "type": "string", - "example": "Bad request caused by invalid email address" - }, - "requestIDs": { - "type": "array", - "items": { - "type": "string" + "ResponseEntry" : { + "type" : "object", + "properties" : { + "statusCode" : { + "type" : "integer", + "format" : "int32", + "example" : 400 + }, + "statusMessage" : { + "type" : "string", + "example" : "Bad request caused by invalid email address" + }, + "requestIDs" : { + "type" : "array", + "items" : { + "type" : "string" } } } }, - "UploadReport": { - "type": "object", - "properties": { - "uploadID": { - "type": "string" - }, - "processedItem": { - "type": "integer", - "format": "int32" - }, - "submittedItem": { - "type": "integer", - "format": "int32" - }, - "responses": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ResponseEntry" - } - }, - "startTime": { - "type": "string", - "format": "date-time", - "example": "2024-10-08T14:55:16.302Z" - }, - "endTime": { - "type": "string", - "format": "date-time", - "example": "2024-10-08T14:55:16.302Z" + "UploadReport" : { + "type" : "object", + "properties" : { + "uploadID" : { + "type" : "string" + }, + "processedItem" : { + "type" : "integer", + "format" : "int32" + }, + "submittedItem" : { + "type" : "integer", + "format" : "int32" + }, + "responses" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/ResponseEntry" + } + }, + "startTime" : { + "type" : "string", + "format" : "date-time", + "example" : "2024-10-08T14:55:16.302Z" + }, + "endTime" : { + "type" : "string", + "format" : "date-time", + "example" : "2024-10-08T14:55:16.302Z" } } }, - "UploadStatus": { - "type": "object", - "properties": { - "uploadID": { - "type": "string" - }, - "processedItem": { - "type": "integer", - "format": "int32" - }, - "submittedItem": { - "type": "integer", - "format": "int32" - }, - "startTime": { - "type": "string", - "format": "date-time", - "example": "2024-10-08T14:55:16.302Z" + "UploadStatus" : { + "type" : "object", + "properties" : { + "uploadID" : { + "type" : "string" + }, + "processedItem" : { + "type" : "integer", + "format" : "int32" + }, + "submittedItem" : { + "type" : "integer", + "format" : "int32" + }, + "startTime" : { + "type" : "string", + "format" : "date-time", + "example" : "2024-10-08T14:55:16.302Z" } } } }, - "securitySchemes": { - "Ocp-Apim-Subscription-Key": { - "type": "apiKey", - "name": "Ocp-Apim-Subscription-Key", - "in": "header" + "securitySchemes" : { + "Ocp-Apim-Subscription-Key" : { + "type" : "apiKey", + "name" : "Ocp-Apim-Subscription-Key", + "in" : "header" } } } -} +} \ No newline at end of file diff --git a/src/main/java/it/gov/pagopa/gpd/upload/controller/SupportController.java b/src/main/java/it/gov/pagopa/gpd/upload/controller/support/SupportController.java similarity index 51% rename from src/main/java/it/gov/pagopa/gpd/upload/controller/SupportController.java rename to src/main/java/it/gov/pagopa/gpd/upload/controller/support/SupportController.java index f8e0f55..9496e43 100644 --- a/src/main/java/it/gov/pagopa/gpd/upload/controller/SupportController.java +++ b/src/main/java/it/gov/pagopa/gpd/upload/controller/support/SupportController.java @@ -1,4 +1,4 @@ -package it.gov.pagopa.gpd.upload.controller; +package it.gov.pagopa.gpd.upload.controller.support; import io.micronaut.http.HttpResponse; import io.micronaut.http.HttpStatus; @@ -15,6 +15,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; +import it.gov.pagopa.gpd.upload.exception.AppException; import it.gov.pagopa.gpd.upload.model.AppInfo; import it.gov.pagopa.gpd.upload.model.ProblemJson; import it.gov.pagopa.gpd.upload.model.UploadReport; @@ -44,42 +45,18 @@ public class SupportController { @ApiResponse(responseCode = "403", description = "Forbidden", content = @Content(schema = @Schema())), @ApiResponse(responseCode = "429", description = "Too many requests.", content = @Content(mediaType = MediaType.TEXT_JSON)), @ApiResponse(responseCode = "500", description = "Service unavailable", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = ProblemJson.class)))}) - @Get(value = "brokers/{broker}/organizations/{organization}/{upload}/status/created/refresh") - public HttpResponse recoverCreateOperationStatus( - @Parameter(description = "The broker code", required = true) - @NotBlank @PathVariable(name = "broker") String broker, - @Parameter(description = "The organization fiscal code", required = true) - @NotBlank @PathVariable(name = "organization") String organization, + @Get(value = "uploads/{upload}/status/refresh") + public HttpResponse recoverStatus( @Parameter(description = "The unique identifier for file upload", required = true) - @NotBlank @PathVariable(name = "upload") String upload - ) { - recoveryService.recoverCreated(broker, organization, upload); - log.info("[Support-API] Status {} recovered", upload); - UploadReport report = statusService.getReport(organization, upload); + @NotBlank @PathVariable(name = "upload") String upload) { + String[] strings = upload.split("_"); - return HttpResponse.status(HttpStatus.OK) - .contentType(MediaType.APPLICATION_JSON) - .body(report); - } + if(strings.length < 3) + throw new AppException(HttpStatus.BAD_REQUEST, "Recover bad request", "The upload UUID should be formatted as __"); - @Operation(summary = "Support API to recover status on CREATE operation", description = "Returns the debt positions upload report recovered.", tags = {"Support API"}) - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = AppInfo.class))), - @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = ProblemJson.class))), - @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(schema = @Schema())), - @ApiResponse(responseCode = "403", description = "Forbidden", content = @Content(schema = @Schema())), - @ApiResponse(responseCode = "429", description = "Too many requests.", content = @Content(mediaType = MediaType.TEXT_JSON)), - @ApiResponse(responseCode = "500", description = "Service unavailable", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = ProblemJson.class)))}) - @Get(value = "brokers/{broker}/organizations/{organization}/{upload}/status/deleted/refresh") - public HttpResponse recoverDeleteOperationStatus( - @Parameter(description = "The broker code", required = true) - @NotBlank @PathVariable(name = "broker") String broker, - @Parameter(description = "The organization fiscal code", required = true) - @NotBlank @PathVariable(name = "organization") String organization, - @Parameter(description = "The unique identifier for file upload", required = true) - @NotBlank @PathVariable(name = "upload") String upload - ) { - recoveryService.recoverDeleted(broker, organization, upload); + String broker = strings[0]; + String organization = strings[1]; + recoveryService.recover(broker, organization, upload); log.info("[Support-API] Status {} recovered", upload); UploadReport report = statusService.getReport(organization, upload); diff --git a/src/main/java/it/gov/pagopa/gpd/upload/entity/MatchResult.java b/src/main/java/it/gov/pagopa/gpd/upload/entity/MatchResult.java new file mode 100644 index 0000000..db4bb2b --- /dev/null +++ b/src/main/java/it/gov/pagopa/gpd/upload/entity/MatchResult.java @@ -0,0 +1,8 @@ +package it.gov.pagopa.gpd.upload.entity; + + +import java.util.List; + +public record MatchResult(List matchingIUPD, List nonMatchingIUPD) { + // used by RecoveryService to store 2 list, match and non-match cases +} \ No newline at end of file diff --git a/src/main/java/it/gov/pagopa/gpd/upload/service/RecoveryService.java b/src/main/java/it/gov/pagopa/gpd/upload/service/RecoveryService.java index 4079db7..ed3a172 100644 --- a/src/main/java/it/gov/pagopa/gpd/upload/service/RecoveryService.java +++ b/src/main/java/it/gov/pagopa/gpd/upload/service/RecoveryService.java @@ -2,11 +2,11 @@ import io.micronaut.http.HttpStatus; import it.gov.pagopa.gpd.upload.client.GPDClient; +import it.gov.pagopa.gpd.upload.entity.MatchResult; import it.gov.pagopa.gpd.upload.entity.ResponseEntry; import it.gov.pagopa.gpd.upload.entity.Status; import it.gov.pagopa.gpd.upload.exception.AppException; import it.gov.pagopa.gpd.upload.model.UploadInput; -import it.gov.pagopa.gpd.upload.model.UploadOperation; import it.gov.pagopa.gpd.upload.model.pd.PaymentPositionModel; import jakarta.inject.Inject; import jakarta.inject.Singleton; @@ -14,9 +14,7 @@ import java.time.LocalDateTime; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; @Singleton @Slf4j @@ -32,26 +30,24 @@ public RecoveryService(StatusService statusService, BlobService blobService, GPD this.gpdClient = gpdClient; } - public Status recoverCreated(String brokerId, String organizationFiscalCode, String uploadId) { + public void recover(String brokerId, String organizationFiscalCode, String uploadId) { UploadInput uploadInput = blobService.getUploadInput(brokerId, organizationFiscalCode, uploadId); - if(!uploadInput.getUploadOperation().equals(UploadOperation.CREATE)) - throw new AppException(HttpStatus.NOT_FOUND, - "Upload operation not processable", String.format("Not exists create operation with upload-id %s", uploadId)); - - List inputIUPD = uploadInput.getPaymentPositionIUPDs(); - return this.recover(organizationFiscalCode, uploadId, inputIUPD, HttpStatus.OK, HttpStatus.CREATED); - } - - public Status recoverDeleted(String brokerId, String organizationFiscalCode, String uploadId) { - UploadInput uploadInput = blobService.getUploadInput(brokerId, organizationFiscalCode, uploadId); - if(!uploadInput.getUploadOperation().equals(UploadOperation.DELETE)) - throw new AppException(HttpStatus.NOT_FOUND, - "Upload operation not processable", String.format("Not exists delete operation with upload-id %s", uploadId)); - List inputIUPD = uploadInput.getPaymentPositionIUPDs(); - return this.recover(organizationFiscalCode, uploadId, inputIUPD, HttpStatus.NOT_FOUND, HttpStatus.NOT_FOUND); + List inputIUPD; + + switch (uploadInput.getUploadOperation()) { + case CREATE: + inputIUPD = uploadInput.getPaymentPositions().stream().map(PaymentPositionModel::getIupd).toList(); + recover(organizationFiscalCode, uploadId, inputIUPD, HttpStatus.OK, HttpStatus.CREATED); + case DELETE: + inputIUPD = uploadInput.getPaymentPositionIUPDs(); + recover(organizationFiscalCode, uploadId, inputIUPD, HttpStatus.NOT_FOUND, HttpStatus.NOT_FOUND); + default: + throw new AppException(HttpStatus.NOT_FOUND, + "Upload operation not processable", String.format("Not exists CREATE or DELETE operation with upload-id %s", uploadId)); + } } - public Status recover(String organizationFiscalCode, String uploadId, List inputIUPD, HttpStatus statusToCheck, HttpStatus uploadStatus) { + private Status recover(String organizationFiscalCode, String uploadId, List inputIUPD, HttpStatus toGetFromGPD, HttpStatus toWrite) { Status current = statusService.getStatus(organizationFiscalCode, uploadId); // check if upload is pending @@ -65,37 +61,45 @@ public Status recover(String organizationFiscalCode, String uploadId, List NOT_EXISTS, EXISTS) - List deletedIUPD = getAlreadyIUPD(organizationFiscalCode, inputIUPD, processedIUPD, statusToCheck); + MatchResult result = match(organizationFiscalCode, inputIUPD, processedIUPD, toGetFromGPD); // update status and save current.upload.addResponse(ResponseEntry.builder() - .requestIDs(deletedIUPD) - .statusCode(uploadStatus.getCode()) - .statusMessage(statusService.getDetail(uploadStatus)) + .requestIDs(result.matchingIUPD()) + .statusCode(toWrite.getCode()) + .statusMessage(statusService.getDetail(toWrite)) + .build()); + // for non-matching IUPD the code is 500 + current.upload.addResponse(ResponseEntry.builder() + .requestIDs(result.nonMatchingIUPD()) + .statusCode(HttpStatus.INTERNAL_SERVER_ERROR.getCode()) + .statusMessage(statusService.getDetail(toWrite)) .build()); current.upload.setEnd(LocalDateTime.now()); return statusService.upsert(current); } - private List getAlreadyIUPD(String organizationFiscalCode, List inputIUPD, List processedIUPD, HttpStatus target) { - Set inputIUPDSet = new HashSet<>(inputIUPD); - Set processedIUPDSet = new HashSet<>(processedIUPD); + private MatchResult match(String organizationFiscalCode, List inputIUPD, List processedIUPD, HttpStatus target) { + List differenceIUPD = inputIUPD.stream() + .filter(iupd -> !processedIUPD.contains(iupd)) + .toList(); - // diff - if(!inputIUPDSet.removeAll(processedIUPDSet)) - throw new AppException(HttpStatus.INTERNAL_SERVER_ERROR, "Internal Server Error", "Internal Server Error"); - - List alreadyIUPD = new ArrayList<>(); + List matchingIUPD = new ArrayList<>(); + List nonMatchingIUPD = new ArrayList<>(); // for each check if position is processed - inputIUPDSet.forEach(id -> { + differenceIUPD.forEach(id -> { // request to GPD HttpStatus httpStatus = gpdClient.getDebtPosition(organizationFiscalCode, id).getStatus(); - if(httpStatus.equals(target)) { // if request was successful - alreadyIUPD.add(id); + // if status code match the target + if(httpStatus.equals(target)) { + matchingIUPD.add(id); + } else { + nonMatchingIUPD.add(id); } }); - return alreadyIUPD; + + return new MatchResult(matchingIUPD, nonMatchingIUPD); } } \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index cc21a3e..dfef5e3 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -12,6 +12,17 @@ micronaut.server.multipart.maxFileSize=104857600 micronaut.server.max-request-size=104857600 micronaut.server.max-request-size.multipart.max-file-size=104857600 +# openapi groups +micronaut.openapi.groups.external.primary=true +micronaut.openapi.groups.external.filename=pagopa-gpd-upload-${openapi.application.version} +micronaut.openapi.groups.external.display-name=GPD-Upload-API +micronaut.openapi.groups.external.packages=it.gov.pagopa.gpd.upload.controller.* +micronaut.openapi.groups.external.packages-exclude[0]=com.micronaut.controller.support.* +micronaut.openapi.groups.internal.primary=false +micronaut.openapi.groups.internal.display-name=GPD-Upload-Support-API +micronaut.openapi.groups.internal.filename=pagopa-gpd-upload-support +micronaut.openapi.groups.internal.packages=it.gov.pagopa.gpd.upload.controller.* + blob.sas.connection=${BLOB_CONNECTION_STRING} blob.container.input=gpd-upload/input zip.content.size=104857600 diff --git a/src/test/java/it/gov/pagopa/gpd/upload/OpenApiGenerationTest.java b/src/test/java/it/gov/pagopa/gpd/upload/OpenApiGenerationTest.java index 8be6815..b716cd9 100644 --- a/src/test/java/it/gov/pagopa/gpd/upload/OpenApiGenerationTest.java +++ b/src/test/java/it/gov/pagopa/gpd/upload/OpenApiGenerationTest.java @@ -36,8 +36,10 @@ class OpenApiGenerationTest { @Test void swaggerSpringPlugin() throws Exception { boolean result = saveOpenAPI("/swagger/pagopa-gpd-upload-" + version + ".json", "openapi.json"); - assertTrue(result); + + boolean resultSupportAPI = saveOpenAPI("/swagger/pagopa-gpd-upload-support.json", "openapi-support-internal.json"); + assertTrue(resultSupportAPI); } private boolean saveOpenAPI(String fromUri, String toFile) throws IOException { From 0ab8970b0a7ae8ca5516968f6a4776b9b2af44f8 Mon Sep 17 00:00:00 2001 From: Angelo Caporaso <56113767+cap-ang@users.noreply.github.com> Date: Thu, 28 Nov 2024 13:04:57 +0100 Subject: [PATCH 04/19] [PAGOPA-2426] feat: Add duplicate validation --- .../upload/config/duplicate/NoDuplicate.java | 22 ++++++++ .../duplicate/NoDuplicateValidator.java | 51 +++++++++++++++++++ .../pagopa/gpd/upload/model/UploadInput.java | 2 + .../upload/model/pd/MultipleIUPDModel.java | 2 + .../model/pd/PaymentPositionsModel.java | 2 + 5 files changed, 79 insertions(+) create mode 100644 src/main/java/it/gov/pagopa/gpd/upload/config/duplicate/NoDuplicate.java create mode 100644 src/main/java/it/gov/pagopa/gpd/upload/config/duplicate/NoDuplicateValidator.java diff --git a/src/main/java/it/gov/pagopa/gpd/upload/config/duplicate/NoDuplicate.java b/src/main/java/it/gov/pagopa/gpd/upload/config/duplicate/NoDuplicate.java new file mode 100644 index 0000000..dbae0ce --- /dev/null +++ b/src/main/java/it/gov/pagopa/gpd/upload/config/duplicate/NoDuplicate.java @@ -0,0 +1,22 @@ +package it.gov.pagopa.gpd.upload.config.duplicate; + +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Constraint(validatedBy = NoDuplicateValidator.class) +@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER }) +@Retention(RetentionPolicy.RUNTIME) +public @interface NoDuplicate { + String message() default "there are duplicates in the list"; + + Class[] groups() default {}; + + Class[] payload() default {}; + + String fieldName() default ""; // Check duplicate on this field +} \ No newline at end of file diff --git a/src/main/java/it/gov/pagopa/gpd/upload/config/duplicate/NoDuplicateValidator.java b/src/main/java/it/gov/pagopa/gpd/upload/config/duplicate/NoDuplicateValidator.java new file mode 100644 index 0000000..5955097 --- /dev/null +++ b/src/main/java/it/gov/pagopa/gpd/upload/config/duplicate/NoDuplicateValidator.java @@ -0,0 +1,51 @@ +package it.gov.pagopa.gpd.upload.config.duplicate; + + +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; + +import java.lang.reflect.Field; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +public class NoDuplicateValidator implements ConstraintValidator> { + + private String fieldName; + + @Override + public void initialize(NoDuplicate constraintAnnotation) { + this.fieldName = constraintAnnotation.fieldName(); + } + + @Override + public boolean isValid(List list, ConstraintValidatorContext context) { + if (list == null) { + return true; + } + + if(Objects.equals(fieldName, "")) { + HashSet unique = new HashSet<>(list); + return unique.size() == list.size(); + } else { + Set seenValues = new HashSet<>(); + + for (Object item : list) { + try { + Field field = item.getClass().getDeclaredField(fieldName); + field.setAccessible(true); + Object value = field.get(item); + if (!seenValues.add(value)) { + return false; + } + } catch (NoSuchFieldException | IllegalAccessException e) { + e.printStackTrace(); + return false; + } + } + + return true; + } + } +} diff --git a/src/main/java/it/gov/pagopa/gpd/upload/model/UploadInput.java b/src/main/java/it/gov/pagopa/gpd/upload/model/UploadInput.java index 23d14f4..58cffa8 100644 --- a/src/main/java/it/gov/pagopa/gpd/upload/model/UploadInput.java +++ b/src/main/java/it/gov/pagopa/gpd/upload/model/UploadInput.java @@ -1,6 +1,7 @@ package it.gov.pagopa.gpd.upload.model; import com.fasterxml.jackson.annotation.JsonProperty; +import it.gov.pagopa.gpd.upload.config.duplicate.NoDuplicate; import it.gov.pagopa.gpd.upload.model.pd.PaymentPositionModel; import jakarta.validation.Valid; import lombok.AllArgsConstructor; @@ -22,5 +23,6 @@ public class UploadInput { @Valid private List<@Valid PaymentPositionModel> paymentPositions; @Valid + @NoDuplicate private List paymentPositionIUPDs; } diff --git a/src/main/java/it/gov/pagopa/gpd/upload/model/pd/MultipleIUPDModel.java b/src/main/java/it/gov/pagopa/gpd/upload/model/pd/MultipleIUPDModel.java index de970e3..65e47be 100644 --- a/src/main/java/it/gov/pagopa/gpd/upload/model/pd/MultipleIUPDModel.java +++ b/src/main/java/it/gov/pagopa/gpd/upload/model/pd/MultipleIUPDModel.java @@ -1,6 +1,7 @@ package it.gov.pagopa.gpd.upload.model.pd; import io.micronaut.core.annotation.Introspected; +import it.gov.pagopa.gpd.upload.config.duplicate.NoDuplicate; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; @@ -23,5 +24,6 @@ public class MultipleIUPDModel { @NotEmpty @Size(min = 1, max = 100000, message = "The list of payment positions IUPD must contain at least one element and at the most " + MAX_IUPD) @NotNull + @NoDuplicate private List paymentPositionIUPDs; } diff --git a/src/main/java/it/gov/pagopa/gpd/upload/model/pd/PaymentPositionsModel.java b/src/main/java/it/gov/pagopa/gpd/upload/model/pd/PaymentPositionsModel.java index e2b71e2..fbfa554 100644 --- a/src/main/java/it/gov/pagopa/gpd/upload/model/pd/PaymentPositionsModel.java +++ b/src/main/java/it/gov/pagopa/gpd/upload/model/pd/PaymentPositionsModel.java @@ -1,6 +1,7 @@ package it.gov.pagopa.gpd.upload.model.pd; import io.micronaut.core.annotation.Introspected; +import it.gov.pagopa.gpd.upload.config.duplicate.NoDuplicate; import jakarta.validation.Valid; import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; @@ -20,6 +21,7 @@ public class PaymentPositionsModel { @Size(min = 1, message = "The list of payment positions must contain at least one element") private List<@Valid PaymentPositionModel> paymentPositions; + @NoDuplicate public @Valid List<@Valid PaymentPositionModel> getPaymentPositions() { return this.paymentPositions; } From 2dea2c12eff3dff9f1492133d3007332d2350a3d Mon Sep 17 00:00:00 2001 From: pagopa-github-bot Date: Thu, 28 Nov 2024 13:09:19 +0000 Subject: [PATCH 05/19] Bump to version 0.1.32-2-recover-delete-operation-status --- helm/Chart.yaml | 4 +- helm/values-dev.yaml | 2 +- helm/values-prod.yaml | 2 +- helm/values-uat.yaml | 2 +- openapi/openapi-support-internal.json | 1253 +++++++++++++------------ openapi/openapi.json | 1253 +++++++++++++------------ pom.xml | 2 +- 7 files changed, 1310 insertions(+), 1208 deletions(-) diff --git a/helm/Chart.yaml b/helm/Chart.yaml index 06e20ac..6ff0315 100644 --- a/helm/Chart.yaml +++ b/helm/Chart.yaml @@ -2,8 +2,8 @@ apiVersion: v2 name: pagopa-gpd-upload description: Microservice that handles file upload of massive debt positions JSON object type: application -version: 0.107.0 -appVersion: 0.1.32-1-recover-delete-operation-status +version: 0.108.0 +appVersion: 0.1.32-2-recover-delete-operation-status dependencies: - name: microservice-chart version: 2.8.0 diff --git a/helm/values-dev.yaml b/helm/values-dev.yaml index b9cb1fd..e649cd5 100644 --- a/helm/values-dev.yaml +++ b/helm/values-dev.yaml @@ -4,7 +4,7 @@ microservice-chart: fullnameOverride: "" image: repository: ghcr.io/pagopa/pagopa-gpd-upload - tag: "0.1.32-1-recover-delete-operation-status" + tag: "0.1.32-2-recover-delete-operation-status" pullPolicy: Always livenessProbe: httpGet: diff --git a/helm/values-prod.yaml b/helm/values-prod.yaml index 876d977..e284786 100644 --- a/helm/values-prod.yaml +++ b/helm/values-prod.yaml @@ -4,7 +4,7 @@ microservice-chart: fullnameOverride: "" image: repository: ghcr.io/pagopa/pagopa-gpd-upload - tag: "0.1.32-1-recover-delete-operation-status" + tag: "0.1.32-2-recover-delete-operation-status" pullPolicy: Always livenessProbe: httpGet: diff --git a/helm/values-uat.yaml b/helm/values-uat.yaml index 9974a69..7d98810 100644 --- a/helm/values-uat.yaml +++ b/helm/values-uat.yaml @@ -4,7 +4,7 @@ microservice-chart: fullnameOverride: "" image: repository: ghcr.io/pagopa/pagopa-gpd-upload - tag: "0.1.32-1-recover-delete-operation-status" + tag: "0.1.32-2-recover-delete-operation-status" pullPolicy: Always livenessProbe: httpGet: diff --git a/openapi/openapi-support-internal.json b/openapi/openapi-support-internal.json index 6ed6089..91a250f 100644 --- a/openapi/openapi-support-internal.json +++ b/openapi/openapi-support-internal.json @@ -1,633 +1,677 @@ { - "openapi" : "3.0.1", - "paths" : { - "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file" : { - "put" : { - "tags" : [ "Debt Positions CRUD via file upload API" ], - "summary" : "The Organization updates the debt positions listed in the file.", - "operationId" : "update-debt-positions-by-file-upload", - "parameters" : [ { - "name" : "broker-code", - "in" : "path", - "description" : "The broker code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" - } - }, { - "name" : "organization-fiscal-code", - "in" : "path", - "description" : "The organization fiscal code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + "openapi": "3.0.1", + "paths": { + "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file": { + "put": { + "tags": [ + "Debt Positions CRUD via file upload API" + ], + "summary": "The Organization updates the debt positions listed in the file.", + "operationId": "update-debt-positions-by-file-upload", + "parameters": [ + { + "name": "broker-code", + "in": "path", + "description": "The broker code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "organization-fiscal-code", + "in": "path", + "description": "The organization fiscal code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } } - } ], - "requestBody" : { - "content" : { - "multipart/form-data" : { - "schema" : { - "type" : "object", - "properties" : { - "file" : { - "type" : "string", - "description" : "File to be uploaded", - "format" : "binary" + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "file": { + "type": "string", + "description": "File to be uploaded", + "format": "binary" } } }, - "encoding" : { - "file" : { - "contentType" : "application/octet-stream" + "encoding": { + "file": { + "contentType": "application/octet-stream" } } } }, - "required" : true + "required": true }, - "responses" : { - "202" : { - "description" : "Request accepted." + "responses": { + "202": { + "description": "Request accepted." }, - "400" : { - "description" : "Malformed request.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "400": { + "description": "Malformed request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "401" : { - "description" : "Wrong or missing function key.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "401": { + "description": "Wrong or missing function key.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "403" : { - "description" : "Forbidden", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "409" : { - "description" : "Conflict: duplicate file found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "409": { + "description": "Conflict: duplicate file found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "429" : { - "description" : "Too many requests.", - "content" : { - "text/json" : { } + "429": { + "description": "Too many requests.", + "content": { + "text/json": {} } }, - "500" : { - "description" : "Service unavailable.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "500": { + "description": "Service unavailable.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } } }, - "security" : [ { - "ApiKey" : [ ] - }, { - "Authorization" : [ ] - } ] - }, - "post" : { - "tags" : [ "Debt Positions CRUD via file upload API" ], - "summary" : "The Organization creates the debt positions listed in the file.", - "operationId" : "create-debt-positions-by-file-upload", - "parameters" : [ { - "name" : "broker-code", - "in" : "path", - "description" : "The broker code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + "security": [ + { + "ApiKey": [] + }, + { + "Authorization": [] } - }, { - "name" : "organization-fiscal-code", - "in" : "path", - "description" : "The organization fiscal code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + ] + }, + "post": { + "tags": [ + "Debt Positions CRUD via file upload API" + ], + "summary": "The Organization creates the debt positions listed in the file.", + "operationId": "create-debt-positions-by-file-upload", + "parameters": [ + { + "name": "broker-code", + "in": "path", + "description": "The broker code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "organization-fiscal-code", + "in": "path", + "description": "The organization fiscal code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } } - } ], - "requestBody" : { - "content" : { - "multipart/form-data" : { - "schema" : { - "type" : "object", - "properties" : { - "file" : { - "type" : "string", - "description" : "File to be uploaded", - "format" : "binary" + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "file": { + "type": "string", + "description": "File to be uploaded", + "format": "binary" } } }, - "encoding" : { - "file" : { - "contentType" : "application/octet-stream" + "encoding": { + "file": { + "contentType": "application/octet-stream" } } } }, - "required" : true + "required": true }, - "responses" : { - "202" : { - "description" : "Request accepted." + "responses": { + "202": { + "description": "Request accepted." }, - "400" : { - "description" : "Malformed request.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "400": { + "description": "Malformed request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "401" : { - "description" : "Wrong or missing function key.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "401": { + "description": "Wrong or missing function key.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "403" : { - "description" : "Forbidden", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "409" : { - "description" : "Conflict: duplicate file found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "409": { + "description": "Conflict: duplicate file found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "429" : { - "description" : "Too many requests.", - "content" : { - "text/json" : { } + "429": { + "description": "Too many requests.", + "content": { + "text/json": {} } }, - "500" : { - "description" : "Service unavailable.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "500": { + "description": "Service unavailable.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } } }, - "security" : [ { - "ApiKey" : [ ] - }, { - "Authorization" : [ ] - } ] - }, - "delete" : { - "tags" : [ "Debt Positions CRUD via file upload API" ], - "summary" : "The Organization deletes the debt positions based on IUPD listed in the file.", - "operationId" : "delete-debt-positions-by-file-upload", - "parameters" : [ { - "name" : "broker-code", - "in" : "path", - "description" : "The broker code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + "security": [ + { + "ApiKey": [] + }, + { + "Authorization": [] } - }, { - "name" : "organization-fiscal-code", - "in" : "path", - "description" : "The organization fiscal code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + ] + }, + "delete": { + "tags": [ + "Debt Positions CRUD via file upload API" + ], + "summary": "The Organization deletes the debt positions based on IUPD listed in the file.", + "operationId": "delete-debt-positions-by-file-upload", + "parameters": [ + { + "name": "broker-code", + "in": "path", + "description": "The broker code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "organization-fiscal-code", + "in": "path", + "description": "The organization fiscal code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } } - } ], - "requestBody" : { - "content" : { - "multipart/form-data" : { - "schema" : { - "type" : "object", - "properties" : { - "file" : { - "type" : "string", - "description" : "File to be uploaded", - "format" : "binary" + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "file": { + "type": "string", + "description": "File to be uploaded", + "format": "binary" } } }, - "encoding" : { - "file" : { - "contentType" : "application/octet-stream" + "encoding": { + "file": { + "contentType": "application/octet-stream" } } } }, - "required" : true + "required": true }, - "responses" : { - "202" : { - "description" : "Request accepted." + "responses": { + "202": { + "description": "Request accepted." }, - "400" : { - "description" : "Malformed request.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "400": { + "description": "Malformed request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "401" : { - "description" : "Wrong or missing function key.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "401": { + "description": "Wrong or missing function key.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "403" : { - "description" : "Forbidden", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "409" : { - "description" : "Conflict: duplicate file found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "409": { + "description": "Conflict: duplicate file found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "429" : { - "description" : "Too many requests.", - "content" : { - "text/json" : { } + "429": { + "description": "Too many requests.", + "content": { + "text/json": {} } }, - "500" : { - "description" : "Service unavailable.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "500": { + "description": "Service unavailable.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } } }, - "security" : [ { - "ApiKey" : [ ] - }, { - "Authorization" : [ ] - } ] + "security": [ + { + "ApiKey": [] + }, + { + "Authorization": [] + } + ] } }, - "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/report" : { - "get" : { - "tags" : [ "Upload Status API" ], - "summary" : "Returns the debt positions upload report.", - "operationId" : "get-debt-positions-upload-report", - "parameters" : [ { - "name" : "broker-code", - "in" : "path", - "description" : "The broker code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" - } - }, { - "name" : "organization-fiscal-code", - "in" : "path", - "description" : "The organization fiscal code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" - } - }, { - "name" : "file-id", - "in" : "path", - "description" : "The unique identifier for file upload", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/report": { + "get": { + "tags": [ + "Upload Status API" + ], + "summary": "Returns the debt positions upload report.", + "operationId": "get-debt-positions-upload-report", + "parameters": [ + { + "name": "broker-code", + "in": "path", + "description": "The broker code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "organization-fiscal-code", + "in": "path", + "description": "The organization fiscal code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "file-id", + "in": "path", + "description": "The unique identifier for file upload", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } } - } ], - "responses" : { - "200" : { - "description" : "Upload report found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UploadReport" + ], + "responses": { + "200": { + "description": "Upload report found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UploadReport" } } } }, - "400" : { - "description" : "Malformed request.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "400": { + "description": "Malformed request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "401" : { - "description" : "Wrong or missing function key.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "401": { + "description": "Wrong or missing function key.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "403" : { - "description" : "Forbidden", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "404" : { - "description" : "Upload report not found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "404": { + "description": "Upload report not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "429" : { - "description" : "Too many requests.", - "content" : { - "text/json" : { } + "429": { + "description": "Too many requests.", + "content": { + "text/json": {} } }, - "500" : { - "description" : "Service unavailable.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "500": { + "description": "Service unavailable.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } } }, - "security" : [ { - "ApiKey" : [ ] - }, { - "Authorization" : [ ] - } ] + "security": [ + { + "ApiKey": [] + }, + { + "Authorization": [] + } + ] } }, - "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/status" : { - "get" : { - "tags" : [ "Upload Status API" ], - "summary" : "Returns the debt positions upload status.", - "operationId" : "get-debt-positions-upload-status", - "parameters" : [ { - "name" : "broker-code", - "in" : "path", - "description" : "The broker code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" - } - }, { - "name" : "organization-fiscal-code", - "in" : "path", - "description" : "The organization fiscal code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" - } - }, { - "name" : "file-id", - "in" : "path", - "description" : "The unique identifier for file upload", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/status": { + "get": { + "tags": [ + "Upload Status API" + ], + "summary": "Returns the debt positions upload status.", + "operationId": "get-debt-positions-upload-status", + "parameters": [ + { + "name": "broker-code", + "in": "path", + "description": "The broker code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "organization-fiscal-code", + "in": "path", + "description": "The organization fiscal code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "file-id", + "in": "path", + "description": "The unique identifier for file upload", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } } - } ], - "responses" : { - "200" : { - "description" : "Upload found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UploadStatus" + ], + "responses": { + "200": { + "description": "Upload found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UploadStatus" } } } }, - "400" : { - "description" : "Malformed request.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "400": { + "description": "Malformed request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "401" : { - "description" : "Wrong or missing function key.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "401": { + "description": "Wrong or missing function key.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "403" : { - "description" : "Forbidden", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "404" : { - "description" : "Upload not found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "404": { + "description": "Upload not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "429" : { - "description" : "Too many requests.", - "content" : { - "text/json" : { } + "429": { + "description": "Too many requests.", + "content": { + "text/json": {} } }, - "500" : { - "description" : "Service unavailable.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "500": { + "description": "Service unavailable.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } } }, - "security" : [ { - "ApiKey" : [ ] - }, { - "Authorization" : [ ] - } ] + "security": [ + { + "ApiKey": [] + }, + { + "Authorization": [] + } + ] } }, - "/info" : { - "get" : { - "tags" : [ "Health check" ], - "summary" : "health check", - "description" : "Return OK if application is started", - "operationId" : "healthCheck", - "responses" : { - "200" : { - "description" : "OK", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/AppInfo" + "/info": { + "get": { + "tags": [ + "Health check" + ], + "summary": "health check", + "description": "Return OK if application is started", + "operationId": "healthCheck", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AppInfo" } } } }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "403" : { - "description" : "Forbidden", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "429" : { - "description" : "Too many requests.", - "content" : { - "text/json" : { } + "429": { + "description": "Too many requests.", + "content": { + "text/json": {} } }, - "500" : { - "description" : "Service unavailable", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "500": { + "description": "Service unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } @@ -635,79 +679,83 @@ } } }, - "/support/uploads/{upload}/status/refresh" : { - "get" : { - "tags" : [ "Support API" ], - "summary" : "Support API to recover status on CREATE operation", - "description" : "Returns the debt positions upload report recovered.", - "operationId" : "recoverStatus", - "parameters" : [ { - "name" : "upload", - "in" : "path", - "description" : "The unique identifier for file upload", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + "/support/uploads/{upload}/status/refresh": { + "get": { + "tags": [ + "Support API" + ], + "summary": "Support API to recover status on CREATE operation", + "description": "Returns the debt positions upload report recovered.", + "operationId": "recoverStatus", + "parameters": [ + { + "name": "upload", + "in": "path", + "description": "The unique identifier for file upload", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } } - } ], - "responses" : { - "200" : { - "description" : "OK", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/AppInfo" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AppInfo" } } } }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "403" : { - "description" : "Forbidden", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "429" : { - "description" : "Too many requests.", - "content" : { - "text/json" : { } + "429": { + "description": "Too many requests.", + "content": { + "text/json": {} } }, - "500" : { - "description" : "Service unavailable", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "500": { + "description": "Service unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } @@ -716,122 +764,125 @@ } } }, - "components" : { - "schemas" : { - "AppInfo" : { - "type" : "object", - "properties" : { - "name" : { - "type" : "string" - }, - "version" : { - "type" : "string" - }, - "environment" : { - "type" : "string" + "components": { + "schemas": { + "AppInfo": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "environment": { + "type": "string" } } }, - "ProblemJson" : { - "type" : "object", - "properties" : { - "title" : { - "type" : "string", - "description" : "A short, summary of the problem type. Written in english and readable for engineers (usually not suited for non technical stakeholders and not localized); example: Service Unavailable" - }, - "status" : { - "type" : "integer", - "description" : "The HTTP status code generated by the origin server for this occurrence of the problem.", - "format" : "int32", - "example" : 200 - }, - "detail" : { - "type" : "string", - "description" : "A human readable explanation specific to this occurrence of the problem.", - "example" : "There was an error processing the request" + "ProblemJson": { + "type": "object", + "properties": { + "title": { + "type": "string", + "description": "A short, summary of the problem type. Written in english and readable for engineers (usually not suited for non technical stakeholders and not localized); example: Service Unavailable" + }, + "status": { + "type": "integer", + "description": "The HTTP status code generated by the origin server for this occurrence of the problem.", + "format": "int32", + "example": 200 + }, + "detail": { + "type": "string", + "description": "A human readable explanation specific to this occurrence of the problem.", + "example": "There was an error processing the request" } } }, - "ResponseEntry" : { - "type" : "object", - "properties" : { - "statusCode" : { - "type" : "integer", - "format" : "int32", - "example" : 400 - }, - "statusMessage" : { - "type" : "string", - "example" : "Bad request caused by invalid email address" - }, - "requestIDs" : { - "type" : "array", - "items" : { - "type" : "string" + "ResponseEntry": { + "type": "object", + "properties": { + "statusCode": { + "type": "integer", + "format": "int32", + "example": 400 + }, + "statusMessage": { + "type": "string", + "example": "Bad request caused by invalid email address" + }, + "requestIDs": { + "type": "array", + "items": { + "type": "string" } } } }, - "UploadReport" : { - "type" : "object", - "properties" : { - "uploadID" : { - "type" : "string" - }, - "processedItem" : { - "type" : "integer", - "format" : "int32" - }, - "submittedItem" : { - "type" : "integer", - "format" : "int32" - }, - "responses" : { - "type" : "array", - "items" : { - "$ref" : "#/components/schemas/ResponseEntry" - } - }, - "startTime" : { - "type" : "string", - "format" : "date-time", - "example" : "2024-10-08T14:55:16.302Z" - }, - "endTime" : { - "type" : "string", - "format" : "date-time", - "example" : "2024-10-08T14:55:16.302Z" + "UploadReport": { + "type": "object", + "properties": { + "uploadID": { + "type": "string" + }, + "processedItem": { + "type": "integer", + "format": "int32" + }, + "submittedItem": { + "type": "integer", + "format": "int32" + }, + "responses": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ResponseEntry" + } + }, + "startTime": { + "type": "string", + "format": "date-time", + "example": "2024-10-08T14:55:16.302Z" + }, + "endTime": { + "type": "string", + "format": "date-time", + "example": "2024-10-08T14:55:16.302Z" } } }, - "UploadStatus" : { - "type" : "object", - "properties" : { - "uploadID" : { - "type" : "string" - }, - "processedItem" : { - "type" : "integer", - "format" : "int32" - }, - "submittedItem" : { - "type" : "integer", - "format" : "int32" - }, - "startTime" : { - "type" : "string", - "format" : "date-time", - "example" : "2024-10-08T14:55:16.302Z" + "UploadStatus": { + "type": "object", + "properties": { + "uploadID": { + "type": "string" + }, + "processedItem": { + "type": "integer", + "format": "int32" + }, + "submittedItem": { + "type": "integer", + "format": "int32" + }, + "startTime": { + "type": "string", + "format": "date-time", + "example": "2024-10-08T14:55:16.302Z" } } } }, - "securitySchemes" : { - "Ocp-Apim-Subscription-Key" : { - "type" : "apiKey", - "name" : "Ocp-Apim-Subscription-Key", - "in" : "header" + "securitySchemes": { + "Ocp-Apim-Subscription-Key": { + "type": "apiKey", + "name": "Ocp-Apim-Subscription-Key", + "in": "header" } } + }, + "info": { + "version": "0.1.32-2-recover-delete-operation-status" } -} \ No newline at end of file +} diff --git a/openapi/openapi.json b/openapi/openapi.json index 6ed6089..91a250f 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -1,633 +1,677 @@ { - "openapi" : "3.0.1", - "paths" : { - "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file" : { - "put" : { - "tags" : [ "Debt Positions CRUD via file upload API" ], - "summary" : "The Organization updates the debt positions listed in the file.", - "operationId" : "update-debt-positions-by-file-upload", - "parameters" : [ { - "name" : "broker-code", - "in" : "path", - "description" : "The broker code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" - } - }, { - "name" : "organization-fiscal-code", - "in" : "path", - "description" : "The organization fiscal code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + "openapi": "3.0.1", + "paths": { + "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file": { + "put": { + "tags": [ + "Debt Positions CRUD via file upload API" + ], + "summary": "The Organization updates the debt positions listed in the file.", + "operationId": "update-debt-positions-by-file-upload", + "parameters": [ + { + "name": "broker-code", + "in": "path", + "description": "The broker code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "organization-fiscal-code", + "in": "path", + "description": "The organization fiscal code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } } - } ], - "requestBody" : { - "content" : { - "multipart/form-data" : { - "schema" : { - "type" : "object", - "properties" : { - "file" : { - "type" : "string", - "description" : "File to be uploaded", - "format" : "binary" + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "file": { + "type": "string", + "description": "File to be uploaded", + "format": "binary" } } }, - "encoding" : { - "file" : { - "contentType" : "application/octet-stream" + "encoding": { + "file": { + "contentType": "application/octet-stream" } } } }, - "required" : true + "required": true }, - "responses" : { - "202" : { - "description" : "Request accepted." + "responses": { + "202": { + "description": "Request accepted." }, - "400" : { - "description" : "Malformed request.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "400": { + "description": "Malformed request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "401" : { - "description" : "Wrong or missing function key.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "401": { + "description": "Wrong or missing function key.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "403" : { - "description" : "Forbidden", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "409" : { - "description" : "Conflict: duplicate file found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "409": { + "description": "Conflict: duplicate file found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "429" : { - "description" : "Too many requests.", - "content" : { - "text/json" : { } + "429": { + "description": "Too many requests.", + "content": { + "text/json": {} } }, - "500" : { - "description" : "Service unavailable.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "500": { + "description": "Service unavailable.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } } }, - "security" : [ { - "ApiKey" : [ ] - }, { - "Authorization" : [ ] - } ] - }, - "post" : { - "tags" : [ "Debt Positions CRUD via file upload API" ], - "summary" : "The Organization creates the debt positions listed in the file.", - "operationId" : "create-debt-positions-by-file-upload", - "parameters" : [ { - "name" : "broker-code", - "in" : "path", - "description" : "The broker code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + "security": [ + { + "ApiKey": [] + }, + { + "Authorization": [] } - }, { - "name" : "organization-fiscal-code", - "in" : "path", - "description" : "The organization fiscal code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + ] + }, + "post": { + "tags": [ + "Debt Positions CRUD via file upload API" + ], + "summary": "The Organization creates the debt positions listed in the file.", + "operationId": "create-debt-positions-by-file-upload", + "parameters": [ + { + "name": "broker-code", + "in": "path", + "description": "The broker code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "organization-fiscal-code", + "in": "path", + "description": "The organization fiscal code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } } - } ], - "requestBody" : { - "content" : { - "multipart/form-data" : { - "schema" : { - "type" : "object", - "properties" : { - "file" : { - "type" : "string", - "description" : "File to be uploaded", - "format" : "binary" + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "file": { + "type": "string", + "description": "File to be uploaded", + "format": "binary" } } }, - "encoding" : { - "file" : { - "contentType" : "application/octet-stream" + "encoding": { + "file": { + "contentType": "application/octet-stream" } } } }, - "required" : true + "required": true }, - "responses" : { - "202" : { - "description" : "Request accepted." + "responses": { + "202": { + "description": "Request accepted." }, - "400" : { - "description" : "Malformed request.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "400": { + "description": "Malformed request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "401" : { - "description" : "Wrong or missing function key.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "401": { + "description": "Wrong or missing function key.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "403" : { - "description" : "Forbidden", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "409" : { - "description" : "Conflict: duplicate file found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "409": { + "description": "Conflict: duplicate file found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "429" : { - "description" : "Too many requests.", - "content" : { - "text/json" : { } + "429": { + "description": "Too many requests.", + "content": { + "text/json": {} } }, - "500" : { - "description" : "Service unavailable.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "500": { + "description": "Service unavailable.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } } }, - "security" : [ { - "ApiKey" : [ ] - }, { - "Authorization" : [ ] - } ] - }, - "delete" : { - "tags" : [ "Debt Positions CRUD via file upload API" ], - "summary" : "The Organization deletes the debt positions based on IUPD listed in the file.", - "operationId" : "delete-debt-positions-by-file-upload", - "parameters" : [ { - "name" : "broker-code", - "in" : "path", - "description" : "The broker code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + "security": [ + { + "ApiKey": [] + }, + { + "Authorization": [] } - }, { - "name" : "organization-fiscal-code", - "in" : "path", - "description" : "The organization fiscal code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + ] + }, + "delete": { + "tags": [ + "Debt Positions CRUD via file upload API" + ], + "summary": "The Organization deletes the debt positions based on IUPD listed in the file.", + "operationId": "delete-debt-positions-by-file-upload", + "parameters": [ + { + "name": "broker-code", + "in": "path", + "description": "The broker code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "organization-fiscal-code", + "in": "path", + "description": "The organization fiscal code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } } - } ], - "requestBody" : { - "content" : { - "multipart/form-data" : { - "schema" : { - "type" : "object", - "properties" : { - "file" : { - "type" : "string", - "description" : "File to be uploaded", - "format" : "binary" + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "file": { + "type": "string", + "description": "File to be uploaded", + "format": "binary" } } }, - "encoding" : { - "file" : { - "contentType" : "application/octet-stream" + "encoding": { + "file": { + "contentType": "application/octet-stream" } } } }, - "required" : true + "required": true }, - "responses" : { - "202" : { - "description" : "Request accepted." + "responses": { + "202": { + "description": "Request accepted." }, - "400" : { - "description" : "Malformed request.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "400": { + "description": "Malformed request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "401" : { - "description" : "Wrong or missing function key.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "401": { + "description": "Wrong or missing function key.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "403" : { - "description" : "Forbidden", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "409" : { - "description" : "Conflict: duplicate file found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "409": { + "description": "Conflict: duplicate file found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "429" : { - "description" : "Too many requests.", - "content" : { - "text/json" : { } + "429": { + "description": "Too many requests.", + "content": { + "text/json": {} } }, - "500" : { - "description" : "Service unavailable.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "500": { + "description": "Service unavailable.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } } }, - "security" : [ { - "ApiKey" : [ ] - }, { - "Authorization" : [ ] - } ] + "security": [ + { + "ApiKey": [] + }, + { + "Authorization": [] + } + ] } }, - "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/report" : { - "get" : { - "tags" : [ "Upload Status API" ], - "summary" : "Returns the debt positions upload report.", - "operationId" : "get-debt-positions-upload-report", - "parameters" : [ { - "name" : "broker-code", - "in" : "path", - "description" : "The broker code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" - } - }, { - "name" : "organization-fiscal-code", - "in" : "path", - "description" : "The organization fiscal code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" - } - }, { - "name" : "file-id", - "in" : "path", - "description" : "The unique identifier for file upload", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/report": { + "get": { + "tags": [ + "Upload Status API" + ], + "summary": "Returns the debt positions upload report.", + "operationId": "get-debt-positions-upload-report", + "parameters": [ + { + "name": "broker-code", + "in": "path", + "description": "The broker code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "organization-fiscal-code", + "in": "path", + "description": "The organization fiscal code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "file-id", + "in": "path", + "description": "The unique identifier for file upload", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } } - } ], - "responses" : { - "200" : { - "description" : "Upload report found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UploadReport" + ], + "responses": { + "200": { + "description": "Upload report found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UploadReport" } } } }, - "400" : { - "description" : "Malformed request.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "400": { + "description": "Malformed request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "401" : { - "description" : "Wrong or missing function key.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "401": { + "description": "Wrong or missing function key.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "403" : { - "description" : "Forbidden", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "404" : { - "description" : "Upload report not found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "404": { + "description": "Upload report not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "429" : { - "description" : "Too many requests.", - "content" : { - "text/json" : { } + "429": { + "description": "Too many requests.", + "content": { + "text/json": {} } }, - "500" : { - "description" : "Service unavailable.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "500": { + "description": "Service unavailable.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } } }, - "security" : [ { - "ApiKey" : [ ] - }, { - "Authorization" : [ ] - } ] + "security": [ + { + "ApiKey": [] + }, + { + "Authorization": [] + } + ] } }, - "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/status" : { - "get" : { - "tags" : [ "Upload Status API" ], - "summary" : "Returns the debt positions upload status.", - "operationId" : "get-debt-positions-upload-status", - "parameters" : [ { - "name" : "broker-code", - "in" : "path", - "description" : "The broker code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" - } - }, { - "name" : "organization-fiscal-code", - "in" : "path", - "description" : "The organization fiscal code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" - } - }, { - "name" : "file-id", - "in" : "path", - "description" : "The unique identifier for file upload", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/status": { + "get": { + "tags": [ + "Upload Status API" + ], + "summary": "Returns the debt positions upload status.", + "operationId": "get-debt-positions-upload-status", + "parameters": [ + { + "name": "broker-code", + "in": "path", + "description": "The broker code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "organization-fiscal-code", + "in": "path", + "description": "The organization fiscal code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "file-id", + "in": "path", + "description": "The unique identifier for file upload", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } } - } ], - "responses" : { - "200" : { - "description" : "Upload found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UploadStatus" + ], + "responses": { + "200": { + "description": "Upload found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UploadStatus" } } } }, - "400" : { - "description" : "Malformed request.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "400": { + "description": "Malformed request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "401" : { - "description" : "Wrong or missing function key.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "401": { + "description": "Wrong or missing function key.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "403" : { - "description" : "Forbidden", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "404" : { - "description" : "Upload not found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "404": { + "description": "Upload not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "429" : { - "description" : "Too many requests.", - "content" : { - "text/json" : { } + "429": { + "description": "Too many requests.", + "content": { + "text/json": {} } }, - "500" : { - "description" : "Service unavailable.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "500": { + "description": "Service unavailable.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } } }, - "security" : [ { - "ApiKey" : [ ] - }, { - "Authorization" : [ ] - } ] + "security": [ + { + "ApiKey": [] + }, + { + "Authorization": [] + } + ] } }, - "/info" : { - "get" : { - "tags" : [ "Health check" ], - "summary" : "health check", - "description" : "Return OK if application is started", - "operationId" : "healthCheck", - "responses" : { - "200" : { - "description" : "OK", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/AppInfo" + "/info": { + "get": { + "tags": [ + "Health check" + ], + "summary": "health check", + "description": "Return OK if application is started", + "operationId": "healthCheck", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AppInfo" } } } }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "403" : { - "description" : "Forbidden", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "429" : { - "description" : "Too many requests.", - "content" : { - "text/json" : { } + "429": { + "description": "Too many requests.", + "content": { + "text/json": {} } }, - "500" : { - "description" : "Service unavailable", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "500": { + "description": "Service unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } @@ -635,79 +679,83 @@ } } }, - "/support/uploads/{upload}/status/refresh" : { - "get" : { - "tags" : [ "Support API" ], - "summary" : "Support API to recover status on CREATE operation", - "description" : "Returns the debt positions upload report recovered.", - "operationId" : "recoverStatus", - "parameters" : [ { - "name" : "upload", - "in" : "path", - "description" : "The unique identifier for file upload", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + "/support/uploads/{upload}/status/refresh": { + "get": { + "tags": [ + "Support API" + ], + "summary": "Support API to recover status on CREATE operation", + "description": "Returns the debt positions upload report recovered.", + "operationId": "recoverStatus", + "parameters": [ + { + "name": "upload", + "in": "path", + "description": "The unique identifier for file upload", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } } - } ], - "responses" : { - "200" : { - "description" : "OK", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/AppInfo" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AppInfo" } } } }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "403" : { - "description" : "Forbidden", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "429" : { - "description" : "Too many requests.", - "content" : { - "text/json" : { } + "429": { + "description": "Too many requests.", + "content": { + "text/json": {} } }, - "500" : { - "description" : "Service unavailable", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "500": { + "description": "Service unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } @@ -716,122 +764,125 @@ } } }, - "components" : { - "schemas" : { - "AppInfo" : { - "type" : "object", - "properties" : { - "name" : { - "type" : "string" - }, - "version" : { - "type" : "string" - }, - "environment" : { - "type" : "string" + "components": { + "schemas": { + "AppInfo": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "environment": { + "type": "string" } } }, - "ProblemJson" : { - "type" : "object", - "properties" : { - "title" : { - "type" : "string", - "description" : "A short, summary of the problem type. Written in english and readable for engineers (usually not suited for non technical stakeholders and not localized); example: Service Unavailable" - }, - "status" : { - "type" : "integer", - "description" : "The HTTP status code generated by the origin server for this occurrence of the problem.", - "format" : "int32", - "example" : 200 - }, - "detail" : { - "type" : "string", - "description" : "A human readable explanation specific to this occurrence of the problem.", - "example" : "There was an error processing the request" + "ProblemJson": { + "type": "object", + "properties": { + "title": { + "type": "string", + "description": "A short, summary of the problem type. Written in english and readable for engineers (usually not suited for non technical stakeholders and not localized); example: Service Unavailable" + }, + "status": { + "type": "integer", + "description": "The HTTP status code generated by the origin server for this occurrence of the problem.", + "format": "int32", + "example": 200 + }, + "detail": { + "type": "string", + "description": "A human readable explanation specific to this occurrence of the problem.", + "example": "There was an error processing the request" } } }, - "ResponseEntry" : { - "type" : "object", - "properties" : { - "statusCode" : { - "type" : "integer", - "format" : "int32", - "example" : 400 - }, - "statusMessage" : { - "type" : "string", - "example" : "Bad request caused by invalid email address" - }, - "requestIDs" : { - "type" : "array", - "items" : { - "type" : "string" + "ResponseEntry": { + "type": "object", + "properties": { + "statusCode": { + "type": "integer", + "format": "int32", + "example": 400 + }, + "statusMessage": { + "type": "string", + "example": "Bad request caused by invalid email address" + }, + "requestIDs": { + "type": "array", + "items": { + "type": "string" } } } }, - "UploadReport" : { - "type" : "object", - "properties" : { - "uploadID" : { - "type" : "string" - }, - "processedItem" : { - "type" : "integer", - "format" : "int32" - }, - "submittedItem" : { - "type" : "integer", - "format" : "int32" - }, - "responses" : { - "type" : "array", - "items" : { - "$ref" : "#/components/schemas/ResponseEntry" - } - }, - "startTime" : { - "type" : "string", - "format" : "date-time", - "example" : "2024-10-08T14:55:16.302Z" - }, - "endTime" : { - "type" : "string", - "format" : "date-time", - "example" : "2024-10-08T14:55:16.302Z" + "UploadReport": { + "type": "object", + "properties": { + "uploadID": { + "type": "string" + }, + "processedItem": { + "type": "integer", + "format": "int32" + }, + "submittedItem": { + "type": "integer", + "format": "int32" + }, + "responses": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ResponseEntry" + } + }, + "startTime": { + "type": "string", + "format": "date-time", + "example": "2024-10-08T14:55:16.302Z" + }, + "endTime": { + "type": "string", + "format": "date-time", + "example": "2024-10-08T14:55:16.302Z" } } }, - "UploadStatus" : { - "type" : "object", - "properties" : { - "uploadID" : { - "type" : "string" - }, - "processedItem" : { - "type" : "integer", - "format" : "int32" - }, - "submittedItem" : { - "type" : "integer", - "format" : "int32" - }, - "startTime" : { - "type" : "string", - "format" : "date-time", - "example" : "2024-10-08T14:55:16.302Z" + "UploadStatus": { + "type": "object", + "properties": { + "uploadID": { + "type": "string" + }, + "processedItem": { + "type": "integer", + "format": "int32" + }, + "submittedItem": { + "type": "integer", + "format": "int32" + }, + "startTime": { + "type": "string", + "format": "date-time", + "example": "2024-10-08T14:55:16.302Z" } } } }, - "securitySchemes" : { - "Ocp-Apim-Subscription-Key" : { - "type" : "apiKey", - "name" : "Ocp-Apim-Subscription-Key", - "in" : "header" + "securitySchemes": { + "Ocp-Apim-Subscription-Key": { + "type": "apiKey", + "name": "Ocp-Apim-Subscription-Key", + "in": "header" } } + }, + "info": { + "version": "0.1.32-2-recover-delete-operation-status" } -} \ No newline at end of file +} diff --git a/pom.xml b/pom.xml index 1b350a3..b21d47b 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 it.gov.pagopa.gpd.upload pagopa-gpd-upload - 0.1.32-1-recover-delete-operation-status + 0.1.32-2-recover-delete-operation-status ${packaging} From 7ba9905e0dae6bdfc0a9d020202015980aefa023 Mon Sep 17 00:00:00 2001 From: Angelo Caporaso <56113767+cap-ang@users.noreply.github.com> Date: Thu, 28 Nov 2024 15:03:22 +0100 Subject: [PATCH 06/19] [PAGOPA-2426] test(Support-API): JUnit --- .../pagopa/gpd/upload/utils/GPDValidator.java | 2 +- .../controller/FileUploadControllerTest.java | 5 +- .../controller/SupportControllerTest.java | 83 +++++++++++++++++++ 3 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 src/test/java/it/gov/pagopa/gpd/upload/controller/SupportControllerTest.java diff --git a/src/main/java/it/gov/pagopa/gpd/upload/utils/GPDValidator.java b/src/main/java/it/gov/pagopa/gpd/upload/utils/GPDValidator.java index 65a8fc9..b5a7e7f 100644 --- a/src/main/java/it/gov/pagopa/gpd/upload/utils/GPDValidator.java +++ b/src/main/java/it/gov/pagopa/gpd/upload/utils/GPDValidator.java @@ -33,7 +33,7 @@ public boolean isValid(T model) throws IOException { invalidValues.add(cv.getMessage()); } throw new AppException(HttpStatus.BAD_REQUEST, "INVALID DEBT POSITIONS", - "The format of the debt positions in the uploaded file is invalid. Invalid values: " + invalidValues); + "Debt positions format is invalid or duplicates were found. Invalid values: " + invalidValues); } log.debug("[GPDValidator@isValid] PaymentPosition with id {} validated", model.hashCode()); diff --git a/src/test/java/it/gov/pagopa/gpd/upload/controller/FileUploadControllerTest.java b/src/test/java/it/gov/pagopa/gpd/upload/controller/FileUploadControllerTest.java index 69c2c19..c46d2de 100644 --- a/src/test/java/it/gov/pagopa/gpd/upload/controller/FileUploadControllerTest.java +++ b/src/test/java/it/gov/pagopa/gpd/upload/controller/FileUploadControllerTest.java @@ -109,6 +109,10 @@ void getUploadStatus_KO() throws IOException { assertEquals(OK, response.getStatus()); } + //////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////MOCK////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////// + @Bean @Primary public BlobService fileUploadService() throws IOException { @@ -125,7 +129,6 @@ public StatusService statusService() throws IOException { return statusService; } - // real repositories are out of scope for this test, @PostConstruct init routine requires connection-string @Bean @Primary diff --git a/src/test/java/it/gov/pagopa/gpd/upload/controller/SupportControllerTest.java b/src/test/java/it/gov/pagopa/gpd/upload/controller/SupportControllerTest.java new file mode 100644 index 0000000..c8e943c --- /dev/null +++ b/src/test/java/it/gov/pagopa/gpd/upload/controller/SupportControllerTest.java @@ -0,0 +1,83 @@ +package it.gov.pagopa.gpd.upload.controller; + +import io.micronaut.context.annotation.Bean; +import io.micronaut.context.annotation.Primary; +import io.micronaut.http.HttpMethod; +import io.micronaut.http.HttpRequest; +import io.micronaut.http.HttpResponse; +import io.micronaut.http.client.HttpClient; +import io.micronaut.http.client.annotation.Client; +import io.micronaut.http.client.exceptions.HttpClientException; +import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import it.gov.pagopa.gpd.upload.model.UploadReport; +import it.gov.pagopa.gpd.upload.repository.BlobStorageRepository; +import it.gov.pagopa.gpd.upload.repository.StatusRepository; +import it.gov.pagopa.gpd.upload.service.RecoveryService; +import it.gov.pagopa.gpd.upload.service.StatusService; +import jakarta.inject.Inject; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import java.io.IOException; + +import static io.micronaut.http.HttpStatus.OK; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.anyString; + +@MicronautTest +public class SupportControllerTest { + + private static final String URI = "support/uploads/broker_organization_uid/status/refresh"; + private static final String BAD_URI = "support/uploads/broker-organization-uid/status/refresh"; + + @Inject + @Client("/") + HttpClient client; + + @Test + void recoverStatus_OK() { + HttpRequest httpRequest = HttpRequest.create(HttpMethod.GET, URI); + HttpResponse response = client.toBlocking().exchange(httpRequest); + + assertNotNull(response); + assertEquals(OK, response.getStatus()); + } + + @Test + void recoverStatus_KO() { + HttpRequest httpRequest = HttpRequest.create(HttpMethod.GET, BAD_URI); + assertThrows(HttpClientException.class, () -> client.toBlocking().exchange(httpRequest)); + } + + //////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////MOCK////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////// + + @Bean + @Primary + public StatusService statusService() throws IOException { + StatusService statusService = Mockito.mock(StatusService.class); + Mockito.when(statusService.getReport(anyString(), anyString())).thenReturn(UploadReport.builder().build()); + return statusService; + } + + @Bean + @Primary + public RecoveryService recoveryService() { + RecoveryService recoveryService = Mockito.mock(RecoveryService.class); + Mockito.doNothing().when(recoveryService).recover(anyString(), anyString(), anyString()); + return recoveryService; + } + + // real repositories are out of scope for this test, @PostConstruct init routine requires connection-string + @Bean + @Primary + public StatusRepository statusRepository() { + return Mockito.mock(StatusRepository.class); + } + @Bean + @Primary + public BlobStorageRepository blobStorageRepository() { + return Mockito.mock(BlobStorageRepository.class); + } +} From 8a72a312f68a8936cedba4d613287520dc3af700 Mon Sep 17 00:00:00 2001 From: Angelo Caporaso <56113767+cap-ang@users.noreply.github.com> Date: Thu, 28 Nov 2024 16:24:40 +0100 Subject: [PATCH 07/19] [PAGOPA-2426] test(RecoveryService): JUnit --- .../duplicate/NoDuplicateValidator.java | 4 +- .../gpd/upload/service/RecoveryService.java | 29 ++-- .../upload/service/RecoveryServiceTest.java | 136 ++++++++++++++++++ 3 files changed, 154 insertions(+), 15 deletions(-) create mode 100644 src/test/java/it/gov/pagopa/gpd/upload/service/RecoveryServiceTest.java diff --git a/src/main/java/it/gov/pagopa/gpd/upload/config/duplicate/NoDuplicateValidator.java b/src/main/java/it/gov/pagopa/gpd/upload/config/duplicate/NoDuplicateValidator.java index 5955097..4bf697c 100644 --- a/src/main/java/it/gov/pagopa/gpd/upload/config/duplicate/NoDuplicateValidator.java +++ b/src/main/java/it/gov/pagopa/gpd/upload/config/duplicate/NoDuplicateValidator.java @@ -3,6 +3,7 @@ import jakarta.validation.ConstraintValidator; import jakarta.validation.ConstraintValidatorContext; +import lombok.extern.slf4j.Slf4j; import java.lang.reflect.Field; import java.util.HashSet; @@ -10,6 +11,7 @@ import java.util.Objects; import java.util.Set; +@Slf4j public class NoDuplicateValidator implements ConstraintValidator> { private String fieldName; @@ -40,7 +42,7 @@ public boolean isValid(List list, ConstraintValidatorContext context) { return false; } } catch (NoSuchFieldException | IllegalAccessException e) { - e.printStackTrace(); + log.error("Exception while detect duplicates: {}, cause: {}", e.getMessage(), e.getCause().getMessage()); return false; } } diff --git a/src/main/java/it/gov/pagopa/gpd/upload/service/RecoveryService.java b/src/main/java/it/gov/pagopa/gpd/upload/service/RecoveryService.java index ed3a172..c485663 100644 --- a/src/main/java/it/gov/pagopa/gpd/upload/service/RecoveryService.java +++ b/src/main/java/it/gov/pagopa/gpd/upload/service/RecoveryService.java @@ -7,6 +7,7 @@ import it.gov.pagopa.gpd.upload.entity.Status; import it.gov.pagopa.gpd.upload.exception.AppException; import it.gov.pagopa.gpd.upload.model.UploadInput; +import it.gov.pagopa.gpd.upload.model.UploadOperation; import it.gov.pagopa.gpd.upload.model.pd.PaymentPositionModel; import jakarta.inject.Inject; import jakarta.inject.Singleton; @@ -30,29 +31,28 @@ public RecoveryService(StatusService statusService, BlobService blobService, GPD this.gpdClient = gpdClient; } - public void recover(String brokerId, String organizationFiscalCode, String uploadId) { + public boolean recover(String brokerId, String organizationFiscalCode, String uploadId) { UploadInput uploadInput = blobService.getUploadInput(brokerId, organizationFiscalCode, uploadId); List inputIUPD; - switch (uploadInput.getUploadOperation()) { - case CREATE: - inputIUPD = uploadInput.getPaymentPositions().stream().map(PaymentPositionModel::getIupd).toList(); - recover(organizationFiscalCode, uploadId, inputIUPD, HttpStatus.OK, HttpStatus.CREATED); - case DELETE: - inputIUPD = uploadInput.getPaymentPositionIUPDs(); - recover(organizationFiscalCode, uploadId, inputIUPD, HttpStatus.NOT_FOUND, HttpStatus.NOT_FOUND); - default: - throw new AppException(HttpStatus.NOT_FOUND, - "Upload operation not processable", String.format("Not exists CREATE or DELETE operation with upload-id %s", uploadId)); + if(uploadInput.getUploadOperation().equals(UploadOperation.CREATE)) { + inputIUPD = uploadInput.getPaymentPositions().stream().map(PaymentPositionModel::getIupd).toList(); + return recover(organizationFiscalCode, uploadId, inputIUPD, HttpStatus.OK, HttpStatus.CREATED); + } else if(uploadInput.getUploadOperation().equals(UploadOperation.DELETE)) { + inputIUPD = uploadInput.getPaymentPositionIUPDs(); + return recover(organizationFiscalCode, uploadId, inputIUPD, HttpStatus.NOT_FOUND, HttpStatus.NOT_FOUND); + } else { + throw new AppException(HttpStatus.NOT_FOUND, "Upload operation not processable", + String.format("Not exists CREATE or DELETE operation with upload-id %s", uploadId)); } } - private Status recover(String organizationFiscalCode, String uploadId, List inputIUPD, HttpStatus toGetFromGPD, HttpStatus toWrite) { + private boolean recover(String organizationFiscalCode, String uploadId, List inputIUPD, HttpStatus toGetFromGPD, HttpStatus toWrite) { Status current = statusService.getStatus(organizationFiscalCode, uploadId); // check if upload is pending if(current.upload.getCurrent() >= current.upload.getTotal()) - return current; + return false; // extract debt position id list List processedIUPD = new ArrayList<>(); @@ -77,7 +77,8 @@ private Status recover(String organizationFiscalCode, String uploadId, List inputIUPD, List processedIUPD, HttpStatus target) { diff --git a/src/test/java/it/gov/pagopa/gpd/upload/service/RecoveryServiceTest.java b/src/test/java/it/gov/pagopa/gpd/upload/service/RecoveryServiceTest.java new file mode 100644 index 0000000..08b3b12 --- /dev/null +++ b/src/test/java/it/gov/pagopa/gpd/upload/service/RecoveryServiceTest.java @@ -0,0 +1,136 @@ +package it.gov.pagopa.gpd.upload.service; + +import io.micronaut.context.annotation.Bean; +import io.micronaut.context.annotation.Primary; +import io.micronaut.http.HttpResponse; +import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import it.gov.pagopa.gpd.upload.client.GPDClient; +import it.gov.pagopa.gpd.upload.entity.Status; +import it.gov.pagopa.gpd.upload.entity.Upload; +import it.gov.pagopa.gpd.upload.model.UploadInput; +import it.gov.pagopa.gpd.upload.model.UploadOperation; +import it.gov.pagopa.gpd.upload.model.pd.PaymentPositionModel; +import it.gov.pagopa.gpd.upload.repository.BlobStorageRepository; +import it.gov.pagopa.gpd.upload.repository.StatusRepository; +import jakarta.inject.Inject; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +import static org.mockito.ArgumentMatchers.*; + +@MicronautTest +public class RecoveryServiceTest { + + static final String CREATE_UPLOAD_ID = "upload-id-create"; + static final String DELETE_UPLOAD_ID = "upload-id-delete"; + + @Inject + RecoveryService recoveryService; + + @Test + void recover_CREATE_UPLOAD_OK() { + Assertions.assertTrue( + recoveryService.recover("broker", "organizaition", CREATE_UPLOAD_ID) + ); + } + + @Test + void recover_DELETE_UPLOAD_OK() { + Assertions.assertTrue( + recoveryService.recover("broker", "organizaition", DELETE_UPLOAD_ID) + ); + } + + //////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////MOCK////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////// + + // real repositories are out of scope for this test, @PostConstruct init routine requires connection-string + @Bean + @Primary + public static BlobStorageRepository blobStorageRepository() { + return Mockito.mock(BlobStorageRepository.class); + } + @Bean + @Primary + public static StatusRepository statusRepository() { + return Mockito.mock(StatusRepository.class); + } + @Bean + @Primary + public static BlobService blobService() { + BlobService blobService = Mockito.mock(BlobService.class); + UploadInput uploadInputDelete = UploadInput.builder() + .uploadOperation(UploadOperation.DELETE) + .paymentPositionIUPDs(List.of("IUPD-1")) + .build(); + UploadInput uploadInputCreate = UploadInput.builder() + .uploadOperation(UploadOperation.CREATE) + .paymentPositions(List.of(PaymentPositionModel.builder() + .iupd("IUPD-1").build())) + .build(); + Mockito.when(blobService.getUploadInput(anyString(), anyString(), eq(CREATE_UPLOAD_ID))).thenReturn(uploadInputCreate); + Mockito.when(blobService.getUploadInput(anyString(), anyString(), eq(DELETE_UPLOAD_ID))).thenReturn(uploadInputDelete); + return blobService; + } + @Bean + @Primary + public static StatusService statusService() { + StatusService statusService = Mockito.mock(StatusService.class); + Mockito.when(statusService.getStatus(anyString(), eq(DELETE_UPLOAD_ID))).thenReturn( + Status.builder() + .id("UPLOAD_KEY") + .brokerID("broker") + .fiscalCode("organization") + .upload(Upload.builder() + .current(0) + .total(1) + .responses(new ArrayList<>()) + .start(LocalDateTime.now().minusHours(1)) + .end(LocalDateTime.now()) + .build()) + .build() + ); + Mockito.when(statusService.getStatus(anyString(), eq(CREATE_UPLOAD_ID))).thenReturn( + Status.builder() + .id("UPLOAD_KEY") + .brokerID("broker") + .fiscalCode("organization") + .upload(Upload.builder() + .current(0) + .total(1) + .responses(new ArrayList<>()) + .start(LocalDateTime.now().minusHours(1)) + .end(LocalDateTime.now()) + .build()) + .build() + ); + Mockito.when(statusService.upsert(any())).thenReturn( + Status.builder() + .id("UPLOAD_KEY") + .brokerID("broker") + .fiscalCode("organization") + .upload(Upload.builder() + .current(1) + .total(1) + .start(LocalDateTime.now().minusHours(1)) + .end(LocalDateTime.now()) + .build()) + .build() + ); + return statusService; + } + @Bean + @Primary + public static GPDClient gpdClient() { + GPDClient gpdClient = Mockito.mock(GPDClient.class); + HttpResponse response = HttpResponse.notFound(); + Mockito.when(gpdClient.getDebtPosition(anyString(), anyString())).thenReturn(response); + return gpdClient; + } +} From c1e35ea3fafd925d2addc3bee351fec7dd6f2754 Mon Sep 17 00:00:00 2001 From: pagopa-github-bot Date: Thu, 28 Nov 2024 15:27:14 +0000 Subject: [PATCH 08/19] Bump to version 0.1.32-3-recover-delete-operation-status --- helm/Chart.yaml | 4 ++-- helm/values-dev.yaml | 2 +- helm/values-prod.yaml | 2 +- helm/values-uat.yaml | 2 +- openapi/openapi-support-internal.json | 2 +- openapi/openapi.json | 2 +- pom.xml | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/helm/Chart.yaml b/helm/Chart.yaml index 6ff0315..8ce95c3 100644 --- a/helm/Chart.yaml +++ b/helm/Chart.yaml @@ -2,8 +2,8 @@ apiVersion: v2 name: pagopa-gpd-upload description: Microservice that handles file upload of massive debt positions JSON object type: application -version: 0.108.0 -appVersion: 0.1.32-2-recover-delete-operation-status +version: 0.109.0 +appVersion: 0.1.32-3-recover-delete-operation-status dependencies: - name: microservice-chart version: 2.8.0 diff --git a/helm/values-dev.yaml b/helm/values-dev.yaml index e649cd5..91ee0c4 100644 --- a/helm/values-dev.yaml +++ b/helm/values-dev.yaml @@ -4,7 +4,7 @@ microservice-chart: fullnameOverride: "" image: repository: ghcr.io/pagopa/pagopa-gpd-upload - tag: "0.1.32-2-recover-delete-operation-status" + tag: "0.1.32-3-recover-delete-operation-status" pullPolicy: Always livenessProbe: httpGet: diff --git a/helm/values-prod.yaml b/helm/values-prod.yaml index e284786..6f9c62d 100644 --- a/helm/values-prod.yaml +++ b/helm/values-prod.yaml @@ -4,7 +4,7 @@ microservice-chart: fullnameOverride: "" image: repository: ghcr.io/pagopa/pagopa-gpd-upload - tag: "0.1.32-2-recover-delete-operation-status" + tag: "0.1.32-3-recover-delete-operation-status" pullPolicy: Always livenessProbe: httpGet: diff --git a/helm/values-uat.yaml b/helm/values-uat.yaml index 7d98810..dba8c25 100644 --- a/helm/values-uat.yaml +++ b/helm/values-uat.yaml @@ -4,7 +4,7 @@ microservice-chart: fullnameOverride: "" image: repository: ghcr.io/pagopa/pagopa-gpd-upload - tag: "0.1.32-2-recover-delete-operation-status" + tag: "0.1.32-3-recover-delete-operation-status" pullPolicy: Always livenessProbe: httpGet: diff --git a/openapi/openapi-support-internal.json b/openapi/openapi-support-internal.json index 91a250f..f75d96c 100644 --- a/openapi/openapi-support-internal.json +++ b/openapi/openapi-support-internal.json @@ -883,6 +883,6 @@ } }, "info": { - "version": "0.1.32-2-recover-delete-operation-status" + "version": "0.1.32-3-recover-delete-operation-status" } } diff --git a/openapi/openapi.json b/openapi/openapi.json index 91a250f..f75d96c 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -883,6 +883,6 @@ } }, "info": { - "version": "0.1.32-2-recover-delete-operation-status" + "version": "0.1.32-3-recover-delete-operation-status" } } diff --git a/pom.xml b/pom.xml index b21d47b..89e9ee4 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 it.gov.pagopa.gpd.upload pagopa-gpd-upload - 0.1.32-2-recover-delete-operation-status + 0.1.32-3-recover-delete-operation-status ${packaging} From c1f81bc79f5eb062845884ecc759de18f0b09653 Mon Sep 17 00:00:00 2001 From: pagopa-github-bot Date: Thu, 28 Nov 2024 16:16:20 +0000 Subject: [PATCH 09/19] Bump to version 0.1.32-4-recover-delete-operation-status --- helm/Chart.yaml | 4 ++-- helm/values-dev.yaml | 2 +- helm/values-prod.yaml | 2 +- helm/values-uat.yaml | 2 +- openapi/openapi-support-internal.json | 2 +- openapi/openapi.json | 2 +- pom.xml | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/helm/Chart.yaml b/helm/Chart.yaml index 8ce95c3..d9a4d58 100644 --- a/helm/Chart.yaml +++ b/helm/Chart.yaml @@ -2,8 +2,8 @@ apiVersion: v2 name: pagopa-gpd-upload description: Microservice that handles file upload of massive debt positions JSON object type: application -version: 0.109.0 -appVersion: 0.1.32-3-recover-delete-operation-status +version: 0.110.0 +appVersion: 0.1.32-4-recover-delete-operation-status dependencies: - name: microservice-chart version: 2.8.0 diff --git a/helm/values-dev.yaml b/helm/values-dev.yaml index 91ee0c4..81c9562 100644 --- a/helm/values-dev.yaml +++ b/helm/values-dev.yaml @@ -4,7 +4,7 @@ microservice-chart: fullnameOverride: "" image: repository: ghcr.io/pagopa/pagopa-gpd-upload - tag: "0.1.32-3-recover-delete-operation-status" + tag: "0.1.32-4-recover-delete-operation-status" pullPolicy: Always livenessProbe: httpGet: diff --git a/helm/values-prod.yaml b/helm/values-prod.yaml index 6f9c62d..469e41e 100644 --- a/helm/values-prod.yaml +++ b/helm/values-prod.yaml @@ -4,7 +4,7 @@ microservice-chart: fullnameOverride: "" image: repository: ghcr.io/pagopa/pagopa-gpd-upload - tag: "0.1.32-3-recover-delete-operation-status" + tag: "0.1.32-4-recover-delete-operation-status" pullPolicy: Always livenessProbe: httpGet: diff --git a/helm/values-uat.yaml b/helm/values-uat.yaml index dba8c25..a84074a 100644 --- a/helm/values-uat.yaml +++ b/helm/values-uat.yaml @@ -4,7 +4,7 @@ microservice-chart: fullnameOverride: "" image: repository: ghcr.io/pagopa/pagopa-gpd-upload - tag: "0.1.32-3-recover-delete-operation-status" + tag: "0.1.32-4-recover-delete-operation-status" pullPolicy: Always livenessProbe: httpGet: diff --git a/openapi/openapi-support-internal.json b/openapi/openapi-support-internal.json index f75d96c..d2aac2f 100644 --- a/openapi/openapi-support-internal.json +++ b/openapi/openapi-support-internal.json @@ -883,6 +883,6 @@ } }, "info": { - "version": "0.1.32-3-recover-delete-operation-status" + "version": "0.1.32-4-recover-delete-operation-status" } } diff --git a/openapi/openapi.json b/openapi/openapi.json index f75d96c..d2aac2f 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -883,6 +883,6 @@ } }, "info": { - "version": "0.1.32-3-recover-delete-operation-status" + "version": "0.1.32-4-recover-delete-operation-status" } } diff --git a/pom.xml b/pom.xml index 89e9ee4..c1f6b56 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 it.gov.pagopa.gpd.upload pagopa-gpd-upload - 0.1.32-3-recover-delete-operation-status + 0.1.32-4-recover-delete-operation-status ${packaging} From 44d719be1cbea5cf989ed91737eef811c3b1ad1c Mon Sep 17 00:00:00 2001 From: Angelo Caporaso <56113767+cap-ang@users.noreply.github.com> Date: Thu, 28 Nov 2024 17:45:20 +0100 Subject: [PATCH 10/19] [PAGOPA-2426] fix --- .../gpd/upload/service/RecoveryService.java | 23 +++++++++++++------ .../controller/SupportControllerTest.java | 2 +- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/main/java/it/gov/pagopa/gpd/upload/service/RecoveryService.java b/src/main/java/it/gov/pagopa/gpd/upload/service/RecoveryService.java index c485663..2f096bc 100644 --- a/src/main/java/it/gov/pagopa/gpd/upload/service/RecoveryService.java +++ b/src/main/java/it/gov/pagopa/gpd/upload/service/RecoveryService.java @@ -51,8 +51,14 @@ private boolean recover(String organizationFiscalCode, String uploadId, List= current.upload.getTotal()) - return false; + if(current.upload.getCurrent() >= current.upload.getTotal()) { + if(current.upload.getEnd() != null) + return false; + // update end-upload-time if it is null + current.upload.setEnd(LocalDateTime.now()); + Status updated = statusService.upsert(current); + return updated != null; + } // extract debt position id list List processedIUPD = new ArrayList<>(); @@ -69,12 +75,15 @@ private boolean recover(String organizationFiscalCode, String uploadId, List Date: Thu, 28 Nov 2024 16:47:01 +0000 Subject: [PATCH 11/19] Bump to version 0.1.32-5-recover-delete-operation-status --- helm/Chart.yaml | 4 ++-- helm/values-dev.yaml | 2 +- helm/values-prod.yaml | 2 +- helm/values-uat.yaml | 2 +- openapi/openapi-support-internal.json | 2 +- openapi/openapi.json | 2 +- pom.xml | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/helm/Chart.yaml b/helm/Chart.yaml index d9a4d58..4ca5b91 100644 --- a/helm/Chart.yaml +++ b/helm/Chart.yaml @@ -2,8 +2,8 @@ apiVersion: v2 name: pagopa-gpd-upload description: Microservice that handles file upload of massive debt positions JSON object type: application -version: 0.110.0 -appVersion: 0.1.32-4-recover-delete-operation-status +version: 0.111.0 +appVersion: 0.1.32-5-recover-delete-operation-status dependencies: - name: microservice-chart version: 2.8.0 diff --git a/helm/values-dev.yaml b/helm/values-dev.yaml index 81c9562..4e864b1 100644 --- a/helm/values-dev.yaml +++ b/helm/values-dev.yaml @@ -4,7 +4,7 @@ microservice-chart: fullnameOverride: "" image: repository: ghcr.io/pagopa/pagopa-gpd-upload - tag: "0.1.32-4-recover-delete-operation-status" + tag: "0.1.32-5-recover-delete-operation-status" pullPolicy: Always livenessProbe: httpGet: diff --git a/helm/values-prod.yaml b/helm/values-prod.yaml index 469e41e..8109c4a 100644 --- a/helm/values-prod.yaml +++ b/helm/values-prod.yaml @@ -4,7 +4,7 @@ microservice-chart: fullnameOverride: "" image: repository: ghcr.io/pagopa/pagopa-gpd-upload - tag: "0.1.32-4-recover-delete-operation-status" + tag: "0.1.32-5-recover-delete-operation-status" pullPolicy: Always livenessProbe: httpGet: diff --git a/helm/values-uat.yaml b/helm/values-uat.yaml index a84074a..61eb5ea 100644 --- a/helm/values-uat.yaml +++ b/helm/values-uat.yaml @@ -4,7 +4,7 @@ microservice-chart: fullnameOverride: "" image: repository: ghcr.io/pagopa/pagopa-gpd-upload - tag: "0.1.32-4-recover-delete-operation-status" + tag: "0.1.32-5-recover-delete-operation-status" pullPolicy: Always livenessProbe: httpGet: diff --git a/openapi/openapi-support-internal.json b/openapi/openapi-support-internal.json index d2aac2f..3d07266 100644 --- a/openapi/openapi-support-internal.json +++ b/openapi/openapi-support-internal.json @@ -883,6 +883,6 @@ } }, "info": { - "version": "0.1.32-4-recover-delete-operation-status" + "version": "0.1.32-5-recover-delete-operation-status" } } diff --git a/openapi/openapi.json b/openapi/openapi.json index d2aac2f..3d07266 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -883,6 +883,6 @@ } }, "info": { - "version": "0.1.32-4-recover-delete-operation-status" + "version": "0.1.32-5-recover-delete-operation-status" } } diff --git a/pom.xml b/pom.xml index c1f6b56..e2056ee 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 it.gov.pagopa.gpd.upload pagopa-gpd-upload - 0.1.32-4-recover-delete-operation-status + 0.1.32-5-recover-delete-operation-status ${packaging} From 48fa01047331570de5e6fe1899981a58721aa0a7 Mon Sep 17 00:00:00 2001 From: Angelo Caporaso <56113767+cap-ang@users.noreply.github.com> Date: Thu, 28 Nov 2024 18:20:40 +0100 Subject: [PATCH 12/19] [PAGOPA-2426] refactoring: Replace file-store with input-stream --- .../repository/BlobStorageRepository.java | 22 ++++++------------- .../gpd/upload/repository/FileRepository.java | 4 ++-- .../gpd/upload/service/BlobService.java | 13 +++++------ 3 files changed, 14 insertions(+), 25 deletions(-) diff --git a/src/main/java/it/gov/pagopa/gpd/upload/repository/BlobStorageRepository.java b/src/main/java/it/gov/pagopa/gpd/upload/repository/BlobStorageRepository.java index 861021a..474237d 100644 --- a/src/main/java/it/gov/pagopa/gpd/upload/repository/BlobStorageRepository.java +++ b/src/main/java/it/gov/pagopa/gpd/upload/repository/BlobStorageRepository.java @@ -43,7 +43,7 @@ public void init() { } @Override - public String upload(String broker, String fiscalCode, File file) throws FileNotFoundException { + public String upload(String broker, String fiscalCode, InputStream inputStream) throws FileNotFoundException { blobServiceClient.createBlobContainerIfNotExists(broker); BlobContainerClient container = blobServiceClient.getBlobContainerClient(broker + "/" + fiscalCode + "/" + INPUT_DIRECTORY); String key = this.createRandomName(broker + "_" + fiscalCode); @@ -57,30 +57,23 @@ public String upload(String broker, String fiscalCode, File file) throws FileNot BlockBlobClient blockBlobClient = blobClient.getBlockBlobClient(); - CompletableFuture uploadFuture = uploadFileAsync(blockBlobClient, file); + CompletableFuture uploadFuture = uploadFileAsync(blockBlobClient, inputStream); uploadFuture.thenAccept(blobName -> { // Handle the result asynchronously - log.debug(String.format("Asynchronous upload completed for blob %s", blobName)); + log.debug("Asynchronous upload completed for blob {}", blobName); }).exceptionally(ex -> { - log.error(String.format("[Error][BlobStorageRepository@upload] Exception while uploading file %s asynchronously: %s", - file.getName(), ex.getMessage())); + log.error("[Error][BlobStorageRepository@upload] Exception while uploading file asynchronously: {}", ex.getMessage()); throw new AppException(HttpStatus.INTERNAL_SERVER_ERROR, "INTERNAL_SERVER_ERROR", "Error uploading file asynchronously", ex); }); return key; } - private CompletableFuture uploadFileAsync(BlockBlobClient blockBlobClient, File file) { + private CompletableFuture uploadFileAsync(BlockBlobClient blockBlobClient, InputStream inputStream) { return CompletableFuture.supplyAsync(() -> { try { - String blobName = this.uploadFileBlocksAsBlockBlob(blockBlobClient, file); - - if(!file.delete()) { - log.error(String.format("[Error][BlobStorageRepository@uploadFileAsync] The file %s was not deleted", file.getName())); - } - - return blobName; + return this.uploadFileBlocksAsBlockBlob(blockBlobClient, inputStream); } catch (IOException e) { throw new AppException(HttpStatus.INTERNAL_SERVER_ERROR, "INTERNAL_SERVER_ERROR", "Error uploading file asynchronously", e); } @@ -91,8 +84,7 @@ private String createRandomName(String namePrefix) { return namePrefix + "_" + UUID.randomUUID().toString().replace("-", ""); } - private String uploadFileBlocksAsBlockBlob(BlockBlobClient blockBlob, File file) throws IOException { - InputStream inputStream = new FileInputStream(file); + private String uploadFileBlocksAsBlockBlob(BlockBlobClient blockBlob, InputStream inputStream) throws IOException { ByteArrayInputStream byteInputStream = null; int blockSize = 1024 * 1024; diff --git a/src/main/java/it/gov/pagopa/gpd/upload/repository/FileRepository.java b/src/main/java/it/gov/pagopa/gpd/upload/repository/FileRepository.java index 45383af..0713db4 100644 --- a/src/main/java/it/gov/pagopa/gpd/upload/repository/FileRepository.java +++ b/src/main/java/it/gov/pagopa/gpd/upload/repository/FileRepository.java @@ -1,8 +1,8 @@ package it.gov.pagopa.gpd.upload.repository; -import java.io.File; import java.io.IOException; +import java.io.InputStream; public interface FileRepository { - String upload(String container, String directory, File file) throws IOException; + String upload(String container, String directory, InputStream inputStream) throws IOException; } diff --git a/src/main/java/it/gov/pagopa/gpd/upload/service/BlobService.java b/src/main/java/it/gov/pagopa/gpd/upload/service/BlobService.java index 9dbec50..14163ae 100644 --- a/src/main/java/it/gov/pagopa/gpd/upload/service/BlobService.java +++ b/src/main/java/it/gov/pagopa/gpd/upload/service/BlobService.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import io.micronaut.context.annotation.Context; import io.micronaut.context.annotation.Value; @@ -22,8 +23,6 @@ import jakarta.inject.Singleton; import java.io.*; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.List; import java.util.UUID; import java.util.zip.ZipEntry; @@ -162,14 +161,12 @@ public String upload(UploadInput uploadInput, String broker, String organization log.debug(String.format("Upload operation %s was launched for broker %s and organization fiscal code %s", uploadInput.getUploadOperation(), broker, organizationFiscalCode)); - // replace file content - File uploadInputFile = Files.createTempFile(Path.of(DESTINATION_DIRECTORY), "gpd_upload_temp", ".json").toFile(); - FileWriter fileWriter = new FileWriter(uploadInputFile); - fileWriter.write(objectMapper.writeValueAsString(uploadInput)); - fileWriter.close(); + // from UploadInput Object to ByteArrayInputStream + objectMapper.enable(SerializationFeature.INDENT_OUTPUT); + ByteArrayInputStream inputStream = new ByteArrayInputStream(objectMapper.writeValueAsBytes(uploadInput)); // upload blob - String fileId = blobStorageRepository.upload(broker, organizationFiscalCode, uploadInputFile); + String fileId = blobStorageRepository.upload(broker, organizationFiscalCode, inputStream); statusService.createUploadStatus(organizationFiscalCode, broker, fileId, totalItem); return fileId; From 7953a05f18e4a64e967d00e92857959b6ae4a8c4 Mon Sep 17 00:00:00 2001 From: pagopa-github-bot Date: Thu, 28 Nov 2024 17:22:05 +0000 Subject: [PATCH 13/19] Bump to version 0.1.32-6-recover-delete-operation-status --- helm/Chart.yaml | 4 ++-- helm/values-dev.yaml | 2 +- helm/values-prod.yaml | 2 +- helm/values-uat.yaml | 2 +- openapi/openapi-support-internal.json | 2 +- openapi/openapi.json | 2 +- pom.xml | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/helm/Chart.yaml b/helm/Chart.yaml index 4ca5b91..81c08e7 100644 --- a/helm/Chart.yaml +++ b/helm/Chart.yaml @@ -2,8 +2,8 @@ apiVersion: v2 name: pagopa-gpd-upload description: Microservice that handles file upload of massive debt positions JSON object type: application -version: 0.111.0 -appVersion: 0.1.32-5-recover-delete-operation-status +version: 0.112.0 +appVersion: 0.1.32-6-recover-delete-operation-status dependencies: - name: microservice-chart version: 2.8.0 diff --git a/helm/values-dev.yaml b/helm/values-dev.yaml index 4e864b1..e3be9ec 100644 --- a/helm/values-dev.yaml +++ b/helm/values-dev.yaml @@ -4,7 +4,7 @@ microservice-chart: fullnameOverride: "" image: repository: ghcr.io/pagopa/pagopa-gpd-upload - tag: "0.1.32-5-recover-delete-operation-status" + tag: "0.1.32-6-recover-delete-operation-status" pullPolicy: Always livenessProbe: httpGet: diff --git a/helm/values-prod.yaml b/helm/values-prod.yaml index 8109c4a..f8d4dd7 100644 --- a/helm/values-prod.yaml +++ b/helm/values-prod.yaml @@ -4,7 +4,7 @@ microservice-chart: fullnameOverride: "" image: repository: ghcr.io/pagopa/pagopa-gpd-upload - tag: "0.1.32-5-recover-delete-operation-status" + tag: "0.1.32-6-recover-delete-operation-status" pullPolicy: Always livenessProbe: httpGet: diff --git a/helm/values-uat.yaml b/helm/values-uat.yaml index 61eb5ea..2183962 100644 --- a/helm/values-uat.yaml +++ b/helm/values-uat.yaml @@ -4,7 +4,7 @@ microservice-chart: fullnameOverride: "" image: repository: ghcr.io/pagopa/pagopa-gpd-upload - tag: "0.1.32-5-recover-delete-operation-status" + tag: "0.1.32-6-recover-delete-operation-status" pullPolicy: Always livenessProbe: httpGet: diff --git a/openapi/openapi-support-internal.json b/openapi/openapi-support-internal.json index 3d07266..2fd15e6 100644 --- a/openapi/openapi-support-internal.json +++ b/openapi/openapi-support-internal.json @@ -883,6 +883,6 @@ } }, "info": { - "version": "0.1.32-5-recover-delete-operation-status" + "version": "0.1.32-6-recover-delete-operation-status" } } diff --git a/openapi/openapi.json b/openapi/openapi.json index 3d07266..2fd15e6 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -883,6 +883,6 @@ } }, "info": { - "version": "0.1.32-5-recover-delete-operation-status" + "version": "0.1.32-6-recover-delete-operation-status" } } diff --git a/pom.xml b/pom.xml index e2056ee..a092cb3 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 it.gov.pagopa.gpd.upload pagopa-gpd-upload - 0.1.32-5-recover-delete-operation-status + 0.1.32-6-recover-delete-operation-status ${packaging} From 8b606631533daa2822922c99b5002fe88a6db307 Mon Sep 17 00:00:00 2001 From: Angelo Caporaso <56113767+cap-ang@users.noreply.github.com> Date: Thu, 28 Nov 2024 18:47:41 +0100 Subject: [PATCH 14/19] [PAGOPA-2426] ci: Update notify integration_test.yml --- .github/workflows/integration_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index b0e2e3e..82cc6d0 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -65,7 +65,7 @@ jobs: needs: [ integration_test ] runs-on: ubuntu-latest name: Notify - if: ${{ always() && inputs.notify == 'true' }} + if: ${{ inputs.notify == 'true' }} steps: - name: Report Status if: ${{ inputs.notify }} From 299fd1ee78f3fb35dfc0a09a5c9f35d960ab01dd Mon Sep 17 00:00:00 2001 From: Angelo Caporaso <56113767+cap-ang@users.noreply.github.com> Date: Mon, 2 Dec 2024 11:40:21 +0100 Subject: [PATCH 15/19] [PAGOPA-2426] fix: Apply review suggestion --- README.md | 4 +- openapi/openapi-support-internal.json | 1277 ++++++++--------- openapi/openapi.json | 1249 ++++++++-------- .../{ => external}/BaseController.java | 2 +- .../{ => external}/FileUploadController.java | 2 +- .../UploadStatusController.java | 2 +- .../controller/support/SupportController.java | 2 +- src/main/resources/application.properties | 3 +- 8 files changed, 1202 insertions(+), 1339 deletions(-) rename src/main/java/it/gov/pagopa/gpd/upload/controller/{ => external}/BaseController.java (98%) rename src/main/java/it/gov/pagopa/gpd/upload/controller/{ => external}/FileUploadController.java (99%) rename src/main/java/it/gov/pagopa/gpd/upload/controller/{ => external}/UploadStatusController.java (99%) diff --git a/README.md b/README.md index 1bb87c6..2b38bb2 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,9 @@ It allows the creditor institutions to: ## Api Documentation 📖 -See the [OpenApi 3 here.](https://editor.swagger.io/?url=https://raw.githubusercontent.com/pagopa/pagopa-gpd-upload/main/openapi/openapi.json) +See the external [OpenApi 3 here.](https://editor.swagger.io/?url=https://raw.githubusercontent.com/pagopa/pagopa-gpd-upload/main/openapi/openapi.json) + +See the internal [OpenApi 3 here.](https://editor.swagger.io/?url=https://raw.githubusercontent.com/pagopa/pagopa-gpd-upload/main/openapi/openapi-support-internal.json) --- diff --git a/openapi/openapi-support-internal.json b/openapi/openapi-support-internal.json index 2fd15e6..89914ed 100644 --- a/openapi/openapi-support-internal.json +++ b/openapi/openapi-support-internal.json @@ -1,677 +1,654 @@ { - "openapi": "3.0.1", - "paths": { - "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file": { - "put": { - "tags": [ - "Debt Positions CRUD via file upload API" - ], - "summary": "The Organization updates the debt positions listed in the file.", - "operationId": "update-debt-positions-by-file-upload", - "parameters": [ - { - "name": "broker-code", - "in": "path", - "description": "The broker code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - }, - { - "name": "organization-fiscal-code", - "in": "path", - "description": "The organization fiscal code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } + "openapi" : "3.0.1", + "info" : { + "title" : "pagopa-gpd-upload", + "description" : "Microservice to manage PagoPA GPD Upload", + "termsOfService" : "https://www.pagopa.gov.it/", + "version" : "0.1.22" + }, + "servers" : [ { + "url" : "http://localhost:8080" + }, { + "url" : "https://{host}{basePath}", + "variables" : { + "basePath" : { + "default" : "/upload/gpd/debt-positions-service/v1", + "enum" : [ "/upload/gpd/debt-positions-service/v1" ] + }, + "host" : { + "default" : "api.dev.platform.pagopa.it", + "enum" : [ "api.dev.platform.pagopa.it", "api.uat.platform.pagopa.it", "api.platform.pagopa.it" ] + } + } + } ], + "paths" : { + "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file" : { + "put" : { + "tags" : [ "Debt Positions CRUD via file upload API" ], + "summary" : "The Organization updates the debt positions listed in the file.", + "operationId" : "update-debt-positions-by-file-upload", + "parameters" : [ { + "name" : "broker-code", + "in" : "path", + "description" : "The broker code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + }, { + "name" : "organization-fiscal-code", + "in" : "path", + "description" : "The organization fiscal code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" } - ], - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "file": { - "type": "string", - "description": "File to be uploaded", - "format": "binary" + } ], + "requestBody" : { + "content" : { + "multipart/form-data" : { + "schema" : { + "type" : "object", + "properties" : { + "file" : { + "type" : "string", + "description" : "File to be uploaded", + "format" : "binary" } } }, - "encoding": { - "file": { - "contentType": "application/octet-stream" + "encoding" : { + "file" : { + "contentType" : "application/octet-stream" } } } }, - "required": true + "required" : true }, - "responses": { - "202": { - "description": "Request accepted." + "responses" : { + "202" : { + "description" : "Request accepted." }, - "400": { - "description": "Malformed request.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "400" : { + "description" : "Malformed request.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "401": { - "description": "Wrong or missing function key.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "401" : { + "description" : "Wrong or missing function key.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "allOf": [], - "anyOf": [], - "oneOf": [] + "403" : { + "description" : "Forbidden", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] } } } }, - "409": { - "description": "Conflict: duplicate file found.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "409" : { + "description" : "Conflict: duplicate file found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "429": { - "description": "Too many requests.", - "content": { - "text/json": {} + "429" : { + "description" : "Too many requests.", + "content" : { + "text/json" : { } } }, - "500": { - "description": "Service unavailable.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "500" : { + "description" : "Service unavailable.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } } }, - "security": [ - { - "ApiKey": [] - }, - { - "Authorization": [] - } - ] + "security" : [ { + "ApiKey" : [ ] + }, { + "Authorization" : [ ] + } ] }, - "post": { - "tags": [ - "Debt Positions CRUD via file upload API" - ], - "summary": "The Organization creates the debt positions listed in the file.", - "operationId": "create-debt-positions-by-file-upload", - "parameters": [ - { - "name": "broker-code", - "in": "path", - "description": "The broker code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - }, - { - "name": "organization-fiscal-code", - "in": "path", - "description": "The organization fiscal code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } + "post" : { + "tags" : [ "Debt Positions CRUD via file upload API" ], + "summary" : "The Organization creates the debt positions listed in the file.", + "operationId" : "create-debt-positions-by-file-upload", + "parameters" : [ { + "name" : "broker-code", + "in" : "path", + "description" : "The broker code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + }, { + "name" : "organization-fiscal-code", + "in" : "path", + "description" : "The organization fiscal code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" } - ], - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "file": { - "type": "string", - "description": "File to be uploaded", - "format": "binary" + } ], + "requestBody" : { + "content" : { + "multipart/form-data" : { + "schema" : { + "type" : "object", + "properties" : { + "file" : { + "type" : "string", + "description" : "File to be uploaded", + "format" : "binary" } } }, - "encoding": { - "file": { - "contentType": "application/octet-stream" + "encoding" : { + "file" : { + "contentType" : "application/octet-stream" } } } }, - "required": true + "required" : true }, - "responses": { - "202": { - "description": "Request accepted." + "responses" : { + "202" : { + "description" : "Request accepted." }, - "400": { - "description": "Malformed request.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "400" : { + "description" : "Malformed request.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "401": { - "description": "Wrong or missing function key.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "401" : { + "description" : "Wrong or missing function key.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "allOf": [], - "anyOf": [], - "oneOf": [] + "403" : { + "description" : "Forbidden", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] } } } }, - "409": { - "description": "Conflict: duplicate file found.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "409" : { + "description" : "Conflict: duplicate file found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "429": { - "description": "Too many requests.", - "content": { - "text/json": {} + "429" : { + "description" : "Too many requests.", + "content" : { + "text/json" : { } } }, - "500": { - "description": "Service unavailable.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "500" : { + "description" : "Service unavailable.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } } }, - "security": [ - { - "ApiKey": [] - }, - { - "Authorization": [] - } - ] + "security" : [ { + "ApiKey" : [ ] + }, { + "Authorization" : [ ] + } ] }, - "delete": { - "tags": [ - "Debt Positions CRUD via file upload API" - ], - "summary": "The Organization deletes the debt positions based on IUPD listed in the file.", - "operationId": "delete-debt-positions-by-file-upload", - "parameters": [ - { - "name": "broker-code", - "in": "path", - "description": "The broker code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - }, - { - "name": "organization-fiscal-code", - "in": "path", - "description": "The organization fiscal code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } + "delete" : { + "tags" : [ "Debt Positions CRUD via file upload API" ], + "summary" : "The Organization deletes the debt positions based on IUPD listed in the file.", + "operationId" : "delete-debt-positions-by-file-upload", + "parameters" : [ { + "name" : "broker-code", + "in" : "path", + "description" : "The broker code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + }, { + "name" : "organization-fiscal-code", + "in" : "path", + "description" : "The organization fiscal code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" } - ], - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "file": { - "type": "string", - "description": "File to be uploaded", - "format": "binary" + } ], + "requestBody" : { + "content" : { + "multipart/form-data" : { + "schema" : { + "type" : "object", + "properties" : { + "file" : { + "type" : "string", + "description" : "File to be uploaded", + "format" : "binary" } } }, - "encoding": { - "file": { - "contentType": "application/octet-stream" + "encoding" : { + "file" : { + "contentType" : "application/octet-stream" } } } }, - "required": true + "required" : true }, - "responses": { - "202": { - "description": "Request accepted." + "responses" : { + "202" : { + "description" : "Request accepted." }, - "400": { - "description": "Malformed request.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "400" : { + "description" : "Malformed request.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "401": { - "description": "Wrong or missing function key.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "401" : { + "description" : "Wrong or missing function key.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "allOf": [], - "anyOf": [], - "oneOf": [] + "403" : { + "description" : "Forbidden", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] } } } }, - "409": { - "description": "Conflict: duplicate file found.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "409" : { + "description" : "Conflict: duplicate file found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "429": { - "description": "Too many requests.", - "content": { - "text/json": {} + "429" : { + "description" : "Too many requests.", + "content" : { + "text/json" : { } } }, - "500": { - "description": "Service unavailable.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "500" : { + "description" : "Service unavailable.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } } }, - "security": [ - { - "ApiKey": [] - }, - { - "Authorization": [] - } - ] + "security" : [ { + "ApiKey" : [ ] + }, { + "Authorization" : [ ] + } ] } }, - "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/report": { - "get": { - "tags": [ - "Upload Status API" - ], - "summary": "Returns the debt positions upload report.", - "operationId": "get-debt-positions-upload-report", - "parameters": [ - { - "name": "broker-code", - "in": "path", - "description": "The broker code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - }, - { - "name": "organization-fiscal-code", - "in": "path", - "description": "The organization fiscal code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - }, - { - "name": "file-id", - "in": "path", - "description": "The unique identifier for file upload", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } + "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/report" : { + "get" : { + "tags" : [ "Upload Status API" ], + "summary" : "Returns the debt positions upload report.", + "operationId" : "get-debt-positions-upload-report", + "parameters" : [ { + "name" : "broker-code", + "in" : "path", + "description" : "The broker code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + }, { + "name" : "organization-fiscal-code", + "in" : "path", + "description" : "The organization fiscal code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + }, { + "name" : "file-id", + "in" : "path", + "description" : "The unique identifier for file upload", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" } - ], - "responses": { - "200": { - "description": "Upload report found.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UploadReport" + } ], + "responses" : { + "200" : { + "description" : "Upload report found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UploadReport" } } } }, - "400": { - "description": "Malformed request.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "400" : { + "description" : "Malformed request.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "401": { - "description": "Wrong or missing function key.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "401" : { + "description" : "Wrong or missing function key.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "allOf": [], - "anyOf": [], - "oneOf": [] + "403" : { + "description" : "Forbidden", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] } } } }, - "404": { - "description": "Upload report not found.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "404" : { + "description" : "Upload report not found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "429": { - "description": "Too many requests.", - "content": { - "text/json": {} + "429" : { + "description" : "Too many requests.", + "content" : { + "text/json" : { } } }, - "500": { - "description": "Service unavailable.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "500" : { + "description" : "Service unavailable.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } } }, - "security": [ - { - "ApiKey": [] - }, - { - "Authorization": [] - } - ] + "security" : [ { + "ApiKey" : [ ] + }, { + "Authorization" : [ ] + } ] } }, - "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/status": { - "get": { - "tags": [ - "Upload Status API" - ], - "summary": "Returns the debt positions upload status.", - "operationId": "get-debt-positions-upload-status", - "parameters": [ - { - "name": "broker-code", - "in": "path", - "description": "The broker code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - }, - { - "name": "organization-fiscal-code", - "in": "path", - "description": "The organization fiscal code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - }, - { - "name": "file-id", - "in": "path", - "description": "The unique identifier for file upload", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } + "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/status" : { + "get" : { + "tags" : [ "Upload Status API" ], + "summary" : "Returns the debt positions upload status.", + "operationId" : "get-debt-positions-upload-status", + "parameters" : [ { + "name" : "broker-code", + "in" : "path", + "description" : "The broker code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + }, { + "name" : "organization-fiscal-code", + "in" : "path", + "description" : "The organization fiscal code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" } - ], - "responses": { - "200": { - "description": "Upload found.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UploadStatus" + }, { + "name" : "file-id", + "in" : "path", + "description" : "The unique identifier for file upload", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "Upload found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UploadStatus" } } } }, - "400": { - "description": "Malformed request.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "400" : { + "description" : "Malformed request.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "401": { - "description": "Wrong or missing function key.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "401" : { + "description" : "Wrong or missing function key.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "allOf": [], - "anyOf": [], - "oneOf": [] + "403" : { + "description" : "Forbidden", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] } } } }, - "404": { - "description": "Upload not found.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "404" : { + "description" : "Upload not found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "429": { - "description": "Too many requests.", - "content": { - "text/json": {} + "429" : { + "description" : "Too many requests.", + "content" : { + "text/json" : { } } }, - "500": { - "description": "Service unavailable.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "500" : { + "description" : "Service unavailable.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } } }, - "security": [ - { - "ApiKey": [] - }, - { - "Authorization": [] - } - ] + "security" : [ { + "ApiKey" : [ ] + }, { + "Authorization" : [ ] + } ] } }, - "/info": { - "get": { - "tags": [ - "Health check" - ], - "summary": "health check", - "description": "Return OK if application is started", - "operationId": "healthCheck", - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AppInfo" + "/info" : { + "get" : { + "tags" : [ "Health check" ], + "summary" : "health check", + "description" : "Return OK if application is started", + "operationId" : "healthCheck", + "responses" : { + "200" : { + "description" : "OK", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/AppInfo" } } } }, - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "400" : { + "description" : "Bad Request", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "allOf": [], - "anyOf": [], - "oneOf": [] + "401" : { + "description" : "Unauthorized", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] } } } }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "allOf": [], - "anyOf": [], - "oneOf": [] + "403" : { + "description" : "Forbidden", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] } } } }, - "429": { - "description": "Too many requests.", - "content": { - "text/json": {} + "429" : { + "description" : "Too many requests.", + "content" : { + "text/json" : { } } }, - "500": { - "description": "Service unavailable", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "500" : { + "description" : "Service unavailable", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } @@ -679,83 +656,79 @@ } } }, - "/support/uploads/{upload}/status/refresh": { - "get": { - "tags": [ - "Support API" - ], - "summary": "Support API to recover status on CREATE operation", - "description": "Returns the debt positions upload report recovered.", - "operationId": "recoverStatus", - "parameters": [ - { - "name": "upload", - "in": "path", - "description": "The unique identifier for file upload", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } + "/support/uploads/{upload}/status/refresh" : { + "get" : { + "tags" : [ "Support API" ], + "summary" : "Support API to recover status on CREATE operation", + "description" : "Returns the debt positions upload report recovered.", + "operationId" : "recoverStatus", + "parameters" : [ { + "name" : "upload", + "in" : "path", + "description" : "The unique identifier for file upload", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AppInfo" + } ], + "responses" : { + "200" : { + "description" : "OK", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/AppInfo" } } } }, - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "400" : { + "description" : "Bad Request", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "allOf": [], - "anyOf": [], - "oneOf": [] + "401" : { + "description" : "Unauthorized", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] } } } }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "allOf": [], - "anyOf": [], - "oneOf": [] + "403" : { + "description" : "Forbidden", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] } } } }, - "429": { - "description": "Too many requests.", - "content": { - "text/json": {} + "429" : { + "description" : "Too many requests.", + "content" : { + "text/json" : { } } }, - "500": { - "description": "Service unavailable", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "500" : { + "description" : "Service unavailable", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } @@ -764,125 +737,123 @@ } } }, - "components": { - "schemas": { - "AppInfo": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "version": { - "type": "string" - }, - "environment": { - "type": "string" + "components" : { + "schemas" : { + "AppInfo" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "version" : { + "type" : "string" + }, + "environment" : { + "type" : "string" } } }, - "ProblemJson": { - "type": "object", - "properties": { - "title": { - "type": "string", - "description": "A short, summary of the problem type. Written in english and readable for engineers (usually not suited for non technical stakeholders and not localized); example: Service Unavailable" - }, - "status": { - "type": "integer", - "description": "The HTTP status code generated by the origin server for this occurrence of the problem.", - "format": "int32", - "example": 200 - }, - "detail": { - "type": "string", - "description": "A human readable explanation specific to this occurrence of the problem.", - "example": "There was an error processing the request" + "ProblemJson" : { + "type" : "object", + "properties" : { + "title" : { + "type" : "string", + "description" : "A short, summary of the problem type. Written in english and readable for engineers (usually not suited for non technical stakeholders and not localized); example: Service Unavailable" + }, + "status" : { + "type" : "integer", + "description" : "The HTTP status code generated by the origin server for this occurrence of the problem.", + "format" : "int32", + "example" : 200 + }, + "detail" : { + "type" : "string", + "description" : "A human readable explanation specific to this occurrence of the problem.", + "example" : "There was an error processing the request" } - } + }, + "description" : "Object returned as response in case of an error." }, - "ResponseEntry": { - "type": "object", - "properties": { - "statusCode": { - "type": "integer", - "format": "int32", - "example": 400 - }, - "statusMessage": { - "type": "string", - "example": "Bad request caused by invalid email address" - }, - "requestIDs": { - "type": "array", - "items": { - "type": "string" + "ResponseEntry" : { + "type" : "object", + "properties" : { + "statusCode" : { + "type" : "integer", + "format" : "int32", + "example" : 400 + }, + "statusMessage" : { + "type" : "string", + "example" : "Bad request caused by invalid email address" + }, + "requestIDs" : { + "type" : "array", + "items" : { + "type" : "string" } } } }, - "UploadReport": { - "type": "object", - "properties": { - "uploadID": { - "type": "string" - }, - "processedItem": { - "type": "integer", - "format": "int32" - }, - "submittedItem": { - "type": "integer", - "format": "int32" - }, - "responses": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ResponseEntry" - } - }, - "startTime": { - "type": "string", - "format": "date-time", - "example": "2024-10-08T14:55:16.302Z" - }, - "endTime": { - "type": "string", - "format": "date-time", - "example": "2024-10-08T14:55:16.302Z" + "UploadReport" : { + "type" : "object", + "properties" : { + "uploadID" : { + "type" : "string" + }, + "processedItem" : { + "type" : "integer", + "format" : "int32" + }, + "submittedItem" : { + "type" : "integer", + "format" : "int32" + }, + "responses" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/ResponseEntry" + } + }, + "startTime" : { + "type" : "string", + "format" : "date-time", + "example" : "2024-10-08T14:55:16.302Z" + }, + "endTime" : { + "type" : "string", + "format" : "date-time", + "example" : "2024-10-08T14:55:16.302Z" } } }, - "UploadStatus": { - "type": "object", - "properties": { - "uploadID": { - "type": "string" - }, - "processedItem": { - "type": "integer", - "format": "int32" - }, - "submittedItem": { - "type": "integer", - "format": "int32" - }, - "startTime": { - "type": "string", - "format": "date-time", - "example": "2024-10-08T14:55:16.302Z" + "UploadStatus" : { + "type" : "object", + "properties" : { + "uploadID" : { + "type" : "string" + }, + "processedItem" : { + "type" : "integer", + "format" : "int32" + }, + "submittedItem" : { + "type" : "integer", + "format" : "int32" + }, + "startTime" : { + "type" : "string", + "format" : "date-time", + "example" : "2024-10-08T14:55:16.302Z" } } } }, - "securitySchemes": { - "Ocp-Apim-Subscription-Key": { - "type": "apiKey", - "name": "Ocp-Apim-Subscription-Key", - "in": "header" + "securitySchemes" : { + "Ocp-Apim-Subscription-Key" : { + "type" : "apiKey", + "name" : "Ocp-Apim-Subscription-Key", + "in" : "header" } } - }, - "info": { - "version": "0.1.32-6-recover-delete-operation-status" } -} +} \ No newline at end of file diff --git a/openapi/openapi.json b/openapi/openapi.json index 2fd15e6..ca11d1d 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -1,761 +1,654 @@ { - "openapi": "3.0.1", - "paths": { - "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file": { - "put": { - "tags": [ - "Debt Positions CRUD via file upload API" - ], - "summary": "The Organization updates the debt positions listed in the file.", - "operationId": "update-debt-positions-by-file-upload", - "parameters": [ - { - "name": "broker-code", - "in": "path", - "description": "The broker code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - }, - { - "name": "organization-fiscal-code", - "in": "path", - "description": "The organization fiscal code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } + "openapi" : "3.0.1", + "info" : { + "title" : "pagopa-gpd-upload", + "description" : "Microservice to manage PagoPA GPD Upload", + "termsOfService" : "https://www.pagopa.gov.it/", + "version" : "0.1.22" + }, + "servers" : [ { + "url" : "http://localhost:8080" + }, { + "url" : "https://{host}{basePath}", + "variables" : { + "basePath" : { + "default" : "/upload/gpd/debt-positions-service/v1", + "enum" : [ "/upload/gpd/debt-positions-service/v1" ] + }, + "host" : { + "default" : "api.dev.platform.pagopa.it", + "enum" : [ "api.dev.platform.pagopa.it", "api.uat.platform.pagopa.it", "api.platform.pagopa.it" ] + } + } + } ], + "paths" : { + "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file" : { + "put" : { + "tags" : [ "Debt Positions CRUD via file upload API" ], + "summary" : "The Organization updates the debt positions listed in the file.", + "operationId" : "update-debt-positions-by-file-upload", + "parameters" : [ { + "name" : "broker-code", + "in" : "path", + "description" : "The broker code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + }, { + "name" : "organization-fiscal-code", + "in" : "path", + "description" : "The organization fiscal code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" } - ], - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "file": { - "type": "string", - "description": "File to be uploaded", - "format": "binary" + } ], + "requestBody" : { + "content" : { + "multipart/form-data" : { + "schema" : { + "type" : "object", + "properties" : { + "file" : { + "type" : "string", + "description" : "File to be uploaded", + "format" : "binary" } } }, - "encoding": { - "file": { - "contentType": "application/octet-stream" + "encoding" : { + "file" : { + "contentType" : "application/octet-stream" } } } }, - "required": true + "required" : true }, - "responses": { - "202": { - "description": "Request accepted." + "responses" : { + "202" : { + "description" : "Request accepted." }, - "400": { - "description": "Malformed request.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "400" : { + "description" : "Malformed request.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "401": { - "description": "Wrong or missing function key.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "401" : { + "description" : "Wrong or missing function key.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "allOf": [], - "anyOf": [], - "oneOf": [] + "403" : { + "description" : "Forbidden", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] } } } }, - "409": { - "description": "Conflict: duplicate file found.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "409" : { + "description" : "Conflict: duplicate file found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "429": { - "description": "Too many requests.", - "content": { - "text/json": {} + "429" : { + "description" : "Too many requests.", + "content" : { + "text/json" : { } } }, - "500": { - "description": "Service unavailable.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "500" : { + "description" : "Service unavailable.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } } }, - "security": [ - { - "ApiKey": [] - }, - { - "Authorization": [] - } - ] + "security" : [ { + "ApiKey" : [ ] + }, { + "Authorization" : [ ] + } ] }, - "post": { - "tags": [ - "Debt Positions CRUD via file upload API" - ], - "summary": "The Organization creates the debt positions listed in the file.", - "operationId": "create-debt-positions-by-file-upload", - "parameters": [ - { - "name": "broker-code", - "in": "path", - "description": "The broker code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - }, - { - "name": "organization-fiscal-code", - "in": "path", - "description": "The organization fiscal code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } + "post" : { + "tags" : [ "Debt Positions CRUD via file upload API" ], + "summary" : "The Organization creates the debt positions listed in the file.", + "operationId" : "create-debt-positions-by-file-upload", + "parameters" : [ { + "name" : "broker-code", + "in" : "path", + "description" : "The broker code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" } - ], - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "file": { - "type": "string", - "description": "File to be uploaded", - "format": "binary" + }, { + "name" : "organization-fiscal-code", + "in" : "path", + "description" : "The organization fiscal code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "multipart/form-data" : { + "schema" : { + "type" : "object", + "properties" : { + "file" : { + "type" : "string", + "description" : "File to be uploaded", + "format" : "binary" } } }, - "encoding": { - "file": { - "contentType": "application/octet-stream" + "encoding" : { + "file" : { + "contentType" : "application/octet-stream" } } } }, - "required": true + "required" : true }, - "responses": { - "202": { - "description": "Request accepted." + "responses" : { + "202" : { + "description" : "Request accepted." }, - "400": { - "description": "Malformed request.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "400" : { + "description" : "Malformed request.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "401": { - "description": "Wrong or missing function key.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "401" : { + "description" : "Wrong or missing function key.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "allOf": [], - "anyOf": [], - "oneOf": [] + "403" : { + "description" : "Forbidden", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] } } } }, - "409": { - "description": "Conflict: duplicate file found.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "409" : { + "description" : "Conflict: duplicate file found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "429": { - "description": "Too many requests.", - "content": { - "text/json": {} + "429" : { + "description" : "Too many requests.", + "content" : { + "text/json" : { } } }, - "500": { - "description": "Service unavailable.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "500" : { + "description" : "Service unavailable.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } } }, - "security": [ - { - "ApiKey": [] - }, - { - "Authorization": [] - } - ] + "security" : [ { + "ApiKey" : [ ] + }, { + "Authorization" : [ ] + } ] }, - "delete": { - "tags": [ - "Debt Positions CRUD via file upload API" - ], - "summary": "The Organization deletes the debt positions based on IUPD listed in the file.", - "operationId": "delete-debt-positions-by-file-upload", - "parameters": [ - { - "name": "broker-code", - "in": "path", - "description": "The broker code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - }, - { - "name": "organization-fiscal-code", - "in": "path", - "description": "The organization fiscal code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } + "delete" : { + "tags" : [ "Debt Positions CRUD via file upload API" ], + "summary" : "The Organization deletes the debt positions based on IUPD listed in the file.", + "operationId" : "delete-debt-positions-by-file-upload", + "parameters" : [ { + "name" : "broker-code", + "in" : "path", + "description" : "The broker code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + }, { + "name" : "organization-fiscal-code", + "in" : "path", + "description" : "The organization fiscal code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" } - ], - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "file": { - "type": "string", - "description": "File to be uploaded", - "format": "binary" + } ], + "requestBody" : { + "content" : { + "multipart/form-data" : { + "schema" : { + "type" : "object", + "properties" : { + "file" : { + "type" : "string", + "description" : "File to be uploaded", + "format" : "binary" } } }, - "encoding": { - "file": { - "contentType": "application/octet-stream" + "encoding" : { + "file" : { + "contentType" : "application/octet-stream" } } } }, - "required": true + "required" : true }, - "responses": { - "202": { - "description": "Request accepted." + "responses" : { + "202" : { + "description" : "Request accepted." }, - "400": { - "description": "Malformed request.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "400" : { + "description" : "Malformed request.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "401": { - "description": "Wrong or missing function key.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "401" : { + "description" : "Wrong or missing function key.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "allOf": [], - "anyOf": [], - "oneOf": [] + "403" : { + "description" : "Forbidden", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] } } } }, - "409": { - "description": "Conflict: duplicate file found.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "409" : { + "description" : "Conflict: duplicate file found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "429": { - "description": "Too many requests.", - "content": { - "text/json": {} + "429" : { + "description" : "Too many requests.", + "content" : { + "text/json" : { } } }, - "500": { - "description": "Service unavailable.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "500" : { + "description" : "Service unavailable.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } } }, - "security": [ - { - "ApiKey": [] - }, - { - "Authorization": [] - } - ] + "security" : [ { + "ApiKey" : [ ] + }, { + "Authorization" : [ ] + } ] } }, - "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/report": { - "get": { - "tags": [ - "Upload Status API" - ], - "summary": "Returns the debt positions upload report.", - "operationId": "get-debt-positions-upload-report", - "parameters": [ - { - "name": "broker-code", - "in": "path", - "description": "The broker code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - }, - { - "name": "organization-fiscal-code", - "in": "path", - "description": "The organization fiscal code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - }, - { - "name": "file-id", - "in": "path", - "description": "The unique identifier for file upload", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } + "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/report" : { + "get" : { + "tags" : [ "Upload Status API" ], + "summary" : "Returns the debt positions upload report.", + "operationId" : "get-debt-positions-upload-report", + "parameters" : [ { + "name" : "broker-code", + "in" : "path", + "description" : "The broker code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + }, { + "name" : "organization-fiscal-code", + "in" : "path", + "description" : "The organization fiscal code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" } - ], - "responses": { - "200": { - "description": "Upload report found.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UploadReport" + }, { + "name" : "file-id", + "in" : "path", + "description" : "The unique identifier for file upload", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "Upload report found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UploadReport" } } } }, - "400": { - "description": "Malformed request.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "400" : { + "description" : "Malformed request.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "401": { - "description": "Wrong or missing function key.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "401" : { + "description" : "Wrong or missing function key.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "allOf": [], - "anyOf": [], - "oneOf": [] + "403" : { + "description" : "Forbidden", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] } } } }, - "404": { - "description": "Upload report not found.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "404" : { + "description" : "Upload report not found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "429": { - "description": "Too many requests.", - "content": { - "text/json": {} + "429" : { + "description" : "Too many requests.", + "content" : { + "text/json" : { } } }, - "500": { - "description": "Service unavailable.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "500" : { + "description" : "Service unavailable.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } } }, - "security": [ - { - "ApiKey": [] - }, - { - "Authorization": [] - } - ] + "security" : [ { + "ApiKey" : [ ] + }, { + "Authorization" : [ ] + } ] } }, - "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/status": { - "get": { - "tags": [ - "Upload Status API" - ], - "summary": "Returns the debt positions upload status.", - "operationId": "get-debt-positions-upload-status", - "parameters": [ - { - "name": "broker-code", - "in": "path", - "description": "The broker code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - }, - { - "name": "organization-fiscal-code", - "in": "path", - "description": "The organization fiscal code", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - }, - { - "name": "file-id", - "in": "path", - "description": "The unique identifier for file upload", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } + "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/status" : { + "get" : { + "tags" : [ "Upload Status API" ], + "summary" : "Returns the debt positions upload status.", + "operationId" : "get-debt-positions-upload-status", + "parameters" : [ { + "name" : "broker-code", + "in" : "path", + "description" : "The broker code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + }, { + "name" : "organization-fiscal-code", + "in" : "path", + "description" : "The organization fiscal code", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" } - ], - "responses": { - "200": { - "description": "Upload found.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UploadStatus" + }, { + "name" : "file-id", + "in" : "path", + "description" : "The unique identifier for file upload", + "required" : true, + "schema" : { + "minLength" : 1, + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "Upload found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UploadStatus" } } } }, - "400": { - "description": "Malformed request.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "400" : { + "description" : "Malformed request.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "401": { - "description": "Wrong or missing function key.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "401" : { + "description" : "Wrong or missing function key.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "allOf": [], - "anyOf": [], - "oneOf": [] + "403" : { + "description" : "Forbidden", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] } } } }, - "404": { - "description": "Upload not found.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "404" : { + "description" : "Upload not found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "429": { - "description": "Too many requests.", - "content": { - "text/json": {} + "429" : { + "description" : "Too many requests.", + "content" : { + "text/json" : { } } }, - "500": { - "description": "Service unavailable.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "500" : { + "description" : "Service unavailable.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } } }, - "security": [ - { - "ApiKey": [] - }, - { - "Authorization": [] - } - ] - } - }, - "/info": { - "get": { - "tags": [ - "Health check" - ], - "summary": "health check", - "description": "Return OK if application is started", - "operationId": "healthCheck", - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AppInfo" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "allOf": [], - "anyOf": [], - "oneOf": [] - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "allOf": [], - "anyOf": [], - "oneOf": [] - } - } - } - }, - "429": { - "description": "Too many requests.", - "content": { - "text/json": {} - } - }, - "500": { - "description": "Service unavailable", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" - } - } - } - } - } + "security" : [ { + "ApiKey" : [ ] + }, { + "Authorization" : [ ] + } ] } }, - "/support/uploads/{upload}/status/refresh": { - "get": { - "tags": [ - "Support API" - ], - "summary": "Support API to recover status on CREATE operation", - "description": "Returns the debt positions upload report recovered.", - "operationId": "recoverStatus", - "parameters": [ - { - "name": "upload", - "in": "path", - "description": "The unique identifier for file upload", - "required": true, - "schema": { - "minLength": 1, - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AppInfo" + "/info" : { + "get" : { + "tags" : [ "Health check" ], + "summary" : "health check", + "description" : "Return OK if application is started", + "operationId" : "healthCheck", + "responses" : { + "200" : { + "description" : "OK", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/AppInfo" } } } }, - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "400" : { + "description" : "Bad Request", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "allOf": [], - "anyOf": [], - "oneOf": [] + "401" : { + "description" : "Unauthorized", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] } } } }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "allOf": [], - "anyOf": [], - "oneOf": [] + "403" : { + "description" : "Forbidden", + "content" : { + "application/json" : { + "schema" : { + "allOf" : [ ], + "anyOf" : [ ], + "oneOf" : [ ] } } } }, - "429": { - "description": "Too many requests.", - "content": { - "text/json": {} + "429" : { + "description" : "Too many requests.", + "content" : { + "text/json" : { } } }, - "500": { - "description": "Service unavailable", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "500" : { + "description" : "Service unavailable", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } @@ -764,125 +657,123 @@ } } }, - "components": { - "schemas": { - "AppInfo": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "version": { - "type": "string" - }, - "environment": { - "type": "string" + "components" : { + "schemas" : { + "AppInfo" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "version" : { + "type" : "string" + }, + "environment" : { + "type" : "string" } } }, - "ProblemJson": { - "type": "object", - "properties": { - "title": { - "type": "string", - "description": "A short, summary of the problem type. Written in english and readable for engineers (usually not suited for non technical stakeholders and not localized); example: Service Unavailable" - }, - "status": { - "type": "integer", - "description": "The HTTP status code generated by the origin server for this occurrence of the problem.", - "format": "int32", - "example": 200 - }, - "detail": { - "type": "string", - "description": "A human readable explanation specific to this occurrence of the problem.", - "example": "There was an error processing the request" + "ProblemJson" : { + "type" : "object", + "properties" : { + "title" : { + "type" : "string", + "description" : "A short, summary of the problem type. Written in english and readable for engineers (usually not suited for non technical stakeholders and not localized); example: Service Unavailable" + }, + "status" : { + "type" : "integer", + "description" : "The HTTP status code generated by the origin server for this occurrence of the problem.", + "format" : "int32", + "example" : 200 + }, + "detail" : { + "type" : "string", + "description" : "A human readable explanation specific to this occurrence of the problem.", + "example" : "There was an error processing the request" } - } + }, + "description" : "Object returned as response in case of an error." }, - "ResponseEntry": { - "type": "object", - "properties": { - "statusCode": { - "type": "integer", - "format": "int32", - "example": 400 - }, - "statusMessage": { - "type": "string", - "example": "Bad request caused by invalid email address" - }, - "requestIDs": { - "type": "array", - "items": { - "type": "string" + "ResponseEntry" : { + "type" : "object", + "properties" : { + "statusCode" : { + "type" : "integer", + "format" : "int32", + "example" : 400 + }, + "statusMessage" : { + "type" : "string", + "example" : "Bad request caused by invalid email address" + }, + "requestIDs" : { + "type" : "array", + "items" : { + "type" : "string" } } } }, - "UploadReport": { - "type": "object", - "properties": { - "uploadID": { - "type": "string" - }, - "processedItem": { - "type": "integer", - "format": "int32" - }, - "submittedItem": { - "type": "integer", - "format": "int32" - }, - "responses": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ResponseEntry" - } - }, - "startTime": { - "type": "string", - "format": "date-time", - "example": "2024-10-08T14:55:16.302Z" - }, - "endTime": { - "type": "string", - "format": "date-time", - "example": "2024-10-08T14:55:16.302Z" + "UploadReport" : { + "type" : "object", + "properties" : { + "uploadID" : { + "type" : "string" + }, + "processedItem" : { + "type" : "integer", + "format" : "int32" + }, + "submittedItem" : { + "type" : "integer", + "format" : "int32" + }, + "responses" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/ResponseEntry" + } + }, + "startTime" : { + "type" : "string", + "format" : "date-time", + "example" : "2024-10-08T14:55:16.302Z" + }, + "endTime" : { + "type" : "string", + "format" : "date-time", + "example" : "2024-10-08T14:55:16.302Z" } } }, - "UploadStatus": { - "type": "object", - "properties": { - "uploadID": { - "type": "string" - }, - "processedItem": { - "type": "integer", - "format": "int32" - }, - "submittedItem": { - "type": "integer", - "format": "int32" - }, - "startTime": { - "type": "string", - "format": "date-time", - "example": "2024-10-08T14:55:16.302Z" + "UploadStatus" : { + "type" : "object", + "properties" : { + "uploadID" : { + "type" : "string" + }, + "processedItem" : { + "type" : "integer", + "format" : "int32" + }, + "submittedItem" : { + "type" : "integer", + "format" : "int32" + }, + "startTime" : { + "type" : "string", + "format" : "date-time", + "example" : "2024-10-08T14:55:16.302Z" } } } }, - "securitySchemes": { - "Ocp-Apim-Subscription-Key": { - "type": "apiKey", - "name": "Ocp-Apim-Subscription-Key", - "in": "header" + "securitySchemes" : { + "Ocp-Apim-Subscription-Key" : { + "type" : "apiKey", + "name" : "Ocp-Apim-Subscription-Key", + "in" : "header" } } - }, - "info": { - "version": "0.1.32-6-recover-delete-operation-status" } -} +} \ No newline at end of file diff --git a/src/main/java/it/gov/pagopa/gpd/upload/controller/BaseController.java b/src/main/java/it/gov/pagopa/gpd/upload/controller/external/BaseController.java similarity index 98% rename from src/main/java/it/gov/pagopa/gpd/upload/controller/BaseController.java rename to src/main/java/it/gov/pagopa/gpd/upload/controller/external/BaseController.java index d9d30c7..62a8d88 100644 --- a/src/main/java/it/gov/pagopa/gpd/upload/controller/BaseController.java +++ b/src/main/java/it/gov/pagopa/gpd/upload/controller/external/BaseController.java @@ -1,4 +1,4 @@ -package it.gov.pagopa.gpd.upload.controller; +package it.gov.pagopa.gpd.upload.controller.external; import io.micronaut.context.annotation.Value; import io.micronaut.http.HttpResponse; diff --git a/src/main/java/it/gov/pagopa/gpd/upload/controller/FileUploadController.java b/src/main/java/it/gov/pagopa/gpd/upload/controller/external/FileUploadController.java similarity index 99% rename from src/main/java/it/gov/pagopa/gpd/upload/controller/FileUploadController.java rename to src/main/java/it/gov/pagopa/gpd/upload/controller/external/FileUploadController.java index e5c6718..6b8267c 100644 --- a/src/main/java/it/gov/pagopa/gpd/upload/controller/FileUploadController.java +++ b/src/main/java/it/gov/pagopa/gpd/upload/controller/external/FileUploadController.java @@ -1,4 +1,4 @@ -package it.gov.pagopa.gpd.upload.controller; +package it.gov.pagopa.gpd.upload.controller.external; import io.micronaut.context.annotation.Value; import io.micronaut.http.HttpHeaders; diff --git a/src/main/java/it/gov/pagopa/gpd/upload/controller/UploadStatusController.java b/src/main/java/it/gov/pagopa/gpd/upload/controller/external/UploadStatusController.java similarity index 99% rename from src/main/java/it/gov/pagopa/gpd/upload/controller/UploadStatusController.java rename to src/main/java/it/gov/pagopa/gpd/upload/controller/external/UploadStatusController.java index 31bc63f..2fddd8a 100644 --- a/src/main/java/it/gov/pagopa/gpd/upload/controller/UploadStatusController.java +++ b/src/main/java/it/gov/pagopa/gpd/upload/controller/external/UploadStatusController.java @@ -1,4 +1,4 @@ -package it.gov.pagopa.gpd.upload.controller; +package it.gov.pagopa.gpd.upload.controller.external; import io.micronaut.http.HttpResponse; import io.micronaut.http.HttpStatus; diff --git a/src/main/java/it/gov/pagopa/gpd/upload/controller/support/SupportController.java b/src/main/java/it/gov/pagopa/gpd/upload/controller/support/SupportController.java index 9496e43..0dd6a2b 100644 --- a/src/main/java/it/gov/pagopa/gpd/upload/controller/support/SupportController.java +++ b/src/main/java/it/gov/pagopa/gpd/upload/controller/support/SupportController.java @@ -37,7 +37,7 @@ public class SupportController { @Inject StatusService statusService; - @Operation(summary = "Support API to recover status on CREATE operation", description = "Returns the debt positions upload report recovered.", tags = {"Support API"}) + @Operation(summary = "Support API to recover status on CREATE and DELETE operation", description = "Returns the debt positions upload report recovered.", tags = {"Support API"}) @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = AppInfo.class))), @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = ProblemJson.class))), diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index dfef5e3..72dc00c 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -16,8 +16,7 @@ micronaut.server.max-request-size.multipart.max-file-size=104857600 micronaut.openapi.groups.external.primary=true micronaut.openapi.groups.external.filename=pagopa-gpd-upload-${openapi.application.version} micronaut.openapi.groups.external.display-name=GPD-Upload-API -micronaut.openapi.groups.external.packages=it.gov.pagopa.gpd.upload.controller.* -micronaut.openapi.groups.external.packages-exclude[0]=com.micronaut.controller.support.* +micronaut.openapi.groups.external.packages=it.gov.pagopa.gpd.upload.controller.external.* micronaut.openapi.groups.internal.primary=false micronaut.openapi.groups.internal.display-name=GPD-Upload-Support-API micronaut.openapi.groups.internal.filename=pagopa-gpd-upload-support From 7e5ff0ee8e20fc61d3df505d84895f077bd39665 Mon Sep 17 00:00:00 2001 From: Angelo Caporaso <56113767+cap-ang@users.noreply.github.com> Date: Mon, 2 Dec 2024 11:43:01 +0100 Subject: [PATCH 16/19] [PAGOPA-2426] fix: Update code_review.yml --- .github/workflows/code_review.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/code_review.yml b/.github/workflows/code_review.yml index 937d4fd..10335cc 100644 --- a/.github/workflows/code_review.yml +++ b/.github/workflows/code_review.yml @@ -40,7 +40,7 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} sonar_token: ${{ secrets.SONAR_TOKEN }} project_key: ${{env.PROJECT_KEY}} - coverage_exclusions: "**/config/**,**/*Mock*,**/model/**,**/entity/*,**/util/*" + coverage_exclusions: "**/config/**,**/model/**,**/entity/*" cpd_exclusions: "**/model/**,**/entity/*" java_version: 17 From 1b8adfa62920a5fc1675a99f449359634d763296 Mon Sep 17 00:00:00 2001 From: Angelo Caporaso <56113767+cap-ang@users.noreply.github.com> Date: Mon, 2 Dec 2024 11:46:44 +0100 Subject: [PATCH 17/19] [PAGOPA-2426] fix: Update code_review.yml --- .github/workflows/code_review.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/code_review.yml b/.github/workflows/code_review.yml index 10335cc..a819d19 100644 --- a/.github/workflows/code_review.yml +++ b/.github/workflows/code_review.yml @@ -40,8 +40,6 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} sonar_token: ${{ secrets.SONAR_TOKEN }} project_key: ${{env.PROJECT_KEY}} - coverage_exclusions: "**/config/**,**/model/**,**/entity/*" - cpd_exclusions: "**/model/**,**/entity/*" java_version: 17 smoke-test: From 80c527e55c459cd60f383fd799ecd1fd697d14ba Mon Sep 17 00:00:00 2001 From: Angelo Caporaso <56113767+cap-ang@users.noreply.github.com> Date: Mon, 2 Dec 2024 15:12:54 +0100 Subject: [PATCH 18/19] [PAGOPA-2426] fix: Update APIs title --- openapi/openapi-support-internal.json | 4 +-- openapi/openapi.json | 2 +- .../it/gov/pagopa/gpd/upload/Application.java | 2 +- src/main/resources/application.properties | 3 ++ .../gpd/upload/OpenApiGenerationTest.java | 30 +++++++++++-------- src/test/resources/application.properties | 1 + 6 files changed, 25 insertions(+), 17 deletions(-) diff --git a/openapi/openapi-support-internal.json b/openapi/openapi-support-internal.json index 89914ed..23179ae 100644 --- a/openapi/openapi-support-internal.json +++ b/openapi/openapi-support-internal.json @@ -1,7 +1,7 @@ { "openapi" : "3.0.1", "info" : { - "title" : "pagopa-gpd-upload", + "title" : "GPD-Upload-Support-API", "description" : "Microservice to manage PagoPA GPD Upload", "termsOfService" : "https://www.pagopa.gov.it/", "version" : "0.1.22" @@ -659,7 +659,7 @@ "/support/uploads/{upload}/status/refresh" : { "get" : { "tags" : [ "Support API" ], - "summary" : "Support API to recover status on CREATE operation", + "summary" : "Support API to recover status on CREATE and DELETE operation", "description" : "Returns the debt positions upload report recovered.", "operationId" : "recoverStatus", "parameters" : [ { diff --git a/openapi/openapi.json b/openapi/openapi.json index ca11d1d..d760470 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -1,7 +1,7 @@ { "openapi" : "3.0.1", "info" : { - "title" : "pagopa-gpd-upload", + "title" : "GPD-Upload-API", "description" : "Microservice to manage PagoPA GPD Upload", "termsOfService" : "https://www.pagopa.gov.it/", "version" : "0.1.22" diff --git a/src/main/java/it/gov/pagopa/gpd/upload/Application.java b/src/main/java/it/gov/pagopa/gpd/upload/Application.java index b0c248a..846191f 100644 --- a/src/main/java/it/gov/pagopa/gpd/upload/Application.java +++ b/src/main/java/it/gov/pagopa/gpd/upload/Application.java @@ -9,7 +9,7 @@ @OpenAPIDefinition( info = @Info( - title = "pagopa-gpd-upload", + title = "${info.application.title}", version = "${openapi.application.version}", description = "Microservice to manage PagoPA GPD Upload", termsOfService = "https://www.pagopa.gov.it/" diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 72dc00c..f46f78b 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,5 +1,6 @@ info.application.artifactId=${project.artifactId} info.application.version=${project.version} +info.application.title=GPD-Upload-API openapi.application.version=0.1.22 info.properties.environment=env micronaut.application.name=GPD-Massive-Upload-service @@ -16,9 +17,11 @@ micronaut.server.max-request-size.multipart.max-file-size=104857600 micronaut.openapi.groups.external.primary=true micronaut.openapi.groups.external.filename=pagopa-gpd-upload-${openapi.application.version} micronaut.openapi.groups.external.display-name=GPD-Upload-API +micronaut.openapi.groups.external.title=GPD-Upload-API micronaut.openapi.groups.external.packages=it.gov.pagopa.gpd.upload.controller.external.* micronaut.openapi.groups.internal.primary=false micronaut.openapi.groups.internal.display-name=GPD-Upload-Support-API +micronaut.openapi.groups.internal.title=GPD-Upload-Support-API micronaut.openapi.groups.internal.filename=pagopa-gpd-upload-support micronaut.openapi.groups.internal.packages=it.gov.pagopa.gpd.upload.controller.* diff --git a/src/test/java/it/gov/pagopa/gpd/upload/OpenApiGenerationTest.java b/src/test/java/it/gov/pagopa/gpd/upload/OpenApiGenerationTest.java index b716cd9..8650854 100644 --- a/src/test/java/it/gov/pagopa/gpd/upload/OpenApiGenerationTest.java +++ b/src/test/java/it/gov/pagopa/gpd/upload/OpenApiGenerationTest.java @@ -33,26 +33,30 @@ class OpenApiGenerationTest { @Client("/") HttpClient client; + @Value("${info.application.title}") + String title; + @Test void swaggerSpringPlugin() throws Exception { - boolean result = saveOpenAPI("/swagger/pagopa-gpd-upload-" + version + ".json", "openapi.json"); + boolean result = saveOpenAPI("/swagger/pagopa-gpd-upload-" + version + ".json", "openapi.json", "GPD-Upload-API"); assertTrue(result); - boolean resultSupportAPI = saveOpenAPI("/swagger/pagopa-gpd-upload-support.json", "openapi-support-internal.json"); + boolean resultSupportAPI = saveOpenAPI("/swagger/pagopa-gpd-upload-support.json", "openapi-support-internal.json", "GPD-Upload-Support-API"); assertTrue(resultSupportAPI); } - private boolean saveOpenAPI(String fromUri, String toFile) throws IOException { - HttpResponse response = client.toBlocking().exchange(fromUri, String.class); - ObjectMapper objectMapper = new ObjectMapper(); - String responseBody = response.getBody().get(); - Object openAPI = objectMapper.readValue(responseBody, Object.class); - String formatted = new ObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(openAPI); - Path basePath = Paths.get("openapi/"); - Files.createDirectories(basePath); - Files.write(basePath.resolve(toFile), formatted.getBytes()); - return true; - } + private boolean saveOpenAPI(String fromUri, String toFile, String newTitle) throws IOException { + HttpResponse response = client.toBlocking().exchange(fromUri, String.class); + ObjectMapper objectMapper = new ObjectMapper(); + String responseBody = response.getBody().get(); + responseBody = responseBody.replace(title, newTitle); + Object openAPI = objectMapper.readValue(responseBody, Object.class); + String formatted = new ObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(openAPI); + Path basePath = Paths.get("openapi/"); + Files.createDirectories(basePath); + Files.write(basePath.resolve(toFile), formatted.getBytes()); + return true; + } @Bean @Primary diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index 73e9eb7..90b16b3 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -1,4 +1,5 @@ info.application.artifactId=gpd-massive-upload +info.application.title=GPD-Upload-API info.application.version=0.1.22 info.properties.environment=test openapi.application.version=0.1.22 From 3c2029559feeda72f8214e2a1bb0182af522017e Mon Sep 17 00:00:00 2001 From: pagopa-github-bot Date: Tue, 3 Dec 2024 13:12:47 +0000 Subject: [PATCH 19/19] Bump to version 0.1.33-1-recover-delete-operation-status --- helm/Chart.yaml | 4 +- helm/values-dev.yaml | 2 +- helm/values-prod.yaml | 2 +- helm/values-uat.yaml | 2 +- openapi/openapi-support-internal.json | 1297 +++++++++++++------------ openapi/openapi.json | 1185 +++++++++++----------- pom.xml | 2 +- 7 files changed, 1302 insertions(+), 1192 deletions(-) diff --git a/helm/Chart.yaml b/helm/Chart.yaml index 17342da..7bc7b36 100644 --- a/helm/Chart.yaml +++ b/helm/Chart.yaml @@ -2,8 +2,8 @@ apiVersion: v2 name: pagopa-gpd-upload description: Microservice that handles file upload of massive debt positions JSON object type: application -version: 0.107.0 -appVersion: 0.1.33 +version: 0.108.0 +appVersion: 0.1.33-1-recover-delete-operation-status dependencies: - name: microservice-chart version: 2.8.0 diff --git a/helm/values-dev.yaml b/helm/values-dev.yaml index 0753fdc..5f4bba5 100644 --- a/helm/values-dev.yaml +++ b/helm/values-dev.yaml @@ -4,7 +4,7 @@ microservice-chart: fullnameOverride: "" image: repository: ghcr.io/pagopa/pagopa-gpd-upload - tag: "0.1.33" + tag: "0.1.33-1-recover-delete-operation-status" pullPolicy: Always livenessProbe: httpGet: diff --git a/helm/values-prod.yaml b/helm/values-prod.yaml index cd77ce9..61c9a8c 100644 --- a/helm/values-prod.yaml +++ b/helm/values-prod.yaml @@ -4,7 +4,7 @@ microservice-chart: fullnameOverride: "" image: repository: ghcr.io/pagopa/pagopa-gpd-upload - tag: "0.1.33" + tag: "0.1.33-1-recover-delete-operation-status" pullPolicy: Always livenessProbe: httpGet: diff --git a/helm/values-uat.yaml b/helm/values-uat.yaml index 34463ac..a0acd85 100644 --- a/helm/values-uat.yaml +++ b/helm/values-uat.yaml @@ -4,7 +4,7 @@ microservice-chart: fullnameOverride: "" image: repository: ghcr.io/pagopa/pagopa-gpd-upload - tag: "0.1.33" + tag: "0.1.33-1-recover-delete-operation-status" pullPolicy: Always livenessProbe: httpGet: diff --git a/openapi/openapi-support-internal.json b/openapi/openapi-support-internal.json index 23179ae..a8dbb71 100644 --- a/openapi/openapi-support-internal.json +++ b/openapi/openapi-support-internal.json @@ -1,654 +1,707 @@ { - "openapi" : "3.0.1", - "info" : { - "title" : "GPD-Upload-Support-API", - "description" : "Microservice to manage PagoPA GPD Upload", - "termsOfService" : "https://www.pagopa.gov.it/", - "version" : "0.1.22" + "openapi": "3.0.1", + "info": { + "title": "GPD-Upload-Support-API", + "description": "Microservice to manage PagoPA GPD Upload", + "termsOfService": "https://www.pagopa.gov.it/", + "version": "0.1.33-1-recover-delete-operation-status" }, - "servers" : [ { - "url" : "http://localhost:8080" - }, { - "url" : "https://{host}{basePath}", - "variables" : { - "basePath" : { - "default" : "/upload/gpd/debt-positions-service/v1", - "enum" : [ "/upload/gpd/debt-positions-service/v1" ] - }, - "host" : { - "default" : "api.dev.platform.pagopa.it", - "enum" : [ "api.dev.platform.pagopa.it", "api.uat.platform.pagopa.it", "api.platform.pagopa.it" ] + "servers": [ + { + "url": "http://localhost:8080" + }, + { + "url": "https://{host}{basePath}", + "variables": { + "basePath": { + "default": "/upload/gpd/debt-positions-service/v1", + "enum": [ + "/upload/gpd/debt-positions-service/v1" + ] + }, + "host": { + "default": "api.dev.platform.pagopa.it", + "enum": [ + "api.dev.platform.pagopa.it", + "api.uat.platform.pagopa.it", + "api.platform.pagopa.it" + ] + } } } - } ], - "paths" : { - "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file" : { - "put" : { - "tags" : [ "Debt Positions CRUD via file upload API" ], - "summary" : "The Organization updates the debt positions listed in the file.", - "operationId" : "update-debt-positions-by-file-upload", - "parameters" : [ { - "name" : "broker-code", - "in" : "path", - "description" : "The broker code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" - } - }, { - "name" : "organization-fiscal-code", - "in" : "path", - "description" : "The organization fiscal code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + ], + "paths": { + "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file": { + "put": { + "tags": [ + "Debt Positions CRUD via file upload API" + ], + "summary": "The Organization updates the debt positions listed in the file.", + "operationId": "update-debt-positions-by-file-upload", + "parameters": [ + { + "name": "broker-code", + "in": "path", + "description": "The broker code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "organization-fiscal-code", + "in": "path", + "description": "The organization fiscal code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } } - } ], - "requestBody" : { - "content" : { - "multipart/form-data" : { - "schema" : { - "type" : "object", - "properties" : { - "file" : { - "type" : "string", - "description" : "File to be uploaded", - "format" : "binary" + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "file": { + "type": "string", + "description": "File to be uploaded", + "format": "binary" } } }, - "encoding" : { - "file" : { - "contentType" : "application/octet-stream" + "encoding": { + "file": { + "contentType": "application/octet-stream" } } } }, - "required" : true + "required": true }, - "responses" : { - "202" : { - "description" : "Request accepted." + "responses": { + "202": { + "description": "Request accepted." }, - "400" : { - "description" : "Malformed request.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "400": { + "description": "Malformed request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "401" : { - "description" : "Wrong or missing function key.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "401": { + "description": "Wrong or missing function key.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "403" : { - "description" : "Forbidden", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "409" : { - "description" : "Conflict: duplicate file found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "409": { + "description": "Conflict: duplicate file found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "429" : { - "description" : "Too many requests.", - "content" : { - "text/json" : { } + "429": { + "description": "Too many requests.", + "content": { + "text/json": {} } }, - "500" : { - "description" : "Service unavailable.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "500": { + "description": "Service unavailable.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } } }, - "security" : [ { - "ApiKey" : [ ] - }, { - "Authorization" : [ ] - } ] - }, - "post" : { - "tags" : [ "Debt Positions CRUD via file upload API" ], - "summary" : "The Organization creates the debt positions listed in the file.", - "operationId" : "create-debt-positions-by-file-upload", - "parameters" : [ { - "name" : "broker-code", - "in" : "path", - "description" : "The broker code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + "security": [ + { + "ApiKey": [] + }, + { + "Authorization": [] } - }, { - "name" : "organization-fiscal-code", - "in" : "path", - "description" : "The organization fiscal code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + ] + }, + "post": { + "tags": [ + "Debt Positions CRUD via file upload API" + ], + "summary": "The Organization creates the debt positions listed in the file.", + "operationId": "create-debt-positions-by-file-upload", + "parameters": [ + { + "name": "broker-code", + "in": "path", + "description": "The broker code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "organization-fiscal-code", + "in": "path", + "description": "The organization fiscal code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } } - } ], - "requestBody" : { - "content" : { - "multipart/form-data" : { - "schema" : { - "type" : "object", - "properties" : { - "file" : { - "type" : "string", - "description" : "File to be uploaded", - "format" : "binary" + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "file": { + "type": "string", + "description": "File to be uploaded", + "format": "binary" } } }, - "encoding" : { - "file" : { - "contentType" : "application/octet-stream" + "encoding": { + "file": { + "contentType": "application/octet-stream" } } } }, - "required" : true + "required": true }, - "responses" : { - "202" : { - "description" : "Request accepted." + "responses": { + "202": { + "description": "Request accepted." }, - "400" : { - "description" : "Malformed request.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "400": { + "description": "Malformed request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "401" : { - "description" : "Wrong or missing function key.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "401": { + "description": "Wrong or missing function key.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "403" : { - "description" : "Forbidden", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "409" : { - "description" : "Conflict: duplicate file found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "409": { + "description": "Conflict: duplicate file found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "429" : { - "description" : "Too many requests.", - "content" : { - "text/json" : { } + "429": { + "description": "Too many requests.", + "content": { + "text/json": {} } }, - "500" : { - "description" : "Service unavailable.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "500": { + "description": "Service unavailable.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } } }, - "security" : [ { - "ApiKey" : [ ] - }, { - "Authorization" : [ ] - } ] - }, - "delete" : { - "tags" : [ "Debt Positions CRUD via file upload API" ], - "summary" : "The Organization deletes the debt positions based on IUPD listed in the file.", - "operationId" : "delete-debt-positions-by-file-upload", - "parameters" : [ { - "name" : "broker-code", - "in" : "path", - "description" : "The broker code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + "security": [ + { + "ApiKey": [] + }, + { + "Authorization": [] } - }, { - "name" : "organization-fiscal-code", - "in" : "path", - "description" : "The organization fiscal code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + ] + }, + "delete": { + "tags": [ + "Debt Positions CRUD via file upload API" + ], + "summary": "The Organization deletes the debt positions based on IUPD listed in the file.", + "operationId": "delete-debt-positions-by-file-upload", + "parameters": [ + { + "name": "broker-code", + "in": "path", + "description": "The broker code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "organization-fiscal-code", + "in": "path", + "description": "The organization fiscal code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } } - } ], - "requestBody" : { - "content" : { - "multipart/form-data" : { - "schema" : { - "type" : "object", - "properties" : { - "file" : { - "type" : "string", - "description" : "File to be uploaded", - "format" : "binary" + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "file": { + "type": "string", + "description": "File to be uploaded", + "format": "binary" } } }, - "encoding" : { - "file" : { - "contentType" : "application/octet-stream" + "encoding": { + "file": { + "contentType": "application/octet-stream" } } } }, - "required" : true + "required": true }, - "responses" : { - "202" : { - "description" : "Request accepted." + "responses": { + "202": { + "description": "Request accepted." }, - "400" : { - "description" : "Malformed request.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "400": { + "description": "Malformed request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "401" : { - "description" : "Wrong or missing function key.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "401": { + "description": "Wrong or missing function key.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "403" : { - "description" : "Forbidden", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "409" : { - "description" : "Conflict: duplicate file found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "409": { + "description": "Conflict: duplicate file found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "429" : { - "description" : "Too many requests.", - "content" : { - "text/json" : { } + "429": { + "description": "Too many requests.", + "content": { + "text/json": {} } }, - "500" : { - "description" : "Service unavailable.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "500": { + "description": "Service unavailable.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } } }, - "security" : [ { - "ApiKey" : [ ] - }, { - "Authorization" : [ ] - } ] + "security": [ + { + "ApiKey": [] + }, + { + "Authorization": [] + } + ] } }, - "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/report" : { - "get" : { - "tags" : [ "Upload Status API" ], - "summary" : "Returns the debt positions upload report.", - "operationId" : "get-debt-positions-upload-report", - "parameters" : [ { - "name" : "broker-code", - "in" : "path", - "description" : "The broker code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" - } - }, { - "name" : "organization-fiscal-code", - "in" : "path", - "description" : "The organization fiscal code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" - } - }, { - "name" : "file-id", - "in" : "path", - "description" : "The unique identifier for file upload", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/report": { + "get": { + "tags": [ + "Upload Status API" + ], + "summary": "Returns the debt positions upload report.", + "operationId": "get-debt-positions-upload-report", + "parameters": [ + { + "name": "broker-code", + "in": "path", + "description": "The broker code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "organization-fiscal-code", + "in": "path", + "description": "The organization fiscal code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "file-id", + "in": "path", + "description": "The unique identifier for file upload", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } } - } ], - "responses" : { - "200" : { - "description" : "Upload report found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UploadReport" + ], + "responses": { + "200": { + "description": "Upload report found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UploadReport" } } } }, - "400" : { - "description" : "Malformed request.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "400": { + "description": "Malformed request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "401" : { - "description" : "Wrong or missing function key.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "401": { + "description": "Wrong or missing function key.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "403" : { - "description" : "Forbidden", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "404" : { - "description" : "Upload report not found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "404": { + "description": "Upload report not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "429" : { - "description" : "Too many requests.", - "content" : { - "text/json" : { } + "429": { + "description": "Too many requests.", + "content": { + "text/json": {} } }, - "500" : { - "description" : "Service unavailable.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "500": { + "description": "Service unavailable.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } } }, - "security" : [ { - "ApiKey" : [ ] - }, { - "Authorization" : [ ] - } ] + "security": [ + { + "ApiKey": [] + }, + { + "Authorization": [] + } + ] } }, - "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/status" : { - "get" : { - "tags" : [ "Upload Status API" ], - "summary" : "Returns the debt positions upload status.", - "operationId" : "get-debt-positions-upload-status", - "parameters" : [ { - "name" : "broker-code", - "in" : "path", - "description" : "The broker code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" - } - }, { - "name" : "organization-fiscal-code", - "in" : "path", - "description" : "The organization fiscal code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" - } - }, { - "name" : "file-id", - "in" : "path", - "description" : "The unique identifier for file upload", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/status": { + "get": { + "tags": [ + "Upload Status API" + ], + "summary": "Returns the debt positions upload status.", + "operationId": "get-debt-positions-upload-status", + "parameters": [ + { + "name": "broker-code", + "in": "path", + "description": "The broker code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "organization-fiscal-code", + "in": "path", + "description": "The organization fiscal code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "file-id", + "in": "path", + "description": "The unique identifier for file upload", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } } - } ], - "responses" : { - "200" : { - "description" : "Upload found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UploadStatus" + ], + "responses": { + "200": { + "description": "Upload found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UploadStatus" } } } }, - "400" : { - "description" : "Malformed request.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "400": { + "description": "Malformed request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "401" : { - "description" : "Wrong or missing function key.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "401": { + "description": "Wrong or missing function key.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "403" : { - "description" : "Forbidden", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "404" : { - "description" : "Upload not found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "404": { + "description": "Upload not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "429" : { - "description" : "Too many requests.", - "content" : { - "text/json" : { } + "429": { + "description": "Too many requests.", + "content": { + "text/json": {} } }, - "500" : { - "description" : "Service unavailable.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "500": { + "description": "Service unavailable.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } } }, - "security" : [ { - "ApiKey" : [ ] - }, { - "Authorization" : [ ] - } ] + "security": [ + { + "ApiKey": [] + }, + { + "Authorization": [] + } + ] } }, - "/info" : { - "get" : { - "tags" : [ "Health check" ], - "summary" : "health check", - "description" : "Return OK if application is started", - "operationId" : "healthCheck", - "responses" : { - "200" : { - "description" : "OK", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/AppInfo" + "/info": { + "get": { + "tags": [ + "Health check" + ], + "summary": "health check", + "description": "Return OK if application is started", + "operationId": "healthCheck", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AppInfo" } } } }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "403" : { - "description" : "Forbidden", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "429" : { - "description" : "Too many requests.", - "content" : { - "text/json" : { } + "429": { + "description": "Too many requests.", + "content": { + "text/json": {} } }, - "500" : { - "description" : "Service unavailable", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "500": { + "description": "Service unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } @@ -656,79 +709,83 @@ } } }, - "/support/uploads/{upload}/status/refresh" : { - "get" : { - "tags" : [ "Support API" ], - "summary" : "Support API to recover status on CREATE and DELETE operation", - "description" : "Returns the debt positions upload report recovered.", - "operationId" : "recoverStatus", - "parameters" : [ { - "name" : "upload", - "in" : "path", - "description" : "The unique identifier for file upload", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + "/support/uploads/{upload}/status/refresh": { + "get": { + "tags": [ + "Support API" + ], + "summary": "Support API to recover status on CREATE and DELETE operation", + "description": "Returns the debt positions upload report recovered.", + "operationId": "recoverStatus", + "parameters": [ + { + "name": "upload", + "in": "path", + "description": "The unique identifier for file upload", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } } - } ], - "responses" : { - "200" : { - "description" : "OK", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/AppInfo" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AppInfo" } } } }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "403" : { - "description" : "Forbidden", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "429" : { - "description" : "Too many requests.", - "content" : { - "text/json" : { } + "429": { + "description": "Too many requests.", + "content": { + "text/json": {} } }, - "500" : { - "description" : "Service unavailable", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "500": { + "description": "Service unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } @@ -737,123 +794,123 @@ } } }, - "components" : { - "schemas" : { - "AppInfo" : { - "type" : "object", - "properties" : { - "name" : { - "type" : "string" - }, - "version" : { - "type" : "string" - }, - "environment" : { - "type" : "string" + "components": { + "schemas": { + "AppInfo": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "environment": { + "type": "string" } } }, - "ProblemJson" : { - "type" : "object", - "properties" : { - "title" : { - "type" : "string", - "description" : "A short, summary of the problem type. Written in english and readable for engineers (usually not suited for non technical stakeholders and not localized); example: Service Unavailable" - }, - "status" : { - "type" : "integer", - "description" : "The HTTP status code generated by the origin server for this occurrence of the problem.", - "format" : "int32", - "example" : 200 - }, - "detail" : { - "type" : "string", - "description" : "A human readable explanation specific to this occurrence of the problem.", - "example" : "There was an error processing the request" + "ProblemJson": { + "type": "object", + "properties": { + "title": { + "type": "string", + "description": "A short, summary of the problem type. Written in english and readable for engineers (usually not suited for non technical stakeholders and not localized); example: Service Unavailable" + }, + "status": { + "type": "integer", + "description": "The HTTP status code generated by the origin server for this occurrence of the problem.", + "format": "int32", + "example": 200 + }, + "detail": { + "type": "string", + "description": "A human readable explanation specific to this occurrence of the problem.", + "example": "There was an error processing the request" } }, - "description" : "Object returned as response in case of an error." + "description": "Object returned as response in case of an error." }, - "ResponseEntry" : { - "type" : "object", - "properties" : { - "statusCode" : { - "type" : "integer", - "format" : "int32", - "example" : 400 - }, - "statusMessage" : { - "type" : "string", - "example" : "Bad request caused by invalid email address" - }, - "requestIDs" : { - "type" : "array", - "items" : { - "type" : "string" + "ResponseEntry": { + "type": "object", + "properties": { + "statusCode": { + "type": "integer", + "format": "int32", + "example": 400 + }, + "statusMessage": { + "type": "string", + "example": "Bad request caused by invalid email address" + }, + "requestIDs": { + "type": "array", + "items": { + "type": "string" } } } }, - "UploadReport" : { - "type" : "object", - "properties" : { - "uploadID" : { - "type" : "string" - }, - "processedItem" : { - "type" : "integer", - "format" : "int32" - }, - "submittedItem" : { - "type" : "integer", - "format" : "int32" - }, - "responses" : { - "type" : "array", - "items" : { - "$ref" : "#/components/schemas/ResponseEntry" - } - }, - "startTime" : { - "type" : "string", - "format" : "date-time", - "example" : "2024-10-08T14:55:16.302Z" - }, - "endTime" : { - "type" : "string", - "format" : "date-time", - "example" : "2024-10-08T14:55:16.302Z" + "UploadReport": { + "type": "object", + "properties": { + "uploadID": { + "type": "string" + }, + "processedItem": { + "type": "integer", + "format": "int32" + }, + "submittedItem": { + "type": "integer", + "format": "int32" + }, + "responses": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ResponseEntry" + } + }, + "startTime": { + "type": "string", + "format": "date-time", + "example": "2024-10-08T14:55:16.302Z" + }, + "endTime": { + "type": "string", + "format": "date-time", + "example": "2024-10-08T14:55:16.302Z" } } }, - "UploadStatus" : { - "type" : "object", - "properties" : { - "uploadID" : { - "type" : "string" - }, - "processedItem" : { - "type" : "integer", - "format" : "int32" - }, - "submittedItem" : { - "type" : "integer", - "format" : "int32" - }, - "startTime" : { - "type" : "string", - "format" : "date-time", - "example" : "2024-10-08T14:55:16.302Z" + "UploadStatus": { + "type": "object", + "properties": { + "uploadID": { + "type": "string" + }, + "processedItem": { + "type": "integer", + "format": "int32" + }, + "submittedItem": { + "type": "integer", + "format": "int32" + }, + "startTime": { + "type": "string", + "format": "date-time", + "example": "2024-10-08T14:55:16.302Z" } } } }, - "securitySchemes" : { - "Ocp-Apim-Subscription-Key" : { - "type" : "apiKey", - "name" : "Ocp-Apim-Subscription-Key", - "in" : "header" + "securitySchemes": { + "Ocp-Apim-Subscription-Key": { + "type": "apiKey", + "name": "Ocp-Apim-Subscription-Key", + "in": "header" } } } -} \ No newline at end of file +} diff --git a/openapi/openapi.json b/openapi/openapi.json index d760470..2ebccc7 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -1,654 +1,707 @@ { - "openapi" : "3.0.1", - "info" : { - "title" : "GPD-Upload-API", - "description" : "Microservice to manage PagoPA GPD Upload", - "termsOfService" : "https://www.pagopa.gov.it/", - "version" : "0.1.22" + "openapi": "3.0.1", + "info": { + "title": "GPD-Upload-API", + "description": "Microservice to manage PagoPA GPD Upload", + "termsOfService": "https://www.pagopa.gov.it/", + "version": "0.1.33-1-recover-delete-operation-status" }, - "servers" : [ { - "url" : "http://localhost:8080" - }, { - "url" : "https://{host}{basePath}", - "variables" : { - "basePath" : { - "default" : "/upload/gpd/debt-positions-service/v1", - "enum" : [ "/upload/gpd/debt-positions-service/v1" ] - }, - "host" : { - "default" : "api.dev.platform.pagopa.it", - "enum" : [ "api.dev.platform.pagopa.it", "api.uat.platform.pagopa.it", "api.platform.pagopa.it" ] + "servers": [ + { + "url": "http://localhost:8080" + }, + { + "url": "https://{host}{basePath}", + "variables": { + "basePath": { + "default": "/upload/gpd/debt-positions-service/v1", + "enum": [ + "/upload/gpd/debt-positions-service/v1" + ] + }, + "host": { + "default": "api.dev.platform.pagopa.it", + "enum": [ + "api.dev.platform.pagopa.it", + "api.uat.platform.pagopa.it", + "api.platform.pagopa.it" + ] + } } } - } ], - "paths" : { - "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file" : { - "put" : { - "tags" : [ "Debt Positions CRUD via file upload API" ], - "summary" : "The Organization updates the debt positions listed in the file.", - "operationId" : "update-debt-positions-by-file-upload", - "parameters" : [ { - "name" : "broker-code", - "in" : "path", - "description" : "The broker code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" - } - }, { - "name" : "organization-fiscal-code", - "in" : "path", - "description" : "The organization fiscal code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + ], + "paths": { + "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file": { + "put": { + "tags": [ + "Debt Positions CRUD via file upload API" + ], + "summary": "The Organization updates the debt positions listed in the file.", + "operationId": "update-debt-positions-by-file-upload", + "parameters": [ + { + "name": "broker-code", + "in": "path", + "description": "The broker code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "organization-fiscal-code", + "in": "path", + "description": "The organization fiscal code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } } - } ], - "requestBody" : { - "content" : { - "multipart/form-data" : { - "schema" : { - "type" : "object", - "properties" : { - "file" : { - "type" : "string", - "description" : "File to be uploaded", - "format" : "binary" + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "file": { + "type": "string", + "description": "File to be uploaded", + "format": "binary" } } }, - "encoding" : { - "file" : { - "contentType" : "application/octet-stream" + "encoding": { + "file": { + "contentType": "application/octet-stream" } } } }, - "required" : true + "required": true }, - "responses" : { - "202" : { - "description" : "Request accepted." + "responses": { + "202": { + "description": "Request accepted." }, - "400" : { - "description" : "Malformed request.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "400": { + "description": "Malformed request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "401" : { - "description" : "Wrong or missing function key.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "401": { + "description": "Wrong or missing function key.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "403" : { - "description" : "Forbidden", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "409" : { - "description" : "Conflict: duplicate file found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "409": { + "description": "Conflict: duplicate file found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "429" : { - "description" : "Too many requests.", - "content" : { - "text/json" : { } + "429": { + "description": "Too many requests.", + "content": { + "text/json": {} } }, - "500" : { - "description" : "Service unavailable.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "500": { + "description": "Service unavailable.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } } }, - "security" : [ { - "ApiKey" : [ ] - }, { - "Authorization" : [ ] - } ] - }, - "post" : { - "tags" : [ "Debt Positions CRUD via file upload API" ], - "summary" : "The Organization creates the debt positions listed in the file.", - "operationId" : "create-debt-positions-by-file-upload", - "parameters" : [ { - "name" : "broker-code", - "in" : "path", - "description" : "The broker code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + "security": [ + { + "ApiKey": [] + }, + { + "Authorization": [] } - }, { - "name" : "organization-fiscal-code", - "in" : "path", - "description" : "The organization fiscal code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + ] + }, + "post": { + "tags": [ + "Debt Positions CRUD via file upload API" + ], + "summary": "The Organization creates the debt positions listed in the file.", + "operationId": "create-debt-positions-by-file-upload", + "parameters": [ + { + "name": "broker-code", + "in": "path", + "description": "The broker code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "organization-fiscal-code", + "in": "path", + "description": "The organization fiscal code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } } - } ], - "requestBody" : { - "content" : { - "multipart/form-data" : { - "schema" : { - "type" : "object", - "properties" : { - "file" : { - "type" : "string", - "description" : "File to be uploaded", - "format" : "binary" + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "file": { + "type": "string", + "description": "File to be uploaded", + "format": "binary" } } }, - "encoding" : { - "file" : { - "contentType" : "application/octet-stream" + "encoding": { + "file": { + "contentType": "application/octet-stream" } } } }, - "required" : true + "required": true }, - "responses" : { - "202" : { - "description" : "Request accepted." + "responses": { + "202": { + "description": "Request accepted." }, - "400" : { - "description" : "Malformed request.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "400": { + "description": "Malformed request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "401" : { - "description" : "Wrong or missing function key.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "401": { + "description": "Wrong or missing function key.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "403" : { - "description" : "Forbidden", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "409" : { - "description" : "Conflict: duplicate file found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "409": { + "description": "Conflict: duplicate file found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "429" : { - "description" : "Too many requests.", - "content" : { - "text/json" : { } + "429": { + "description": "Too many requests.", + "content": { + "text/json": {} } }, - "500" : { - "description" : "Service unavailable.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "500": { + "description": "Service unavailable.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } } }, - "security" : [ { - "ApiKey" : [ ] - }, { - "Authorization" : [ ] - } ] - }, - "delete" : { - "tags" : [ "Debt Positions CRUD via file upload API" ], - "summary" : "The Organization deletes the debt positions based on IUPD listed in the file.", - "operationId" : "delete-debt-positions-by-file-upload", - "parameters" : [ { - "name" : "broker-code", - "in" : "path", - "description" : "The broker code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + "security": [ + { + "ApiKey": [] + }, + { + "Authorization": [] } - }, { - "name" : "organization-fiscal-code", - "in" : "path", - "description" : "The organization fiscal code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + ] + }, + "delete": { + "tags": [ + "Debt Positions CRUD via file upload API" + ], + "summary": "The Organization deletes the debt positions based on IUPD listed in the file.", + "operationId": "delete-debt-positions-by-file-upload", + "parameters": [ + { + "name": "broker-code", + "in": "path", + "description": "The broker code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "organization-fiscal-code", + "in": "path", + "description": "The organization fiscal code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } } - } ], - "requestBody" : { - "content" : { - "multipart/form-data" : { - "schema" : { - "type" : "object", - "properties" : { - "file" : { - "type" : "string", - "description" : "File to be uploaded", - "format" : "binary" + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "file": { + "type": "string", + "description": "File to be uploaded", + "format": "binary" } } }, - "encoding" : { - "file" : { - "contentType" : "application/octet-stream" + "encoding": { + "file": { + "contentType": "application/octet-stream" } } } }, - "required" : true + "required": true }, - "responses" : { - "202" : { - "description" : "Request accepted." + "responses": { + "202": { + "description": "Request accepted." }, - "400" : { - "description" : "Malformed request.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "400": { + "description": "Malformed request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "401" : { - "description" : "Wrong or missing function key.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "401": { + "description": "Wrong or missing function key.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "403" : { - "description" : "Forbidden", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "409" : { - "description" : "Conflict: duplicate file found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "409": { + "description": "Conflict: duplicate file found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "429" : { - "description" : "Too many requests.", - "content" : { - "text/json" : { } + "429": { + "description": "Too many requests.", + "content": { + "text/json": {} } }, - "500" : { - "description" : "Service unavailable.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "500": { + "description": "Service unavailable.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } } }, - "security" : [ { - "ApiKey" : [ ] - }, { - "Authorization" : [ ] - } ] + "security": [ + { + "ApiKey": [] + }, + { + "Authorization": [] + } + ] } }, - "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/report" : { - "get" : { - "tags" : [ "Upload Status API" ], - "summary" : "Returns the debt positions upload report.", - "operationId" : "get-debt-positions-upload-report", - "parameters" : [ { - "name" : "broker-code", - "in" : "path", - "description" : "The broker code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" - } - }, { - "name" : "organization-fiscal-code", - "in" : "path", - "description" : "The organization fiscal code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" - } - }, { - "name" : "file-id", - "in" : "path", - "description" : "The unique identifier for file upload", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/report": { + "get": { + "tags": [ + "Upload Status API" + ], + "summary": "Returns the debt positions upload report.", + "operationId": "get-debt-positions-upload-report", + "parameters": [ + { + "name": "broker-code", + "in": "path", + "description": "The broker code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "organization-fiscal-code", + "in": "path", + "description": "The organization fiscal code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "file-id", + "in": "path", + "description": "The unique identifier for file upload", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } } - } ], - "responses" : { - "200" : { - "description" : "Upload report found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UploadReport" + ], + "responses": { + "200": { + "description": "Upload report found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UploadReport" } } } }, - "400" : { - "description" : "Malformed request.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "400": { + "description": "Malformed request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "401" : { - "description" : "Wrong or missing function key.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "401": { + "description": "Wrong or missing function key.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "403" : { - "description" : "Forbidden", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "404" : { - "description" : "Upload report not found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "404": { + "description": "Upload report not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "429" : { - "description" : "Too many requests.", - "content" : { - "text/json" : { } + "429": { + "description": "Too many requests.", + "content": { + "text/json": {} } }, - "500" : { - "description" : "Service unavailable.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "500": { + "description": "Service unavailable.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } } }, - "security" : [ { - "ApiKey" : [ ] - }, { - "Authorization" : [ ] - } ] + "security": [ + { + "ApiKey": [] + }, + { + "Authorization": [] + } + ] } }, - "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/status" : { - "get" : { - "tags" : [ "Upload Status API" ], - "summary" : "Returns the debt positions upload status.", - "operationId" : "get-debt-positions-upload-status", - "parameters" : [ { - "name" : "broker-code", - "in" : "path", - "description" : "The broker code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" - } - }, { - "name" : "organization-fiscal-code", - "in" : "path", - "description" : "The organization fiscal code", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" - } - }, { - "name" : "file-id", - "in" : "path", - "description" : "The unique identifier for file upload", - "required" : true, - "schema" : { - "minLength" : 1, - "type" : "string" + "/brokers/{broker-code}/organizations/{organization-fiscal-code}/debtpositions/file/{file-id}/status": { + "get": { + "tags": [ + "Upload Status API" + ], + "summary": "Returns the debt positions upload status.", + "operationId": "get-debt-positions-upload-status", + "parameters": [ + { + "name": "broker-code", + "in": "path", + "description": "The broker code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "organization-fiscal-code", + "in": "path", + "description": "The organization fiscal code", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "name": "file-id", + "in": "path", + "description": "The unique identifier for file upload", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } } - } ], - "responses" : { - "200" : { - "description" : "Upload found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UploadStatus" + ], + "responses": { + "200": { + "description": "Upload found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UploadStatus" } } } }, - "400" : { - "description" : "Malformed request.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "400": { + "description": "Malformed request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "401" : { - "description" : "Wrong or missing function key.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "401": { + "description": "Wrong or missing function key.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "403" : { - "description" : "Forbidden", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "404" : { - "description" : "Upload not found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "404": { + "description": "Upload not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "429" : { - "description" : "Too many requests.", - "content" : { - "text/json" : { } + "429": { + "description": "Too many requests.", + "content": { + "text/json": {} } }, - "500" : { - "description" : "Service unavailable.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "500": { + "description": "Service unavailable.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } } }, - "security" : [ { - "ApiKey" : [ ] - }, { - "Authorization" : [ ] - } ] + "security": [ + { + "ApiKey": [] + }, + { + "Authorization": [] + } + ] } }, - "/info" : { - "get" : { - "tags" : [ "Health check" ], - "summary" : "health check", - "description" : "Return OK if application is started", - "operationId" : "healthCheck", - "responses" : { - "200" : { - "description" : "OK", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/AppInfo" + "/info": { + "get": { + "tags": [ + "Health check" + ], + "summary": "health check", + "description": "Return OK if application is started", + "operationId": "healthCheck", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AppInfo" } } } }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "403" : { - "description" : "Forbidden", - "content" : { - "application/json" : { - "schema" : { - "allOf" : [ ], - "anyOf" : [ ], - "oneOf" : [ ] + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "allOf": [], + "anyOf": [], + "oneOf": [] } } } }, - "429" : { - "description" : "Too many requests.", - "content" : { - "text/json" : { } + "429": { + "description": "Too many requests.", + "content": { + "text/json": {} } }, - "500" : { - "description" : "Service unavailable", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProblemJson" + "500": { + "description": "Service unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" } } } @@ -657,123 +710,123 @@ } } }, - "components" : { - "schemas" : { - "AppInfo" : { - "type" : "object", - "properties" : { - "name" : { - "type" : "string" - }, - "version" : { - "type" : "string" - }, - "environment" : { - "type" : "string" + "components": { + "schemas": { + "AppInfo": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "environment": { + "type": "string" } } }, - "ProblemJson" : { - "type" : "object", - "properties" : { - "title" : { - "type" : "string", - "description" : "A short, summary of the problem type. Written in english and readable for engineers (usually not suited for non technical stakeholders and not localized); example: Service Unavailable" - }, - "status" : { - "type" : "integer", - "description" : "The HTTP status code generated by the origin server for this occurrence of the problem.", - "format" : "int32", - "example" : 200 - }, - "detail" : { - "type" : "string", - "description" : "A human readable explanation specific to this occurrence of the problem.", - "example" : "There was an error processing the request" + "ProblemJson": { + "type": "object", + "properties": { + "title": { + "type": "string", + "description": "A short, summary of the problem type. Written in english and readable for engineers (usually not suited for non technical stakeholders and not localized); example: Service Unavailable" + }, + "status": { + "type": "integer", + "description": "The HTTP status code generated by the origin server for this occurrence of the problem.", + "format": "int32", + "example": 200 + }, + "detail": { + "type": "string", + "description": "A human readable explanation specific to this occurrence of the problem.", + "example": "There was an error processing the request" } }, - "description" : "Object returned as response in case of an error." + "description": "Object returned as response in case of an error." }, - "ResponseEntry" : { - "type" : "object", - "properties" : { - "statusCode" : { - "type" : "integer", - "format" : "int32", - "example" : 400 - }, - "statusMessage" : { - "type" : "string", - "example" : "Bad request caused by invalid email address" - }, - "requestIDs" : { - "type" : "array", - "items" : { - "type" : "string" + "ResponseEntry": { + "type": "object", + "properties": { + "statusCode": { + "type": "integer", + "format": "int32", + "example": 400 + }, + "statusMessage": { + "type": "string", + "example": "Bad request caused by invalid email address" + }, + "requestIDs": { + "type": "array", + "items": { + "type": "string" } } } }, - "UploadReport" : { - "type" : "object", - "properties" : { - "uploadID" : { - "type" : "string" - }, - "processedItem" : { - "type" : "integer", - "format" : "int32" - }, - "submittedItem" : { - "type" : "integer", - "format" : "int32" - }, - "responses" : { - "type" : "array", - "items" : { - "$ref" : "#/components/schemas/ResponseEntry" - } - }, - "startTime" : { - "type" : "string", - "format" : "date-time", - "example" : "2024-10-08T14:55:16.302Z" - }, - "endTime" : { - "type" : "string", - "format" : "date-time", - "example" : "2024-10-08T14:55:16.302Z" + "UploadReport": { + "type": "object", + "properties": { + "uploadID": { + "type": "string" + }, + "processedItem": { + "type": "integer", + "format": "int32" + }, + "submittedItem": { + "type": "integer", + "format": "int32" + }, + "responses": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ResponseEntry" + } + }, + "startTime": { + "type": "string", + "format": "date-time", + "example": "2024-10-08T14:55:16.302Z" + }, + "endTime": { + "type": "string", + "format": "date-time", + "example": "2024-10-08T14:55:16.302Z" } } }, - "UploadStatus" : { - "type" : "object", - "properties" : { - "uploadID" : { - "type" : "string" - }, - "processedItem" : { - "type" : "integer", - "format" : "int32" - }, - "submittedItem" : { - "type" : "integer", - "format" : "int32" - }, - "startTime" : { - "type" : "string", - "format" : "date-time", - "example" : "2024-10-08T14:55:16.302Z" + "UploadStatus": { + "type": "object", + "properties": { + "uploadID": { + "type": "string" + }, + "processedItem": { + "type": "integer", + "format": "int32" + }, + "submittedItem": { + "type": "integer", + "format": "int32" + }, + "startTime": { + "type": "string", + "format": "date-time", + "example": "2024-10-08T14:55:16.302Z" } } } }, - "securitySchemes" : { - "Ocp-Apim-Subscription-Key" : { - "type" : "apiKey", - "name" : "Ocp-Apim-Subscription-Key", - "in" : "header" + "securitySchemes": { + "Ocp-Apim-Subscription-Key": { + "type": "apiKey", + "name": "Ocp-Apim-Subscription-Key", + "in": "header" } } } -} \ No newline at end of file +} diff --git a/pom.xml b/pom.xml index b9ff881..b8a8fb0 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 it.gov.pagopa.gpd.upload pagopa-gpd-upload - 0.1.33 + 0.1.33-1-recover-delete-operation-status ${packaging}