Skip to content

Commit

Permalink
Merge branch 'feature/436844_get_all_vocabularies' into 'develop'
Browse files Browse the repository at this point in the history
feature/436844_get_all_vocabularies

See merge request upm-inesdata/inesdata-connector!31
  • Loading branch information
Samuel Sierra Silva committed Jul 29, 2024
2 parents 87e3c38 + 739d3c9 commit 8f17da7
Show file tree
Hide file tree
Showing 45 changed files with 1,087 additions and 40 deletions.
2 changes: 1 addition & 1 deletion docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM eclipse-temurin:17-jre
FROM eclipse-temurin:17-jre-jammy
ARG CONNECTOR_JAR

# System env vars
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.upm.inesdata.auth;

import org.eclipse.edc.api.auth.spi.AuthenticationService;
import org.eclipse.edc.api.auth.spi.registry.ApiAuthenticationRegistry;
import org.eclipse.edc.runtime.metamodel.annotation.Extension;
import org.eclipse.edc.runtime.metamodel.annotation.Inject;
import org.eclipse.edc.runtime.metamodel.annotation.Provides;
Expand Down Expand Up @@ -29,6 +30,8 @@ public class Oauth2JwtAuthenticationExtension implements ServiceExtension {
@Inject
private IdentityService identityService;
@Inject
private ApiAuthenticationRegistry authenticationRegistry;
@Inject
private Vault vault;

@Override
Expand All @@ -45,6 +48,6 @@ public void initialize(ServiceExtensionContext context) {
var rolesConfig = context.getConfig(AUTH_SETTING_ALLOWEDROLES);
List<String> allowedRoles = rolesConfig.partition().map(conf -> conf.getString(ROLE_PROPERTY_NAME)).collect(Collectors.toList());

context.registerService(AuthenticationService.class, new Oauth2JwtAuthenticationService(identityService, participantId, allowedRoles));
authenticationRegistry.register("management-api", new Oauth2JwtAuthenticationService(identityService, participantId, allowedRoles));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -107,28 +107,23 @@ private WhereClause generateVocabularyWhereClause(Criterion criterion) {

switch (propertiesList.length) {
case 3 ->
generateNonObjectPropertySQL(sqlWhereBuilder, propertiesList, criterion.getOperandRight().toString());
case 4 ->
generateNonObjectPropertySQL(sqlWhereBuilder, propertiesList, criterion.getOperandRight().toString(), false);
case 4 -> {
if (propertiesList[3].equals("'@id'")) {
generateNonObjectPropertySQL(sqlWhereBuilder, propertiesList, criterion.getOperandRight().toString(), true);
} else {
generateObjectPropertySQL(sqlWhereBuilder, propertiesList, criterion.getOperandRight().toString());
}

}

default -> throw new InvalidRequestException("Invalid vocabulary argument in the operandLeft: %s"
.formatted(criterion.getOperandLeft().toString()));
}

return new WhereClause(sqlWhereBuilder.toString(), unmodifiableCollection(new ArrayList<>()));
}

private void generateNonObjectPropertySQL(StringBuilder sqlWhereBuilder, String[] propertiesList, String operandRight) {
sqlWhereBuilder.append("(properties::jsonb -> ")
.append(propertiesList[0])
.append(" -> ")
.append(propertiesList[1])
.append(")::jsonb @> '[{")
.append(propertiesList[2].replaceAll("'", "\""))
.append(": [{\"@value\": \"")
.append(operandRight)
.append("\"}]}]'::jsonb");
}

private void generateObjectPropertySQL(StringBuilder sqlWhereBuilder, String[] propertiesList, String operandRight) {
sqlWhereBuilder.append("EXISTS (SELECT 1 FROM jsonb_array_elements((properties::jsonb -> ")
.append(propertiesList[0])
Expand All @@ -143,6 +138,18 @@ private void generateObjectPropertySQL(StringBuilder sqlWhereBuilder, String[] p
.append("\"}]}]')");
}

private void generateNonObjectPropertySQL(StringBuilder sqlWhereBuilder, String[] propertiesList, String operandRight, boolean isIdProperty) {
sqlWhereBuilder.append("(properties::jsonb -> ")
.append(propertiesList[0])
.append(" -> ")
.append(propertiesList[1])
.append(")::jsonb @> '[{")
.append(propertiesList[2].replaceAll("'", "\""))
.append(isIdProperty ? ": [{\"@id\": \"" : ": [{\"@value\": \"")
.append(operandRight)
.append("\"}]}]'::jsonb");
}

private String[] splitByDotOutsideQuotes(String input) {
List<String> parts = new ArrayList<>();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.upm.inesdata.catalog;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.eclipse.edc.catalog.directory.InMemoryNodeDirectory;
import org.eclipse.edc.crawler.spi.TargetNodeDirectory;
Expand Down Expand Up @@ -35,7 +36,10 @@ public class FromRegistrationServiceParticipantsExtension implements ServiceExte
public void initialize(ServiceExtensionContext context) {
var periodSeconds = context.getSetting(EXECUTION_PLAN_PERIOD_SECONDS, DEFAULT_EXECUTION_PERIOD_SECONDS);
var monitor = context.getMonitor();
var participantRegistrationService = new ParticipantRegistrationService(monitor, new ObjectMapper());
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
var participantRegistrationService = new ParticipantRegistrationService(monitor, objectMapper);

// Initial update
updateTargetNodeDirectory(context, participantRegistrationService);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.List;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.client.Client;
Expand Down Expand Up @@ -47,9 +48,6 @@ public ParticipantRegistrationService(Monitor monitor, ObjectMapper objectMapper
this.objectMapper = objectMapper;
}




/**
* Makes an HTTP GET request to the specified URL and returns the response as a string.
*
Expand All @@ -72,29 +70,61 @@ public String makeHttpGetRequest(String url, Result<TokenRepresentation> tokenRe
* @return list of TargetNodes from configuration
*/
public List<TargetNode> getTargetNodes(Config baseConfig, Result<TokenRepresentation> tokenRepresentationResult) {
var response = getNodes(baseConfig, tokenRepresentationResult);
if(response != null){
return processResponseToTargetNodes(response);
}else{
return new ArrayList<>();
}
}

/**
* Retrieve SharedUrlParticipant from configuration
*
* @param baseConfig EDC Configuration
* @param tokenRepresentationResult token
* @return list of SharedUrlParticipant from configuration
*/
public List<SharedUrlParticipant> getSharedUrlParticipantNodes(Config baseConfig, Result<TokenRepresentation> tokenRepresentationResult) {
var response = getNodes(baseConfig, tokenRepresentationResult);
if(response != null){
return processResponseToSharedUrlParticipant(response);
}else{
return new ArrayList<>();
}
}

private String getNodes(Config baseConfig, Result<TokenRepresentation> tokenRepresentationResult) {
var participantsConfig = baseConfig.getConfig(EDC_CATALOG_REGISTRATION_SERVICE_HOST);

if (participantsConfig.getEntries().isEmpty()) {
monitor.severe("Error processing url registration service.");
return new ArrayList<>();
return null;
} else {
var url = participantsConfig.getEntries().get(EDC_CATALOG_REGISTRATION_SERVICE_HOST) + RESOURCE_URL;

try {
String response = makeHttpGetRequest(url, tokenRepresentationResult);
if(response==null){
return new ArrayList<>();
}
// Process the response and convert it to TargetNodes
// Assuming a method processResponseToTargetNodes(response)
return processResponseToTargetNodes(response);
return makeHttpGetRequest(url, tokenRepresentationResult);
} catch (Exception e) {
monitor.severe("Exception occurred while making HTTP GET request: " + e.getMessage());
return new ArrayList<>();
return null;
}
}
}


private List<SharedUrlParticipant> processResponseToSharedUrlParticipant(String response) {
List<SharedUrlParticipant> sharedUrlParticipants = new ArrayList<>();

try {
sharedUrlParticipants = objectMapper.readValue(response, new TypeReference<>() {});
} catch (Exception e) {
monitor.severe("Failed to deserialize the registration service response");
}

return sharedUrlParticipants;
}

private List<TargetNode> processResponseToTargetNodes(String response) {
List<TargetNode> targetNodes = new ArrayList<>();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.upm.inesdata.catalog;

public class SharedUrlParticipant {
private String participantId;
private String url;
private String sharedUrl;

public String getParticipantId() {
return participantId;
}

public void setParticipantId(String participantId) {
this.participantId = participantId;
}

public String getUrl() {
return url;
}

public void setUrl(String url) {
this.url = url;
}

public String getSharedUrl() {
return sharedUrl;
}

public void setSharedUrl(String sharedUrl) {
this.sharedUrl = sharedUrl;
}
}
Empty file.
12 changes: 12 additions & 0 deletions extensions/shared-api-configuration/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
plugins {
`java-library`
id("com.gmv.inesdata.edc-application")
}

dependencies {
api(libs.edc.web.spi)
api(libs.edc.auth.spi)
api(libs.edc.iam.oauth2.service)
api(libs.edc.spi.jsonld)
api(libs.edc.jersey.providers.lib)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package org.upm.inesdata.api.shared.configuration;

import org.eclipse.edc.api.auth.spi.AuthenticationRequestFilter;
import org.eclipse.edc.api.auth.spi.registry.ApiAuthenticationRegistry;
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.Provides;
import org.eclipse.edc.runtime.metamodel.annotation.Setting;
import org.eclipse.edc.runtime.metamodel.annotation.SettingContext;
import org.eclipse.edc.spi.EdcException;
import org.eclipse.edc.spi.iam.IdentityService;
import org.eclipse.edc.spi.system.ExecutorInstrumentation;
import org.eclipse.edc.spi.system.Hostname;
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.web.jersey.providers.jsonld.JerseyJsonLdInterceptor;
import org.eclipse.edc.web.jersey.providers.jsonld.ObjectMapperProvider;
import org.eclipse.edc.web.spi.WebServer;
import org.eclipse.edc.web.spi.WebService;
import org.eclipse.edc.web.spi.configuration.WebServiceConfiguration;
import org.eclipse.edc.web.spi.configuration.WebServiceConfigurer;
import org.eclipse.edc.web.spi.configuration.WebServiceSettings;

import java.net.URI;

import static java.lang.String.format;
import static org.eclipse.edc.policy.model.OdrlNamespace.ODRL_PREFIX;
import static org.eclipse.edc.policy.model.OdrlNamespace.ODRL_SCHEMA;
import static org.eclipse.edc.spi.constants.CoreConstants.JSON_LD;

/**
* This extension provides generic endpoints which are open to all connectors.
*/
@Provides(SharedApiUrl.class)
@Extension(value = SharedApiConfigurationExtension.NAME)
public class SharedApiConfigurationExtension implements ServiceExtension {
public static final String NAME = "Shared Public API";

private static final int DEFAULT_SHARED_PORT = 8186;
private static final String SHARED_CONTEXT_PATH = "/api/v1/shared";

@SettingContext("Shared API context setting key")
private static final String SHARED_CONFIG_KEY = "web.http.shared";

@Setting(value = "Base url of the shared API endpoint without the trailing slash. This should correspond to the values configured " +
"in '" + DEFAULT_SHARED_PORT + "' and '" + SHARED_CONTEXT_PATH + "'.", defaultValue = "http://<HOST>:" + DEFAULT_SHARED_PORT + SHARED_CONTEXT_PATH)
private static final String SHARED_ENDPOINT = "edc.shared.endpoint";

private static final WebServiceSettings SHARED_SETTINGS = WebServiceSettings.Builder.newInstance()
.apiConfigKey(SHARED_CONFIG_KEY)
.contextAlias("shared")
.defaultPath(SHARED_CONTEXT_PATH)
.defaultPort(DEFAULT_SHARED_PORT)
.name(NAME)
.build();

private static final String SHARED_SCOPE = "SHARED_API";

@Inject
private WebServer webServer;
@Inject
private ApiAuthenticationRegistry authenticationRegistry;
@Inject
private WebServiceConfigurer webServiceConfigurer;
@Inject
private WebService webService;
@Inject
private ExecutorInstrumentation executorInstrumentation;
@Inject
private Hostname hostname;
@Inject
private IdentityService identityService;
@Inject
private JsonLd jsonLd;
@Inject
private TypeManager typeManager;

@Override
public String name() {
return NAME;
}

@Override
public void initialize(ServiceExtensionContext context) {
var config = context.getConfig(SHARED_CONFIG_KEY);
var configuration = webServiceConfigurer.configure(config, webServer, SHARED_SETTINGS);

context.registerService(SharedApiUrl.class, sharedApiUrl(context, configuration));

var authenticationFilter = new AuthenticationRequestFilter(authenticationRegistry, "shared-api");
webService.registerResource("shared", authenticationFilter);

jsonLd.registerNamespace(ODRL_PREFIX, ODRL_SCHEMA, SHARED_SCOPE);
var jsonLdMapper = typeManager.getMapper(JSON_LD);
webService.registerResource("shared", new ObjectMapperProvider(jsonLdMapper));
webService.registerResource("shared", new JerseyJsonLdInterceptor(jsonLd, jsonLdMapper, SHARED_SCOPE));
}

private SharedApiUrl sharedApiUrl(ServiceExtensionContext context, WebServiceConfiguration config) {
var callbackAddress = context.getSetting(SHARED_ENDPOINT, format("http://%s:%s%s", hostname.get(), config.getPort(), config.getPath()));
try {
var url = URI.create(callbackAddress);
return () -> url;
} catch (IllegalArgumentException e) {
context.getMonitor().severe("Error creating shared endpoint url", e);
throw new EdcException(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.upm.inesdata.api.shared.configuration;

import java.net.URI;

/**
* Provides the Shared Api URL exposed, useful for setting callbacks.
*/
@FunctionalInterface
public interface SharedApiUrl {

/**
* URI on which the Shared API is exposed
*
* @return Shared API URI.
*/
URI get();
}
Loading

0 comments on commit 8f17da7

Please sign in to comment.