Skip to content

Commit

Permalink
use TCK extension in tests
Browse files Browse the repository at this point in the history
  • Loading branch information
paullatzelsperger committed Dec 4, 2024
1 parent 22dafd7 commit 04c5f1b
Show file tree
Hide file tree
Showing 38 changed files with 1,985 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ public <I extends RemoteMessage, R, E extends ErrorMessage> Response createResou

var token = request.getToken();
if (token == null) {
monitor.severe("DSP: No auth token provided - returning 401");
return unauthorized(request);
}

Expand Down
33 changes: 33 additions & 0 deletions extensions/tck-extension/build.gradle.kts
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)
}
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) {
}
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));
}
}
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");
}
}
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();
}
}
Loading

0 comments on commit 04c5f1b

Please sign in to comment.