Skip to content

Commit

Permalink
Merge pull request #752 from catenax-ng/feature/#249-extend-policies-…
Browse files Browse the repository at this point in the history
…structure

Feature/#249 policy controller enchancements
  • Loading branch information
ds-psosnowski authored Feb 5, 2024
2 parents 995284a + 465ca26 commit 66c68aa
Show file tree
Hide file tree
Showing 9 changed files with 483 additions and 296 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@
import static org.eclipse.tractusx.irs.common.ApiConstants.UNAUTHORIZED_DESC;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;

import java.util.List;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
Expand All @@ -38,13 +36,15 @@
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import jakarta.validation.Valid;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.tractusx.irs.common.auth.IrsRoles;
import org.eclipse.tractusx.irs.dtos.ErrorResponse;
import org.eclipse.tractusx.irs.edc.client.policy.Policy;
import org.eclipse.tractusx.irs.edc.client.transformer.EdcTransformer;
import org.eclipse.tractusx.irs.policystore.models.CreatePolicyRequest;
import org.eclipse.tractusx.irs.policystore.models.PolicyResponse;
import org.eclipse.tractusx.irs.policystore.models.UpdatePolicyRequest;
import org.eclipse.tractusx.irs.policystore.services.PolicyStoreService;
import org.springframework.http.HttpStatus;
Expand Down Expand Up @@ -133,8 +133,10 @@ public void registerAllowedPolicy(final @RequestBody CreatePolicyRequest request
@GetMapping("/policies")
@ResponseStatus(HttpStatus.OK)
@PreAuthorize("hasAuthority('" + IrsRoles.ADMIN_IRS + "')")
public List<Policy> getPolicies() {
return service.getStoredPolicies();
public List<PolicyResponse> getPolicies() {
return service.getStoredPolicies().stream()
.map(PolicyResponse::fromPolicy)
.toList();
}

@Operation(operationId = "deleteAllowedPolicy",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/********************************************************************************
* Copyright (c) 2022,2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
* Copyright (c) 2021,2024 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/
package org.eclipse.tractusx.irs.policystore.models;

/**
* Context representation for get all policies response
*/
public record Context(String odrl) {
private static final String ODRL_VALUE = "http://www.w3.org/ns/odrl/2/";

public static Context getDefault() {
return new Context(ODRL_VALUE);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/********************************************************************************
* Copyright (c) 2022,2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
* Copyright (c) 2021,2024 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/
package org.eclipse.tractusx.irs.policystore.models;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Builder;
import org.eclipse.tractusx.irs.edc.client.policy.Policy;

/**
* Payload representation for get all policies response
*/
@Builder
public record Payload(
@JsonProperty("@context") Context context,
@JsonProperty("@id") String policyId,
Policy policy
) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/********************************************************************************
* Copyright (c) 2022,2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
* Copyright (c) 2021,2024 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/
package org.eclipse.tractusx.irs.policystore.models;

import java.time.OffsetDateTime;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import org.eclipse.tractusx.irs.edc.client.policy.Policy;

/**
* Policy representation for get all policies response
*/
@Builder
@Schema(example = PolicyResponse.EXAMPLE_PAYLOAD)
public record PolicyResponse(OffsetDateTime validUntil, Payload payload) {

@SuppressWarnings({"FileTabCharacter", "java:S2479"})
// required to show correctly example payload in open-api
public static final String EXAMPLE_PAYLOAD = """
[
{
"validUntil": "2025-12-12T23:59:59.999Z",
"payload": {
"@context": {
"odrl": "http://www.w3.org/ns/odrl/2/"
},
"@id": "policy-id",
"policy": {
"odrl:permission": [
{
"odrl:action": "USE",
"odrl:constraint": {
"odrl:and": [
{
"odrl:leftOperand": "Membership",
"odrl:operator": {
"@id": "odrl:eq"
},
"odrl:rightOperand": "active"
},
{
"odrl:leftOperand": "PURPOSE",
"odrl:operator": {
"@id": "odrl:eq"
},
"odrl:rightOperand": "ID 3.1 Trace"
}
]
}
}
]
}
}
}
]
""";

public static PolicyResponse fromPolicy(final Policy policy) {
return PolicyResponse.builder()
.validUntil(policy.getValidUntil())
.payload(Payload.builder()
.policyId(policy.getPolicyId())
.context(Context.getDefault())
.policy(policy)
.build())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,8 @@

/**
* Request object for policy update
*
*/
@Schema(description = "Request to add a policy")
public record UpdatePolicyRequest(@Schema(description = "Timestamp after which the policy will no longer be accepted in negotiations") @NotNull OffsetDateTime validUntil) {

public record UpdatePolicyRequest(
@Schema(description = "Timestamp after which the policy will no longer be accepted in negotiations") @NotNull OffsetDateTime validUntil) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
********************************************************************************/
package org.eclipse.tractusx.irs.policystore.services;

import java.time.Clock;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
Expand Down Expand Up @@ -57,17 +58,20 @@ public class PolicyStoreService implements AcceptedPoliciesProvider {
private final String apiAllowedBpn;
private final List<Policy> allowedPoliciesFromConfig;
private final PolicyPersistence persistence;
private final Clock clock;
private static final String MISSING_REQUEST_FIELD_MESSAGE = "Request does not contain all required fields. Missing: %s";

public PolicyStoreService(@Value("${apiAllowedBpn:}") final String apiAllowedBpn,
final DefaultAcceptedPoliciesConfig defaultAcceptedPoliciesConfig, final PolicyPersistence persistence) {
final DefaultAcceptedPoliciesConfig defaultAcceptedPoliciesConfig, final PolicyPersistence persistence, final Clock clock) {
this.apiAllowedBpn = apiAllowedBpn;

this.allowedPoliciesFromConfig = createDefaultPolicyFromConfig(defaultAcceptedPoliciesConfig);

this.persistence = persistence;
this.clock = clock;
}

public void registerPolicy(final Policy policy) {
validatePolicy(policy);
policy.setCreatedOn(OffsetDateTime.now(clock));
log.info("Registering new policy with id {}, valid until {}", policy.getPolicyId(), policy.getValidUntil());
try {
persistence.save(apiAllowedBpn, policy);
Expand All @@ -76,6 +80,19 @@ public void registerPolicy(final Policy policy) {
}
}

/**
* Checks whether policy from register policy request has all required fields
* @param policy policy to register
*/
private void validatePolicy(final Policy policy) {
if (policy.getPermissions() == null) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, String.format(MISSING_REQUEST_FIELD_MESSAGE, "odrl:permission"));
}
if (policy.getPermissions().stream().anyMatch(p -> p.getConstraint() == null)) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, String.format(MISSING_REQUEST_FIELD_MESSAGE, "odrl:constraint"));
}
}

public List<Policy> getStoredPolicies() {
log.info("Reading all stored polices for BPN {}", apiAllowedBpn);
final var storedPolicies = persistence.readAll(apiAllowedBpn);
Expand Down
Loading

0 comments on commit 66c68aa

Please sign in to comment.