diff --git a/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/VocabularyApiExtension.java b/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/VocabularyApiExtension.java index 09b3e91..febe52e 100644 --- a/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/VocabularyApiExtension.java +++ b/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/VocabularyApiExtension.java @@ -23,11 +23,11 @@ import org.upm.inesdata.vocabulary.transformer.JsonObjectToVocabularyTransformer; import org.upm.inesdata.vocabulary.validator.VocabularyValidator; +import java.util.Map; + import static org.eclipse.edc.spi.constants.CoreConstants.JSON_LD; import static org.upm.inesdata.spi.vocabulary.domain.Vocabulary.EDC_VOCABULARY_TYPE; -import java.util.Map; - /** * Extension that provides an API for managing vocabularies */ @@ -74,14 +74,6 @@ public VocabularyService vocabularyService() { return new VocabularyServiceImpl(vocabularyIndex, transactionContext); } - /** - * Provides a default in memory vocabularyIndex - */ - @Provider(isDefault = true) - public VocabularyIndex defaultVocabularyIndex() { - return getVocabularyIndex(); - } - /** * Initializes the service */ @@ -107,14 +99,4 @@ public void initialize(ServiceExtensionContext context) { healthCheckService.addLivenessProvider(() -> successResult); } } - - /** - * Creates a InMemoryVocabularyIndex if not exists - */ - private InMemoryVocabularyIndex getVocabularyIndex() { - if (defaultVocabularyIndex == null) { - defaultVocabularyIndex = new InMemoryVocabularyIndex(); - } - return defaultVocabularyIndex; - } } diff --git a/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/controller/VocabularyApi.java b/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/controller/VocabularyApi.java index acb5a62..e96d394 100644 --- a/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/controller/VocabularyApi.java +++ b/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/controller/VocabularyApi.java @@ -13,6 +13,7 @@ import jakarta.json.JsonObject; import org.eclipse.edc.api.model.ApiCoreSchema; import org.eclipse.edc.connector.controlplane.contract.spi.types.offer.ContractOffer; +import org.upm.inesdata.spi.vocabulary.domain.Vocabulary; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; @@ -125,7 +126,8 @@ record VocabularyOutputSchema( { "@id": "vocabularyId", "name": "vocabulary name", - "jsonSchema": "{ \\"title\\": \\"vocabulary\\", \\"type\\": \\"object\\", \\"properties\\": { \\"name\\": { \\"type\\": \\"string\\", \\"title\\": \\"Name\\" }, \\"dct:keyword\\": { \\"type\\": \\"array\\", \\"title\\": \\"Keywords\\", \\"items\\": { \\"type\\": \\"string\\" } } }, \\"required\\": [ \\"name\\" ], \\"@context\\": { \\"dct\\": \\"http:\\/\\/purl.org\\/dc\\/terms\\/\" } }" + "jsonSchema": "{ \\"title\\": \\"vocabulary\\", \\"type\\": \\"object\\", \\"properties\\": { \\"name\\": { \\"type\\": \\"string\\", \\"title\\": \\"Name\\" }, \\"dct:keyword\\": { \\"type\\": \\"array\\", \\"title\\": \\"Keywords\\", \\"items\\": { \\"type\\": \\"string\\" } } }, \\"required\\": [ \\"name\\" ], \\"@context\\": { \\"dct\\": \\"http:\\/\\/purl.org\\/dc\\/terms\\/\" } }", + "category": "dataset" } """; } diff --git a/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/controller/VocabularyApiController.java b/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/controller/VocabularyApiController.java index 48bc1d6..523115c 100644 --- a/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/controller/VocabularyApiController.java +++ b/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/controller/VocabularyApiController.java @@ -11,7 +11,7 @@ import jakarta.ws.rs.PathParam; import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.MediaType; - +import org.eclipse.edc.api.model.IdResponse; import org.eclipse.edc.spi.EdcException; import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.spi.result.Result; @@ -28,8 +28,6 @@ import static org.eclipse.edc.web.spi.exception.ServiceResultHandler.exceptionMapper; import static org.upm.inesdata.spi.vocabulary.domain.Vocabulary.EDC_VOCABULARY_TYPE; -import org.eclipse.edc.api.model.IdResponse; - /** * Implementation of the controller for {@link Vocabulary} managing. */ diff --git a/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/service/VocabularyServiceImpl.java b/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/service/VocabularyServiceImpl.java index e72ed5c..9ed1d0b 100644 --- a/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/service/VocabularyServiceImpl.java +++ b/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/service/VocabularyServiceImpl.java @@ -2,7 +2,6 @@ import org.eclipse.edc.spi.result.ServiceResult; import org.eclipse.edc.transaction.spi.TransactionContext; - import org.upm.inesdata.spi.vocabulary.VocabularyIndex; import org.upm.inesdata.spi.vocabulary.VocabularyService; import org.upm.inesdata.spi.vocabulary.domain.Vocabulary; @@ -43,7 +42,9 @@ public ServiceResult> search() { @Override public ServiceResult create(Vocabulary vocabulary) { return transactionContext.execute(() -> { + // Create new vocabulary var createResult = index.create(vocabulary); + if (createResult.succeeded()) { return ServiceResult.success(vocabulary); } @@ -62,6 +63,7 @@ public ServiceResult delete(String vocabularyId) { @Override public ServiceResult update(Vocabulary vocabulary) { return transactionContext.execute(() -> { + // Update vocabulary var updatedVocabulary = index.updateVocabulary(vocabulary); return ServiceResult.from(updatedVocabulary); }); diff --git a/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/storage/InMemoryVocabularyIndex.java b/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/storage/InMemoryVocabularyIndex.java index 1ce1afb..d961d79 100644 --- a/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/storage/InMemoryVocabularyIndex.java +++ b/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/storage/InMemoryVocabularyIndex.java @@ -1,8 +1,8 @@ package org.upm.inesdata.vocabulary.storage; import org.eclipse.edc.spi.result.StoreResult; -import org.upm.inesdata.spi.vocabulary.domain.Vocabulary; import org.upm.inesdata.spi.vocabulary.VocabularyIndex; +import org.upm.inesdata.spi.vocabulary.domain.Vocabulary; import java.util.Map; import java.util.Objects; @@ -103,5 +103,4 @@ public StoreResult updateVocabulary(Vocabulary vocabulary) { private Vocabulary delete(String vocabularyId) { return cache.remove(vocabularyId); } - } diff --git a/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/transformer/JsonObjectFromVocabularyTransformer.java b/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/transformer/JsonObjectFromVocabularyTransformer.java index 92599d5..811cec0 100644 --- a/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/transformer/JsonObjectFromVocabularyTransformer.java +++ b/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/transformer/JsonObjectFromVocabularyTransformer.java @@ -3,7 +3,6 @@ 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; @@ -12,11 +11,12 @@ import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; - import static org.upm.inesdata.spi.vocabulary.domain.Vocabulary.EDC_VOCABULARY_TYPE; +import static org.upm.inesdata.spi.vocabulary.domain.Vocabulary.PROPERTY_CATEGORY; import static org.upm.inesdata.spi.vocabulary.domain.Vocabulary.PROPERTY_JSON_SCHEMA; import static org.upm.inesdata.spi.vocabulary.domain.Vocabulary.PROPERTY_NAME; + /** * Creates a JsonObject from a {@link Vocabulary} */ @@ -39,7 +39,8 @@ public JsonObjectFromVocabularyTransformer(JsonBuilderFactory jsonFactory, Objec .add(ID, vocabulary.getId()) .add(TYPE, EDC_VOCABULARY_TYPE) .add(PROPERTY_NAME, vocabulary.getName()) - .add(PROPERTY_JSON_SCHEMA, vocabulary.getJsonSchema()); + .add(PROPERTY_JSON_SCHEMA, vocabulary.getJsonSchema()) + .add(PROPERTY_CATEGORY, vocabulary.getCategory()); return builder.build(); } diff --git a/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/transformer/JsonObjectToVocabularyTransformer.java b/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/transformer/JsonObjectToVocabularyTransformer.java index be99616..b46d88e 100644 --- a/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/transformer/JsonObjectToVocabularyTransformer.java +++ b/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/transformer/JsonObjectToVocabularyTransformer.java @@ -7,6 +7,7 @@ import org.jetbrains.annotations.Nullable; import org.upm.inesdata.spi.vocabulary.domain.Vocabulary; +import static org.upm.inesdata.spi.vocabulary.domain.Vocabulary.PROPERTY_CATEGORY; import static org.upm.inesdata.spi.vocabulary.domain.Vocabulary.PROPERTY_JSON_SCHEMA; import static org.upm.inesdata.spi.vocabulary.domain.Vocabulary.PROPERTY_NAME; @@ -30,6 +31,7 @@ public JsonObjectToVocabularyTransformer() { visitProperties(jsonObject, key -> switch (key) { case PROPERTY_NAME -> value -> builder.name(transformString(value, context)); case PROPERTY_JSON_SCHEMA -> value -> builder.jsonSchema(transformString(value, context)); + case PROPERTY_CATEGORY -> value -> builder.category(transformString(value, context)); default -> doNothing(); }); diff --git a/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/validator/MandatoryJsonField.java b/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/validator/MandatoryJsonField.java index 02dfd40..d21e323 100644 --- a/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/validator/MandatoryJsonField.java +++ b/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/validator/MandatoryJsonField.java @@ -4,11 +4,11 @@ import jakarta.json.JsonObject; import jakarta.json.JsonReader; import jakarta.json.stream.JsonParsingException; -import java.io.StringReader; import org.eclipse.edc.validator.jsonobject.JsonLdPath; import org.eclipse.edc.validator.spi.ValidationResult; import org.eclipse.edc.validator.spi.Validator; +import java.io.StringReader; import java.util.Optional; import static java.lang.String.format; diff --git a/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/validator/VocabularyValidator.java b/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/validator/VocabularyValidator.java index 1b1753c..494c487 100644 --- a/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/validator/VocabularyValidator.java +++ b/extensions/vocabulary-api/src/main/java/org/upm/inesdata/vocabulary/validator/VocabularyValidator.java @@ -6,6 +6,7 @@ import org.eclipse.edc.validator.jsonobject.validators.OptionalIdNotBlank; import org.eclipse.edc.validator.spi.Validator; +import static org.upm.inesdata.spi.vocabulary.domain.Vocabulary.PROPERTY_CATEGORY; import static org.upm.inesdata.spi.vocabulary.domain.Vocabulary.PROPERTY_JSON_SCHEMA; import static org.upm.inesdata.spi.vocabulary.domain.Vocabulary.PROPERTY_NAME; @@ -21,6 +22,7 @@ public static Validator instance() { return JsonObjectValidator.newValidator() .verifyId(OptionalIdNotBlank::new) .verify(PROPERTY_NAME, MandatoryObject::new) + .verify(PROPERTY_CATEGORY, MandatoryObject::new) .verify(PROPERTY_JSON_SCHEMA, MandatoryJsonField::new) .build(); } diff --git a/extensions/vocabulary-index-sql/docs/schema.sql b/extensions/vocabulary-index-sql/docs/schema.sql index e6bd609..cb8d1a8 100644 --- a/extensions/vocabulary-index-sql/docs/schema.sql +++ b/extensions/vocabulary-index-sql/docs/schema.sql @@ -5,6 +5,7 @@ CREATE TABLE IF NOT EXISTS edc_vocabulary created_at BIGINT NOT NULL, json_schema JSON DEFAULT '{}', name VARCHAR NOT NULL, + category VARCHAR NOT NULL PRIMARY KEY (id) ); diff --git a/extensions/vocabulary-index-sql/src/main/java/org/upm/inesdata/vocabulary/sql/index/SqlVocabularyIndex.java b/extensions/vocabulary-index-sql/src/main/java/org/upm/inesdata/vocabulary/sql/index/SqlVocabularyIndex.java index e2207c4..6cb0121 100644 --- a/extensions/vocabulary-index-sql/src/main/java/org/upm/inesdata/vocabulary/sql/index/SqlVocabularyIndex.java +++ b/extensions/vocabulary-index-sql/src/main/java/org/upm/inesdata/vocabulary/sql/index/SqlVocabularyIndex.java @@ -9,10 +9,9 @@ import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; import org.eclipse.edc.transaction.spi.TransactionContext; import org.jetbrains.annotations.Nullable; - +import org.upm.inesdata.spi.vocabulary.VocabularyIndex; import org.upm.inesdata.spi.vocabulary.domain.Vocabulary; import org.upm.inesdata.vocabulary.sql.index.schema.VocabularyStatements; -import org.upm.inesdata.spi.vocabulary.VocabularyIndex; import java.sql.Connection; import java.sql.ResultSet; @@ -74,7 +73,7 @@ public StoreResult create(Vocabulary vocabulary) { return transactionContext.execute(() -> { try (var connection = getConnection()) { if (existsById(vocabularyId, connection)) { - var msg = format(VocabularyIndex.VOCABULARY_NOT_FOUND_TEMPLATE, vocabularyId); + var msg = format(VocabularyIndex.VOCABULARY_EXISTS_TEMPLATE, vocabularyId); return StoreResult.alreadyExists(msg); } @@ -82,6 +81,7 @@ public StoreResult create(Vocabulary vocabulary) { vocabularyId, vocabulary.getCreatedAt(), vocabulary.getName(), + vocabulary.getCategory(), toJson(vocabulary.getJsonSchema()) ); @@ -121,6 +121,7 @@ public StoreResult updateVocabulary(Vocabulary vocabulary) { queryExecutor.execute(connection, vocabularyStatements.getUpdateVocabularyTemplate(), vocabulary.getName(), toJson(vocabulary.getJsonSchema()), + vocabulary.getCategory(), vocabularyId ); @@ -150,6 +151,7 @@ private Vocabulary mapVocabulary(ResultSet resultSet) throws SQLException { .id(resultSet.getString(vocabularyStatements.getVocabularyIdColumn())) .createdAt(resultSet.getLong(vocabularyStatements.getCreatedAtColumn())) .name(resultSet.getString(vocabularyStatements.getNameColumn())) + .category(resultSet.getString(vocabularyStatements.getCategoryColumn())) .jsonSchema(resultSet.getString(vocabularyStatements.getJsonSchemaColumn())) .build(); } diff --git a/extensions/vocabulary-index-sql/src/main/java/org/upm/inesdata/vocabulary/sql/index/schema/BaseSqlDialectStatements.java b/extensions/vocabulary-index-sql/src/main/java/org/upm/inesdata/vocabulary/sql/index/schema/BaseSqlDialectStatements.java index 19e2fda..0725adc 100644 --- a/extensions/vocabulary-index-sql/src/main/java/org/upm/inesdata/vocabulary/sql/index/schema/BaseSqlDialectStatements.java +++ b/extensions/vocabulary-index-sql/src/main/java/org/upm/inesdata/vocabulary/sql/index/schema/BaseSqlDialectStatements.java @@ -1,9 +1,9 @@ package org.upm.inesdata.vocabulary.sql.index.schema; -import org.upm.inesdata.vocabulary.sql.index.schema.postgres.VocabularyMapping; import org.eclipse.edc.spi.query.QuerySpec; import org.eclipse.edc.sql.translation.SqlOperatorTranslator; import org.eclipse.edc.sql.translation.SqlQueryStatement; +import org.upm.inesdata.vocabulary.sql.index.schema.postgres.VocabularyMapping; import static java.lang.String.format; @@ -24,6 +24,7 @@ public String getInsertVocabularyTemplate() { .column(getVocabularyIdColumn()) .column(getCreatedAtColumn()) .column(getNameColumn()) + .column(getCategoryColumn()) .jsonColumn(getJsonSchemaColumn()) .insertInto(getVocabularyTable()); } @@ -33,6 +34,7 @@ public String getUpdateVocabularyTemplate() { return executeStatement() .column(getNameColumn()) .jsonColumn(getJsonSchemaColumn()) + .column(getCategoryColumn()) .update(getVocabularyTable(), getVocabularyIdColumn()); } diff --git a/extensions/vocabulary-index-sql/src/main/java/org/upm/inesdata/vocabulary/sql/index/schema/VocabularyStatements.java b/extensions/vocabulary-index-sql/src/main/java/org/upm/inesdata/vocabulary/sql/index/schema/VocabularyStatements.java index fece7d0..0ccb9ff 100644 --- a/extensions/vocabulary-index-sql/src/main/java/org/upm/inesdata/vocabulary/sql/index/schema/VocabularyStatements.java +++ b/extensions/vocabulary-index-sql/src/main/java/org/upm/inesdata/vocabulary/sql/index/schema/VocabularyStatements.java @@ -33,6 +33,10 @@ default String getJsonSchemaColumn() { return "json_schema"; } + default String getCategoryColumn() { + return "category"; + } + default String getCreatedAtColumn() { return "created_at"; } diff --git a/extensions/vocabulary-index-sql/src/main/java/org/upm/inesdata/vocabulary/sql/index/schema/postgres/VocabularyMapping.java b/extensions/vocabulary-index-sql/src/main/java/org/upm/inesdata/vocabulary/sql/index/schema/postgres/VocabularyMapping.java index 9df69b4..dfd627c 100644 --- a/extensions/vocabulary-index-sql/src/main/java/org/upm/inesdata/vocabulary/sql/index/schema/postgres/VocabularyMapping.java +++ b/extensions/vocabulary-index-sql/src/main/java/org/upm/inesdata/vocabulary/sql/index/schema/postgres/VocabularyMapping.java @@ -14,6 +14,7 @@ public VocabularyMapping(VocabularyStatements statements) { add("id", statements.getVocabularyIdColumn()); add("createdAt", statements.getCreatedAtColumn()); add("name", statements.getNameColumn()); + add("category", statements.getCategoryColumn()); add("json_schema", new JsonFieldTranslator(statements.getJsonSchemaColumn())); } diff --git a/resources/sql/vocabulary-schema.sql b/resources/sql/vocabulary-schema.sql index e6bd609..cb8d1a8 100644 --- a/resources/sql/vocabulary-schema.sql +++ b/resources/sql/vocabulary-schema.sql @@ -5,6 +5,7 @@ CREATE TABLE IF NOT EXISTS edc_vocabulary created_at BIGINT NOT NULL, json_schema JSON DEFAULT '{}', name VARCHAR NOT NULL, + category VARCHAR NOT NULL PRIMARY KEY (id) ); diff --git a/spi/vocabulary-spi/src/main/java/org/upm/inesdata/spi/vocabulary/VocabularyIndex.java b/spi/vocabulary-spi/src/main/java/org/upm/inesdata/spi/vocabulary/VocabularyIndex.java index 4bf45b4..8a89aeb 100644 --- a/spi/vocabulary-spi/src/main/java/org/upm/inesdata/spi/vocabulary/VocabularyIndex.java +++ b/spi/vocabulary-spi/src/main/java/org/upm/inesdata/spi/vocabulary/VocabularyIndex.java @@ -1,9 +1,9 @@ package org.upm.inesdata.spi.vocabulary; -import org.upm.inesdata.spi.vocabulary.domain.Vocabulary; import org.eclipse.edc.runtime.metamodel.annotation.ExtensionPoint; import org.eclipse.edc.spi.persistence.EdcPersistenceException; import org.eclipse.edc.spi.result.StoreResult; +import org.upm.inesdata.spi.vocabulary.domain.Vocabulary; import java.util.stream.Stream; diff --git a/spi/vocabulary-spi/src/main/java/org/upm/inesdata/spi/vocabulary/domain/Vocabulary.java b/spi/vocabulary-spi/src/main/java/org/upm/inesdata/spi/vocabulary/domain/Vocabulary.java index b2f25ae..9fece22 100644 --- a/spi/vocabulary-spi/src/main/java/org/upm/inesdata/spi/vocabulary/domain/Vocabulary.java +++ b/spi/vocabulary-spi/src/main/java/org/upm/inesdata/spi/vocabulary/domain/Vocabulary.java @@ -20,11 +20,13 @@ public class Vocabulary extends Entity { public static final String PROPERTY_ID = EDC_NAMESPACE + "id"; public static final String PROPERTY_NAME = EDC_NAMESPACE + "name"; public static final String PROPERTY_JSON_SCHEMA = EDC_NAMESPACE + "jsonSchema"; + public static final String PROPERTY_CATEGORY = EDC_NAMESPACE + "category"; public static final String EDC_VOCABULARY_TYPE = EDC_NAMESPACE + "Vocabulary"; private String name; private String jsonSchema; + private String category; private Vocabulary() { } @@ -37,11 +39,17 @@ public String getJsonSchema() { return jsonSchema; } + public String getCategory() { + return category; + } + + public Builder toBuilder() { return Vocabulary.Builder.newInstance() .id(id) .name(name) .jsonSchema(jsonSchema) + .category(category) .createdAt(createdAt); } @@ -74,6 +82,11 @@ public Builder jsonSchema(String jsonSchema) { return self(); } + public Builder category(String category) { + entity.category = category; + return self(); + } + @Override public Builder createdAt(long value) { entity.createdAt = value;