Skip to content

Commit

Permalink
fix: Abide to the DataOfferCreationRequest.PolicyEnum rule (#1055)
Browse files Browse the repository at this point in the history
  • Loading branch information
ununhexium committed Oct 7, 2024
1 parent 0577721 commit 09e39f6
Show file tree
Hide file tree
Showing 9 changed files with 296 additions and 34 deletions.
10 changes: 5 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ please see [changelog_updates.md](docs/dev/changelog_updates.md).

#### Patch Changes

- Fix issues with the Create Data Offer Endpoint ([PR#1055](https://github.com/sovity/edc-ce/pull/1055))

### Deployment Migration Notes

_No special deployment migration steps required_
Expand All @@ -26,8 +28,6 @@ _No special deployment migration steps required_
- Dev EDC: `ghcr.io/sovity/edc-dev:{{ VERSION }}`
- sovity EDC CE: `ghcr.io/sovity/edc-ce:{{ VERSION }}`
- MDS EDC CE: `ghcr.io/sovity/edc-ce-mds:{{ VERSION }}`
- Dev Catalog Crawler: `ghcr.io/sovity/catalog-crawler-dev:{{ VERSION }}`
- Catalog Crawler CE: `ghcr.io/sovity/catalog-crawler-ce:{{ VERSION }}`
- Connector UI Docker Image: `ghcr.io/sovity/edc-ui:{{ UI VERSION }}`


Expand Down Expand Up @@ -226,7 +226,7 @@ MDS 2.2 release
#### Major Changes

- Complex policies using AND, OR and XONE:
- Complex policy support in the Connector UI.
- Complex policy support in the Connector UI.
- The `UiPolicy` model has been adjusted to support complex expressions including `AND`, `OR` and `XONE`.
- The `createPolicyDefinition` has been marked as deprecated in favor of the new `createPolicyDefinitionV2` endpoint that supports complex policies.
- Removed the recently rushed `createPolicyDefinitionUseCase` endpoint in favor of the new `createPolicyDefinitionV2` endpoint.
Expand Down Expand Up @@ -271,7 +271,7 @@ MDS 2.2 intermediate release

- API Wrapper UI API: Data sources are now well-typed.
- The Broker has been removed in favor of the Authority Portal:
- A new Deployment Unit, the ["Data Catalog Crawler"](extensions/catalog-crawler/README.md), has been added.
- A new Deployment Unit, the ["Data Catalog Crawler"](https://github.com/sovity/edc-ce/tree/v9.0.0/extensions/catalog-crawler/README.md), has been added.
- Each "Data Catalog Crawler" connects to an existing Authority Portal Deployment's DB.
- Each "Data Catalog Crawler" is responsible for crawling exactly one environment.
- The Data Catalog functionality of the Broker has been integrated into the Authority Portal.
Expand All @@ -294,7 +294,7 @@ MDS 2.2 intermediate release
- The database migration system has been moved from multiple migration history tables to a single one.
- Broker:
- The broker has been removed. For Authority Portal users, please check out the new
[Data Catalog Crawler Productive Deployment Guide](docs/deployment-guide/goals/catalog-crawler-production/README.md).
[Data Catalog Crawler Productive Deployment Guide](https://github.com/sovity/edc-ce/tree/v9.0.0/docs/deployment-guide/goals/catalog-crawler-production/README.md).
- Any previous broker deployment's database is not required anymore.
- Please care that only some environment variables look similar. It is recommended to create fresh deployments.

Expand Down
2 changes: 1 addition & 1 deletion docs/api/sovity-edc-api-wrapper.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -948,7 +948,7 @@ components:
$ref: '#/components/schemas/UiAssetCreateRequest'
policy:
type: string
description: Which policy to apply to this asset.
description: Which policy to apply to this asset creation.
enum:
- DONT_PUBLISH
- PUBLISH_UNRESTRICTED
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public class DataOfferCreationRequest {
@Schema(description = "The asset to create", requiredMode = REQUIRED)
private UiAssetCreateRequest uiAssetCreateRequest;

@Schema(description = "Which policy to apply to this asset.", requiredMode = REQUIRED)
@Schema(description = "Which policy to apply to this asset creation.", requiredMode = REQUIRED)
private PolicyDefinitionChoiceEnum policy;

@Schema(description = "Policy Expression.", requiredMode = NOT_REQUIRED)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,15 @@

package de.sovity.edc.ext.wrapper.api.ui.model;

import io.swagger.v3.oas.annotations.media.Schema;

import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;

public enum PolicyDefinitionChoiceEnum {
@Schema(description = "Only create the asset", requiredMode = REQUIRED)
DONT_PUBLISH,
@Schema(description = "Create the asset and assigns the always-true policy in the contract definition", requiredMode = REQUIRED)
PUBLISH_UNRESTRICTED,
@Schema(description = "Create the asset, a policy and a contract definition", requiredMode = REQUIRED)
PUBLISH_RESTRICTED
}
1 change: 1 addition & 0 deletions extensions/wrapper/wrapper/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ dependencies {

implementation(project(":extensions:contract-termination"))
implementation(project(":extensions:database-direct-access"))
implementation(project(":extensions:policy-always-true"))
implementation(project(":extensions:sovity-messenger"))
implementation(project(":utils:jooq-database-access"))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.eclipse.edc.connector.transfer.spi.store.TransferProcessStore;
import org.eclipse.edc.jsonld.spi.JsonLd;
import org.eclipse.edc.policy.engine.spi.PolicyEngine;
import org.eclipse.edc.policy.engine.spi.RuleBindingRegistry;
import org.eclipse.edc.protocol.dsp.api.configuration.DspApiConfiguration;
import org.eclipse.edc.runtime.metamodel.annotation.Inject;
import org.eclipse.edc.runtime.metamodel.annotation.Setting;
Expand Down Expand Up @@ -78,6 +79,8 @@ public class WrapperExtension implements ServiceExtension {
@Inject
private PolicyEngine policyEngine;
@Inject
private RuleBindingRegistry ruleBindingRegistry;
@Inject
private TransferProcessService transferProcessService;
@Inject
private TransferProcessStore transferProcessStore;
Expand Down Expand Up @@ -122,6 +125,7 @@ public void initialize(ServiceExtensionContext context) {
policyDefinitionService,
policyDefinitionStore,
policyEngine,
ruleBindingRegistry,
transferProcessService,
transferProcessStore,
typeTransformerRegistry
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
import de.sovity.edc.ext.wrapper.controller.PlaceholderEndpointController;
import de.sovity.edc.extension.contacttermination.ContractAgreementTerminationService;
import de.sovity.edc.extension.db.directaccess.DslContextFactory;
import de.sovity.edc.extension.policy.services.AlwaysTruePolicyDefinitionService;
import de.sovity.edc.utils.catalog.DspCatalogService;
import de.sovity.edc.utils.catalog.mapper.DspDataOfferBuilder;
import lombok.NoArgsConstructor;
Expand All @@ -96,6 +97,7 @@
import org.eclipse.edc.connector.transfer.spi.store.TransferProcessStore;
import org.eclipse.edc.jsonld.spi.JsonLd;
import org.eclipse.edc.policy.engine.spi.PolicyEngine;
import org.eclipse.edc.policy.engine.spi.RuleBindingRegistry;
import org.eclipse.edc.runtime.metamodel.annotation.Inject;
import org.eclipse.edc.spi.asset.AssetIndex;
import org.eclipse.edc.spi.monitor.Monitor;
Expand Down Expand Up @@ -135,6 +137,7 @@ public static WrapperExtensionContext buildContext(
PolicyDefinitionService policyDefinitionService,
PolicyDefinitionStore policyDefinitionStore,
PolicyEngine policyEngine,
RuleBindingRegistry ruleBindingRegistry,
TransferProcessService transferProcessService,
TransferProcessStore transferProcessStore,
TypeTransformerRegistry typeTransformerRegistry
Expand Down Expand Up @@ -250,10 +253,14 @@ public static WrapperExtensionContext buildContext(
miwConfigBuilder,
selfDescriptionService
);
var alwaysTruePolicyService = new AlwaysTruePolicyDefinitionService(
policyDefinitionService
);
var dataOfferPageApiService = new DataOfferPageApiService(
assetApiService,
contractDefinitionApiService,
policyDefinitionApiService
policyDefinitionApiService,
alwaysTruePolicyService
);
var uiResource = new UiResourceImpl(
contractAgreementApiService,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import de.sovity.edc.ext.wrapper.api.ui.pages.asset.AssetApiService;
import de.sovity.edc.ext.wrapper.api.ui.pages.contract_definitions.ContractDefinitionApiService;
import de.sovity.edc.ext.wrapper.api.ui.pages.policy.PolicyDefinitionApiService;
import de.sovity.edc.extension.policy.AlwaysTruePolicyConstants;
import de.sovity.edc.extension.policy.services.AlwaysTruePolicyDefinitionService;
import lombok.RequiredArgsConstructor;
import lombok.val;
import org.eclipse.edc.spi.types.domain.asset.Asset;
Expand All @@ -32,6 +34,7 @@ public class DataOfferPageApiService {
private final AssetApiService assetApiService;
private final ContractDefinitionApiService contractDefinitionApiService;
private final PolicyDefinitionApiService policyDefinitionApiService;
private final AlwaysTruePolicyDefinitionService alwaysTruePolicyDefinitionService;

@NotNull
public IdAvailabilityResponse checkIfPolicyIdAvailable(DSLContext dsl, String id) {
Expand Down Expand Up @@ -66,45 +69,106 @@ private boolean isIdAvailable(DSLContext dsl, Table<?> table, TableField<?, Stri
}

public IdResponseDto createDataOffer(DSLContext dsl, DataOfferCreationRequest dataOfferCreationRequest) {

val commonId = dataOfferCreationRequest.getUiAssetCreateRequest().getId();

val assetIdExists = checkIfAssetIdAvailable(dsl, commonId).isAvailable();
if (!assetIdExists) {
throw new InvalidRequestException("Asset with id %s already exists".formatted(commonId));
}
return switch (dataOfferCreationRequest.getPolicy()) {
case DONT_PUBLISH -> createButDontPublish(dsl, dataOfferCreationRequest, commonId);
case PUBLISH_UNRESTRICTED -> createAndPublishUnrestricted(dsl, dataOfferCreationRequest, commonId);
case PUBLISH_RESTRICTED -> createAndPublishRestricted(dsl, dataOfferCreationRequest, commonId);
};
}

val policyIdExists = checkIfPolicyIdAvailable(dsl, commonId).isAvailable();
if (!policyIdExists) {
throw new InvalidRequestException("Policy with id %s already exists".formatted(commonId));
private @NotNull IdResponseDto createAndPublishUnrestricted(
DSLContext dsl,
DataOfferCreationRequest dataOfferCreationRequest,
String commonId
) {
val assetId = commonId;
val contractDefinitionId = commonId;
val policyId = AlwaysTruePolicyConstants.POLICY_DEFINITION_ID;

checkAssetIdAvailable(dsl, assetId);
checkContractDefinitionIdAvailable(dsl, contractDefinitionId);

if (!alwaysTruePolicyDefinitionService.exists()) {
// the default always-true policy has been deleted, recreate it.
alwaysTruePolicyDefinitionService.create();
}

assetApiService.createAsset(dataOfferCreationRequest.getUiAssetCreateRequest());

return createContractDefinition(assetId, policyId, contractDefinitionId);
}

private @NotNull IdResponseDto createAndPublishRestricted(
DSLContext dsl,
DataOfferCreationRequest dataOfferCreationRequest,
String commonId
) {
val assetId = commonId;
val policyId = commonId;
val contractDefinitionId = commonId;

checkAssetIdAvailable(dsl, assetId);
checkPolicyIdAvailable(dsl, policyId);
checkContractDefinitionIdAvailable(dsl, contractDefinitionId);

assetApiService.createAsset(dataOfferCreationRequest.getUiAssetCreateRequest());

val policyExpression = Optional.ofNullable(dataOfferCreationRequest.getUiPolicyExpression())
.orElseThrow(() -> new InvalidRequestException("Missing policy expression"));
policyDefinitionApiService.createPolicyDefinitionV2(new PolicyDefinitionCreateDto(policyId, policyExpression));

createContractDefinition(assetId, policyId, contractDefinitionId);

return new IdResponseDto(commonId, OffsetDateTime.now());
}

private @NotNull IdResponseDto createButDontPublish(
DSLContext dsl,
DataOfferCreationRequest dataOfferCreationRequest,
String commonId
) {
checkAssetIdAvailable(dsl, commonId);
return assetApiService.createAsset(dataOfferCreationRequest.getUiAssetCreateRequest());
}

private void checkContractDefinitionIdAvailable(DSLContext dsl, String commonId) {
val contractDefinitionIdExists = checkIfContractDefinitionIdAvailable(dsl, commonId).isAvailable();
if (!contractDefinitionIdExists) {
throw new InvalidRequestException("Contract definition with id %s already exists".formatted(commonId));
}
}

assetApiService.createAsset(dataOfferCreationRequest.getUiAssetCreateRequest());

val maybeNewPolicy = Optional.ofNullable(dataOfferCreationRequest.getUiPolicyExpression());
private void checkPolicyIdAvailable(DSLContext dsl, String commonId) {
val policyIdExists = checkIfPolicyIdAvailable(dsl, commonId).isAvailable();
if (!policyIdExists) {
throw new InvalidRequestException("Policy with id %s already exists".formatted(commonId));
}
}

maybeNewPolicy.ifPresent(
policy -> policyDefinitionApiService.createPolicyDefinitionV2(new PolicyDefinitionCreateDto(commonId, policy)));
private void checkAssetIdAvailable(DSLContext dsl, String commonId) {
val assetIdExists = checkIfAssetIdAvailable(dsl, commonId).isAvailable();
if (!assetIdExists) {
throw new InvalidRequestException("Asset with id %s already exists".formatted(commonId));
}
}

private @NotNull IdResponseDto createContractDefinition(String assetId, String policyId, String contractDefinitionId) {
val cd = new ContractDefinitionRequest();
cd.setAssetSelector(List.of(UiCriterion.builder()
.operandLeft(Asset.PROPERTY_ID)
.operator(UiCriterionOperator.EQ)
.operandRight(UiCriterionLiteral.builder()
.type(UiCriterionLiteralType.VALUE)
.value(commonId)
.value(assetId)
.build())
.build()));
cd.setAccessPolicyId(commonId);
cd.setContractPolicyId(commonId);
cd.setContractDefinitionId(commonId);
cd.setAccessPolicyId(policyId);
cd.setContractPolicyId(policyId);
cd.setContractDefinitionId(contractDefinitionId);

contractDefinitionApiService.createContractDefinition(cd);

return new IdResponseDto(commonId, OffsetDateTime.now());
return contractDefinitionApiService.createContractDefinition(cd);
}
}
Loading

0 comments on commit 09e39f6

Please sign in to comment.