Skip to content

Commit

Permalink
docs: add openapi examples for policy definition endpoints (#3272)
Browse files Browse the repository at this point in the history
  • Loading branch information
ndr-brt authored Jul 6, 2023
1 parent a96918e commit fcf729d
Show file tree
Hide file tree
Showing 35 changed files with 393 additions and 1,204 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@
import org.eclipse.edc.spi.system.ConfigurationExtension;
import org.eclipse.edc.spi.system.ServiceExtensionContext;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;

import static java.util.Optional.ofNullable;
import static org.mockito.Mockito.mock;

/**
* This variant of the {@link DefaultServiceExtensionContext} maintains a list of service mocks, so that they will be used for dependency resolution
Expand All @@ -39,12 +41,17 @@
public class TestServiceExtensionContext extends DefaultServiceExtensionContext {
private final LinkedHashMap<Class<?>, Object> serviceMocks;

public static ServiceExtensionContext testServiceExtensionContext() {
var context = new TestServiceExtensionContext(mock(), Collections.emptyList(), new LinkedHashMap<>());
context.initialize();
return context;
}

public TestServiceExtensionContext(Monitor monitor, List<ConfigurationExtension> configurationExtensions, LinkedHashMap<Class<?>, Object> serviceMocks) {
super(monitor, configurationExtensions);
this.serviceMocks = serviceMocks;
}


@Override
public <T> boolean hasService(Class<T> type) {
return (serviceMocks != null && serviceMocks.containsKey(type)) || super.hasService(type);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package org.eclipse.edc.protocol.dsp.transform;

import jakarta.json.Json;
import org.eclipse.edc.jsonld.transformer.OdrlTransformersFactory;
import org.eclipse.edc.jsonld.transformer.from.JsonObjectFromAssetTransformer;
import org.eclipse.edc.jsonld.transformer.from.JsonObjectFromCatalogTransformer;
import org.eclipse.edc.jsonld.transformer.from.JsonObjectFromCriterionTransformer;
Expand All @@ -23,19 +24,12 @@
import org.eclipse.edc.jsonld.transformer.from.JsonObjectFromDistributionTransformer;
import org.eclipse.edc.jsonld.transformer.from.JsonObjectFromPolicyTransformer;
import org.eclipse.edc.jsonld.transformer.from.JsonObjectFromQuerySpecTransformer;
import org.eclipse.edc.jsonld.transformer.to.JsonObjectToActionTransformer;
import org.eclipse.edc.jsonld.transformer.to.JsonObjectToAssetTransformer;
import org.eclipse.edc.jsonld.transformer.to.JsonObjectToCatalogTransformer;
import org.eclipse.edc.jsonld.transformer.to.JsonObjectToConstraintTransformer;
import org.eclipse.edc.jsonld.transformer.to.JsonObjectToCriterionTransformer;
import org.eclipse.edc.jsonld.transformer.to.JsonObjectToDataServiceTransformer;
import org.eclipse.edc.jsonld.transformer.to.JsonObjectToDatasetTransformer;
import org.eclipse.edc.jsonld.transformer.to.JsonObjectToDistributionTransformer;
import org.eclipse.edc.jsonld.transformer.to.JsonObjectToDutyTransformer;
import org.eclipse.edc.jsonld.transformer.to.JsonObjectToOperatorTransformer;
import org.eclipse.edc.jsonld.transformer.to.JsonObjectToPermissionTransformer;
import org.eclipse.edc.jsonld.transformer.to.JsonObjectToPolicyTransformer;
import org.eclipse.edc.jsonld.transformer.to.JsonObjectToProhibitionTransformer;
import org.eclipse.edc.jsonld.transformer.to.JsonObjectToQuerySpecTransformer;
import org.eclipse.edc.jsonld.transformer.to.JsonValueToGenericTypeTransformer;
import org.eclipse.edc.policy.model.AtomicConstraint;
Expand Down Expand Up @@ -89,17 +83,15 @@ public void initialize(ServiceExtensionContext context) {
registry.register(new JsonObjectFromCriterionTransformer(jsonBuilderFactory, mapper));

// JSON-LD to EDC model transformers
// DCAT transformers
registry.register(new JsonObjectToCatalogTransformer());
registry.register(new JsonObjectToDataServiceTransformer());
registry.register(new JsonObjectToDatasetTransformer());
registry.register(new JsonObjectToDistributionTransformer());
registry.register(new JsonObjectToPolicyTransformer());
registry.register(new JsonObjectToPermissionTransformer());
registry.register(new JsonObjectToProhibitionTransformer());
registry.register(new JsonObjectToDutyTransformer());
registry.register(new JsonObjectToActionTransformer());
registry.register(new JsonObjectToConstraintTransformer());
registry.register(new JsonObjectToOperatorTransformer());

// ODRL Transformers
OdrlTransformersFactory.jsonObjectToOdrlTransformers().forEach(registry::register);

registry.register(new JsonValueToGenericTypeTransformer(mapper));
registry.register(new JsonObjectToAssetTransformer());
registry.register(new JsonObjectToQuerySpecTransformer());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
*
* 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
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation
*
*/

package org.eclipse.edc.jsonld.transformer;

import org.eclipse.edc.jsonld.transformer.to.JsonObjectToActionTransformer;
import org.eclipse.edc.jsonld.transformer.to.JsonObjectToConstraintTransformer;
import org.eclipse.edc.jsonld.transformer.to.JsonObjectToDutyTransformer;
import org.eclipse.edc.jsonld.transformer.to.JsonObjectToOperatorTransformer;
import org.eclipse.edc.jsonld.transformer.to.JsonObjectToPermissionTransformer;
import org.eclipse.edc.jsonld.transformer.to.JsonObjectToPolicyTransformer;
import org.eclipse.edc.jsonld.transformer.to.JsonObjectToProhibitionTransformer;
import org.eclipse.edc.transform.spi.TypeTransformer;

import java.util.stream.Stream;

public final class OdrlTransformersFactory {

private OdrlTransformersFactory() {
}

public static Stream<TypeTransformer<?, ?>> jsonObjectToOdrlTransformers() {
return Stream.of(
new JsonObjectToPolicyTransformer(),
new JsonObjectToPermissionTransformer(),
new JsonObjectToProhibitionTransformer(),
new JsonObjectToDutyTransformer(),
new JsonObjectToActionTransformer(),
new JsonObjectToConstraintTransformer(),
new JsonObjectToOperatorTransformer()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,31 +24,31 @@
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.json.JsonArray;
import jakarta.json.JsonObject;
import org.eclipse.edc.api.model.IdResponseDto;
import org.eclipse.edc.api.model.QuerySpecDto;
import org.eclipse.edc.connector.api.management.policy.model.PolicyDefinitionRequestDto;
import org.eclipse.edc.connector.api.management.policy.model.PolicyDefinitionResponseDto;
import org.eclipse.edc.connector.api.management.policy.model.PolicyDefinitionUpdateDto;
import org.eclipse.edc.api.model.ApiCoreSchema;
import org.eclipse.edc.web.spi.ApiErrorDetail;

import static org.eclipse.edc.connector.policy.spi.PolicyDefinition.EDC_POLICY_DEFINITION_TYPE;
import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID;
import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE;

@OpenAPIDefinition
@Tag(name = "Policy Definition")
public interface PolicyDefinitionApi {

@Operation(description = "Returns all policy definitions according to a query",
requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = QuerySpecDto.class))),
requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = ApiCoreSchema.QuerySpecSchema.class))),
responses = {
@ApiResponse(responseCode = "200", description = "The policy definitions matching the query",
content = @Content(array = @ArraySchema(schema = @Schema(implementation = PolicyDefinitionResponseDto.class)))),
content = @Content(array = @ArraySchema(schema = @Schema(implementation = PolicyDefinitionOutputSchema.class)))),
@ApiResponse(responseCode = "400", description = "Request was malformed",
content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiErrorDetail.class)))) }
content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiErrorDetail.class))))}
)
JsonArray queryPolicyDefinitions(JsonObject querySpecDto);

@Operation(description = "Gets a policy definition with the given ID",
responses = {
@ApiResponse(responseCode = "200", description = "The policy definition",
content = @Content(schema = @Schema(implementation = PolicyDefinitionResponseDto.class))),
content = @Content(schema = @Schema(implementation = PolicyDefinitionOutputSchema.class))),
@ApiResponse(responseCode = "400", description = "Request was malformed, e.g. id was null",
content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiErrorDetail.class)))),
@ApiResponse(responseCode = "404", description = "An policy definition with the given ID does not exist",
Expand All @@ -58,14 +58,14 @@ public interface PolicyDefinitionApi {
JsonObject getPolicyDefinition(String id);

@Operation(description = "Creates a new policy definition",
requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = PolicyDefinitionRequestDto.class))),
requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = PolicyDefinitionInputSchema.class))),
responses = {
@ApiResponse(responseCode = "200", description = "policy definition was created successfully. Returns the Policy Definition Id and created timestamp",
content = @Content(schema = @Schema(implementation = IdResponseDto.class))),
content = @Content(schema = @Schema(implementation = ApiCoreSchema.IdResponseSchema.class))),
@ApiResponse(responseCode = "400", description = "Request body was malformed",
content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiErrorDetail.class)))),
@ApiResponse(responseCode = "409", description = "Could not create policy definition, because a contract definition with that ID already exists",
content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiErrorDetail.class)))) }
content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiErrorDetail.class))))}
)
JsonObject createPolicyDefinition(JsonObject policyDefinition);

Expand All @@ -85,7 +85,7 @@ public interface PolicyDefinitionApi {
void deletePolicyDefinition(String id);

@Operation(description = "Updates an existing Policy, If the Policy is not found, an error is reported",
requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = PolicyDefinitionUpdateDto.class))),
requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = PolicyDefinitionInputSchema.class))),
responses = {
@ApiResponse(responseCode = "200", description = "policy definition was updated successfully. Returns the Policy Definition Id and updated timestamp"),
@ApiResponse(responseCode = "400", description = "Request body was malformed",
Expand All @@ -95,4 +95,68 @@ public interface PolicyDefinitionApi {
}
)
void updatePolicyDefinition(String id, JsonObject policyDefinition);

@Schema(example = PolicyDefinitionInputSchema.POLICY_DEFINITION_INPUT_EXAMPLE)
record PolicyDefinitionInputSchema(
@Schema(name = ID)
String id,
@Schema(name = TYPE, example = EDC_POLICY_DEFINITION_TYPE)
String type) {

// policy example took from https://w3c.github.io/odrl/bp/
public static final String POLICY_DEFINITION_INPUT_EXAMPLE = """
{
"@context": { "edc": "https://w3id.org/edc/v0.0.1/ns/" },
"@id": "definition-id",
"policy": {
"@context": "http://www.w3.org/ns/odrl.jsonld",
"@type": "Set",
"uid": "http://example.com/policy:1010",
"permission": [{
"target": "http://example.com/asset:9898.movie",
"action": "display",
"constraint": [{
"leftOperand": "spatial",
"operator": "eq",
"rightOperand": "https://www.wikidata.org/wiki/Q183",
"comment": "i.e Germany"
}]
}]
}
}
""";
}

@Schema(example = PolicyDefinitionOutputSchema.POLICY_DEFINITION_OUTPUT_EXAMPLE)
record PolicyDefinitionOutputSchema(
@Schema(name = ID)
String id,
@Schema(name = TYPE, example = EDC_POLICY_DEFINITION_TYPE)
String type) {

// policy example took from https://w3c.github.io/odrl/bp/
public static final String POLICY_DEFINITION_OUTPUT_EXAMPLE = """
{
"@context": { "edc": "https://w3id.org/edc/v0.0.1/ns/" },
"@id": "definition-id",
"policy": {
"@context": "http://www.w3.org/ns/odrl.jsonld",
"@type": "Set",
"uid": "http://example.com/policy:1010",
"permission": [{
"target": "http://example.com/asset:9898.movie",
"action": "display",
"constraint": [{
"leftOperand": "spatial",
"operator": "eq",
"rightOperand": "https://www.wikidata.org/wiki/Q183",
"comment": "i.e Germany"
}]
}]
},
"createdAt": 1688465655
}
""";
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@
import jakarta.ws.rs.Produces;
import org.eclipse.edc.api.model.IdResponseDto;
import org.eclipse.edc.api.model.QuerySpecDto;
import org.eclipse.edc.connector.api.management.policy.model.PolicyDefinitionRequestDto;
import org.eclipse.edc.connector.api.management.policy.model.PolicyDefinitionResponseDto;
import org.eclipse.edc.connector.api.management.policy.model.PolicyDefinitionUpdateDto;
import org.eclipse.edc.connector.api.management.policy.model.PolicyDefinitionUpdateWrapperDto;
import org.eclipse.edc.connector.policy.spi.PolicyDefinition;
import org.eclipse.edc.connector.spi.policydefinition.PolicyDefinitionService;
import org.eclipse.edc.spi.EdcException;
Expand All @@ -46,7 +42,7 @@
import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;
import static java.lang.String.format;
import static org.eclipse.edc.api.model.QuerySpecDto.EDC_QUERY_SPEC_TYPE;
import static org.eclipse.edc.connector.api.management.policy.model.PolicyDefinitionRequestDto.EDC_POLICY_DEFINITION_TYPE;
import static org.eclipse.edc.connector.policy.spi.PolicyDefinition.EDC_POLICY_DEFINITION_TYPE;
import static org.eclipse.edc.web.spi.exception.ServiceResultHandler.exceptionMapper;

@Consumes(APPLICATION_JSON)
Expand Down Expand Up @@ -84,8 +80,7 @@ public JsonArray queryPolicyDefinitions(JsonObject querySpecDto) {

try (var stream = service.query(querySpec).orElseThrow(exceptionMapper(PolicyDefinition.class))) {
return stream
.map(policyDefinition -> transformerRegistry.transform(policyDefinition, PolicyDefinitionResponseDto.class)
.compose(dto -> transformerRegistry.transform(dto, JsonObject.class)))
.map(policyDefinition -> transformerRegistry.transform(policyDefinition, JsonObject.class))
.filter(Result::succeeded)
.map(Result::getContent)
.collect(toJsonArray());
Expand All @@ -101,8 +96,7 @@ public JsonObject getPolicyDefinition(@PathParam("id") String id) {
throw new ObjectNotFoundException(PolicyDefinition.class, id);
}

return transformerRegistry.transform(definition, PolicyDefinitionResponseDto.class)
.compose(dto -> transformerRegistry.transform(dto, JsonObject.class))
return transformerRegistry.transform(definition, JsonObject.class)
.orElseThrow(failure -> new ObjectNotFoundException(PolicyDefinition.class, id));
}

Expand All @@ -111,8 +105,7 @@ public JsonObject getPolicyDefinition(@PathParam("id") String id) {
public JsonObject createPolicyDefinition(JsonObject request) {
validatorRegistry.validate(EDC_POLICY_DEFINITION_TYPE, request).orElseThrow(ValidationFailureException::new);

var definition = transformerRegistry.transform(request, PolicyDefinitionRequestDto.class)
.compose(dto -> transformerRegistry.transform(dto, PolicyDefinition.class))
var definition = transformerRegistry.transform(request, PolicyDefinition.class)
.orElseThrow(InvalidRequestException::new);

var createdDefinition = service.create(definition)
Expand Down Expand Up @@ -143,12 +136,7 @@ public void deletePolicyDefinition(@PathParam("id") String id) {
public void updatePolicyDefinition(@PathParam("id") String id, JsonObject input) {
validatorRegistry.validate(EDC_POLICY_DEFINITION_TYPE, input).orElseThrow(ValidationFailureException::new);

var policyDefinition = transformerRegistry.transform(input, PolicyDefinitionUpdateDto.class)
.map(dto -> PolicyDefinitionUpdateWrapperDto.Builder.newInstance()
.policyId(id)
.updateRequest(dto)
.build())
.compose(wrapper -> transformerRegistry.transform(wrapper, PolicyDefinition.class))
var policyDefinition = transformerRegistry.transform(input, PolicyDefinition.class)
.orElseThrow(InvalidRequestException::new);

service.update(policyDefinition)
Expand Down
Loading

0 comments on commit fcf729d

Please sign in to comment.