From 52805322a84f7556f879a917d94f4bf74f9b6f91 Mon Sep 17 00:00:00 2001 From: Matthias Fischer Date: Sat, 11 May 2024 01:21:18 +0200 Subject: [PATCH 01/10] feat(impl): [#559] add delete policy endpoint for single BPNL --- .../controllers/PolicyStoreController.java | 13 +++++++++++++ .../policystore/services/PolicyStoreService.java | 2 +- .../services/PolicyStoreServiceTest.java | 12 ++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/controllers/PolicyStoreController.java b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/controllers/PolicyStoreController.java index 470f714830..ba62207c14 100644 --- a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/controllers/PolicyStoreController.java +++ b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/controllers/PolicyStoreController.java @@ -42,6 +42,7 @@ import io.swagger.v3.oas.annotations.security.SecurityRequirement; import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; +import jakarta.validation.constraints.Pattern; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; @@ -217,6 +218,18 @@ public void deleteAllowedPolicy(@PathVariable("policyId") final String policyId) service.deletePolicy(policyId); } + @DeleteMapping("/policies/{policyId}/bpnl/{bpnl}") + @ResponseStatus(HttpStatus.OK) + @PreAuthorize("hasAuthority('" + IrsRoles.ADMIN_IRS + "')") + public void removeAllowedPolicyFromBpnl( + // TODO (#528): add validation + //@ValidPolicyId + @PathVariable("policyId") final String policyId, // + @Pattern(regexp = BPN_REGEX, message = " Invalid BPN.") // + @PathVariable("bpnl") final String bpnl) { + service.deletePolicyForEachBpn(policyId, List.of(bpnl)); + } + @Operation(operationId = "updateAllowedPolicy", summary = "Updates existing policies.", security = @SecurityRequirement(name = "api_key"), tags = { "Item Relationship Service" }, description = "Updates existing policies.") diff --git a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/services/PolicyStoreService.java b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/services/PolicyStoreService.java index a47ba48ea5..8f6f83afb0 100644 --- a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/services/PolicyStoreService.java +++ b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/services/PolicyStoreService.java @@ -218,7 +218,7 @@ public void deletePolicy(final String policyId) { } } - private void deletePolicyForEachBpn(final String policyId, final List bpnList) { + public void deletePolicyForEachBpn(final String policyId, final List bpnList) { try { for (final String bpn : bpnList) { persistence.delete(bpn, policyId); diff --git a/irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/services/PolicyStoreServiceTest.java b/irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/services/PolicyStoreServiceTest.java index 802a60114c..ac47fd0b4d 100644 --- a/irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/services/PolicyStoreServiceTest.java +++ b/irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/services/PolicyStoreServiceTest.java @@ -40,6 +40,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.UUID; import jakarta.json.Json; import jakarta.json.JsonObject; @@ -355,6 +356,17 @@ private Constraints createConstraints() { @Nested class DeletePolicyTests { + @Test + void deletePolicyForEachBpn_success() { + // ACT + final String policyId = UUID.randomUUID().toString(); + testee.deletePolicyForEachBpn(policyId, List.of("BPN1", "BPN2")); + + // ASSERT + verify(persistenceMock).delete("BPN1", policyId); + verify(persistenceMock).delete("BPN2", policyId); + } + @Test void deletePolicy_deleteSuccessful() { // ARRANGE From 40d54ab22807667d43b6fb43a832e1375aa70725 Mon Sep 17 00:00:00 2001 From: Matthias Fischer Date: Sat, 11 May 2024 01:22:06 +0200 Subject: [PATCH 02/10] feat(impl): [#559] add test step definition --- .../irs/cucumber/E2ETestHelperForPolicyStoreApi.java | 10 ++++++++++ .../E2ETestStepDefinitionsForPolicyStoreApi.java | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/irs-cucumber-tests/src/test/java/org/eclipse/tractusx/irs/cucumber/E2ETestHelperForPolicyStoreApi.java b/irs-cucumber-tests/src/test/java/org/eclipse/tractusx/irs/cucumber/E2ETestHelperForPolicyStoreApi.java index 55dccb54c7..776975e328 100644 --- a/irs-cucumber-tests/src/test/java/org/eclipse/tractusx/irs/cucumber/E2ETestHelperForPolicyStoreApi.java +++ b/irs-cucumber-tests/src/test/java/org/eclipse/tractusx/irs/cucumber/E2ETestHelperForPolicyStoreApi.java @@ -250,6 +250,16 @@ public static ValidatableResponse deletePolicy( .then(); } + public static ValidatableResponse removePolicyFromBpnl( + final AuthenticationPropertiesBuilder authenticationPropertiesBuilder, final String policyId, + final String bpnl) { + return givenAuthentication(authenticationPropertiesBuilder).pathParam("policyId", policyId) + .pathParam("bpnl", bpnl) + .when() + .delete(URL_IRS_POLICIES + "/{policyId}/bpnl/{bpnl}") + .then(); + } + @Data @NoArgsConstructor public static final class PolicyAttributes { diff --git a/irs-cucumber-tests/src/test/java/org/eclipse/tractusx/irs/cucumber/E2ETestStepDefinitionsForPolicyStoreApi.java b/irs-cucumber-tests/src/test/java/org/eclipse/tractusx/irs/cucumber/E2ETestStepDefinitionsForPolicyStoreApi.java index a775f3c0b0..f3d32ea204 100644 --- a/irs-cucumber-tests/src/test/java/org/eclipse/tractusx/irs/cucumber/E2ETestStepDefinitionsForPolicyStoreApi.java +++ b/irs-cucumber-tests/src/test/java/org/eclipse/tractusx/irs/cucumber/E2ETestStepDefinitionsForPolicyStoreApi.java @@ -177,6 +177,12 @@ public void iDeletePolicyWithPolicyId(final String policyId) { policyId); } + @When("I remove the policy {string} from BPN {string}") + public void iRemovePolicyFromBpnl(final String policyId, final String bpnl) { + this.deletePoliciesResponse = E2ETestHelperForPolicyStoreApi.removePolicyFromBpnl( + this.authenticationPropertiesBuilder, policyId, bpnl); + } + @Then("the delete policy response should have HTTP status {int}") public void theDeletePolicyResponseShouldHaveStatus(final int httpStatus) { this.deletePoliciesResponse.statusCode(httpStatus); From 6da1ec9c81f65783703f597d1002295b1e398f64 Mon Sep 17 00:00:00 2001 From: Matthias Fischer Date: Sat, 11 May 2024 01:34:32 +0200 Subject: [PATCH 03/10] feat(impl): [#559] update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7162b38fd0..756db15581 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ _**For better traceability add the corresponding GitHub issue number in each cha ### Added +- Added endpoint for dedicated removal of policy from BPNL. #559 - Cucumber test step definitions for Policy Store API (Happy Path) including some test helper utilities. #518 From 183658e4c1c7c9b755849e84ebbdfbdc8d04f5c8 Mon Sep 17 00:00:00 2001 From: Matthias Fischer Date: Sat, 11 May 2024 01:36:38 +0200 Subject: [PATCH 04/10] feat(impl): [#559] correct CHANGELOG.md --- CHANGELOG.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 756db15581..69c7f45589 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,13 @@ _**For better traceability add the corresponding GitHub issue number in each cha ## [Unreleased] +## Added + +- Added endpoint for dedicated removal of policy from BPNL. #559 + + + + ## [5.1.1] - 2024-05-08 ### Fixed @@ -16,7 +23,6 @@ _**For better traceability add the corresponding GitHub issue number in each cha ### Added -- Added endpoint for dedicated removal of policy from BPNL. #559 - Cucumber test step definitions for Policy Store API (Happy Path) including some test helper utilities. #518 From 7e61c02d9746800e32d183f307b50d5fe28bfa31 Mon Sep 17 00:00:00 2001 From: Matthias Fischer Date: Sat, 11 May 2024 02:57:14 +0200 Subject: [PATCH 05/10] feat(impl): [#559] write irs-api.actual.yaml if there are differences (to simplify comparison) --- .../tractusx/irs/IrsApplicationTests.java | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsApplicationTests.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsApplicationTests.java index da34d33cc1..b902f986e4 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsApplicationTests.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsApplicationTests.java @@ -28,6 +28,7 @@ import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -88,20 +89,25 @@ void generatedOpenApiMatchesContract() throws Exception { final Map definedYamlMap = mapper.readerForMapOf(Object.class).readValue(definedYaml); final Map generatedYamlMap = mapper.readerForMapOf(Object.class).readValue(generatedYaml); - // To correctly display both documentations examples - manual and generated by annotations - - // we need to remove verification for some "examples", otherwise one or another won't display correctly - assertThat(generatedYamlMap) - - .usingRecursiveComparison() - - .ignoringFields("components.schemas.PageResult.example") - .ignoringFields("components.schemas.AspectModels.example") - .ignoringFields("components.schemas.BatchOrderResponse.example") - .ignoringFields("components.schemas.Jobs.example") - .ignoringFields("components.schemas.Policy") - .ignoringFields("components.schemas.BatchResponse.example") - - .isEqualTo(definedYamlMap); + try { + // To correctly display both documentations examples - manual and generated by annotations - + // we need to remove verification for some "examples", otherwise one or another won't display correctly + assertThat(generatedYamlMap) + + .usingRecursiveComparison() + + .ignoringFields("components.schemas.PageResult.example") + .ignoringFields("components.schemas.AspectModels.example") + .ignoringFields("components.schemas.BatchOrderResponse.example") + .ignoringFields("components.schemas.Jobs.example") + .ignoringFields("components.schemas.Policy") + .ignoringFields("components.schemas.BatchResponse.example") + + .isEqualTo(definedYamlMap); + } catch (AssertionError e) { + // write changed API to file for easier comparison + Files.writeString(Paths.get("../docs/src/api/irs-api.actual.yaml"), generatedYaml); + } } From 862c6470f2d1944404253e045175918a0fada235 Mon Sep 17 00:00:00 2001 From: Matthias Fischer Date: Sat, 11 May 2024 02:57:44 +0200 Subject: [PATCH 06/10] feat(impl): [#559] add OpenAPI annotations --- .../controllers/PolicyStoreController.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/controllers/PolicyStoreController.java b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/controllers/PolicyStoreController.java index ba62207c14..d25100f0d1 100644 --- a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/controllers/PolicyStoreController.java +++ b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/controllers/PolicyStoreController.java @@ -218,6 +218,30 @@ public void deleteAllowedPolicy(@PathVariable("policyId") final String policyId) service.deletePolicy(policyId); } + @Operation(operationId = "removeAllowedPolicyFromBpnl", + summary = "Removes a policy from BPNL that should no longer be accepted in EDC negotiation.", + security = @SecurityRequirement(name = "api_key"), tags = { "Item Relationship Service" }, + description = "Removes a policy from BPNL that should no longer be accepted in EDC negotiation.") + @ApiResponses(value = { @ApiResponse(responseCode = "200"), + @ApiResponse(responseCode = "400", description = "Policy deletion failed.", + content = { @Content(mediaType = APPLICATION_JSON_VALUE, + schema = @Schema(implementation = ErrorResponse.class), + examples = @ExampleObject(name = "error", + ref = "#/components/examples/error-response-400")) + }), + @ApiResponse(responseCode = "401", description = UNAUTHORIZED_DESC, + content = { @Content(mediaType = APPLICATION_JSON_VALUE, + schema = @Schema(implementation = ErrorResponse.class), + examples = @ExampleObject(name = "error", + ref = "#/components/examples/error-response-401")) + }), + @ApiResponse(responseCode = "403", description = FORBIDDEN_DESC, + content = { @Content(mediaType = APPLICATION_JSON_VALUE, + schema = @Schema(implementation = ErrorResponse.class), + examples = @ExampleObject(name = "error", + ref = "#/components/examples/error-response-403")) + }), + }) @DeleteMapping("/policies/{policyId}/bpnl/{bpnl}") @ResponseStatus(HttpStatus.OK) @PreAuthorize("hasAuthority('" + IrsRoles.ADMIN_IRS + "')") From 408c48de813e2d8f9459c24f13a5cfe683448fe9 Mon Sep 17 00:00:00 2001 From: Matthias Fischer Date: Sat, 11 May 2024 02:58:28 +0200 Subject: [PATCH 07/10] feat(impl): [#559] update .gitignore to ignore irs-api.actual.yaml --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 95c2c9c5ec..4ed293562b 100644 --- a/.gitignore +++ b/.gitignore @@ -74,3 +74,4 @@ docs/src/diagram-replacer/plantuml.jar # Helm Chart Dependencies /charts/item-relationship-service/Chart.lock /charts/item-relationship-service/charts/ +/docs/src/api/irs-api.actual.yaml From 7fe10365787a432849f4ef842abc63b80b3564e4 Mon Sep 17 00:00:00 2001 From: Matthias Fischer Date: Sat, 11 May 2024 02:59:06 +0200 Subject: [PATCH 08/10] feat(impl): [#559] update irs-api.yaml --- docs/src/api/irs-api.yaml | 53 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/docs/src/api/irs-api.yaml b/docs/src/api/irs-api.yaml index 41e0d96965..80128e2185 100644 --- a/docs/src/api/irs-api.yaml +++ b/docs/src/api/irs-api.yaml @@ -1016,6 +1016,59 @@ paths: summary: Removes a policy that should no longer be accepted in EDC negotiation. tags: - Item Relationship Service + /irs/policies/{policyId}/bpnl/{bpnl}: + delete: + description: Removes a policy from BPNL that should no longer be accepted in + EDC negotiation. + operationId: removeAllowedPolicyFromBpnl + parameters: + - in: path + name: policyId + required: true + schema: + type: string + - in: path + name: bpnl + required: true + schema: + type: string + pattern: "(BPN)[LSA][\\w\\d]{10}[\\w\\d]{2}" + responses: + "200": + description: OK + "400": + content: + application/json: + examples: + error: + $ref: '#/components/examples/error-response-400' + schema: + $ref: '#/components/schemas/ErrorResponse' + description: Policy deletion failed. + "401": + content: + application/json: + examples: + error: + $ref: '#/components/examples/error-response-401' + schema: + $ref: '#/components/schemas/ErrorResponse' + description: No valid authentication credentials. + "403": + content: + application/json: + examples: + error: + $ref: '#/components/examples/error-response-403' + schema: + $ref: '#/components/schemas/ErrorResponse' + description: Authorization refused by server. + security: + - api_key: [] + summary: Removes a policy from BPNL that should no longer be accepted in EDC + negotiation. + tags: + - Item Relationship Service components: examples: aspect-models-list: From 763ddbd2a5ac93109d1afed8a76ece5cc6de525f Mon Sep 17 00:00:00 2001 From: Matthias Fischer Date: Mon, 13 May 2024 14:03:13 +0200 Subject: [PATCH 09/10] Update CHANGELOG.md Co-authored-by: Jaro Hartmann <57985712+ds-jhartmann@users.noreply.github.com> --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69c7f45589..5c5706a037 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,8 +13,6 @@ _**For better traceability add the corresponding GitHub issue number in each cha - Added endpoint for dedicated removal of policy from BPNL. #559 - - ## [5.1.1] - 2024-05-08 ### Fixed From 7bef9368209ae37d204d71553990c34914b7e775 Mon Sep 17 00:00:00 2001 From: Matthias Fischer Date: Mon, 13 May 2024 14:04:25 +0200 Subject: [PATCH 10/10] remove uncommented code with TODO #528 --- .../irs/policystore/controllers/PolicyStoreController.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/controllers/PolicyStoreController.java b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/controllers/PolicyStoreController.java index d25100f0d1..10968b392d 100644 --- a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/controllers/PolicyStoreController.java +++ b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/controllers/PolicyStoreController.java @@ -246,8 +246,6 @@ public void deleteAllowedPolicy(@PathVariable("policyId") final String policyId) @ResponseStatus(HttpStatus.OK) @PreAuthorize("hasAuthority('" + IrsRoles.ADMIN_IRS + "')") public void removeAllowedPolicyFromBpnl( - // TODO (#528): add validation - //@ValidPolicyId @PathVariable("policyId") final String policyId, // @Pattern(regexp = BPN_REGEX, message = " Invalid BPN.") // @PathVariable("bpnl") final String bpnl) {