Skip to content

Commit

Permalink
Showing 9 changed files with 435 additions and 203 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2022,2023 Contributors to the Eclipse Foundation
// Copyright (c) 2022,2024 Contributors to the Eclipse Foundation
//
// See the NOTICE file(s) distributed with this work for additional
// information regarding copyright ownership.
@@ -53,10 +53,12 @@ static Matcher matchSkill(String key) {
* @param contract of skill optional
* @param dist of skill required
* @param isFederated whether skill maybe synchronized in catalogue
* @param allowServicePattern regex for service to call in skill
* @param denyServicePattern regex for services denied in skill
* @param ontologies a set of ontologies
* @return skill id
*/
String put(String key, String skill, String name, String description, String version, String contract, SkillDistribution dist, boolean isFederated, String... ontologies);
String put(String key, String skill, String name, String description, String version, String contract, SkillDistribution dist, boolean isFederated, String allowServicePattern, String denyServicePattern, String... ontologies);

/**
* return the skill distribution
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2022,2023 Contributors to the Eclipse Foundation
// Copyright (c) 2022,2024 Contributors to the Eclipse Foundation
//
// See the NOTICE file(s) distributed with this work for additional
// information regarding copyright ownership.
@@ -63,13 +63,13 @@ public class AgentController {
protected final SparqlQueryProcessor processor;
protected final DelegationService delegationService;

/**
/**
* creates a new agent controller
*
* @param monitor logging subsystem
* @param monitor logging subsystem
* @param agreementController agreement controller for remote skill/queries
* @param config configuration
* @param processor sparql processor
* @param config configuration
* @param processor sparql processor
*/
public AgentController(Monitor monitor, AgreementController agreementController, AgentConfig config, SparqlQueryProcessor processor, SkillStore skillStore, DelegationService delegationService) {
this.monitor = monitor;
@@ -95,7 +95,7 @@ public String toString() {
* @return response
*/
@POST
@Consumes({"application/sparql-query", "application/sparql-results+json"})
@Consumes({ "application/sparql-query", "application/sparql-results+json" })
public Response postSparqlQuery(@QueryParam("asset") String asset,
@Context HttpHeaders headers,
@Context HttpServletRequest request,
@@ -118,7 +118,7 @@ public Response postSparqlQuery(@QueryParam("asset") String asset,
* @return response compatible with graphdb convention
*/
@POST
@Consumes({"application/x-www-form-urlencoded"})
@Consumes({ "application/x-www-form-urlencoded" })
public Response postFormQuery(@QueryParam("asset") String asset,
@Context HttpHeaders headers,
@Context HttpServletRequest request,
@@ -143,7 +143,7 @@ public Response postFormQuery(@QueryParam("asset") String asset,
*/
@POST
@Path("/repositories/AGENT")
@Consumes({"application/x-www-form-urlencoded"})
@Consumes({ "application/x-www-form-urlencoded" })
public Response postFormRepositoryQuery(@QueryParam("asset") String asset,
@Context HttpHeaders headers,
@Context HttpServletRequest request,
@@ -429,15 +429,15 @@ public Response executeQuery(String asset, HttpHeaders headers, HttpServletReque
/**
* endpoint for posting a skill
*
* @param query mandatory query
* @param asset asset key
* @param name asset name
* @param query mandatory query
* @param asset asset key
* @param name asset name
* @param description asset description
* @param version asset version
* @param contract asset contract
* @param mode asset mode
* @param version asset version
* @param contract asset contract
* @param mode asset mode
* @param isFederated whether it appears in fed catalogue
* @param ontologies list of ontologies
* @param ontologies list of ontologies
* @return only status
*/
@POST
@@ -451,11 +451,13 @@ public Response postSkill(String query,
@QueryParam("contract") String contract,
@QueryParam("distributionMode") SkillDistribution mode,
@QueryParam("isFederated") boolean isFederated,
@QueryParam("allowServicesPattern") String allowServicePattern,
@QueryParam("denyServicesPattern") String denyServicePattern,
@QueryParam("ontology") String[] ontologies
) {
monitor.debug(String.format("Received a POST skill request %s %s %s %s %s %b %s ", asset, name, description, version, contract, mode.getMode(), isFederated, query));
monitor.debug(String.format("Received a POST skill request %s %s %s %s %s %b %s %s %s ", asset, name, description, version, contract, mode.getMode(), isFederated, allowServicePattern, denyServicePattern, query));
Response.ResponseBuilder rb;
if (skillStore.put(asset, query, name, description, version, contract, mode, isFederated, ontologies) != null) {
if (skillStore.put(asset, query, name, description, version, contract, mode, isFederated, allowServicePattern, denyServicePattern, ontologies) != null) {
rb = Response.ok();
} else {
rb = Response.status(HttpStatus.SC_CREATED);
@@ -471,7 +473,7 @@ public Response postSkill(String query,
*/
@GET
@Path("/skill")
@Produces({"application/sparql-query"})
@Produces({ "application/sparql-query" })
public Response getSkill(@QueryParam("asset") String asset) {
monitor.debug(String.format("Received a GET skill request %s", asset));
Response.ResponseBuilder rb;
Original file line number Diff line number Diff line change
@@ -105,8 +105,9 @@ public class DataManagement {
" \"proxyPath\": \"false\",\n" +
" \"proxyMethod\": \"true\",\n" +
" \"proxyQueryParams\": \"true\",\n" +
" \"proxyBody\": \"true\"\n" +
" }\n" +
" \"proxyBody\": \"true\",\n" +
" \"cx-common:allowServicePattern\": \"%10$s\",\n" +
" \"cx-common:denyServicePattern\": \"%11$s\"\n" +
"}\n";

public static final String SKILL_ASSET_CREATE_BODY_V3 = "{\n" +
@@ -140,7 +141,9 @@ public class DataManagement {
" \"proxyPath\": \"false\",\n" +
" \"proxyMethod\": \"true\",\n" +
" \"proxyQueryParams\": \"true\",\n" +
" \"proxyBody\": \"true\"\n" +
" \"proxyBody\": \"true\",\n" +
" \"cx-common:allowServicePattern\": \"%10$s\",\n" +
" \"cx-common:denyServicePattern\": \"%11$s\"\n" +
" }\n" +
"}\n";

@@ -215,10 +218,10 @@ public class DataManagement {
/**
* creates a service wrapper
*
* @param monitor logger
* @param monitor logger
* @param typeManager serialization
* @param httpClient remoting
* @param config typed config
* @param httpClient remoting
* @param config typed config
*/
public DataManagement(Monitor monitor, TypeManager typeManager, OkHttpClient httpClient, AgentConfig config) {
this.monitor = monitor;
@@ -233,7 +236,7 @@ public DataManagement(Monitor monitor, TypeManager typeManager, OkHttpClient htt
* TODO replace by accessing the federated data catalogue
*
* @param remoteControlPlaneIdsUrl url of the remote control plane ids endpoint
* @param assetId (connector-unique) identifier of the asset
* @param assetId (connector-unique) identifier of the asset
* @return a collection of contract options to access the given asset
* @throws IOException in case that the remote call did not succeed
*/
@@ -248,7 +251,7 @@ public DcatCatalog findContractOffers(String remoteControlPlaneIdsUrl, String as
* Access the catalogue
*
* @param remoteControlPlaneIdsUrl url of the remote control plane ids endpoint
* @param spec query specification
* @param spec query specification
* @return catalog object
* @throws IOException in case something went wrong
*/
@@ -313,19 +316,23 @@ public List<Asset> listAssets(QuerySpec spec) throws IOException {
/**
* creates or updates a given asset
*
* @param assetId key
* @param name of skill
* @param description of skill
* @param version of skill
* @param contract of skill
* @param ontologies of skill
* @param distributionMode of skill
* @param isFederated whether it should be distributed
* @param query of skill
* @param assetId key
* @param name of skill
* @param description of skill
* @param version of skill
* @param contract of skill
* @param ontologies of skill
* @param distributionMode of skill
* @param isFederated whether it should be distributed
* @param query of skill
* @param allowServicePattern option allow service pattern
* @param denyServicePattern optional deny service pattern
* @return idresponse
* @throws IOException in case interaction with EDC went wrong
*/
public IdResponse createOrUpdateSkill(String assetId, String name, String description, String version, String contract, String ontologies, String distributionMode, boolean isFederated, String query) throws IOException {
public IdResponse createOrUpdateSkill(String assetId, String name, String description, String version, String contract,
String ontologies, String distributionMode, boolean isFederated, String query, String allowServicePattern,
String denyServicePattern) throws IOException {

String apiVersion = config.isPrerelease() ? "/v2" : "/v3";
var url = String.format(ASSET_CREATE_CALL, config.getControlPlaneManagementProviderUrl(), apiVersion);
@@ -336,7 +343,14 @@ public IdResponse createOrUpdateSkill(String assetId, String name, String descri
}
String spec = config.isPrerelease() ? ASSET_CREATE_BODY : SKILL_ASSET_CREATE_BODY_V3;

var assetSpec = String.format(spec, assetId, name, description, version, contract, ontologies, distributionMode, isFederated, query);
if (allowServicePattern == null) {
allowServicePattern = config.getServiceAllowPattern().pattern();
}
if (denyServicePattern == null) {
denyServicePattern = config.getServiceDenyPattern().pattern();
}
var assetSpec = String.format(spec, assetId, name, description, version, contract, ontologies, distributionMode,
isFederated, query, allowServicePattern, denyServicePattern);

var request = new Request.Builder().url(url).post(RequestBody.create(assetSpec, MediaType.parse("application/json")));
config.getControlPlaneManagementHeaders().forEach(request::addHeader);

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2022,2023 Contributors to the Eclipse Foundation
// Copyright (c) 2022,2024 Contributors to the Eclipse Foundation
//
// See the NOTICE file(s) distributed with this work for additional
// information regarding copyright ownership.
@@ -51,7 +51,7 @@ public boolean isSkill(String key) {
}

@Override
public String put(String key, String skill, String name, String description, String version, String contract, SkillDistribution dist, boolean isFederated, String... ontologies) {
public String put(String key, String skill, String name, String description, String version, String contract, SkillDistribution dist, boolean isFederated, String allowServicePatern, String denyServicePattern, String... ontologies) {
if (name == null) {
name = "No name given";
}
@@ -75,7 +75,9 @@ public String put(String key, String skill, String name, String description, Str
ontologiesString,
dist.getDistributionMode(),
isFederated,
typeManager.getMapper().writeValueAsString(TextNode.valueOf(skill))
typeManager.getMapper().writeValueAsString(TextNode.valueOf(skill)),
allowServicePatern,
denyServicePattern
).getId();
} catch (IOException e) {
return null;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2022,2023 Contributors to the Eclipse Foundation
// Copyright (c) 2022,2024 Contributors to the Eclipse Foundation
//
// See the NOTICE file(s) distributed with this work for additional
// information regarding copyright ownership.
@@ -43,7 +43,7 @@ public boolean isSkill(String key) {
}

@Override
public String put(String key, String skill, String name, String description, String version, String contract, SkillDistribution dist, boolean isFederated, String... ontologies) {
public String put(String key, String skill, String name, String description, String version, String contract, SkillDistribution dist, boolean isFederated, String allowServicePattern, String denyServicePattern, String... ontologies) {
skills.put(key, skill);
return key;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2022,2023 Contributors to the Eclipse Foundation
// Copyright (c) 2022,2024 Contributors to the Eclipse Foundation
//
// See the NOTICE file(s) distributed with this work for additional
// information regarding copyright ownership.
@@ -381,7 +381,8 @@ public void testParameterizedQueryFilterContains() throws IOException {
public void testParameterizedSkill() throws IOException {
String query="PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> SELECT ?what WHERE { VALUES (?what) { (\"@input\"^^xsd:int)} }";
String asset="urn:cx:Skill:cx:Test";
try (var response=agentController.postSkill(query,asset,null,null,null,null,SkillDistribution.ALL,false,null)) {
try (var response=agentController.postSkill(query,asset,null,null,null,null,
SkillDistribution.ALL,false,null, null, null)) {
assertEquals(200,response.getStatus(),"post skill successful");
String result = testExecute("GET", null, asset, "*/*", List.of(new AbstractMap.SimpleEntry<>("input", "84")));
JsonNode root = mapper.readTree(result);
@@ -399,7 +400,8 @@ public void testParameterizedSkill() throws IOException {
public void testRemotingSkill() throws IOException {
String query="PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> SELECT ?subject WHERE { SERVICE<http://localhost:8898/match> { VALUES (?subject) { (<@input>)} } }";
String asset="urn:cx:Skill:cx:Test";
try(var response=agentController.postSkill(query,asset,null,null,null,null,SkillDistribution.ALL,false,null)) {
try(var response=agentController.postSkill(query,asset,null,null,null,null,SkillDistribution.ALL,
false,null, null, null)) {
assertEquals(200,response.getStatus(),"post skill successful");
String result = testExecute("GET", null, asset, "*/*", List.of(new AbstractMap.SimpleEntry<>("input", "urn:cx:AnonymousSerializedPart#GB4711")));
JsonNode root = mapper.readTree(result);

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2022,2023 Contributors to the Eclipse Foundation
// Copyright (c) 2022,2024 Contributors to the Eclipse Foundation
//
// See the NOTICE file(s) distributed with this work for additional
// information regarding copyright ownership.
@@ -305,7 +305,7 @@ public void testDefaultService() throws IOException {
builder.url("http://localhost:8080");
builder.addHeader("Accept","application/sparql-results+json");
builder.put(RequestBody.create(query, MediaType.parse("application/sparql-query")));
try (Response response=processor.execute(builder.build(),null,null,Map.of())) {
try (Response response=processor.execute(builder.build(),null,null,Map.of(DataspaceServiceExecutor.ALLOW_SYMBOL.getSymbol(),"(http|edc)s://.*"))) {
assertTrue(response.isSuccessful(), "Successful result");
JsonNode root = mapper.readTree(Objects.requireNonNull(response.body()).string());
JsonNode bindings = root.get("results").get("bindings");

0 comments on commit 3072a10

Please sign in to comment.