From 7e9353112e59fd1c3bd41569560b25ef510778a9 Mon Sep 17 00:00:00 2001 From: ppel Date: Fri, 14 Jun 2024 14:07:52 +0200 Subject: [PATCH 1/2] #433814 - Created extensions and api for counting the total number of elements of an entity --- extensions/count-elements-api/README.md | 3 + .../count-elements-api/build.gradle.kts | 25 ++++++ .../CountElementsApiExtension.java | 80 +++++++++++++++++++ .../controller/CountElementsApi.java | 36 +++++++++ .../CountElementsApiController.java | 44 ++++++++++ .../service/CountElementsServiceImpl.java | 21 +++++ ...JsonObjectFromCountElementTransformer.java | 38 +++++++++ ...rg.eclipse.edc.spi.system.ServiceExtension | 1 + .../count-elements-sql/build.gradle.kts | 17 ++++ extensions/count-elements-sql/docs/er.puml | 9 +++ extensions/count-elements-sql/docs/schema.sql | 12 +++ .../sql/index/SqlCountElementsIndex.java | 45 +++++++++++ ...SqlCountElementsIndexServiceExtension.java | 58 ++++++++++++++ .../schema/BaseSqlDialectStatements.java | 42 ++++++++++ .../index/schema/CountElementsStatements.java | 52 ++++++++++++ .../postgres/PostgresDialectStatements.java | 17 ++++ ...rg.eclipse.edc.spi.system.ServiceExtension | 1 + extensions/vocabulary-api/build.gradle.kts | 1 + launchers/connector/build.gradle.kts | 4 + settings.gradle.kts | 3 + spi/count-elements-spi/README.md | 1 + spi/count-elements-spi/build.gradle.kts | 8 ++ .../countelements/domain/CountElement.java | 58 ++++++++++++++ .../index/CountElementsIndex.java | 19 +++++ .../spi/countelements/package-info.java | 18 +++++ .../service/CountElementsService.java | 17 ++++ 26 files changed, 630 insertions(+) create mode 100644 extensions/count-elements-api/README.md create mode 100644 extensions/count-elements-api/build.gradle.kts create mode 100644 extensions/count-elements-api/src/main/java/org/upm/inesdata/countelements/CountElementsApiExtension.java create mode 100644 extensions/count-elements-api/src/main/java/org/upm/inesdata/countelements/controller/CountElementsApi.java create mode 100644 extensions/count-elements-api/src/main/java/org/upm/inesdata/countelements/controller/CountElementsApiController.java create mode 100644 extensions/count-elements-api/src/main/java/org/upm/inesdata/countelements/service/CountElementsServiceImpl.java create mode 100644 extensions/count-elements-api/src/main/java/org/upm/inesdata/countelements/transformer/JsonObjectFromCountElementTransformer.java create mode 100644 extensions/count-elements-api/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension create mode 100644 extensions/count-elements-sql/build.gradle.kts create mode 100644 extensions/count-elements-sql/docs/er.puml create mode 100644 extensions/count-elements-sql/docs/schema.sql create mode 100644 extensions/count-elements-sql/src/main/java/org/upm/inesdata/countelements/sql/index/SqlCountElementsIndex.java create mode 100644 extensions/count-elements-sql/src/main/java/org/upm/inesdata/countelements/sql/index/SqlCountElementsIndexServiceExtension.java create mode 100644 extensions/count-elements-sql/src/main/java/org/upm/inesdata/countelements/sql/index/schema/BaseSqlDialectStatements.java create mode 100644 extensions/count-elements-sql/src/main/java/org/upm/inesdata/countelements/sql/index/schema/CountElementsStatements.java create mode 100644 extensions/count-elements-sql/src/main/java/org/upm/inesdata/countelements/sql/index/schema/postgres/PostgresDialectStatements.java create mode 100644 extensions/count-elements-sql/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension create mode 100644 spi/count-elements-spi/README.md create mode 100644 spi/count-elements-spi/build.gradle.kts create mode 100644 spi/count-elements-spi/src/main/java/org/upm/inesdata/spi/countelements/domain/CountElement.java create mode 100644 spi/count-elements-spi/src/main/java/org/upm/inesdata/spi/countelements/index/CountElementsIndex.java create mode 100644 spi/count-elements-spi/src/main/java/org/upm/inesdata/spi/countelements/package-info.java create mode 100644 spi/count-elements-spi/src/main/java/org/upm/inesdata/spi/countelements/service/CountElementsService.java diff --git a/extensions/count-elements-api/README.md b/extensions/count-elements-api/README.md new file mode 100644 index 0000000..81156d0 --- /dev/null +++ b/extensions/count-elements-api/README.md @@ -0,0 +1,3 @@ +# Count Elements API + +Provides a management API for getting the total number of elements of an entity. diff --git a/extensions/count-elements-api/build.gradle.kts b/extensions/count-elements-api/build.gradle.kts new file mode 100644 index 0000000..591e963 --- /dev/null +++ b/extensions/count-elements-api/build.gradle.kts @@ -0,0 +1,25 @@ +plugins { + `java-library` + id("com.gmv.inesdata.edc-application") +} + +dependencies { + api(project(":spi:count-elements-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.swagger.annotations.jakarta) + runtimeOnly(libs.edc.spi.jsonld) + runtimeOnly(libs.edc.json.ld.lib) +} diff --git a/extensions/count-elements-api/src/main/java/org/upm/inesdata/countelements/CountElementsApiExtension.java b/extensions/count-elements-api/src/main/java/org/upm/inesdata/countelements/CountElementsApiExtension.java new file mode 100644 index 0000000..f11392f --- /dev/null +++ b/extensions/count-elements-api/src/main/java/org/upm/inesdata/countelements/CountElementsApiExtension.java @@ -0,0 +1,80 @@ +package org.upm.inesdata.countelements; + +import jakarta.json.Json; +import org.eclipse.edc.connector.api.management.configuration.ManagementApiConfiguration; +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.system.ServiceExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.spi.system.health.HealthCheckService; +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.web.spi.WebService; +import org.upm.inesdata.countelements.controller.CountElementsApiController; +import org.upm.inesdata.countelements.service.CountElementsServiceImpl; +import org.upm.inesdata.countelements.transformer.JsonObjectFromCountElementTransformer; +import org.upm.inesdata.spi.countelements.index.CountElementsIndex; +import org.upm.inesdata.spi.countelements.service.CountElementsService; + +import java.util.Map; + +import static org.eclipse.edc.spi.constants.CoreConstants.JSON_LD; + +/** + * Extension that provides an API for getting the total number of elements of an entity + */ +@Extension(value = CountElementsApiExtension.NAME) +public class CountElementsApiExtension implements ServiceExtension { + + public static final String NAME = "CountElement Elements API Extension"; + + @Inject + private WebService webService; + + @Inject + private TypeTransformerRegistry transformerRegistry; + + @Inject(required = false) + private HealthCheckService healthCheckService; + + @Inject + private ManagementApiConfiguration config; + + @Inject + private TypeManager typeManager; + + @Inject + private CountElementsIndex countElementsIndex; + + @Inject + private TransactionContext transactionContext; + + @Override + public String name() { + return NAME; + } + + /** + * Provides a default countElementsService implementation + */ + @Provider(isDefault = true) + public CountElementsService countElementsService() { + return new CountElementsServiceImpl(countElementsIndex, transactionContext); + } + + /** + * Initializes the service + */ + @Override + public void initialize(ServiceExtensionContext context) { + var factory = Json.createBuilderFactory(Map.of()); + var jsonLdMapper = typeManager.getMapper(JSON_LD); + var managementApiTransformerRegistry = transformerRegistry.forContext("management-api"); + managementApiTransformerRegistry.register(new JsonObjectFromCountElementTransformer(factory, jsonLdMapper)); + + var countElementsApiController = new CountElementsApiController(countElementsService(), managementApiTransformerRegistry); + webService.registerResource(config.getContextAlias(), countElementsApiController); + } +} diff --git a/extensions/count-elements-api/src/main/java/org/upm/inesdata/countelements/controller/CountElementsApi.java b/extensions/count-elements-api/src/main/java/org/upm/inesdata/countelements/controller/CountElementsApi.java new file mode 100644 index 0000000..bb40db4 --- /dev/null +++ b/extensions/count-elements-api/src/main/java/org/upm/inesdata/countelements/controller/CountElementsApi.java @@ -0,0 +1,36 @@ +package org.upm.inesdata.countelements.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 org.eclipse.edc.api.model.ApiCoreSchema; + +@OpenAPIDefinition( + info = @Info(description = "CountElement the elements of an entity.", + title = "CountElement Elements API", version = "1")) +@Tag(name = "CountElements") +public interface CountElementsApi { + + /** + * Gets the total elements of an entity type. + * + * @param entityType entity type + * @return the total number of elements + */ + @Operation(description = "CountElement the elements of an entity", + responses = { + @ApiResponse(responseCode = "200", description = "The total number of elements", + content = @Content(schema = @Schema(implementation = Long.class))), + @ApiResponse(responseCode = "400", description = "Request was malformed, e.g. entityType was null", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiCoreSchema.ApiErrorDetailSchema.class)))), + @ApiResponse(responseCode = "404", description = "The entity type given does not exist", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiCoreSchema.ApiErrorDetailSchema.class)))) + } + ) + long countElements(String entityType); +} diff --git a/extensions/count-elements-api/src/main/java/org/upm/inesdata/countelements/controller/CountElementsApiController.java b/extensions/count-elements-api/src/main/java/org/upm/inesdata/countelements/controller/CountElementsApiController.java new file mode 100644 index 0000000..cd68ae8 --- /dev/null +++ b/extensions/count-elements-api/src/main/java/org/upm/inesdata/countelements/controller/CountElementsApiController.java @@ -0,0 +1,44 @@ +package org.upm.inesdata.countelements.controller; + +import jakarta.ws.rs.BadRequestException; +import jakarta.ws.rs.GET; +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.transform.spi.TypeTransformerRegistry; +import org.upm.inesdata.spi.countelements.service.CountElementsService; + +import java.util.Objects; + +@Produces({MediaType.APPLICATION_JSON}) +@Path("/pagination") +public class CountElementsApiController implements CountElementsApi { + + private final CountElementsService service; + private final TypeTransformerRegistry transformerRegistry; + + public CountElementsApiController(CountElementsService service, TypeTransformerRegistry transformerRegistry) { + this.service = service; + this.transformerRegistry = transformerRegistry; + } + + @GET + @Path("/count") + @Override + public long countElements(@QueryParam("type") String entityType) { + if (!Objects.equals(entityType, "asset") && !Objects.equals(entityType, "policyDefinition") + && !Objects.equals(entityType, "contractDefinition") + && !Objects.equals(entityType, "contractAgreement") + && !Objects.equals(entityType, "transferProcess")) { + throw new BadRequestException("Entity type provided is not valid"); + } + + var count = service.countElements(entityType); + +// JsonObject result = transformerRegistry.transform(count, JsonObject.class) +// .orElseThrow(f -> new EdcException(f.getFailureDetail())); + + return count.getCount(); + } +} diff --git a/extensions/count-elements-api/src/main/java/org/upm/inesdata/countelements/service/CountElementsServiceImpl.java b/extensions/count-elements-api/src/main/java/org/upm/inesdata/countelements/service/CountElementsServiceImpl.java new file mode 100644 index 0000000..91ec4cc --- /dev/null +++ b/extensions/count-elements-api/src/main/java/org/upm/inesdata/countelements/service/CountElementsServiceImpl.java @@ -0,0 +1,21 @@ +package org.upm.inesdata.countelements.service; + +import org.eclipse.edc.transaction.spi.TransactionContext; +import org.upm.inesdata.spi.countelements.domain.CountElement; +import org.upm.inesdata.spi.countelements.index.CountElementsIndex; +import org.upm.inesdata.spi.countelements.service.CountElementsService; + +public class CountElementsServiceImpl implements CountElementsService { + private final CountElementsIndex countElementsIndex; + private final TransactionContext transactionContext; + + public CountElementsServiceImpl(CountElementsIndex countElementsIndex, TransactionContext transactionContext) { + this.countElementsIndex = countElementsIndex; + this.transactionContext = transactionContext; + } + + @Override + public CountElement countElements(String entityType) { + return transactionContext.execute(() -> countElementsIndex.countElements(entityType)); + } +} diff --git a/extensions/count-elements-api/src/main/java/org/upm/inesdata/countelements/transformer/JsonObjectFromCountElementTransformer.java b/extensions/count-elements-api/src/main/java/org/upm/inesdata/countelements/transformer/JsonObjectFromCountElementTransformer.java new file mode 100644 index 0000000..4071c03 --- /dev/null +++ b/extensions/count-elements-api/src/main/java/org/upm/inesdata/countelements/transformer/JsonObjectFromCountElementTransformer.java @@ -0,0 +1,38 @@ +package org.upm.inesdata.countelements.transformer; + +import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.json.JsonBuilderFactory; +import jakarta.json.JsonObject; +import org.eclipse.edc.jsonld.spi.transformer.AbstractJsonLdTransformer; +import org.eclipse.edc.transform.spi.TransformerContext; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.upm.inesdata.spi.countelements.domain.CountElement; + +import static org.upm.inesdata.spi.countelements.domain.CountElement.PROPERTY_COUNT; + + +/** + * Creates a JsonObject from a {@link CountElement} + */ +public class JsonObjectFromCountElementTransformer extends AbstractJsonLdTransformer { + private final ObjectMapper mapper; + private final JsonBuilderFactory jsonFactory; + + /** + * Constructor + */ + public JsonObjectFromCountElementTransformer(JsonBuilderFactory jsonFactory, ObjectMapper jsonLdMapper) { + super(CountElement.class, JsonObject.class); + this.jsonFactory = jsonFactory; + this.mapper = jsonLdMapper; + } + + @Override + public @Nullable JsonObject transform(@NotNull CountElement countElement, @NotNull TransformerContext context) { + var builder = jsonFactory.createObjectBuilder() + .add(PROPERTY_COUNT, countElement.getCount()); + + return builder.build(); + } +} diff --git a/extensions/count-elements-api/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/extensions/count-elements-api/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension new file mode 100644 index 0000000..b9629a1 --- /dev/null +++ b/extensions/count-elements-api/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -0,0 +1 @@ +org.upm.inesdata.countelements.CountElementsApiExtension \ No newline at end of file diff --git a/extensions/count-elements-sql/build.gradle.kts b/extensions/count-elements-sql/build.gradle.kts new file mode 100644 index 0000000..91b8c6a --- /dev/null +++ b/extensions/count-elements-sql/build.gradle.kts @@ -0,0 +1,17 @@ +plugins { + `java-library` + id("com.gmv.inesdata.edc-application") +} + +dependencies { + api(project(":spi:count-elements-spi")) + implementation(project(":extensions:count-elements-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) +} + + diff --git a/extensions/count-elements-sql/docs/er.puml b/extensions/count-elements-sql/docs/er.puml new file mode 100644 index 0000000..f081ea7 --- /dev/null +++ b/extensions/count-elements-sql/docs/er.puml @@ -0,0 +1,9 @@ +@startuml +entity edc_vocabulary { + * id: string <> + * name: string + * jsonSchema: string + * createdAt: long + -- +} +@enduml \ No newline at end of file diff --git a/extensions/count-elements-sql/docs/schema.sql b/extensions/count-elements-sql/docs/schema.sql new file mode 100644 index 0000000..cb8d1a8 --- /dev/null +++ b/extensions/count-elements-sql/docs/schema.sql @@ -0,0 +1,12 @@ +-- table: edc_vocabulary +CREATE TABLE IF NOT EXISTS edc_vocabulary +( + id VARCHAR NOT NULL, + created_at BIGINT NOT NULL, + json_schema JSON DEFAULT '{}', + name VARCHAR NOT NULL, + category VARCHAR NOT NULL + PRIMARY KEY (id) +); + +COMMENT ON COLUMN edc_vocabulary.json_schema IS 'JSON Schema with the vocabulary'; diff --git a/extensions/count-elements-sql/src/main/java/org/upm/inesdata/countelements/sql/index/SqlCountElementsIndex.java b/extensions/count-elements-sql/src/main/java/org/upm/inesdata/countelements/sql/index/SqlCountElementsIndex.java new file mode 100644 index 0000000..9f314c6 --- /dev/null +++ b/extensions/count-elements-sql/src/main/java/org/upm/inesdata/countelements/sql/index/SqlCountElementsIndex.java @@ -0,0 +1,45 @@ +package org.upm.inesdata.countelements.sql.index; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.eclipse.edc.spi.persistence.EdcPersistenceException; +import org.eclipse.edc.sql.QueryExecutor; +import org.eclipse.edc.sql.store.AbstractSqlStore; +import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; +import org.eclipse.edc.transaction.spi.TransactionContext; +import org.upm.inesdata.countelements.sql.index.schema.CountElementsStatements; +import org.upm.inesdata.spi.countelements.domain.CountElement; +import org.upm.inesdata.spi.countelements.index.CountElementsIndex; + +import java.sql.SQLException; +import java.util.Objects; + +/** + * Implementation of the CountElementsIndex with SQL databases + */ +public class SqlCountElementsIndex extends AbstractSqlStore implements CountElementsIndex { + + private final CountElementsStatements countElementsStatements; + + public SqlCountElementsIndex(DataSourceRegistry dataSourceRegistry, + String dataSourceName, + TransactionContext transactionContext, + ObjectMapper objectMapper, + CountElementsStatements countElementsStatements, + QueryExecutor queryExecutor) { + super(dataSourceRegistry, dataSourceName, transactionContext, objectMapper, queryExecutor); + this.countElementsStatements = Objects.requireNonNull(countElementsStatements); + } + + @Override + public CountElement countElements(String entityType) { + try (var connection = getConnection()) { + var sql = countElementsStatements.getCount(entityType); + long count = queryExecutor.single(connection, true, r -> r.getLong(1), sql); + return CountElement.Builder.newInstance().count(count).build(); + } catch (SQLException e) { + throw new EdcPersistenceException(e); + } + + } + +} diff --git a/extensions/count-elements-sql/src/main/java/org/upm/inesdata/countelements/sql/index/SqlCountElementsIndexServiceExtension.java b/extensions/count-elements-sql/src/main/java/org/upm/inesdata/countelements/sql/index/SqlCountElementsIndexServiceExtension.java new file mode 100644 index 0000000..a6dc050 --- /dev/null +++ b/extensions/count-elements-sql/src/main/java/org/upm/inesdata/countelements/sql/index/SqlCountElementsIndexServiceExtension.java @@ -0,0 +1,58 @@ +package org.upm.inesdata.countelements.sql.index; + +import org.eclipse.edc.runtime.metamodel.annotation.Extension; +import org.eclipse.edc.runtime.metamodel.annotation.Inject; +import org.eclipse.edc.runtime.metamodel.annotation.Provides; +import org.eclipse.edc.runtime.metamodel.annotation.Setting; +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.sql.QueryExecutor; +import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; +import org.eclipse.edc.transaction.spi.TransactionContext; +import org.upm.inesdata.countelements.sql.index.schema.CountElementsStatements; +import org.upm.inesdata.countelements.sql.index.schema.postgres.PostgresDialectStatements; +import org.upm.inesdata.spi.countelements.index.CountElementsIndex; + +/** + * Extension that counts elements in SQL databases + */ +@Provides({CountElementsIndex.class}) +@Extension(value = "SQL count elements index") +public class SqlCountElementsIndexServiceExtension implements ServiceExtension { + + /** + * Name of the vocabulary datasource. + */ + @Setting(required = true) + public static final String DATASOURCE_SETTING_NAME = "edc.datasource.countelements.name"; + + @Inject + private DataSourceRegistry dataSourceRegistry; + + @Inject + private TransactionContext transactionContext; + + @Inject(required = false) + private CountElementsStatements dialect; + + @Inject + private TypeManager typeManager; + + @Inject + private QueryExecutor queryExecutor; + + @Override + public void initialize(ServiceExtensionContext context) { + var dataSourceName = context.getConfig().getString(DATASOURCE_SETTING_NAME, DataSourceRegistry.DEFAULT_DATASOURCE); + + var sqlCountElementsLoader = new SqlCountElementsIndex(dataSourceRegistry, dataSourceName, transactionContext, typeManager.getMapper(), + getDialect(), queryExecutor); + + context.registerService(CountElementsIndex.class, sqlCountElementsLoader); + } + + private CountElementsStatements getDialect() { + return dialect != null ? dialect : new PostgresDialectStatements(); + } +} diff --git a/extensions/count-elements-sql/src/main/java/org/upm/inesdata/countelements/sql/index/schema/BaseSqlDialectStatements.java b/extensions/count-elements-sql/src/main/java/org/upm/inesdata/countelements/sql/index/schema/BaseSqlDialectStatements.java new file mode 100644 index 0000000..d83e2df --- /dev/null +++ b/extensions/count-elements-sql/src/main/java/org/upm/inesdata/countelements/sql/index/schema/BaseSqlDialectStatements.java @@ -0,0 +1,42 @@ +package org.upm.inesdata.countelements.sql.index.schema; + +import org.eclipse.edc.sql.translation.SqlOperatorTranslator; + +import static java.lang.String.format; + +/** + * Manages Vocabularies using specific SQL queries + */ +public class BaseSqlDialectStatements implements CountElementsStatements { + + protected final SqlOperatorTranslator operatorTranslator; + + public BaseSqlDialectStatements(SqlOperatorTranslator operatorTranslator) { + this.operatorTranslator = operatorTranslator; + } + + @Override + public String getCount(String entityType) { + String tableName = null; + switch (entityType) { + case "asset": + tableName = getAssetTable(); + break; + case "policyDefinition": + tableName = getPolicyDefinitionTable(); + break; + case "contractDefinition": + tableName = getContractDefinitionTable(); + break; + case "contractAgreement": + tableName = getContractAgreementTable(); + break; + case "transferProcess": + tableName = getTransferProcessTable(); + break; + } + return format("SELECT COUNT(*) FROM %s", + tableName); + } + +} diff --git a/extensions/count-elements-sql/src/main/java/org/upm/inesdata/countelements/sql/index/schema/CountElementsStatements.java b/extensions/count-elements-sql/src/main/java/org/upm/inesdata/countelements/sql/index/schema/CountElementsStatements.java new file mode 100644 index 0000000..3372676 --- /dev/null +++ b/extensions/count-elements-sql/src/main/java/org/upm/inesdata/countelements/sql/index/schema/CountElementsStatements.java @@ -0,0 +1,52 @@ +package org.upm.inesdata.countelements.sql.index.schema; + +import org.eclipse.edc.runtime.metamodel.annotation.ExtensionPoint; +import org.eclipse.edc.sql.statement.SqlStatements; + +/** + * Defines queries used by the SqlCountElementsIndexServiceExtension. + */ +@ExtensionPoint +public interface CountElementsStatements extends SqlStatements { + + /** + * The asset table name. + */ + default String getAssetTable() { + return "edc_asset"; + } + + /** + * The policy definition table name. + */ + default String getPolicyDefinitionTable() { + return "edc_policydefinitions"; + } + + /** + * The contract agreement table name. + */ + default String getContractAgreementTable() { + return "edc_contract_agreement"; + } + + /** + * The contract definition table name. + */ + default String getContractDefinitionTable() { + return "edc_contract_definitions"; + } + + /** + * The vocabulary table name. + */ + default String getTransferProcessTable() { + return "edc_transfer_process"; + } + + /** + * SELECT COUNT clause. + */ + String getCount(String entityType); + +} diff --git a/extensions/count-elements-sql/src/main/java/org/upm/inesdata/countelements/sql/index/schema/postgres/PostgresDialectStatements.java b/extensions/count-elements-sql/src/main/java/org/upm/inesdata/countelements/sql/index/schema/postgres/PostgresDialectStatements.java new file mode 100644 index 0000000..63b507e --- /dev/null +++ b/extensions/count-elements-sql/src/main/java/org/upm/inesdata/countelements/sql/index/schema/postgres/PostgresDialectStatements.java @@ -0,0 +1,17 @@ +package org.upm.inesdata.countelements.sql.index.schema.postgres; + +import org.eclipse.edc.sql.dialect.PostgresDialect; +import org.eclipse.edc.sql.translation.PostgresqlOperatorTranslator; +import org.upm.inesdata.countelements.sql.index.schema.BaseSqlDialectStatements; + +public class PostgresDialectStatements extends BaseSqlDialectStatements { + + public PostgresDialectStatements() { + super(new PostgresqlOperatorTranslator()); + } + + @Override + public String getFormatAsJsonOperator() { + return PostgresDialect.getJsonCastOperator(); + } +} diff --git a/extensions/count-elements-sql/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/extensions/count-elements-sql/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension new file mode 100644 index 0000000..de32490 --- /dev/null +++ b/extensions/count-elements-sql/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -0,0 +1 @@ +org.upm.inesdata.countelements.sql.index.SqlCountElementsIndexServiceExtension \ No newline at end of file diff --git a/extensions/vocabulary-api/build.gradle.kts b/extensions/vocabulary-api/build.gradle.kts index 910d678..b0b18f6 100644 --- a/extensions/vocabulary-api/build.gradle.kts +++ b/extensions/vocabulary-api/build.gradle.kts @@ -15,6 +15,7 @@ dependencies { 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) diff --git a/launchers/connector/build.gradle.kts b/launchers/connector/build.gradle.kts index 5a131a6..05178e0 100644 --- a/launchers/connector/build.gradle.kts +++ b/launchers/connector/build.gradle.kts @@ -55,6 +55,7 @@ dependencies { implementation(libs.edc.sql.policy.definition.store) implementation(libs.edc.sql.transfer.process.store) implementation(project(":extensions:vocabulary-index-sql")) + implementation(project(":extensions:count-elements-sql")) // Persistencia data plane implementation(libs.edc.sql.data.plane.store) @@ -77,6 +78,9 @@ dependencies { // Storage assets implementation(project(":extensions:store-asset-api")) + + // Count elements + implementation(project(":extensions:count-elements-api")) runtimeOnly(libs.edc.transaction.local) runtimeOnly(libs.postgres) diff --git a/settings.gradle.kts b/settings.gradle.kts index d127ea0..dd84eb2 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -7,6 +7,7 @@ rootProject.name = "inesdata-connector" // SPI include(":spi:vocabulary-spi") +include(":spi:count-elements-spi") // Extensions include(":extensions:auth-oauth2-jwt") @@ -16,6 +17,8 @@ include(":extensions:policy-time-interval") include(":extensions:vocabulary-api") include(":extensions:vocabulary-index-sql") include(":extensions:store-asset-api") +include(":extensions:count-elements-api") +include(":extensions:count-elements-sql") // Connector include(":launchers:connector") diff --git a/spi/count-elements-spi/README.md b/spi/count-elements-spi/README.md new file mode 100644 index 0000000..7c1dcaa --- /dev/null +++ b/spi/count-elements-spi/README.md @@ -0,0 +1 @@ +This module contains extension points and interfaces specifically for the Inesdata Count Elements feature. \ No newline at end of file diff --git a/spi/count-elements-spi/build.gradle.kts b/spi/count-elements-spi/build.gradle.kts new file mode 100644 index 0000000..5f7ff12 --- /dev/null +++ b/spi/count-elements-spi/build.gradle.kts @@ -0,0 +1,8 @@ +plugins { + `java-library` + id("com.gmv.inesdata.edc-application") +} + +dependencies { + api(libs.edc.spi.core) +} diff --git a/spi/count-elements-spi/src/main/java/org/upm/inesdata/spi/countelements/domain/CountElement.java b/spi/count-elements-spi/src/main/java/org/upm/inesdata/spi/countelements/domain/CountElement.java new file mode 100644 index 0000000..2ed4691 --- /dev/null +++ b/spi/count-elements-spi/src/main/java/org/upm/inesdata/spi/countelements/domain/CountElement.java @@ -0,0 +1,58 @@ +package org.upm.inesdata.spi.countelements.domain; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; +import org.eclipse.edc.spi.entity.Entity; + +/** + * The {@link CountElement} of elements of an entity + */ +@JsonDeserialize(builder = CountElement.Builder.class) +public class CountElement extends Entity { + + public static final String PROPERTY_COUNT = "count"; + private long count; + + private CountElement() { + } + + public long getCount() { + return count; + } + + + public Builder toBuilder() { + return CountElement.Builder.newInstance() + .count(count); + } + + @JsonPOJOBuilder(withPrefix = "") + public static class Builder extends Entity.Builder { + + protected Builder(CountElement countElement) { + super(countElement); + } + + @JsonCreator + public static Builder newInstance() { + return new Builder(new CountElement()); + } + + public Builder count(long count) { + entity.count = count; + return self(); + } + + @Override + public Builder self() { + return this; + } + + @Override + public CountElement build() { + super.build(); + return entity; + } + } +} diff --git a/spi/count-elements-spi/src/main/java/org/upm/inesdata/spi/countelements/index/CountElementsIndex.java b/spi/count-elements-spi/src/main/java/org/upm/inesdata/spi/countelements/index/CountElementsIndex.java new file mode 100644 index 0000000..031a8ea --- /dev/null +++ b/spi/count-elements-spi/src/main/java/org/upm/inesdata/spi/countelements/index/CountElementsIndex.java @@ -0,0 +1,19 @@ +package org.upm.inesdata.spi.countelements.index; + +import org.eclipse.edc.runtime.metamodel.annotation.ExtensionPoint; +import org.upm.inesdata.spi.countelements.domain.CountElement; + +/** + * Query interface for counting elements. + **/ +@ExtensionPoint +public interface CountElementsIndex { + + /** + * Counts all contract agreements + * + * @param entityType entity type + * @return the number of contract agreements + */ + CountElement countElements(String entityType); +} diff --git a/spi/count-elements-spi/src/main/java/org/upm/inesdata/spi/countelements/package-info.java b/spi/count-elements-spi/src/main/java/org/upm/inesdata/spi/countelements/package-info.java new file mode 100644 index 0000000..4a0e1ca --- /dev/null +++ b/spi/count-elements-spi/src/main/java/org/upm/inesdata/spi/countelements/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2020 - 2022 Microsoft Corporation + * + * 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: + * Microsoft Corporation - initial API and implementation + * + */ + +@Spi("CountElement services") +package org.upm.inesdata.spi.countelements; + +import org.eclipse.edc.runtime.metamodel.annotation.Spi; diff --git a/spi/count-elements-spi/src/main/java/org/upm/inesdata/spi/countelements/service/CountElementsService.java b/spi/count-elements-spi/src/main/java/org/upm/inesdata/spi/countelements/service/CountElementsService.java new file mode 100644 index 0000000..10d3802 --- /dev/null +++ b/spi/count-elements-spi/src/main/java/org/upm/inesdata/spi/countelements/service/CountElementsService.java @@ -0,0 +1,17 @@ +package org.upm.inesdata.spi.countelements.service; + +import org.upm.inesdata.spi.countelements.domain.CountElement; + +/** + * Service interface for getting the total number of elements of an entity. + */ +public interface CountElementsService { + + /** + * Gets the total number of elements of an entity. + * + * @param entityType entity type + * @return the total number of elements + */ + CountElement countElements(String entityType); +} From f6db1fd9df30f375df0ae8084e2c0c60431361ed Mon Sep 17 00:00:00 2001 From: ppel Date: Tue, 18 Jun 2024 09:09:59 +0200 Subject: [PATCH 2/2] #433814 - Deleted unnecesary doc --- extensions/count-elements-sql/docs/er.puml | 9 --------- extensions/count-elements-sql/docs/schema.sql | 12 ------------ 2 files changed, 21 deletions(-) delete mode 100644 extensions/count-elements-sql/docs/er.puml delete mode 100644 extensions/count-elements-sql/docs/schema.sql diff --git a/extensions/count-elements-sql/docs/er.puml b/extensions/count-elements-sql/docs/er.puml deleted file mode 100644 index f081ea7..0000000 --- a/extensions/count-elements-sql/docs/er.puml +++ /dev/null @@ -1,9 +0,0 @@ -@startuml -entity edc_vocabulary { - * id: string <> - * name: string - * jsonSchema: string - * createdAt: long - -- -} -@enduml \ No newline at end of file diff --git a/extensions/count-elements-sql/docs/schema.sql b/extensions/count-elements-sql/docs/schema.sql deleted file mode 100644 index cb8d1a8..0000000 --- a/extensions/count-elements-sql/docs/schema.sql +++ /dev/null @@ -1,12 +0,0 @@ --- table: edc_vocabulary -CREATE TABLE IF NOT EXISTS edc_vocabulary -( - id VARCHAR NOT NULL, - created_at BIGINT NOT NULL, - json_schema JSON DEFAULT '{}', - name VARCHAR NOT NULL, - category VARCHAR NOT NULL - PRIMARY KEY (id) -); - -COMMENT ON COLUMN edc_vocabulary.json_schema IS 'JSON Schema with the vocabulary';