Skip to content

Commit

Permalink
feat: Implement first version of the federated catalog connector (#2)
Browse files Browse the repository at this point in the history
* poc federated catalog

* finalisation of poc. TODO: propper e2e text

* First check

* Add config description

* Cleanup

---------

Co-authored-by: Yalz <[email protected]>
  • Loading branch information
Tomvbe and Yalz authored Nov 30, 2023
1 parent 2b46782 commit 9f45c26
Show file tree
Hide file tree
Showing 14 changed files with 369 additions and 19 deletions.
16 changes: 11 additions & 5 deletions README.MD
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
# VSDS Dataspace connector

This repository provides a connector build that can be used to create a dataspace with an LDES Server.
This repository provides connector builds that can be used to create a dataspace with an LDES Server.

To create the image run the following docker command from the root directory:
To create the images run the following docker commands from the root directory:

```bash
docker build -t vsds-dataspace-connector .
```
1. Image for consumer and provider connectors
```bash
docker build -t vsds-dataspace-connector:local . -f ./http-pull-connector/Dockerfile
```

2. Image for the federated catalog connector
```bash
docker build -t vsds-federated-catalog-connector:local . -f ./federated-catalog-connector/Dockerfile
```

> **Note**: These connectors are not production ready and should only be used for development purposes.

Expand Down
131 changes: 119 additions & 12 deletions e2e-test/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,7 @@ This property is used to define the endpoint exposed by the control plane to val

## Run the connectors

Before we can start the connectors, we are going to build the image:

```bash
docker build -t vsds-dataspace-connector:local ../.
```

After building the image, we can start the connectors with the following command:
We can start the connectors with the following command:

```bash
docker compose --profile connectors up -d
Expand All @@ -134,7 +128,53 @@ order.
> drop it from the command. it's just used to format the output, and the same advice should be
> applied to all calls that use `jq`.
### 1. Register data plane instance for provider
### 0. Federated catalog connector - State before datasets are provided by the provider connector
When the federated catalog connector is started, it will crawl the connectors defined in [nodes-dc.json](federated-catalog/nodes-dc.json).
In our test, this is done for the first time, 5 seconds after startup as defined by "edc.catalog.cache.execution.delay.seconds" in the [config](federated-catalog/catalog-configuration.properties).
We can request the Federated Catalog with the following request:
```bash
curl 'http://localhost:8181/api/federatedcatalog' \
-H 'Content-Type: application/json' \
-d '{"criteria":[]}' \
-s | jq
```
If you do this before the provider connectors have been crawled, then you will get an empty response:
```json
[]
```
After the first crawl we get the following response, which contains the connector but no datasets yet:
```json
[
{
"@id": "b05dd09e-f1d4-4c6b-9174-3b532480eb7b",
"@type": "dcat:Catalog",
"dcat:dataset": [],
"dcat:service": {
"@id": "c3e3e29b-84c8-4322-af59-7a4c524e190e",
"@type": "dcat:DataService",
"dct:terms": "connector",
"dct:endpointUrl": "http://provider-connector:19194/protocol"
},
"edc:originator": "http://provider-connector:19194/protocol",
"edc:participantId": "provider",
"@context": {
"dct": "https://purl.org/dc/terms/",
"edc": "https://w3id.org/edc/v0.0.1/ns/",
"dcat": "https://www.w3.org/ns/dcat/",
"odrl": "http://www.w3.org/ns/odrl/2/",
"dspace": "https://w3id.org/dspace/v0.8/"
}
}
]
```
### 1. Provider connector - Register data plane instance for provider
Before a consumer can start talking to a provider, it is necessary to register the data plane
instance of a connector. This is done by sending a POST request to the management API of the
Expand All @@ -161,7 +201,7 @@ curl -H 'Content-Type: application/json' \
-X POST "http://localhost:19193/management/v2/dataplanes" | -s | jq
```
### 2. Register data plane instance for consumer
### 2. Consumer connector - Register data plane instance for consumer
The same thing that is done for the provider must be done for the consumer
Expand All @@ -182,7 +222,7 @@ curl -H 'Content-Type: application/json' \
-X POST "http://localhost:29193/management/v2/dataplanes"
```
### 3. Create an Asset on the provider side
### 3. Provider connector - Create an Asset on the provider side
The provider connector needs to transfer a file to the location specified by the consumer connector
when the data are requested. In order to offer any data, the provider must maintain an internal list
Expand Down Expand Up @@ -226,7 +266,7 @@ Additional properties on `HttpData` can be used to allow consumers to enrich the
- `proxyBody`: allows attaching a body.
- `proxyMethod`: allows specifying the Http Method (default `GET`)
### 4. Create a Policy on the provider
### 4. Provider connector - Create a Policy on the provider
In order to manage the accessibility rules of an asset, it is essential to create a policy. However,
to keep things simple, we will choose a policy that gives direct access to all the assets that are
Expand All @@ -250,7 +290,7 @@ curl -d '{
-s | jq
```
### 5. Create a contract definition on Provider
### 5. Provider connector - Create a contract definition on Provider
To ensure an exchange between providers and consumers, the supplier must create a contract offer for
the good, on the basis of which a contract agreement can be negotiated. The contract definition
Expand Down Expand Up @@ -354,6 +394,73 @@ Sample output:
}
```
Additionally, the Federated Catalog will now also include this entry.
This may take a couple of seconds as the federated catalog connector only polls the provider every 5 seconds as defined by "edc.catalog.cache.execution.period.seconds" in the [config](federated-catalog/catalog-configuration.properties).
```bash
curl 'http://localhost:8181/api/federatedcatalog' \
-H 'Content-Type: application/json' \
-d '{"criteria":[]}' \
-s | jq
```
should output something like this
```json
[
{
"@id": "960d2187-c845-4e1c-9f5e-8beebc83171f",
"@type": "dcat:Catalog",
"dcat:dataset": {
"@id": "devices",
"@type": "dcat:Dataset",
"odrl:hasPolicy": {
"@id": "MQ==:ZGV2aWNlcw==:MWFiNGIwMzYtM2Y1Ni00ZmIwLWJlNzMtYjg5YzM4MTNkMDYz",
"@type": "odrl:Set",
"odrl:permission": [],
"odrl:prohibition": [],
"odrl:obligation": [],
"odrl:target": "devices"
},
"dcat:distribution": [
{
"@type": "dcat:Distribution",
"dct:format": {
"@id": "HttpProxy"
},
"dcat:accessService": "c3e3e29b-84c8-4322-af59-7a4c524e190e"
},
{
"@type": "dcat:Distribution",
"dct:format": {
"@id": "HttpData"
},
"dcat:accessService": "c3e3e29b-84c8-4322-af59-7a4c524e190e"
}
],
"edc:name": "device models",
"edc:id": "devices",
"edc:contenttype": "application/n-quads"
},
"dcat:service": {
"@id": "c3e3e29b-84c8-4322-af59-7a4c524e190e",
"@type": "dcat:DataService",
"dct:terms": "connector",
"dct:endpointUrl": "http://provider-connector:19194/protocol"
},
"edc:originator": "http://provider-connector:19194/protocol",
"edc:participantId": "provider",
"@context": {
"dct": "https://purl.org/dc/terms/",
"edc": "https://w3id.org/edc/v0.0.1/ns/",
"dcat": "https://www.w3.org/ns/dcat/",
"odrl": "http://www.w3.org/ns/odrl/2/",
"dspace": "https://w3id.org/dspace/v0.8/"
}
}
]
```
### 8. Start the workbench with the LdesClient
```bash
Expand Down
29 changes: 27 additions & 2 deletions e2e-test/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ services:
provider-connector:
container_name: connector_provider-connector
image: vsds-dataspace-connector:local
build:
context: ..
dockerfile: http-pull-connector/Dockerfile
environment:
- EDC_KEYSTORE=certs/cert.pfx
- EDC_KEYSTORE_PASSWORD=123456
Expand All @@ -27,6 +30,9 @@ services:
consumer-connector:
container_name: connector_consumer-connector
image: vsds-dataspace-connector:local
build:
context: ..
dockerfile: http-pull-connector/Dockerfile
environment:
- EDC_KEYSTORE=certs/cert.pfx
- EDC_KEYSTORE_PASSWORD=123456
Expand All @@ -47,6 +53,26 @@ services:
profiles:
- connectors

federated-catalog-connector:
container_name: federated-catalog-connector
image: vsds-federated-catalog-connector:local
build:
context: ..
dockerfile: federated-catalog-connector/Dockerfile
environment:
- EDC_FS_CONFIG=config/catalog-configuration.properties
- FCC_DIRECTORY_FILE=config/nodes-dc.json
depends_on: [ provider-connector ]
volumes:
- ./federated-catalog/catalog-configuration.properties:/app/config/catalog-configuration.properties
- ./federated-catalog/nodes-dc.json:/app/config/nodes-dc.json
ports:
- "8181:8181"
networks:
- ldes
profiles:
- connectors

test-message-generator:
container_name: connector_test-message-generator
image: ghcr.io/informatievlaanderen/test-message-generator:latest
Expand Down Expand Up @@ -112,8 +138,7 @@ services:
- delay-started

ldio-workbench:
# image: ghcr.io/informatievlaanderen/ldi-orchestrator:latest
image: conn-client:latest
image: ldes/ldi-orchestrator:1.10.0-SNAPSHOT
container_name: connector_ldio-workbench
environment:
- SPRING_CONFIG_NAME=application
Expand Down
6 changes: 6 additions & 0 deletions e2e-test/federated-catalog/catalog-configuration.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
edc.catalog.cache.execution.delay.seconds=5
edc.catalog.cache.execution.period.seconds=5
edc.catalog.cache.partition.num.crawlers=1
edc.ids.id=urn:connector:fcc
edc.web.rest.cors.enabled=true
edc.web.rest.cors.headers="origin,content-type,accept,authorization,x-api-key"
9 changes: 9 additions & 0 deletions e2e-test/federated-catalog/nodes-dc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[
{
"name": "provider-connector",
"url": "http://provider-connector:19194/protocol",
"supportedProtocols": [
"dataspace-protocol-http"
]
}
]
14 changes: 14 additions & 0 deletions federated-catalog-connector/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Build the jar file
FROM openjdk:18-ea-bullseye AS build

WORKDIR /app
COPY ./ .
RUN ./gradlew clean build

# Run the jar file
FROM openjdk:18-ea-bullseye
WORKDIR /app
COPY --from=build /app/federated-catalog-connector/build/libs/federated-catalog-connector.jar .

# Specify the command to run your application
CMD java -Dedc.fs.config=$EDC_FS_CONFIG -Dfcc.directory.file=$FCC_DIRECTORY_FILE -jar /app/federated-catalog-connector.jar
9 changes: 9 additions & 0 deletions federated-catalog-connector/README.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Federated catalog connector

Supported configuration:

| property | description | required | default |
|--------------------------------------------|------------------------------------------------------------------------------------------------------------------|----------|-----------------------------------------|
| edc.catalog.cache.execution.delay.seconds | The initial delay for the cache crawler engine. | no | N/A (no initial execution will be done) |
| edc.catalog.cache.execution.period.seconds | The time to elapse between two crawl runs. | no | 60 |
| edc.catalog.cache.partition.num.crawlers | The number of crawlers (execution threads) that should be used. The engine will re-use crawlers when necessary. | no | 2 |
50 changes: 50 additions & 0 deletions federated-catalog-connector/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (c) 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
*
*/

plugins {
`java-library`
id("application")
alias(libs.plugins.shadow)
}

dependencies {
runtimeOnly(libs.edc.catalog.core)
runtimeOnly(libs.edc.catalog.api)
implementation(libs.edc.catalog.spi)
implementation(libs.edc.configuration.filesystem)

implementation(libs.edc.util)
runtimeOnly(libs.edc.spi.jsonld)

runtimeOnly(libs.bundles.edc.connector)
runtimeOnly(libs.edc.control.plane.core)
runtimeOnly(libs.edc.data.plane.selector.core)

// IDS stuff
runtimeOnly(libs.edc.dsp)
runtimeOnly(libs.edc.iam.mock)
}

application {
mainClass.set("org.eclipse.edc.boot.system.runtime.BaseRuntime")
}

var distTar = tasks.getByName("distTar")
var distZip = tasks.getByName("distZip")

tasks.withType<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar> {
mergeServiceFiles()
archiveFileName.set("federated-catalog-connector.jar")
dependsOn(distTar, distZip)
}
Loading

0 comments on commit 9f45c26

Please sign in to comment.