-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'feature/440645-transferencia-inesdata' into 'develop'
Feature/440645 transferencia inesdata See merge request upm-inesdata/inesdata-connector!34
- Loading branch information
Showing
10 changed files
with
353 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# InesData Transfer Process API | ||
Provides a management API to handle InesData Transfer Process entities. This API expands the functionality of the existing control-plane management API by introducing a new endpoint for the initialization of data transfers to the connector's own MinIO storage. | ||
|
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 @@ | ||
plugins { | ||
`java-library` | ||
id("com.gmv.inesdata.edc-application") | ||
} | ||
|
||
dependencies { | ||
api(libs.edc.spi.core) | ||
implementation(libs.edc.transfer.process.api) | ||
implementation(libs.edc.api.management.lib) | ||
implementation(libs.edc.web.spi) | ||
|
||
implementation(libs.edc.connector.core) | ||
implementation(libs.edc.api.core) | ||
implementation(libs.edc.lib.util) | ||
implementation(libs.edc.lib.transform) | ||
implementation(libs.edc.dsp.api.configuration) | ||
implementation(libs.edc.api.management.config) | ||
implementation(libs.swagger.annotations.jakarta) | ||
implementation(libs.edc.transaction.spi) | ||
implementation(libs.edc.lib.validator) | ||
implementation(libs.edc.validator.spi) | ||
implementation(libs.swagger.annotations.jakarta) | ||
runtimeOnly(libs.edc.spi.jsonld) | ||
runtimeOnly(libs.edc.json.ld.lib) | ||
} |
73 changes: 73 additions & 0 deletions
73
.../src/main/java/org/upm/inesdata/inesdatatransfer/InesdataTransferProcessApiExtension.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,73 @@ | ||
package org.upm.inesdata.inesdatatransfer; | ||
|
||
import jakarta.json.Json; | ||
import jakarta.json.JsonBuilderFactory; | ||
import org.eclipse.edc.connector.controlplane.api.management.transferprocess.transform.JsonObjectFromTransferProcessTransformer; | ||
import org.eclipse.edc.connector.controlplane.api.management.transferprocess.transform.JsonObjectFromTransferStateTransformer; | ||
import org.eclipse.edc.connector.controlplane.api.management.transferprocess.transform.JsonObjectToSuspendTransferTransformer; | ||
import org.eclipse.edc.connector.controlplane.api.management.transferprocess.transform.JsonObjectToTerminateTransferTransformer; | ||
import org.eclipse.edc.connector.controlplane.api.management.transferprocess.transform.JsonObjectToTransferRequestTransformer; | ||
import org.eclipse.edc.connector.controlplane.api.management.transferprocess.validation.TerminateTransferValidator; | ||
import org.eclipse.edc.connector.controlplane.services.spi.transferprocess.TransferProcessService; | ||
import org.eclipse.edc.runtime.metamodel.annotation.Extension; | ||
import org.eclipse.edc.runtime.metamodel.annotation.Inject; | ||
import org.eclipse.edc.spi.security.Vault; | ||
import org.eclipse.edc.spi.system.ServiceExtension; | ||
import org.eclipse.edc.spi.system.ServiceExtensionContext; | ||
import org.eclipse.edc.transform.spi.TypeTransformerRegistry; | ||
import org.eclipse.edc.validator.spi.JsonObjectValidatorRegistry; | ||
import org.eclipse.edc.web.spi.WebService; | ||
import org.upm.inesdata.inesdatatransfer.controller.InesdataTransferProcessApiController; | ||
import org.upm.inesdata.inesdatatransfer.validations.InesdataTransferRequestValidator; | ||
|
||
import java.util.Collections; | ||
|
||
@Extension("Management API: Inesdata Transfer Process") | ||
public class InesdataTransferProcessApiExtension implements ServiceExtension { | ||
public static final String NAME = "Management API: Transfer Process"; | ||
public static final String DEFAULT_VALUE = ""; | ||
public static final String AWS_ACCESS_KEY = "edc.aws.access.key"; | ||
public static final String AWS_SECRET_ACCESS = "edc.aws.secret.access.key"; | ||
public static final String AWS_ENDPOINT_OVERRIDE = "edc.aws.endpoint.override"; | ||
public static final String AWS_REGION = "edc.aws.region"; | ||
public static final String AWS_BUCKET_NAME = "edc.aws.bucket.name"; | ||
|
||
|
||
@Inject | ||
private WebService webService; | ||
@Inject | ||
private TypeTransformerRegistry transformerRegistry; | ||
@Inject | ||
private TransferProcessService service; | ||
@Inject | ||
private JsonObjectValidatorRegistry validatorRegistry; | ||
@Inject | ||
private Vault vault; | ||
|
||
public InesdataTransferProcessApiExtension() { | ||
} | ||
|
||
public String name() { | ||
return "Management API: Inesdata Transfer Process"; | ||
} | ||
|
||
public void initialize(ServiceExtensionContext context) { | ||
JsonBuilderFactory builderFactory = Json.createBuilderFactory(Collections.emptyMap()); | ||
TypeTransformerRegistry managementApiTransformerRegistry = this.transformerRegistry.forContext("management-api"); | ||
managementApiTransformerRegistry.register(new JsonObjectFromTransferProcessTransformer(builderFactory)); | ||
managementApiTransformerRegistry.register(new JsonObjectFromTransferStateTransformer(builderFactory)); | ||
managementApiTransformerRegistry.register(new JsonObjectToTerminateTransferTransformer()); | ||
managementApiTransformerRegistry.register(new JsonObjectToSuspendTransferTransformer()); | ||
managementApiTransformerRegistry.register(new JsonObjectToTransferRequestTransformer()); | ||
// Leer las variables de entorno | ||
var accessKey = vault.resolveSecret(context.getSetting(AWS_ACCESS_KEY, DEFAULT_VALUE)); | ||
var secretKey = vault.resolveSecret(context.getSetting(AWS_SECRET_ACCESS, DEFAULT_VALUE)); | ||
var endpointOverride = context.getSetting(AWS_ENDPOINT_OVERRIDE, DEFAULT_VALUE); | ||
var regionName = context.getSetting(AWS_REGION, DEFAULT_VALUE); | ||
var bucketName = context.getSetting(AWS_BUCKET_NAME, DEFAULT_VALUE); | ||
|
||
this.validatorRegistry.register("https://w3id.org/edc/v0.0.1/ns/TransferRequest", InesdataTransferRequestValidator.instance(context.getMonitor())); | ||
this.validatorRegistry.register("https://w3id.org/edc/v0.0.1/ns/TerminateTransfer", TerminateTransferValidator.instance()); | ||
this.webService.registerResource("management", new InesdataTransferProcessApiController(context.getMonitor(), this.service, managementApiTransformerRegistry, this.validatorRegistry, bucketName, regionName, accessKey, secretKey, endpointOverride)); | ||
} | ||
} |
124 changes: 124 additions & 0 deletions
124
...rc/main/java/org/upm/inesdata/inesdatatransfer/controller/InesdataTransferProcessApi.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,124 @@ | ||
package org.upm.inesdata.inesdatatransfer.controller; | ||
|
||
import io.swagger.v3.oas.annotations.OpenAPIDefinition; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.info.Info; | ||
import io.swagger.v3.oas.annotations.links.Link; | ||
import io.swagger.v3.oas.annotations.links.LinkParameter; | ||
import io.swagger.v3.oas.annotations.media.ArraySchema; | ||
import io.swagger.v3.oas.annotations.media.Content; | ||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import io.swagger.v3.oas.annotations.parameters.RequestBody; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||
import io.swagger.v3.oas.annotations.tags.Tag; | ||
import jakarta.json.JsonArray; | ||
import jakarta.json.JsonObject; | ||
import org.eclipse.edc.api.management.schema.ManagementApiSchema; | ||
import org.eclipse.edc.api.model.ApiCoreSchema; | ||
import org.eclipse.edc.connector.controlplane.api.management.transferprocess.v3.TransferProcessApiV3; | ||
|
||
import java.util.List; | ||
|
||
import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; | ||
import static org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferRequest.TRANSFER_REQUEST_TYPE; | ||
import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.CONTEXT; | ||
import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; | ||
|
||
@OpenAPIDefinition( | ||
info = @Info( | ||
version = "v3" | ||
) | ||
) | ||
@Tag( | ||
name = "Transfer Process V3" | ||
) | ||
public interface InesdataTransferProcessApi { | ||
String ASYNC_WARNING = "Due to the asynchronous nature of transfers, a successful response only indicates that the request was successfully received. This may take a long time, so clients must poll the /{id}/state endpoint to track the state."; | ||
|
||
@Operation( | ||
description = "Initiates a data transfer with the given parameters. Due to the asynchronous nature of transfers, a successful response only indicates that the request was successfully received. This may take a long time, so clients must poll the /{id}/state endpoint to track the state.", | ||
requestBody = @RequestBody( | ||
content = {@Content( | ||
schema = @Schema( | ||
implementation = TransferRequestSchema.class | ||
) | ||
)} | ||
), | ||
responses = {@ApiResponse( | ||
responseCode = "200", | ||
description = "The transfer was successfully initiated. Returns the transfer process ID and created timestamp", | ||
content = {@Content( | ||
schema = @Schema( | ||
implementation = ApiCoreSchema.IdResponseSchema.class | ||
) | ||
)}, | ||
links = {@Link( | ||
name = "poll-state", | ||
operationId = "getTransferProcessStateV3", | ||
parameters = {@LinkParameter( | ||
name = "id", | ||
expression = "$response.body#/id" | ||
)} | ||
)} | ||
), @ApiResponse( | ||
responseCode = "400", | ||
description = "Request body was malformed", | ||
content = {@Content( | ||
array = @ArraySchema( | ||
schema = @Schema( | ||
implementation = ApiCoreSchema.ApiErrorDetailSchema.class | ||
) | ||
) | ||
)} | ||
)} | ||
) | ||
JsonObject initiateTransferProcess(JsonObject var1); | ||
|
||
|
||
@Schema(name = "TransferRequest", example = TransferProcessApiV3.TransferRequestSchema.TRANSFER_REQUEST_EXAMPLE) | ||
record TransferRequestSchema( | ||
@Schema(name = CONTEXT, requiredMode = REQUIRED) | ||
Object context, | ||
@Schema(name = TYPE, example = TRANSFER_REQUEST_TYPE) | ||
String type, | ||
@Schema(requiredMode = REQUIRED) | ||
String protocol, | ||
@Schema(requiredMode = REQUIRED) | ||
String counterPartyAddress, | ||
@Schema(requiredMode = REQUIRED) | ||
String contractId, | ||
@Schema(deprecated = true) | ||
String assetId, | ||
@Schema(requiredMode = REQUIRED) | ||
String transferType, | ||
ApiCoreSchema.DataAddressSchema dataDestination, | ||
@Schema(additionalProperties = Schema.AdditionalPropertiesValue.TRUE) | ||
ManagementApiSchema.FreeFormPropertiesSchema privateProperties, | ||
List<ManagementApiSchema.CallbackAddressSchema> callbackAddresses) { | ||
|
||
public static final String TRANSFER_REQUEST_EXAMPLE = """ | ||
{ | ||
"@context": { "@vocab": "https://w3id.org/edc/v0.0.1/ns/" }, | ||
"@type": "https://w3id.org/edc/v0.0.1/ns/TransferRequest", | ||
"protocol": "dataspace-protocol-http", | ||
"counterPartyAddress": "http://provider-address", | ||
"contractId": "contract-id", | ||
"transferType": "transferType", | ||
"dataDestination": { | ||
"type": "data-destination-type" | ||
}, | ||
"privateProperties": { | ||
"private-key": "private-value" | ||
}, | ||
"callbackAddresses": [{ | ||
"transactional": false, | ||
"uri": "http://callback/url", | ||
"events": ["contract.negotiation", "transfer.process"], | ||
"authKey": "auth-key", | ||
"authCodeId": "auth-code-id" | ||
}] | ||
} | ||
"""; | ||
} | ||
|
||
} |
93 changes: 93 additions & 0 deletions
93
...va/org/upm/inesdata/inesdatatransfer/controller/InesdataTransferProcessApiController.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,93 @@ | ||
package org.upm.inesdata.inesdatatransfer.controller; | ||
|
||
import jakarta.json.JsonObject; | ||
import jakarta.ws.rs.Consumes; | ||
import jakarta.ws.rs.POST; | ||
import jakarta.ws.rs.Path; | ||
import jakarta.ws.rs.Produces; | ||
import org.eclipse.edc.api.model.IdResponse; | ||
import org.eclipse.edc.connector.controlplane.services.spi.transferprocess.TransferProcessService; | ||
import org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferProcess; | ||
import org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferRequest; | ||
import org.eclipse.edc.spi.EdcException; | ||
import org.eclipse.edc.spi.constants.CoreConstants; | ||
import org.eclipse.edc.spi.monitor.Monitor; | ||
import org.eclipse.edc.spi.types.domain.DataAddress; | ||
import org.eclipse.edc.transform.spi.TypeTransformerRegistry; | ||
import org.eclipse.edc.validator.spi.JsonObjectValidatorRegistry; | ||
import org.eclipse.edc.web.spi.exception.InvalidRequestException; | ||
import org.eclipse.edc.web.spi.exception.ValidationFailureException; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
import static java.lang.String.format; | ||
import static org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferRequest.TRANSFER_REQUEST_TYPE; | ||
import static org.eclipse.edc.web.spi.exception.ServiceResultHandler.mapToException; | ||
|
||
@Consumes({ "application/json" }) | ||
@Produces({ "application/json" }) | ||
@Path("/v3/inesdatatransferprocesses") | ||
public class InesdataTransferProcessApiController implements InesdataTransferProcessApi { | ||
|
||
protected final Monitor monitor; | ||
private final TransferProcessService service; | ||
private final TypeTransformerRegistry transformerRegistry; | ||
private final JsonObjectValidatorRegistry validatorRegistry; | ||
private final String bucketName; | ||
private final String region; | ||
private final String accessKey; | ||
private final String secretKey; | ||
private final String endpointOverride; | ||
|
||
public InesdataTransferProcessApiController(Monitor monitor, TransferProcessService service, | ||
TypeTransformerRegistry transformerRegistry, JsonObjectValidatorRegistry validatorRegistry, String bucketName, | ||
String region, String accessKey, String secretKey, String endpointOverride) { | ||
this.monitor = monitor; | ||
this.service = service; | ||
this.transformerRegistry = transformerRegistry; | ||
this.validatorRegistry = validatorRegistry; | ||
this.bucketName = bucketName; | ||
this.region = region; | ||
this.accessKey = accessKey; | ||
this.secretKey = secretKey; | ||
this.endpointOverride = endpointOverride; | ||
} | ||
|
||
@POST | ||
public JsonObject initiateTransferProcess(JsonObject request) { | ||
validatorRegistry.validate(TRANSFER_REQUEST_TYPE, request).orElseThrow(ValidationFailureException::new); | ||
|
||
var transferRequest = transformerRegistry.transform(request, TransferRequest.class) | ||
.orElseThrow(InvalidRequestException::new); | ||
|
||
DataAddress dataDestination = getDataDestinationProperties(); | ||
|
||
var tRequest = TransferRequest.Builder.newInstance().id(transferRequest.getId()) | ||
.transferType(transferRequest.getTransferType()).callbackAddresses(transferRequest.getCallbackAddresses()) | ||
.contractId(transferRequest.getContractId()).counterPartyAddress(transferRequest.getCounterPartyAddress()) | ||
.protocol(transferRequest.getProtocol()).privateProperties(transferRequest.getPrivateProperties()) | ||
.dataDestination(dataDestination).build(); | ||
|
||
var createdTransfer = service.initiateTransfer(tRequest) | ||
.onSuccess(d -> monitor.debug(format("Transfer Process created %s", d.getId()))) | ||
.orElseThrow(it -> mapToException(it, TransferProcess.class)); | ||
|
||
var responseDto = IdResponse.Builder.newInstance().id(createdTransfer.getId()) | ||
.createdAt(createdTransfer.getCreatedAt()).build(); | ||
|
||
return transformerRegistry.transform(responseDto, JsonObject.class) | ||
.orElseThrow(f -> new EdcException("Error creating response body: " + f.getFailureDetail())); | ||
} | ||
|
||
private DataAddress getDataDestinationProperties() { | ||
Map<String, Object> properties = new HashMap<>(); | ||
properties.put(CoreConstants.EDC_NAMESPACE + "bucketName", bucketName); | ||
properties.put(CoreConstants.EDC_NAMESPACE + "region", region); | ||
properties.put(CoreConstants.EDC_NAMESPACE + "type", "AmazonS3"); | ||
properties.put(CoreConstants.EDC_NAMESPACE + "endpointOverride", endpointOverride); | ||
properties.put(CoreConstants.EDC_NAMESPACE + "accessKeyId", accessKey); | ||
properties.put(CoreConstants.EDC_NAMESPACE + "secretAccessKey", secretKey); | ||
return DataAddress.Builder.newInstance().properties(properties).build(); | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
.../java/org/upm/inesdata/inesdatatransfer/validations/InesdataTransferRequestValidator.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,30 @@ | ||
package org.upm.inesdata.inesdatatransfer.validations; | ||
|
||
import jakarta.json.JsonObject; | ||
import org.eclipse.edc.spi.monitor.Monitor; | ||
import org.eclipse.edc.validator.jsonobject.JsonObjectValidator; | ||
import org.eclipse.edc.validator.jsonobject.validators.LogDeprecatedValue; | ||
import org.eclipse.edc.validator.jsonobject.validators.MandatoryValue; | ||
import org.eclipse.edc.validator.jsonobject.validators.OptionalIdNotBlank; | ||
import org.eclipse.edc.validator.spi.Validator; | ||
|
||
import static org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferRequest.TRANSFER_REQUEST_ASSET_ID; | ||
import static org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferRequest.TRANSFER_REQUEST_CONTRACT_ID; | ||
import static org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferRequest.TRANSFER_REQUEST_COUNTER_PARTY_ADDRESS; | ||
import static org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferRequest.TRANSFER_REQUEST_PROTOCOL; | ||
import static org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferRequest.TRANSFER_REQUEST_TRANSFER_TYPE; | ||
|
||
public class InesdataTransferRequestValidator { | ||
|
||
public static Validator<JsonObject> instance(Monitor monitor) { | ||
return JsonObjectValidator.newValidator() | ||
.verifyId(OptionalIdNotBlank::new) | ||
.verify(TRANSFER_REQUEST_ASSET_ID, path -> new LogDeprecatedValue(path, TRANSFER_REQUEST_ASSET_ID, "no attribute, as %s already provide such information".formatted(TRANSFER_REQUEST_CONTRACT_ID), monitor)) | ||
.verify(TRANSFER_REQUEST_COUNTER_PARTY_ADDRESS, MandatoryValue::new) | ||
.verify(TRANSFER_REQUEST_CONTRACT_ID, MandatoryValue::new) | ||
.verify(TRANSFER_REQUEST_PROTOCOL, MandatoryValue::new) | ||
.verify(TRANSFER_REQUEST_TRANSFER_TYPE, MandatoryValue::new) | ||
.build(); | ||
} | ||
|
||
} |
1 change: 1 addition & 0 deletions
1
...cess-api/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension
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 @@ | ||
org.upm.inesdata.inesdatatransfer.InesdataTransferProcessApiExtension |
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
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