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

fix: Abide to the DataOfferCreationRequest.PolicyEnum rule #1055

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ please see [changelog_updates.md](docs/dev/changelog_updates.md).
#### Patch Changes

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

### Deployment Migration Notes

Expand Down
6 changes: 3 additions & 3 deletions docs/api/sovity-edc-api-wrapper.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -623,11 +623,11 @@ components:
DataSourceType:
type: string
description: Supported Data Source Types by UiDataSource
default: CUSTOM
enum:
- HTTP_DATA
- ON_REQUEST
- CUSTOM
default: CUSTOM
SecretValue:
type: object
properties:
Expand Down Expand Up @@ -835,14 +835,14 @@ components:
UiDataSourceHttpDataMethod:
type: string
description: Supported HTTP Methods by UiDataSource
default: GET
enum:
- GET
- POST
- PUT
- PATCH
- DELETE
- OPTIONS
default: GET
UiDataSourceOnRequest:
required:
- contactEmail
Expand Down 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
}
3 changes: 3 additions & 0 deletions extensions/wrapper/wrapper/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ dependencies {
annotationProcessor(libs.lombok)
compileOnly(libs.lombok)


implementation(project(":config"))

api(project(":extensions:wrapper:wrapper-api"))
api(project(":extensions:wrapper:wrapper-common-mappers"))
api(project(":utils:catalog-parser"))
Expand All @@ -22,6 +24,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.spi.CoreConstants;
Expand Down Expand Up @@ -74,6 +75,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 @@ -118,6 +121,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 de.sovity.edc.utils.config.ConfigProps;
Expand All @@ -97,6 +98,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 @@ -136,6 +138,7 @@ public static WrapperExtensionContext buildContext(
PolicyDefinitionService policyDefinitionService,
PolicyDefinitionStore policyDefinitionStore,
PolicyEngine policyEngine,
RuleBindingRegistry ruleBindingRegistry,
TransferProcessService transferProcessService,
TransferProcessStore transferProcessStore,
TypeTransformerRegistry typeTransformerRegistry
Expand Down Expand Up @@ -251,10 +254,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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ class AlwaysTrueMigrationTest {
private static final E2eTestExtension E2E_TEST_EXTENSION = new E2eTestExtension(
withModule(":launchers:connectors:sovity-dev").toBuilder()
.consumerConfigCustomizer(config -> config.setProperty(
ConfigProps.EDC_FLYWAY_ADDITIONAL_MIGRATION_LOCATIONS, "classpath:db/additional-test-data/always-true-policy-legacy"
ConfigProps.EDC_FLYWAY_ADDITIONAL_MIGRATION_LOCATIONS, "classpath:db/additional-test-data/always-true-policy-migrated"
))
.providerConfigCustomizer(config -> config.setProperty(
ConfigProps.EDC_FLYWAY_ADDITIONAL_MIGRATION_LOCATIONS, "classpath:db/additional-test-data/always-true-policy-migrated"
ConfigProps.EDC_FLYWAY_ADDITIONAL_MIGRATION_LOCATIONS, "classpath:db/additional-test-data/always-true-policy-legacy"
))
.build()
);
Expand Down
Loading
Loading