-
Notifications
You must be signed in to change notification settings - Fork 245
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
22dafd7
commit 04c5f1b
Showing
38 changed files
with
1,985 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* | ||
* Copyright (c) 2024 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 | ||
* | ||
*/ | ||
|
||
plugins { | ||
`java-library` | ||
} | ||
|
||
dependencies { | ||
implementation(project(":spi:common:core-spi")) | ||
implementation(project(":spi:control-plane:contract-spi")) | ||
implementation(project(":spi:control-plane:asset-spi")) | ||
implementation(project(":spi:control-plane:control-plane-spi")) | ||
implementation(project(":spi:common:web-spi")) | ||
implementation(libs.jakarta.rsApi) | ||
} | ||
|
||
// If the EDC Build Plugin is used, every module gets visited during Publishing by default. | ||
// Single modules can be excluded by setting the "publish" flag to false: | ||
|
||
edcBuild { | ||
publish.set(false) | ||
} |
25 changes: 25 additions & 0 deletions
25
...xtension/src/main/java/org/eclipse/edc/tck/dsp/controller/ContractNegotiationRequest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/* | ||
* Copyright (c) 2024 Metaform Systems, Inc. | ||
* | ||
* 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: | ||
* Metaform Systems, Inc. - initial API and implementation | ||
* | ||
*/ | ||
|
||
package org.eclipse.edc.tck.dsp.controller; | ||
|
||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
|
||
/** | ||
* Initiates a negotiation request | ||
*/ | ||
public record ContractNegotiationRequest(@JsonProperty("providerId") String providerId, | ||
@JsonProperty("connectorAddress") String connectorAddress, | ||
@JsonProperty("offerId") String offerId) { | ||
} |
52 changes: 52 additions & 0 deletions
52
...ck-extension/src/main/java/org/eclipse/edc/tck/dsp/controller/TckControllerExtension.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package org.eclipse.edc.tck.dsp.controller; | ||
|
||
import org.eclipse.edc.connector.controlplane.services.spi.contractnegotiation.ContractNegotiationService; | ||
import org.eclipse.edc.runtime.metamodel.annotation.Inject; | ||
import org.eclipse.edc.spi.system.ServiceExtension; | ||
import org.eclipse.edc.spi.system.ServiceExtensionContext; | ||
import org.eclipse.edc.web.spi.WebServer; | ||
import org.eclipse.edc.web.spi.WebService; | ||
import org.eclipse.edc.web.spi.configuration.WebServiceConfigurer; | ||
import org.eclipse.edc.web.spi.configuration.WebServiceSettings; | ||
|
||
/** | ||
* Bootstraps the TCK web hook. | ||
*/ | ||
public class TckControllerExtension implements ServiceExtension { | ||
private static final String NAME = "DSP TCK Controller"; | ||
private static final String PROTOCOL = "tck"; | ||
|
||
private static final WebServiceSettings SETTINGS = WebServiceSettings.Builder.newInstance() | ||
.apiConfigKey(PROTOCOL) | ||
.contextAlias("tck") | ||
.defaultPath("/tck") | ||
.defaultPort(8687) | ||
.useDefaultContext(false) | ||
.name("Tck API") | ||
.build(); | ||
|
||
|
||
@Inject | ||
private WebServiceConfigurer configurator; | ||
|
||
@Inject | ||
private WebService webService; | ||
|
||
@Inject | ||
private WebServer webServer; | ||
|
||
@Inject | ||
private ContractNegotiationService negotiationService; | ||
|
||
@Override | ||
public String name() { | ||
return NAME; | ||
} | ||
|
||
@Override | ||
public void initialize(ServiceExtensionContext context) { | ||
var config = context.getConfig(PROTOCOL); | ||
configurator.configure(config, webServer, SETTINGS); | ||
webService.registerResource(PROTOCOL, new TckWebhookController(negotiationService)); | ||
} | ||
} |
63 changes: 63 additions & 0 deletions
63
.../tck-extension/src/main/java/org/eclipse/edc/tck/dsp/controller/TckWebhookController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/* | ||
* Copyright (c) 2024 Metaform Systems, Inc. | ||
* | ||
* 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: | ||
* Metaform Systems, Inc. - initial API and implementation | ||
* | ||
*/ | ||
|
||
package org.eclipse.edc.tck.dsp.controller; | ||
|
||
import jakarta.ws.rs.Consumes; | ||
import jakarta.ws.rs.POST; | ||
import jakarta.ws.rs.Path; | ||
import jakarta.ws.rs.Produces; | ||
import org.eclipse.edc.connector.controlplane.contract.spi.types.negotiation.ContractRequest; | ||
import org.eclipse.edc.connector.controlplane.contract.spi.types.offer.ContractOffer; | ||
import org.eclipse.edc.connector.controlplane.services.spi.contractnegotiation.ContractNegotiationService; | ||
import org.eclipse.edc.policy.model.Policy; | ||
import org.eclipse.edc.spi.types.domain.callback.CallbackAddress; | ||
|
||
import java.util.List; | ||
|
||
import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON; | ||
|
||
/** | ||
* Implements TCK web hooks. | ||
*/ | ||
@Consumes(APPLICATION_JSON) | ||
@Produces(APPLICATION_JSON) | ||
@Path("/negotiations") | ||
public class TckWebhookController { | ||
|
||
private ContractNegotiationService negotiationService; | ||
|
||
public TckWebhookController(ContractNegotiationService negotiationService) { | ||
this.negotiationService = negotiationService; | ||
} | ||
|
||
@POST | ||
@Path("requests") | ||
public void startNegotiation(ContractNegotiationRequest request) { | ||
|
||
var contractOffer = ContractOffer.Builder.newInstance() | ||
.id(request.offerId()) | ||
.assetId(request.offerId()) | ||
.policy(Policy.Builder.newInstance().assigner(request.providerId()).build()) | ||
.build(); | ||
var contractRequest = ContractRequest.Builder.newInstance() | ||
.callbackAddresses(List.of(CallbackAddress.Builder.newInstance().uri(request.connectorAddress()).build())) | ||
.counterPartyAddress(request.connectorAddress()) | ||
.contractOffer(contractOffer) | ||
.protocol("dataspace-protocol-http") | ||
.build(); | ||
negotiationService.initiateNegotiation(contractRequest); | ||
System.out.println("Negotiation"); | ||
} | ||
} |
165 changes: 165 additions & 0 deletions
165
extensions/tck-extension/src/main/java/org/eclipse/edc/tck/dsp/data/DataAssembly.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
/* | ||
* Copyright (c) 2024 Metaform Systems, Inc. | ||
* | ||
* 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: | ||
* Metaform Systems, Inc. - initial API and implementation | ||
* | ||
*/ | ||
|
||
package org.eclipse.edc.tck.dsp.data; | ||
|
||
import org.eclipse.edc.connector.controlplane.asset.spi.domain.Asset; | ||
import org.eclipse.edc.connector.controlplane.contract.spi.event.contractnegotiation.ContractNegotiationAccepted; | ||
import org.eclipse.edc.connector.controlplane.contract.spi.event.contractnegotiation.ContractNegotiationAgreed; | ||
import org.eclipse.edc.connector.controlplane.contract.spi.event.contractnegotiation.ContractNegotiationEvent; | ||
import org.eclipse.edc.connector.controlplane.contract.spi.event.contractnegotiation.ContractNegotiationOffered; | ||
import org.eclipse.edc.connector.controlplane.contract.spi.types.negotiation.ContractNegotiation; | ||
import org.eclipse.edc.connector.controlplane.contract.spi.types.offer.ContractDefinition; | ||
import org.eclipse.edc.connector.controlplane.policy.spi.PolicyDefinition; | ||
import org.eclipse.edc.policy.model.Policy; | ||
import org.eclipse.edc.spi.types.domain.DataAddress; | ||
import org.eclipse.edc.tck.dsp.guard.Trigger; | ||
import org.eclipse.edc.tck.dsp.recorder.StepRecorder; | ||
|
||
import java.util.List; | ||
import java.util.Set; | ||
import java.util.function.Consumer; | ||
|
||
import static java.util.stream.Collectors.toSet; | ||
import static org.eclipse.edc.connector.controlplane.contract.spi.types.negotiation.ContractNegotiationStates.REQUESTED; | ||
|
||
/** | ||
* Assembles data for the TCK scenarios. | ||
*/ | ||
public class DataAssembly { | ||
private static final Set<String> ASSET_IDS = Set.of("ACN0101", "ACN0102", "ACN0103", "ACN0104", | ||
"ACN0201", "ACN0202", "ACN0203", "ACN0204", "ACN0205", "ACN0206", "ACN0207", | ||
"ACN0301", "ACN0302", "ACN0303", "ACN0304"); | ||
|
||
private static final String POLICY_ID = "P123"; | ||
private static final String CONTRACT_DEFINITION_ID = "CD123"; | ||
|
||
public static Set<Asset> createAssets() { | ||
return ASSET_IDS.stream().map(DataAssembly::createAsset).collect(toSet()); | ||
} | ||
|
||
public static Set<PolicyDefinition> createPolicyDefinitions() { | ||
return Set.of(PolicyDefinition.Builder.newInstance() | ||
.id(POLICY_ID) | ||
.policy(Policy.Builder.newInstance().build()) | ||
.build()); | ||
} | ||
|
||
public static Set<ContractDefinition> createContractDefinitions() { | ||
return Set.of(ContractDefinition.Builder.newInstance() | ||
.id(CONTRACT_DEFINITION_ID) | ||
.accessPolicyId(POLICY_ID) | ||
.contractPolicyId(POLICY_ID) | ||
.build()); | ||
} | ||
|
||
public static StepRecorder<ContractNegotiation> createNegotiationRecorder() { | ||
var recorder = new StepRecorder<ContractNegotiation>(); | ||
|
||
record01NegotiationSequences(recorder); | ||
record02NegotiationSequences(recorder); | ||
record03NegotiationSequences(recorder); | ||
|
||
recordC01NegotiationSequences(recorder); | ||
|
||
return recorder.repeat(); | ||
} | ||
|
||
private static void recordC01NegotiationSequences(StepRecorder<ContractNegotiation> recorder) { | ||
} | ||
|
||
private static void record01NegotiationSequences(StepRecorder<ContractNegotiation> recorder) { | ||
recorder.record("ACN0101", ContractNegotiation::transitionOffering); | ||
|
||
recorder.record("ACN0102", ContractNegotiation::transitionOffering) | ||
.record("ACN0102", ContractNegotiation::transitionTerminating); | ||
|
||
recorder.record("ACN0103", ContractNegotiation::transitionOffering) | ||
.record("ACN0103", ContractNegotiation::transitionAgreeing) | ||
.record("ACN0103", ContractNegotiation::transitionFinalizing); | ||
|
||
recorder.record("ACN0104", ContractNegotiation::transitionAgreeing) | ||
.record("ACN0104", ContractNegotiation::transitionFinalizing); | ||
} | ||
|
||
private static void record02NegotiationSequences(StepRecorder<ContractNegotiation> recorder) { | ||
recorder.record("ACN0201", ContractNegotiation::transitionTerminating); | ||
|
||
recorder.record("ACN0202", ContractNegotiation::transitionRequested); | ||
|
||
recorder.record("ACN0203", ContractNegotiation::transitionAgreeing); | ||
|
||
recorder.record("ACN0204", ContractNegotiation::transitionOffering); | ||
|
||
recorder.record("ACN0205", ContractNegotiation::transitionOffering); | ||
|
||
recorder.record("ACN0206", contractNegotiation -> { | ||
// only transition if in requested | ||
if (contractNegotiation.getState() == REQUESTED.code()) { | ||
contractNegotiation.transitionOffering(); | ||
} | ||
}); | ||
|
||
recorder.record("ACN0207", ContractNegotiation::transitionAgreeing) | ||
.record("ACN0207", ContractNegotiation::transitionTerminating); | ||
} | ||
|
||
private static void record03NegotiationSequences(StepRecorder<ContractNegotiation> recorder) { | ||
recorder.record("ACN0301", ContractNegotiation::transitionAgreeing) | ||
.record("ACN0301", ContractNegotiation::transitionFinalizing); | ||
|
||
recorder.record("ACN0302", ContractNegotiation::transitionOffering); | ||
recorder.record("ACN0303", ContractNegotiation::transitionOffering) | ||
.record("ACN0303", ContractNegotiation::transitionAccepting); | ||
|
||
recorder.record("ACN0304", ContractNegotiation::transitionOffering); | ||
} | ||
|
||
public static List<Trigger<ContractNegotiation>> createNegotiationTriggers() { | ||
return List.of( | ||
createTrigger(ContractNegotiationOffered.class, "ACN0205", ContractNegotiation::transitionTerminating), | ||
createTrigger(ContractNegotiationAccepted.class, "ACN0206", ContractNegotiation::transitionTerminating), | ||
createTrigger(ContractNegotiationOffered.class, "C0101", contractNegotiation -> { | ||
contractNegotiation.transitionAccepting(); | ||
contractNegotiation.setPending(false); | ||
}), | ||
createTrigger(ContractNegotiationAgreed.class, "C0101", contractNegotiation -> { | ||
contractNegotiation.transitionVerifying(); | ||
contractNegotiation.setPending(false); | ||
}) | ||
|
||
); | ||
} | ||
|
||
private static <E extends ContractNegotiationEvent> Trigger<ContractNegotiation> createTrigger(Class<E> type, | ||
String assetId, | ||
Consumer<ContractNegotiation> action) { | ||
return new Trigger<>(event -> { | ||
if (event.getClass().equals(type)) { | ||
return assetId.equals(((ContractNegotiationEvent) event).getLastContractOffer().getAssetId()); | ||
} | ||
return false; | ||
}, action); | ||
} | ||
|
||
private DataAssembly() { | ||
} | ||
|
||
private static Asset createAsset(String id) { | ||
return Asset.Builder.newInstance() | ||
.id(id) | ||
.dataAddress(DataAddress.Builder.newInstance().type("HTTP").build()) | ||
.build(); | ||
} | ||
} |
Oops, something went wrong.