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: workflow for creating an offering #351

Merged
merged 37 commits into from
Jun 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
00d2965
feat(wrapper): create OfferingResource
steffen-biehs Apr 20, 2023
2bdce2a
test(wrapper): Add API test for offering endpoint
timdah Apr 21, 2023
55efa4e
refactor(wrapper): return response for createOfferingEndpoint
timdah Apr 24, 2023
5223572
refactor(wrapper): delete unnecessary variable
timdah Apr 24, 2023
2700c95
[WIP] feat(wrapper): model dtos
timdah Apr 27, 2023
59283c3
feat(wrapper): replace incomplete and add missing model schemas in op…
timdah Apr 27, 2023
e532d20
feat(wrapper): create OfferingResource
steffen-biehs Apr 20, 2023
80fc660
test(wrapper): Add API test for offering endpoint
timdah Apr 21, 2023
8690a83
refactor(wrapper): return response for createOfferingEndpoint
timdah Apr 24, 2023
6eea9eb
refactor(wrapper): delete unnecessary variable
timdah Apr 24, 2023
46851b2
[WIP] feat(wrapper): model dtos
timdah Apr 27, 2023
0253e2f
feat(wrapper): replace incomplete and add missing model schemas in op…
timdah Apr 27, 2023
156cf61
feat(wrapper): Implement PolicyDTO and MappingService
timdah May 17, 2023
7606e35
Merge remote-tracking branch 'origin/feat/182-create-offering-tests' …
timdah May 17, 2023
aff0a40
feat(wrapper): Implement PolicyDTO and MappingService
timdah May 17, 2023
bf88b7f
feat(wrapper): Implement first PolicyMappingService test
timdah May 22, 2023
9d4bc1a
docs(wrapper): Checkstyle conform JavaDoc
timdah May 22, 2023
70c80f4
fix(wrapper): OfferingService tests
timdah May 22, 2023
d3075cf
test: update PolicyMappingServiceTest
ronjaquensel May 23, 2023
707f3f9
test: rename OfferingResourceTest
ronjaquensel May 23, 2023
f70c163
test: add OfferingServiceTest
ronjaquensel May 23, 2023
a37037e
chore: checkstyle
ronjaquensel May 25, 2023
fc414d8
refactor(wrapper): PR #351 suggestions
timdah May 30, 2023
51adee0
fix(wrapper): Tests
timdah May 31, 2023
6bceae9
refactor(wrapper): Replace loops with java streams
timdah May 31, 2023
5ecb331
refactor(wrapper): Move offering endpoint to use-case api
timdah May 31, 2023
306e7c3
refactor(wrapper): Move validation to service
timdah May 31, 2023
fb3e887
Merge branch 'main' into feat/182-create-offering-tests
timdah May 31, 2023
9023de7
chore(model): add ExpressionDto
ronjaquensel Jun 1, 2023
dd0b778
docs(common-api): JavaDoc and OpenAPI schema
timdah Jun 1, 2023
172f7a3
fix(wrapper): offering tests
timdah Jun 1, 2023
1101856
chore(policy): throw exception when permission missing
ronjaquensel Jun 2, 2023
718a070
refactor(common-api): policy model
timdah Jun 6, 2023
2122be2
refactor(wrapper): consistent naming
timdah Jun 6, 2023
8d5d8e0
fix(wrapper): import order
timdah Jun 13, 2023
bb6b777
Merge branch 'main' into feat/182-create-offering-tests
timdah Jun 13, 2023
625e4e6
Merge branch 'main' into feat/182-create-offering-tests
richardtreier Jun 26, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,14 @@
package de.sovity.edc.ext.wrapper.api.common.model;

import io.swagger.v3.oas.annotations.media.Schema;
import java.time.OffsetDateTime;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.ToString;

import java.time.OffsetDateTime;
import java.util.Map;

@Getter
@Setter
@ToString
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package de.sovity.edc.ext.wrapper.api.common.model;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.ToString;

/**
* Opinionated DTO of an EDC Constraint for permissions.
*
* @author [email protected]
*/
@Getter
@Setter
@ToString
@AllArgsConstructor
@RequiredArgsConstructor
@Schema(description =
"Type-Safe OpenAPI generator friendly Constraint DTO that supports an opinionated"
+ " subset of the original EDC Constraint Entity.")
public class AtomicConstraintDto {

@Schema(description = "Left part of the constraint.",
requiredMode = Schema.RequiredMode.REQUIRED)
private String leftExpression;
@Schema(description = "Operator to connect both parts of the constraint.",
requiredMode = Schema.RequiredMode.REQUIRED)
private OperatorDto operator;
@Schema(description = "Right part of the constraint.",
requiredMode = Schema.RequiredMode.REQUIRED)
private String rightExpression;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package de.sovity.edc.ext.wrapper.api.common.model;

import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

/**
* Expression constraints for policies.
*
* @author [email protected]
*/
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class ExpressionDto {

@Schema(description = """
Expression types:
* `EMPTY` - No constraints for the policy
* `ATOMIC_CONSTRAINT` - A single constraint for the policy
* `AND` - Several constraints, all of which must be respected
* `OR` - Several constraints, of which at least one must be respected
* `XOR` - Several constraints, of which exactly one must be respected
"""
)
private Type type;
private AtomicConstraintDto atomicConstraint;
private List<ExpressionDto> and;
private List<ExpressionDto> or;
private List<ExpressionDto> xor;

/**
* Sum type enum.
*/
public enum Type {
EMPTY, ATOMIC_CONSTRAINT, AND, OR, XOR
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package de.sovity.edc.ext.wrapper.api.common.model;

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

/**
* The set of supported expression operators. Not all operators may be supported for particular
* expression types.
* Copied from EDC policy-model.
*
* @author [email protected]
*/
@Schema(description = "Operator for constraints")
public enum OperatorDto {
/**
* Operator expressing equality of two operands.
*/
EQ,
/**
* Operator expressing inequality of two operands.
*/
NEQ,
/**
* Operator expressing left operand is greater than right operand.
*/
GT,
/**
* Operator expressing left operand is greater or equal than to the right operand.
*/
GEQ,
/**
* Operator expressing left operand is lesser than to the right operand.
*/
LT,
/**
* Operator expressing left operand is lesser or equal than to the right operand.
*/
LEQ,
/**
* Operator expressing left operand is contained in the right operand.
*/
IN
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package de.sovity.edc.ext.wrapper.api.common.model;

import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema.RequiredMode;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

/**
* Subset of the possible permissions in the EDC.
*
* @author [email protected]
*/
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Builder(toBuilder = true)
public class PermissionDto {

@Schema(description = "Possible constraints for the permission",
requiredMode = RequiredMode.REQUIRED)
private ExpressionDto constraints;
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,34 @@
package de.sovity.edc.ext.wrapper.api.common.model;

import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema.RequiredMode;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.ToString;

/**
* Opinionated subset of the EDC policy.
*
* @author [email protected]
*/
@Getter
@Setter
@ToString
@AllArgsConstructor
@Builder(toBuilder = true)
@RequiredArgsConstructor
@Schema(description = "Type-Safe OpenAPI generator friendly Policy DTO that supports an opinionated" +
" subset of the original EDC Policy Entity.")
@Schema(description = "Type-Safe OpenAPI generator friendly Policy DTO that supports an opinionated"
+ " subset of the original EDC Policy Entity.")
public class PolicyDto {
@Schema(description = "Legacy JSON as built by the Management API. Will be replaced " +
"in the future by a type-safe variant without polymorphisms that can be used " +
"for our generated clients.", requiredMode = Schema.RequiredMode.REQUIRED)
private Object legacyPolicy;

@Schema(description = "Legacy JSON as built by the Management API. Will be replaced "
+ "in the future by a type-safe variant without polymorphisms that can be used "
+ "for our generated clients.", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private String legacyPolicy;

@Schema(description = "Permission for this policy", requiredMode = RequiredMode.NOT_REQUIRED)
private PermissionDto permission;
}
3 changes: 2 additions & 1 deletion 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:wrapper:wrapper-common-api"))
implementation(project(":extensions:wrapper:wrapper-ee-api"))
api("${edcGroup}:contract-definition-api:${edcVersion}")
api("${edcGroup}:asset-api:${edcVersion}")
api("${edcGroup}:control-plane-spi:${edcVersion}")
api("${edcGroup}:core-spi:${edcVersion}")
api("${edcGroup}:policy-definition-api:${edcVersion}")
Expand All @@ -42,6 +43,7 @@ dependencies {
testImplementation("io.rest-assured:rest-assured:${restAssured}")
testImplementation("org.assertj:assertj-core:${assertj}")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.3")
testImplementation("org.mockito:mockito-core:5.3.1")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.9.3")
}

Expand All @@ -59,7 +61,6 @@ tasks.withType<io.swagger.v3.plugins.gradle.tasks.ResolveTask> {
resourcePackages = setOf("de.sovity.edc.ext.wrapper.api")
}


task<org.openapitools.generator.gradle.plugin.tasks.GenerateTask>("openApiGenerateTypeScriptClient") {
dependsOn("resolve")
generatorName.set("typescript-fetch")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

package de.sovity.edc.ext.wrapper;

import org.eclipse.edc.api.transformer.DtoTransformerRegistry;
import org.eclipse.edc.connector.api.management.configuration.ManagementApiConfiguration;
import org.eclipse.edc.connector.contract.spi.negotiation.store.ContractNegotiationStore;
import org.eclipse.edc.connector.contract.spi.offer.store.ContractDefinitionStore;
Expand Down Expand Up @@ -51,6 +52,8 @@ public class WrapperExtension implements ServiceExtension {
private ContractNegotiationStore contractNegotiationStore;
@Inject
private TransferProcessService transferProcessService;
@Inject
private DtoTransformerRegistry dtoTransformerRegistry;

@Override
public String name() {
Expand All @@ -67,7 +70,8 @@ public void initialize(ServiceExtensionContext context) {
transferProcessStore,
contractAgreementService,
contractNegotiationStore,
transferProcessService
transferProcessService,
dtoTransformerRegistry
);

wrapperExtensionContext.jaxRsResources().forEach(resource ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@
import de.sovity.edc.ext.wrapper.api.ui.services.TransferProcessStateService;
import de.sovity.edc.ext.wrapper.api.usecase.UseCaseResource;
import de.sovity.edc.ext.wrapper.api.usecase.services.KpiApiService;
import de.sovity.edc.ext.wrapper.api.usecase.services.OfferingService;
import de.sovity.edc.ext.wrapper.api.usecase.services.PolicyMappingService;
import de.sovity.edc.ext.wrapper.api.usecase.services.SupportedPolicyApiService;
import lombok.NoArgsConstructor;
import org.eclipse.edc.api.transformer.DtoTransformerRegistry;
import org.eclipse.edc.connector.contract.spi.negotiation.store.ContractNegotiationStore;
import org.eclipse.edc.connector.contract.spi.offer.store.ContractDefinitionStore;
import org.eclipse.edc.connector.policy.spi.store.PolicyDefinitionStore;
Expand All @@ -39,13 +42,14 @@
/**
* Manual Dependency Injection.
* <p>
* We want to develop as Java Backend Development is done, but we have
* no CDI / DI Framework to rely on.
* We want to develop as Java Backend Development is done, but we have no CDI / DI Framework to rely
* on.
* <p>
* EDC {@link Inject} only works in {@link WrapperExtension}.
*/
@NoArgsConstructor(access = lombok.AccessLevel.PRIVATE)
public class WrapperExtensionContextBuilder {

public static WrapperExtensionContext buildContext(
AssetIndex assetIndex,
ContractDefinitionStore contractDefinitionStore,
Expand All @@ -54,11 +58,13 @@ public static WrapperExtensionContext buildContext(
TransferProcessStore transferProcessStore,
ContractAgreementService contractAgreementService,
ContractNegotiationStore contractNegotiationStore,
TransferProcessService transferProcessService
TransferProcessService transferProcessService,
DtoTransformerRegistry dtoTransformerRegistry
) {
// UI API
var transferProcessStateService = new TransferProcessStateService();
var contractAgreementPageCardBuilder = new ContractAgreementPageCardBuilder(transferProcessStateService);
var contractAgreementPageCardBuilder = new ContractAgreementPageCardBuilder(
transferProcessStateService);
var contractAgreementDataFetcher = new ContractAgreementDataFetcher(
contractAgreementService,
contractNegotiationStore,
Expand All @@ -79,7 +85,11 @@ public static WrapperExtensionContext buildContext(
contractAgreementService
);
var supportedPolicyApiService = new SupportedPolicyApiService(policyEngine);
var useCaseResource = new UseCaseResource(kpiApiService, supportedPolicyApiService);
var policyMappingService = new PolicyMappingService();
var offeringService = new OfferingService(assetIndex, policyDefinitionStore,
contractDefinitionStore, dtoTransformerRegistry, policyMappingService);
var useCaseResource = new UseCaseResource(kpiApiService, supportedPolicyApiService,
offeringService);

// Collect all JAX-RS resources
return new WrapperExtensionContext(List.of(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,30 @@

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

import static de.sovity.edc.ext.wrapper.utils.EdcDateUtils.utcMillisToOffsetDateTime;
import static de.sovity.edc.ext.wrapper.utils.EdcDateUtils.utcSecondsToOffsetDateTime;
import static de.sovity.edc.ext.wrapper.utils.MapUtils.mapValues;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.sovity.edc.ext.wrapper.api.common.model.AssetDto;
import de.sovity.edc.ext.wrapper.api.common.model.PolicyDto;
import de.sovity.edc.ext.wrapper.api.ui.model.ContractAgreementCard;
import de.sovity.edc.ext.wrapper.api.ui.model.ContractAgreementDirection;
import de.sovity.edc.ext.wrapper.api.ui.model.ContractAgreementTransferProcess;
import java.util.Comparator;
import java.util.List;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.edc.connector.contract.spi.types.agreement.ContractAgreement;
import org.eclipse.edc.connector.contract.spi.types.negotiation.ContractNegotiation;
import org.eclipse.edc.connector.transfer.spi.types.TransferProcess;
import org.eclipse.edc.policy.model.Policy;
import org.eclipse.edc.spi.types.domain.asset.Asset;
import org.jetbrains.annotations.NotNull;

import java.util.Comparator;
import java.util.List;

import static de.sovity.edc.ext.wrapper.utils.EdcDateUtils.utcMillisToOffsetDateTime;
import static de.sovity.edc.ext.wrapper.utils.EdcDateUtils.utcSecondsToOffsetDateTime;
import static de.sovity.edc.ext.wrapper.utils.MapUtils.mapValues;

@Slf4j
@RequiredArgsConstructor
public class ContractAgreementPageCardBuilder {
private final TransferProcessStateService transferProcessStateService;
Expand Down Expand Up @@ -67,23 +70,33 @@ private List<ContractAgreementTransferProcess> buildTransferProcesses(
) {
return transferProcessEntities.stream()
.map(this::buildContractAgreementTransfer)
.sorted(Comparator.comparing(ContractAgreementTransferProcess::getLastUpdatedDate).reversed())
.sorted(Comparator.comparing(ContractAgreementTransferProcess::getLastUpdatedDate)
.reversed())
.toList();
}

@NotNull
private ContractAgreementTransferProcess buildContractAgreementTransfer(TransferProcess transferProcessEntity) {
private ContractAgreementTransferProcess buildContractAgreementTransfer(
TransferProcess transferProcessEntity) {
var transferProcess = new ContractAgreementTransferProcess();
transferProcess.setTransferProcessId(transferProcessEntity.getId());
transferProcess.setLastUpdatedDate(utcMillisToOffsetDateTime(transferProcessEntity.getUpdatedAt()));
transferProcess.setState(transferProcessStateService.buildTransferProcessState(transferProcessEntity.getState()));
transferProcess.setLastUpdatedDate(
utcMillisToOffsetDateTime(transferProcessEntity.getUpdatedAt()));
transferProcess.setState(transferProcessStateService.buildTransferProcessState(
transferProcessEntity.getState()));
transferProcess.setErrorMessage(transferProcessEntity.getErrorDetail());
return transferProcess;
}

@NotNull
private PolicyDto buildPolicyDto(@NonNull Policy policy) {
return new PolicyDto(policy);
var mapper = new ObjectMapper();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Klappt das auch in Randfällen? Brauchen wir keinen vorkonfigurierten Object Mapper vom Core-EDC?

Ggf. könnten ja manche Unterklassen, die uns jetzt nicht bekannt sind, nicht gemappt werden?

Oder wisst ihr, dass der Core-EDC so oder so nichts anderes machen würde?

try {
return PolicyDto.builder().legacyPolicy(mapper.writeValueAsString(policy)).build();
} catch (JsonProcessingException ex) {
log.error("Could not serialize policy: {}", ex.getMessage(), ex);
return PolicyDto.builder().build();
}
}

@NotNull
Expand Down
Loading