Skip to content

Commit

Permalink
Merge branch 'feature/434249-endpoint-catalogo-federado' into 'develop'
Browse files Browse the repository at this point in the history
Feature/434249 endpoint catalogo federado

See merge request upm-inesdata/inesdata-connector!22
  • Loading branch information
ralconada-gmv committed Jun 19, 2024
2 parents e802dc1 + edc8b67 commit 31bf6d2
Show file tree
Hide file tree
Showing 26 changed files with 1,718 additions and 0 deletions.
3 changes: 3 additions & 0 deletions extensions/federated-catalog-cache-api/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Federated Catalog API

Provides a management API for getting the federated catalog paginated.
30 changes: 30 additions & 0 deletions extensions/federated-catalog-cache-api/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
plugins {
`java-library`
id("com.gmv.inesdata.edc-application")
}

dependencies {
api(project(":spi:federated-catalog-cache-spi"))
api(libs.edc.spi.core)
implementation(libs.edc.spi.transform)
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.edc.json.ld.lib)
runtimeOnly(libs.edc.spi.jsonld)
runtimeOnly(libs.edc.json.ld.lib)
implementation(libs.edc.control.plane.transform)
implementation(libs.edc.federated.catalog.api)
implementation(libs.edc.federated.catalog.core)
implementation(libs.edc.federated.catalog.spi)

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package org.upm.inesdata.federated;

import jakarta.json.Json;
import org.eclipse.edc.connector.api.management.configuration.ManagementApiConfiguration;
import org.eclipse.edc.connector.controlplane.transform.edc.from.JsonObjectFromAssetTransformer;
import org.eclipse.edc.connector.controlplane.transform.edc.to.JsonObjectToAssetTransformer;
import org.eclipse.edc.jsonld.spi.JsonLd;
import org.eclipse.edc.runtime.metamodel.annotation.Extension;
import org.eclipse.edc.runtime.metamodel.annotation.Inject;
import org.eclipse.edc.runtime.metamodel.annotation.Provider;
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.spi.types.TypeManager;
import org.eclipse.edc.transaction.spi.TransactionContext;
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.federated.controller.FederatedCatalogCacheApiController;
import org.upm.inesdata.federated.service.FederatedCatalogCacheServiceImpl;
import org.upm.inesdata.spi.federated.FederatedCatalogCacheService;
import org.upm.inesdata.spi.federated.index.PaginatedFederatedCacheStoreIndex;

import java.util.Map;

import static org.eclipse.edc.spi.constants.CoreConstants.JSON_LD;
/**
* Extension that provides an API for managing vocabularies
*/
@Extension(value = FederatedCatalogCacheApiExtension.NAME)
public class FederatedCatalogCacheApiExtension implements ServiceExtension {

public static final String NAME = "StorageAsset API Extension";
@Inject
private WebService webService;

@Inject
private ManagementApiConfiguration config;

@Inject
private TypeManager typeManager;

@Inject
private TransactionContext transactionContext;

@Inject
private TypeTransformerRegistry transformerRegistry;

@Inject
private JsonObjectValidatorRegistry validator;
@Inject
private JsonLd jsonLd;

@Inject
private Vault vault;

@Inject
private PaginatedFederatedCacheStoreIndex paginatedFederatedCacheStoreIndex;

@Override
public String name() {
return NAME;
}
/**
* Provides a default federatedCatalogCacheService implementation
*/
@Provider(isDefault = true)
public FederatedCatalogCacheService federatedCatalogCacheService() {
return new FederatedCatalogCacheServiceImpl(paginatedFederatedCacheStoreIndex,transactionContext);
}

/**
* Initializes the service
*/
@Override
public void initialize(ServiceExtensionContext context) {
var monitor = context.getMonitor();

var managementApiTransformerRegistry = transformerRegistry.forContext("management-api");

var factory = Json.createBuilderFactory(Map.of());
var jsonLdMapper = typeManager.getMapper(JSON_LD);
managementApiTransformerRegistry.register(new JsonObjectFromAssetTransformer(factory, jsonLdMapper));
managementApiTransformerRegistry.register(new JsonObjectToAssetTransformer());

var federatedCatalogCacheApiController = new FederatedCatalogCacheApiController(this.federatedCatalogCacheService(), managementApiTransformerRegistry,
validator,monitor);
webService.registerResource(config.getContextAlias(), federatedCatalogCacheApiController);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.upm.inesdata.federated.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.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
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.connector.controlplane.contract.spi.types.offer.ContractOffer;

/**
* This interface represents the API for accessing the Federated Catalog. It provides operations to obtain catalogs with
* dataset pagination.
*/
@OpenAPIDefinition(
info = @Info(description = "This represents the Federated Catalog API.", title = "Federated Catalog API",
version = "1"))
@Tag(name = "Federated Catalog")
public interface FederatedCatalogCacheApi {
/**
* Obtains all catalogs with dataset pagination based on the provided query specification.
*
* @param querySpec the specification of the query which includes filters, sorting, and pagination details.
* @return a JsonArray containing the list of catalogs that match the query criteria, potentially empty.
*/
@Operation(description = "Obtains all Catalog with dataset pagination", responses = {
@ApiResponse(responseCode = "200", description = "A list of Catalog is returned, potentially empty",
content = @Content(array = @ArraySchema(schema = @Schema(implementation = ContractOffer.class)))),
@ApiResponse(responseCode = "500", description = "A Query could not be completed due to an internal error") }

)
JsonArray getFederatedCatalog(JsonObject querySpec);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package org.upm.inesdata.federated.controller;

import jakarta.json.JsonArray;
import jakarta.json.JsonObject;
import jakarta.servlet.annotation.MultipartConfig;
import jakarta.ws.rs.BadRequestException;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType;
import org.eclipse.edc.jsonld.spi.JsonLd;
import org.eclipse.edc.spi.monitor.Monitor;
import org.eclipse.edc.spi.query.QuerySpec;
import org.eclipse.edc.spi.result.AbstractResult;
import org.eclipse.edc.spi.result.Result;
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 org.upm.inesdata.spi.federated.FederatedCatalogCacheService;

import java.util.Objects;

import static jakarta.json.stream.JsonCollectors.toJsonArray;
import static org.eclipse.edc.spi.query.QuerySpec.EDC_QUERY_SPEC_TYPE;
import static org.eclipse.edc.web.spi.exception.ServiceResultHandler.exceptionMapper;

/**
* Controller class for the Federated Catalog Cache API. This class implements the {@link FederatedCatalogCacheApi}
* interface and provides the API endpoints to interact with the federated catalog cache.
*/
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@Path("/federatedcatalog")
public class FederatedCatalogCacheApiController implements FederatedCatalogCacheApi {
private final TypeTransformerRegistry transformerRegistry;
private final FederatedCatalogCacheService service;
private final JsonObjectValidatorRegistry validator;
private final Monitor monitor;

/**
* Constructs a FederatedCatalogCacheApiController with the specified dependencies.
*
* @param service the service used to access the federated catalog cache.
* @param transformerRegistry the registry for type transformers.
* @param validator the registry for JSON object validators.
* @param monitor the monitor used for logging and monitoring.
*/
public FederatedCatalogCacheApiController(FederatedCatalogCacheService service,
TypeTransformerRegistry transformerRegistry, JsonObjectValidatorRegistry validator, Monitor monitor) {
this.transformerRegistry = transformerRegistry;
this.service = service;
this.validator = validator;
this.monitor = monitor;
}

/**
* (non-javadoc)
*
* @see FederatedCatalogCacheApi#getFederatedCatalog(JsonObject)
*/
@Override
@POST
@Path("/request")
public JsonArray getFederatedCatalog(JsonObject querySpecJson) {
QuerySpec querySpec;
if (querySpecJson == null) {
querySpec = QuerySpec.Builder.newInstance().build();
} else {
validator.validate(EDC_QUERY_SPEC_TYPE, querySpecJson).orElseThrow(ValidationFailureException::new);

querySpec = transformerRegistry.transform(querySpecJson, QuerySpec.class)
.orElseThrow(InvalidRequestException::new);
}
return service.searchPagination(querySpec).orElseThrow(exceptionMapper(QuerySpec.class, null)).stream()
.map(it -> transformerRegistry.transform(it, JsonObject.class))
.peek(r -> r.onFailure(f -> monitor.warning(f.getFailureDetail()))).filter(Result::succeeded)
.map(Result::getContent).collect(toJsonArray());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package org.upm.inesdata.federated.service;

import jakarta.json.JsonObject;
import org.eclipse.edc.connector.controlplane.catalog.spi.Catalog;
import org.eclipse.edc.spi.query.QuerySpec;
import org.eclipse.edc.spi.result.ServiceResult;
import org.eclipse.edc.transaction.spi.TransactionContext;
import org.upm.inesdata.federated.controller.FederatedCatalogCacheApi;
import org.upm.inesdata.spi.federated.FederatedCatalogCacheService;
import org.upm.inesdata.spi.federated.index.PaginatedFederatedCacheStoreIndex;

import java.util.Collection;

/**
* Implementation of the {@link FederatedCatalogCacheService} interface
*/
public class FederatedCatalogCacheServiceImpl implements FederatedCatalogCacheService {

private final PaginatedFederatedCacheStoreIndex index;
private final TransactionContext transactionContext;

/**
* Constructs a FederatedCatalogCacheServiceImpl with the specified dependencies.
*
* @param index the paginated federated cache store index used for managing the catalog cache.
* @param transactionContext the context for handling transactions.
*/
public FederatedCatalogCacheServiceImpl(PaginatedFederatedCacheStoreIndex index,
TransactionContext transactionContext) {
this.index = index;

this.transactionContext = transactionContext;
}

/**
* (non-javadoc)
*
* @see FederatedCatalogCacheService#searchPagination(QuerySpec)
*/
@Override
public ServiceResult<Collection<Catalog>> searchPagination(QuerySpec querySpec) {
return transactionContext.execute(() -> ServiceResult.success(index.queryPagination(querySpec)));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
org.upm.inesdata.federated.FederatedCatalogCacheApiExtension
64 changes: 64 additions & 0 deletions extensions/federated-catalog-cache-sql/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# SQL Federated Catalog

Provides SQL persistence for federated catalog.

## Prerequisites

Please apply this [schema](docs/schema.sql) to your SQL database.

## Entity Diagram

![ER Diagram](////www.plantuml.com/plantuml/png/ZPF1QiCm38RlUGgTn_82ePIU1cMC3ShEnR6Lef5OHbRBHhjtNzA4uR3Cv2hfp_T9mRkeHlJSjGLw9Vq2TFPeZPgMJt0j01w0N0LHXVm9Dfktv-tsNWrzZ2m5utN_Ep1sX0FsJOmLl9YmETnRZ_1QVw3LCOsVWGJxNCtSel5ziIoBxoArSBr5HCrQSDEWP3XhNAPjzodWQGGiEXqZoeKiPiKKfOkpiw1tWSdhkxH9_I-1XbvzLc8_4HgMpkZiOuF7OTHOyXu78kggfQO3B2sNkKrE8k4a0BZTofAlwS-jmB9NGpuk3oxBpLEpLXfDJrb14BwGmrWa-F-dyu1rRZlqRdXPFm00)
<!--
```plantuml
@startuml
entity edc_catalog {
* id: string <<PK>>
* participantId: string
* properties: Map<String, Object>
* expired: boolean
--
}
entity edc_dataset {
* id: string <<PK>>
* offers: Map<String, Object>
* properties: Map<String, Object>
* catalogId: string <<FK>>
--
}
entity edc_data_service {
* id: string <<PK>>
* terms: string
* endpointUrl: string
--
}
entity edc_distribution {
* format: string
* dataServiceId: string <<FK>>
* datasetId: string <<FK>>
--
}
entity edc_catalog_data_service {
* catalogId: string <<FK>>
* dataServiceId: string <<FK>>
--
}
edc_catalog ||--o{ edc_dataset: contains
edc_catalog ||--o{ edc_catalog_data_service: contains
edc_data_service ||--o{ edc_distribution: provides
edc_dataset ||--o{ edc_distribution: contains
edc_data_service ||--o{ edc_catalog_data_service: contains
@enduml
```
-->

## Configuration

| Key | Description | Mandatory |
|:-------------------------------------|:-------------------------------------------|---|
| edc.datasource.federatedCatalog.name | Datasource used to store federated catalog | X |
18 changes: 18 additions & 0 deletions extensions/federated-catalog-cache-sql/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
plugins {
`java-library`
id("com.gmv.inesdata.edc-application")
}

dependencies {
api(project(":spi:federated-catalog-cache-spi"))
implementation(libs.edc.federated.catalog.api)
api(libs.edc.spi.core)
api(libs.edc.transaction.spi)
implementation(libs.edc.transaction.spi)
implementation(libs.edc.transaction.datasource.spi)
implementation(libs.edc.sql.core)
implementation(libs.edc.lib.util)
implementation(libs.edc.federated.catalog.core)
}


Loading

0 comments on commit 31bf6d2

Please sign in to comment.