Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Feat/559 Dedicated Removal of Policy from BPNL #614

Merged
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
dsmf marked this conversation as resolved.
Show resolved Hide resolved

### Fixed
Expand Down
53 changes: 53 additions & 0 deletions docs/src/api/irs-api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -88,20 +89,25 @@ void generatedOpenApiMatchesContract() throws Exception {
final Map<String, Object> definedYamlMap = mapper.readerForMapOf(Object.class).readValue(definedYaml);
final Map<String, Object> 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);
}

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -217,6 +218,42 @@ 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 + "')")
public void removeAllowedPolicyFromBpnl(
// TODO (#528): add validation
//@ValidPolicyId
dsmf marked this conversation as resolved.
Show resolved Hide resolved
@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.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ public void deletePolicy(final String policyId) {
}
}

private void deletePolicyForEachBpn(final String policyId, final List<String> bpnList) {
public void deletePolicyForEachBpn(final String policyId, final List<String> bpnList) {
try {
for (final String bpn : bpnList) {
persistence.delete(bpn, policyId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
Loading