Skip to content

Commit

Permalink
chore(dsp-negotiation-dispatcher): implement delegates
Browse files Browse the repository at this point in the history
  • Loading branch information
juliapampus committed Apr 20, 2023
1 parent 80e5580 commit 36e2fb1
Show file tree
Hide file tree
Showing 11 changed files with 1,308 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
package org.eclipse.edc.protocol.dsp.negotiation.dispatcher;

import org.eclipse.edc.jsonld.transformer.JsonLdTransformerRegistry;
import org.eclipse.edc.protocol.dsp.negotiation.dispatcher.delegate.ContractAgreementMessageDelegate;
import org.eclipse.edc.protocol.dsp.negotiation.dispatcher.delegate.ContractAgreementVerificationMessageDelegate;
import org.eclipse.edc.protocol.dsp.negotiation.dispatcher.delegate.ContractNegotiationEventMessageDelegate;
import org.eclipse.edc.protocol.dsp.negotiation.dispatcher.delegate.ContractOfferRequestDelegate;
import org.eclipse.edc.protocol.dsp.negotiation.dispatcher.delegate.ContractRejectionHttpDelegate;
import org.eclipse.edc.protocol.dsp.negotiation.dispatcher.delegate.ContractAgreementMessageHttpDelegate;
import org.eclipse.edc.protocol.dsp.negotiation.dispatcher.delegate.ContractAgreementVerificationMessageHttpDelegate;
import org.eclipse.edc.protocol.dsp.negotiation.dispatcher.delegate.ContractNegotiationEventMessageHttpDelegate;
import org.eclipse.edc.protocol.dsp.negotiation.dispatcher.delegate.ContractNegotiationTerminationMessageHttpDelegate;
import org.eclipse.edc.protocol.dsp.negotiation.dispatcher.delegate.ContractRequestMessageHttpDelegate;
import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpRemoteMessageDispatcher;
import org.eclipse.edc.runtime.metamodel.annotation.Extension;
import org.eclipse.edc.runtime.metamodel.annotation.Inject;
Expand Down Expand Up @@ -50,10 +50,10 @@ public String name() {
public void initialize(ServiceExtensionContext context) {
var objectMapper = typeManager.getMapper(TYPE_MANAGER_CONTEXT_JSON_LD);

messageDispatcher.registerDelegate(new ContractAgreementMessageDelegate(objectMapper, transformerRegistry));
messageDispatcher.registerDelegate(new ContractAgreementVerificationMessageDelegate(objectMapper, transformerRegistry));
messageDispatcher.registerDelegate(new ContractNegotiationEventMessageDelegate(objectMapper, transformerRegistry));
messageDispatcher.registerDelegate(new ContractOfferRequestDelegate(objectMapper, transformerRegistry));
messageDispatcher.registerDelegate(new ContractRejectionHttpDelegate(objectMapper, transformerRegistry));
messageDispatcher.registerDelegate(new ContractAgreementMessageHttpDelegate(objectMapper, transformerRegistry));
messageDispatcher.registerDelegate(new ContractAgreementVerificationMessageHttpDelegate(objectMapper, transformerRegistry));
messageDispatcher.registerDelegate(new ContractNegotiationEventMessageHttpDelegate(objectMapper, transformerRegistry));
messageDispatcher.registerDelegate(new ContractNegotiationTerminationMessageHttpDelegate(objectMapper, transformerRegistry));
messageDispatcher.registerDelegate(new ContractRequestMessageHttpDelegate(objectMapper, transformerRegistry));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
* Copyright (c) 2023 Fraunhofer Institute for Software and Systems Engineering
*
* 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:
* Fraunhofer Institute for Software and Systems Engineering - initial API and implementation
*
*/

package org.eclipse.edc.protocol.dsp.negotiation.dispatcher.delegate;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.json.Json;
import jakarta.json.JsonObject;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.eclipse.edc.connector.contract.spi.types.agreement.ContractAgreementMessage;
import org.eclipse.edc.jsonld.transformer.JsonLdTransformerRegistry;
import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpDispatcherDelegate;
import org.eclipse.edc.spi.EdcException;

import java.util.function.Function;

import static java.lang.String.format;
import static java.lang.String.join;
import static org.eclipse.edc.jsonld.util.JsonLdUtil.compact;
import static org.eclipse.edc.protocol.dsp.negotiation.spi.NegotiationApiPaths.AGREEMENT;
import static org.eclipse.edc.protocol.dsp.negotiation.spi.NegotiationApiPaths.BASE_PATH;
import static org.eclipse.edc.protocol.dsp.transform.transformer.Namespaces.DSPACE_PREFIX;
import static org.eclipse.edc.protocol.dsp.transform.transformer.Namespaces.DSPACE_SCHEMA;
import static org.eclipse.edc.protocol.dsp.transform.transformer.Namespaces.ODRL_PREFIX;
import static org.eclipse.edc.protocol.dsp.transform.transformer.Namespaces.ODRL_SCHEMA;

/**
* Delegate for dispatching contract agreement message as defined in the dataspace protocol specification.
*/
public class ContractAgreementMessageHttpDelegate implements DspHttpDispatcherDelegate<ContractAgreementMessage, Object> {

private static final String APPLICATION_JSON = "application/json";

private final ObjectMapper mapper;
private final JsonLdTransformerRegistry transformerRegistry;

public ContractAgreementMessageHttpDelegate(ObjectMapper mapper, JsonLdTransformerRegistry transformerRegistry) {
this.mapper = mapper;
this.transformerRegistry = transformerRegistry;
}

@Override
public Class<ContractAgreementMessage> getMessageType() {
return ContractAgreementMessage.class;
}

/**
* Sends a contract agreement message. The request body is constructed as defined in the dataspace
* protocol. The request is sent to the remote component using the path from the http binding.
*
* @param message the message.
* @return the built okhttp request.
*/
@Override
public Request buildRequest(ContractAgreementMessage message) {
var requestBody = RequestBody.create(toJson(message), MediaType.get(APPLICATION_JSON));
return new Request.Builder()
.url(message.getCallbackAddress() + BASE_PATH + message.getProcessId() + AGREEMENT)
.header("Content-Type", APPLICATION_JSON)
.post(requestBody)
.build();
}

/**
* Parses the response to an agreement message. The JSON-LD structure from the response body is
* expanded and returned.
*
* @return a function that contains the response body or null.
*/
@Override
public Function<Response, Object> parseResponse() {
return response -> null;
}

private String toJson(ContractAgreementMessage message) {
try {
var transformResult = transformerRegistry.transform(message, JsonObject.class);
if (transformResult.succeeded()) {
var compacted = compact(transformResult.getContent(), jsonLdContext());
return mapper.writeValueAsString(compacted);
}
throw new EdcException(format("Failed to write request: %s", join(", ", transformResult.getFailureMessages())));
} catch (JsonProcessingException e) {
throw new EdcException("Failed to serialize agreement message", e);
}
}

// TODO refactor according to https://github.com/eclipse-edc/Connector/issues/2763
private JsonObject jsonLdContext() {
return Json.createObjectBuilder()
.add(DSPACE_PREFIX, DSPACE_SCHEMA)
.add(ODRL_PREFIX, ODRL_SCHEMA)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Copyright (c) 2023 Fraunhofer Institute for Software and Systems Engineering
*
* 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:
* Fraunhofer Institute for Software and Systems Engineering - initial API and implementation
*
*/

package org.eclipse.edc.protocol.dsp.negotiation.dispatcher.delegate;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.json.Json;
import jakarta.json.JsonObject;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.eclipse.edc.connector.contract.spi.types.agreement.ContractAgreementVerificationMessage;
import org.eclipse.edc.jsonld.transformer.JsonLdTransformerRegistry;
import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpDispatcherDelegate;
import org.eclipse.edc.spi.EdcException;

import java.util.function.Function;

import static java.lang.String.format;
import static java.lang.String.join;
import static org.eclipse.edc.jsonld.util.JsonLdUtil.compact;
import static org.eclipse.edc.protocol.dsp.negotiation.spi.NegotiationApiPaths.AGREEMENT;
import static org.eclipse.edc.protocol.dsp.negotiation.spi.NegotiationApiPaths.BASE_PATH;
import static org.eclipse.edc.protocol.dsp.negotiation.spi.NegotiationApiPaths.VERIFICATION;
import static org.eclipse.edc.protocol.dsp.transform.transformer.Namespaces.DSPACE_PREFIX;
import static org.eclipse.edc.protocol.dsp.transform.transformer.Namespaces.DSPACE_SCHEMA;

/**
* Delegate for dispatching contract agreement verification message as defined in the dataspace protocol specification.
*/
public class ContractAgreementVerificationMessageHttpDelegate implements DspHttpDispatcherDelegate<ContractAgreementVerificationMessage, Object> {

private static final String APPLICATION_JSON = "application/json";

private final ObjectMapper mapper;
private final JsonLdTransformerRegistry transformerRegistry;

public ContractAgreementVerificationMessageHttpDelegate(ObjectMapper mapper, JsonLdTransformerRegistry transformerRegistry) {
this.mapper = mapper;
this.transformerRegistry = transformerRegistry;
}

@Override
public Class<ContractAgreementVerificationMessage> getMessageType() {
return ContractAgreementVerificationMessage.class;
}

/**
* Sends a contract agreement verification message. The request body is constructed as defined in
* the dataspace protocol. The request is sent to the remote component using the path from the http
* binding.
*
* @param message the message.
* @return the built okhttp request.
*/
@Override
public Request buildRequest(ContractAgreementVerificationMessage message) {
var requestBody = RequestBody.create(toJson(message), MediaType.get(APPLICATION_JSON));
return new Request.Builder()
.url(message.getCallbackAddress() + BASE_PATH + message.getProcessId() + AGREEMENT + VERIFICATION)
.header("Content-Type", APPLICATION_JSON)
.post(requestBody)
.build();
}

/**
* Parses the response to an agreement verification message. The JSON-LD structure from the response
* body is expanded and returned.
*
* @return a function that contains the response body or null.
*/
@Override
public Function<Response, Object> parseResponse() {
return response -> null;
}

private String toJson(ContractAgreementVerificationMessage message) {
try {
var transformResult = transformerRegistry.transform(message, JsonObject.class);
if (transformResult.succeeded()) {
var compacted = compact(transformResult.getContent(), jsonLdContext());
return mapper.writeValueAsString(compacted);
}
throw new EdcException(format("Failed to write request: %s", join(", ", transformResult.getFailureMessages())));
} catch (JsonProcessingException e) {
throw new EdcException("Failed to serialize agreement verification message", e);
}
}

// TODO refactor according to https://github.com/eclipse-edc/Connector/issues/2763
private JsonObject jsonLdContext() {
return Json.createObjectBuilder()
.add(DSPACE_PREFIX, DSPACE_SCHEMA)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* Copyright (c) 2023 Fraunhofer Institute for Software and Systems Engineering
*
* 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:
* Fraunhofer Institute for Software and Systems Engineering - initial API and implementation
*
*/

package org.eclipse.edc.protocol.dsp.negotiation.dispatcher.delegate;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.json.Json;
import jakarta.json.JsonObject;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.eclipse.edc.connector.contract.spi.types.agreement.ContractNegotiationEventMessage;
import org.eclipse.edc.jsonld.transformer.JsonLdTransformerRegistry;
import org.eclipse.edc.protocol.dsp.spi.dispatcher.DspHttpDispatcherDelegate;
import org.eclipse.edc.spi.EdcException;

import java.util.function.Function;

import static java.lang.String.format;
import static java.lang.String.join;
import static org.eclipse.edc.jsonld.util.JsonLdUtil.compact;
import static org.eclipse.edc.protocol.dsp.negotiation.spi.NegotiationApiPaths.BASE_PATH;
import static org.eclipse.edc.protocol.dsp.negotiation.spi.NegotiationApiPaths.EVENT;
import static org.eclipse.edc.protocol.dsp.transform.transformer.Namespaces.DSPACE_PREFIX;
import static org.eclipse.edc.protocol.dsp.transform.transformer.Namespaces.DSPACE_SCHEMA;

/**
* Delegate for dispatching contract negotiation event message as defined in the dataspace protocol specification.
*/
public class ContractNegotiationEventMessageHttpDelegate implements DspHttpDispatcherDelegate<ContractNegotiationEventMessage, Object> {

private static final String APPLICATION_JSON = "application/json";

private final ObjectMapper mapper;
private final JsonLdTransformerRegistry transformerRegistry;

public ContractNegotiationEventMessageHttpDelegate(ObjectMapper mapper, JsonLdTransformerRegistry transformerRegistry) {
this.mapper = mapper;
this.transformerRegistry = transformerRegistry;
}

@Override
public Class<ContractNegotiationEventMessage> getMessageType() {
return ContractNegotiationEventMessage.class;
}

/**
* Sends a contract negotiation event message. The request body is constructed as defined in the
* dataspace protocol. The request is sent to the remote component using the path from the http
* binding.
*
* @param message the message.
* @return the built okhttp request.
*/
@Override
public Request buildRequest(ContractNegotiationEventMessage message) {
var requestBody = RequestBody.create(toJson(message), MediaType.get(APPLICATION_JSON));
return new Request.Builder()
.url(message.getCallbackAddress() + BASE_PATH + message.getProcessId() + EVENT)
.header("Content-Type", APPLICATION_JSON)
.post(requestBody)
.build();
}

/**
* Parses the response to a contract negotiation event message. The JSON-LD structure from the response
* body is expanded and returned.
*
* @return a function that contains the response body or null.
*/
@Override
public Function<Response, Object> parseResponse() {
return response -> null;
}

private String toJson(ContractNegotiationEventMessage message) {
try {
var transformResult = transformerRegistry.transform(message, JsonObject.class);
if (transformResult.succeeded()) {
var compacted = compact(transformResult.getContent(), jsonLdContext());
return mapper.writeValueAsString(compacted);
}
throw new EdcException(format("Failed to write request: %s", join(", ", transformResult.getFailureMessages())));
} catch (JsonProcessingException e) {
throw new EdcException("Failed to serialize negotiation event message", e);
}
}

// TODO refactor according to https://github.com/eclipse-edc/Connector/issues/2763
private JsonObject jsonLdContext() {
return Json.createObjectBuilder()
.add(DSPACE_PREFIX, DSPACE_SCHEMA)
.build();
}
}
Loading

0 comments on commit 36e2fb1

Please sign in to comment.