Skip to content

Commit

Permalink
Merge branch 'main' into 1373-gap-create-data-offer-endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
ununhexium authored Sep 11, 2024
2 parents 2b22334 + 84361a0 commit de7def8
Show file tree
Hide file tree
Showing 22 changed files with 637 additions and 35 deletions.
6 changes: 3 additions & 3 deletions .env
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Env variables for docker-compose.yaml
EDC_IMAGE=ghcr.io/sovity/edc-dev:10.2.0
TEST_BACKEND_IMAGE=ghcr.io/sovity/test-backend:10.2.0
EDC_UI_IMAGE=ghcr.io/sovity/edc-ui:4.1.2
EDC_IMAGE=ghcr.io/sovity/edc-dev:10.3.0
TEST_BACKEND_IMAGE=ghcr.io/sovity/test-backend:10.3.0
EDC_UI_IMAGE=ghcr.io/sovity/edc-ui:4.1.3
EDC_UI_ACTIVE_PROFILE=sovity-open-source
37 changes: 37 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,43 @@ please see [changelog_updates.md](docs/dev/changelog_updates.md).
- Catalog Crawler CE: `ghcr.io/sovity/catalog-crawler-ce:{{ VERSION }}`
- Connector UI Docker Image: `ghcr.io/sovity/edc-ui:{{ UI VERSION }}`


## [10.3.0] - 2024-09-04

### Overview

Minor updates for contracts termination

### Detailed Changes

#### Minor Changes

- MDS only
- Log contract termination events in the LoggingHouse

#### Patch Changes

- EDC CE
- API request examples updates

- EDC UI
- Check the contract limits before negotiating a new one.
- Changed the title of Contract Definitions to Data Offers.
- Enhanced EDC UI terminologies for the Create Data Offer tab.
- Date and time display fixes, unified date format.

### Deployment Migration Notes

#### Compatible Versions

- Connector Backend Docker Images:
- Dev EDC: `ghcr.io/sovity/edc-dev:10.3.0`
- sovity EDC CE: `ghcr.io/sovity/edc-ce:10.3.0`
- MDS EDC CE: `ghcr.io/sovity/edc-ce-mds:10.3.0`
- Dev Catalog Crawler: `ghcr.io/sovity/catalog-crawler-dev:10.3.0`
- Catalog Crawler CE: `ghcr.io/sovity/catalog-crawler-ce:10.3.0`
- Connector UI Docker Image: `ghcr.io/sovity/edc-ui:4.1.3`

## [10.2.0] - 2024-08-20

### Overview
Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ subprojects {
tasks.register("printClasspath") {
group = libs.versions.edcGroup.get()
description = "The EdcRuntimeExtension JUnit Extension requires the gradle task 'printClasspath'"
println(sourceSets.main.get().runtimeClasspath.asPath);
println(sourceSets.main.get().runtimeClasspath.asPath)
}

java {
Expand Down
7 changes: 3 additions & 4 deletions docs/api/postman_collection.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"info": {
"_postman_id": "5cf38057-4fc0-4ff0-a0de-1ad96e0d7725",
"_postman_id": "213f5ff6-e5c6-41bb-9202-8e6cf60fec0c",
"name": "sovity EDC Community Edition Copy",
"description": "This is the official postman collection for the sovity EDC Community Edition.\n\nThe Management-API is based on core-edc v0.2.1.\n\nsovity EDC Community Edition: [https://github.com/sovity/edc-ce](https://github.com/sovity/edc-ce)\n\nLicense: [https://github.com/sovity/edc-ce/blob/main/LICENSE](https://github.com/sovity/edc-ce/blob/main/LICENSE)",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
Expand Down Expand Up @@ -212,7 +212,7 @@
}
},
"url": {
"raw": "{{PROVIDER_EDC_MANAGEMENT_URL}}/wrapper/ui/pages/asset-page/assets/{{ASSET_ID}}/metadata",
"raw": "{{PROVIDER_EDC_MANAGEMENT_URL}}/wrapper/ui/pages/asset-page/assets/{{ASSET_ID}}",
"host": [
"{{PROVIDER_EDC_MANAGEMENT_URL}}"
],
Expand All @@ -222,8 +222,7 @@
"pages",
"asset-page",
"assets",
"{{ASSET_ID}}",
"metadata"
"{{ASSET_ID}}"
],
"query": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,20 @@

import de.sovity.edc.extension.contacttermination.query.ContractAgreementTerminationDetailsQuery;
import de.sovity.edc.extension.contacttermination.query.TerminateContractQuery;
import de.sovity.edc.extension.messenger.SovityMessage;
import de.sovity.edc.extension.messenger.SovityMessenger;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.val;
import org.eclipse.edc.spi.EdcException;
import org.eclipse.edc.spi.monitor.Monitor;
import org.eclipse.edc.spi.observe.Observable;
import org.eclipse.edc.spi.observe.ObservableImpl;
import org.jetbrains.annotations.Nullable;
import org.jooq.DSLContext;

import java.time.OffsetDateTime;
import java.util.function.Consumer;

import static de.sovity.edc.ext.db.jooq.enums.ContractTerminatedBy.COUNTERPARTY;
import static de.sovity.edc.ext.db.jooq.enums.ContractTerminatedBy.SELF;
Expand All @@ -37,15 +42,20 @@ public class ContractAgreementTerminationService {
private final TerminateContractQuery terminateContractQuery;
private final Monitor monitor;
private final String thisParticipantId;
@Getter
private final Observable<ContractTerminationObserver> contractTerminationObservable = new ObservableImpl<>();

/**
* This is to terminate an EDC's own contract.
* If the termination comes from an external system, use
* {@link #terminateCounterpartyAgreement(DSLContext, String, ContractTerminationParam)}
* {@link #terminateAgreementAsCounterparty(DSLContext, String, ContractTerminationParam)}
* to validate the counter-party's identity.
*/
public OffsetDateTime terminateAgreementOrThrow(DSLContext dsl, ContractTerminationParam termination) {

val starterEvent = ContractTerminationEvent.from(termination, OffsetDateTime.now(), thisParticipantId);
notifyObservers(it -> it.contractTerminationStartedFromThisInstance(starterEvent));

val details = contractAgreementTerminationDetailsQuery.fetchAgreementDetailsOrThrow(dsl, termination.contractAgreementId());

if (details == null) {
Expand All @@ -58,16 +68,22 @@ public OffsetDateTime terminateAgreementOrThrow(DSLContext dsl, ContractTerminat

val terminatedAt = terminateContractQuery.terminateConsumerAgreementOrThrow(dsl, termination, SELF);

val endEvent = ContractTerminationEvent.from(termination, terminatedAt, thisParticipantId);
notifyObservers(it -> it.contractTerminationCompletedOnThisInstance(endEvent));

notifyTerminationToProvider(details.counterpartyAddress(), termination);

return terminatedAt;
}

public OffsetDateTime terminateCounterpartyAgreement(
public OffsetDateTime terminateAgreementAsCounterparty(
DSLContext dsl,
@Nullable String identity,
ContractTerminationParam termination
) {
val starterEvent = ContractTerminationEvent.from(termination, OffsetDateTime.now(), null);
notifyObservers(it -> it.contractTerminatedByCounterpartyStarted(starterEvent));

val details = contractAgreementTerminationDetailsQuery.fetchAgreementDetailsOrThrow(dsl, termination.contractAgreementId());

if (details == null) {
Expand All @@ -90,15 +106,35 @@ public OffsetDateTime terminateCounterpartyAgreement(

val agent = thisParticipantId.equals(details.counterpartyId()) ? SELF : COUNTERPARTY;

return terminateContractQuery.terminateConsumerAgreementOrThrow(dsl, termination, agent);
val result = terminateContractQuery.terminateConsumerAgreementOrThrow(dsl, termination, agent);

val endEvent = ContractTerminationEvent.from(termination, OffsetDateTime.now(), details.counterpartyId());
notifyObservers(it -> it.contractTerminatedByCounterparty(endEvent));

return result;
}

public void notifyTerminationToProvider(String counterPartyAddress, ContractTerminationParam termination) {

val notificationEvent = ContractTerminationEvent.from(termination, OffsetDateTime.now(), null);
notifyObservers(it -> it.contractTerminationOnCounterpartyStarted(notificationEvent));

sovityMessenger.send(
SovityMessage.class,
counterPartyAddress,
new ContractTerminationMessage(
termination.contractAgreementId(),
termination.detail(),
termination.reason()));
}

private void notifyObservers(Consumer<ContractTerminationObserver> call) {
for (val listener : contractTerminationObservable.getListeners()) {
try {
call.accept(listener);
} catch (Exception e) {
monitor.warning("Failure when notifying the contract termination listener.", e);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2024 sovity GmbH
*
* 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:
* sovity GmbH - initial API and implementation
*
*/

package de.sovity.edc.extension.contacttermination;

import java.time.OffsetDateTime;

public record ContractTerminationEvent(
String contractAgreementId,
String detail,
String reason,
OffsetDateTime timestamp,
String origin
) {
public static ContractTerminationEvent from(ContractTerminationParam contractTerminationParam, OffsetDateTime dateTime, String origin) {
return new ContractTerminationEvent(
contractTerminationParam.contractAgreementId(),
contractTerminationParam.detail(),
contractTerminationParam.reason(),
dateTime,
origin
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ private void setupMessenger(ContractAgreementTerminationService terminationServi
ContractTerminationMessage.class,
(claims, termination) ->
dslContextFactory.transactionResult(dsl ->
terminationService.terminateCounterpartyAgreement(
terminationService.terminateAgreementAsCounterparty(
dsl,
participantAgentService.createFor(claims).getIdentity(),
buildTerminationRequest(termination))));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2024 sovity GmbH
*
* 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:
* sovity GmbH - initial API and implementation
*
*/

package de.sovity.edc.extension.contacttermination;

public interface ContractTerminationObserver {

/**
* Indicates that a contract termination was started by this EDC.
*/
default void contractTerminationStartedFromThisInstance(ContractTerminationEvent contractTerminationEvent) {
}

/**
* Indicates that the first step to terminate a contract, terminating a contract on this EDC instance itself, was successful.
* The contract is now marked as terminated on this EDC's side.
*/
default void contractTerminationCompletedOnThisInstance(ContractTerminationEvent contractTerminationEvent) {
}

/**
* Indicates that a contract termination on the counterparty EDC was started.
*/
default void contractTerminationOnCounterpartyStarted(ContractTerminationEvent contractTerminationEvent) {
}

/**
* Indicates that a contract termination was started by a counterparty EDC terminated successfully
*/
default void contractTerminatedByCounterpartyStarted(ContractTerminationEvent contractTerminationEvent) {
}

/**
* Indicates that a contract termination initiated by a counterparty EDC terminated successfully
* The contract is now marked as terminated on this EDC.
*/
default void contractTerminatedByCounterparty(ContractTerminationEvent contractTerminationEvent) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ public class TerminateContractQuery {
public OffsetDateTime terminateConsumerAgreementOrThrow(
DSLContext dsl,
ContractTerminationParam termination,
ContractTerminatedBy terminatedBy) {

ContractTerminatedBy terminatedBy
) {
val tooAccurate = OffsetDateTime.now();
val now = tooAccurate.truncatedTo(ChronoUnit.MICROS);

Expand Down
44 changes: 44 additions & 0 deletions extensions/mds-logginghouse-binder/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<!-- PROJECT LOGO -->
<br />
<div align="center">
<a href="https://github.com/sovity/edc-ce">
<img src="https://raw.githubusercontent.com/sovity/edc-ui/main/src/assets/images/sovity_logo.svg" alt="Logo" width="300">
</a>

<h3 align="center">EDC-Connector Extension:<br />MDS Contract Termination - LoggingHouse binder</h3>

<p align="center">
<a href="https://github.com/sovity/edc-ce/issues/new?template=bug_report.md">Report Bug</a>
·
<a href="https://github.com/sovity/edc-ce/issues/new?template=feature_request.md">Request Feature</a>
</p>
</div>


## About this Extension

It links the Contract Termination events with the LoggingHouse.

## Why does this extension exist?

MDS needs to log the events generated when terminating a contract with their Logging House extension.
The Logging House is an external dependency and the linkage must only happen for the MDS variant.

This extension implements this specific task.

## Architecture

```mermaid
flowchart TD
Binder(MDS LoggingHouse Binder) --> LoggingHouse(Logging House Extension)
Binder(MDS LoggingHouse Binder) --> ContractTermination(Contract Termination Extension)
MDS(MDS CE) --> Binder
```

## License

Apache License 2.0 - see [LICENSE](../../LICENSE)

## Contact

sovity GmbH - [email protected]
Loading

0 comments on commit de7def8

Please sign in to comment.