Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(WIP) Enabling of Knowledge Layer #50

Open
wants to merge 48 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 44 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
db8e01a
Add basis directory structure with readme files
chrizmc May 23, 2024
64e06ec
add basic setup of informationlayer containing basic dbrouter and rea…
chrizmc May 29, 2024
5ee12fd
add files
claireqiu May 31, 2024
75c0eb3
Fixed readme format of config.js
sschleemilch Jun 6, 2024
a77d8a3
Renamed knowledge-connector -> connector
sschleemilch Jun 6, 2024
327db86
Removed dead README link
sschleemilch Jun 6, 2024
69da82d
Fixed README formatting and fixed typos
sschleemilch Jun 6, 2024
9bb7dc4
Updated docs, added config.js
sschleemilch Jun 6, 2024
e0d7aa6
Added handlers layer
sschleemilch Jun 6, 2024
9722e2b
Hint for hard coded realmdb and js formatting
sschleemilch Jun 6, 2024
dbbed43
Fixed require path for new structure
sschleemilch Jun 6, 2024
f98ef6f
Added missing dot in readme
chrizmc Jun 18, 2024
0da163a
Fixed wrong readme link
chrizmc Jun 18, 2024
0c83de4
add basic router parts
chrizmc Jul 8, 2024
3e36432
Add environment variable functionallity and update README files.
chrizmc Jul 9, 2024
72ab98b
Update link URL and create a IoTDB connection using the IoTDB Handler
chrizmc Jul 24, 2024
c075e51
Update the authentification configuration for the IoTDB handler
chrizmc Jul 31, 2024
684f3f9
Add validator for message format and IoTDB message processing
chrizmc Aug 7, 2024
62e8402
Extend supported data points in RealmDB Handler
sschleemilch Aug 9, 2024
cd597d1
Support for UseCase endpoits in IoTDB Handler
sschleemilch Aug 9, 2024
5f142ab
Add write support to realmdb
sschleemilch Aug 13, 2024
56a1109
Extracted common methods
sschleemilch Aug 21, 2024
6d28e89
Support dots separation for endpoint naming in realm db
aw-muc Aug 22, 2024
deff29c
• Import supported endpoints for IoTDB and RealmDB from YAML/JSON fil…
aw-muc Aug 27, 2024
c8ef06d
Dockerize informations-layer
aw-muc Sep 6, 2024
7f1ae37
Fixed doc typos
sschleemilch Sep 6, 2024
838af3f
Remove unnecessary config files and add it as gitignore.
aw-muc Sep 13, 2024
dfb873f
Data transmission via websocket client in knowledge layer:
aw-muc Sep 16, 2024
28ec28b
Documentation for new data source within information layer
aw-muc Sep 16, 2024
b84a37e
Handle and send error message within information layer for websocket …
aw-muc Sep 16, 2024
8614c90
Vehicle data point knowledge layer configuration
sschleemilch Sep 26, 2024
e68d6bb
CMake windows support
sschleemilch Sep 27, 2024
bbe803f
Add --help CLI feature to display configured and default parameters
chrizmc Oct 9, 2024
9559d7f
Use configuration file to organize the use case model directory
chrizmc Oct 9, 2024
ffce704
Configure RDFox environment
chrizmc Oct 9, 2024
24b871e
Develop RDFox adapter for rest api integration
Oct 17, 2024
1bcadd7
Refactored information-layer Docs (#36)
sschleemilch Oct 21, 2024
7ae2fb4
- Migrate JS to TypeScript
aw-muc Oct 21, 2024
c936c4b
add hello world kl usecase readme
chrizmc Oct 21, 2024
cd64ada
IMplementation of Thrift to access IoTDB without TypeScript; JavaScri…
aw-muc Oct 23, 2024
7465d61
Switched README graph to mermaid
sschleemilch Oct 30, 2024
c078a05
Subscription functionality for IoTDB data layer
aw-muc Nov 4, 2024
21236aa
Locate another transformation function in transformations.ts, too
chrizmc Nov 13, 2024
9693e64
Add instruction how to build and run tests
chrizmc Nov 13, 2024
d9da312
change _ to . notation in readme
chrizmc Nov 14, 2024
c76f57a
Transform Json data into RDF triples using SHACL shapes and SPARQ…
Nov 26, 2024
21e519b
Add subscription status message after subscribe/unsubscribe when usin…
chrizmc Dec 2, 2024
43a1758
Add session management to Information Layer
chrizmc Dec 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# IntelliJ Settings
.idea

# VSCode Settings
.vscode
6 changes: 6 additions & 0 deletions cdsp/information-layer/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# ignore mongodb generated files
mongodb-realm

# ignore all node generated file
node_modules
package-lock.json
8 changes: 8 additions & 0 deletions cdsp/information-layer/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# MongoDB Realm
mongodb-realm/

# Node.js
node_modules/

# typescript migration
dist
5 changes: 5 additions & 0 deletions cdsp/information-layer/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#ignore node modules
node_modules

#ignore autogenerated files by thrift
handlers/src/iotdb/gen-nodejs
24 changes: 24 additions & 0 deletions cdsp/information-layer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
FROM node:22.5.1

WORKDIR /app

COPY package.json .
COPY tsconfig.json .
COPY handlers ./handlers
COPY utils ./utils
COPY router ./router

# Install dependencies, including workspaces
RUN npm install

# Transpile TypeScript to JavaScript
RUN npm run build

# Remove devDependencies to reduce the final image size
RUN npm prune --omit=dev

# Expose the necessary port
EXPOSE 8080

# Command to run the WebSocket server
CMD ["node", "./dist/router/src/websocket-server.js"]
233 changes: 233 additions & 0 deletions cdsp/information-layer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
# Information Layer

The information layer is responsible for providing a raw data access [API](#api) (read, write, subscribe).
Its intention is to abstract the underlying data storage database technology.

Clients can interact with it using websockets and JSON payload.


The information-layer consists of two logical components:
- database handler: Interaction with the chosen database, configurable
- router: API provider that connects to the database handler

```mermaid
flowchart LR
client <--> router
router <--> handlers
handlers <--> realm_handler
handlers <--> iotdb_handler
realm_handler <--> realmdb
iotdb_handler <--> iotdb
```

# Hello World Setup

### Build the typescript application natively

Make sure all libraries are installed
```bash
npm install
```
Build the application
```bash
npm run build
```
Run the unit tests
```bash
npx jest
```
or
```bash
npx jest --verbose
```

## Backend Option 1: IoTDB

### Start the database

Start the db:
```bash
docker run -d --rm --name iotdb -p 6667:6667 -p 9003:9003 apache/iotdb:latest
```
Connect to it via cli:
```bash
docker exec -it iotdb ./start-cli.sh -h 127.0.0.1 -p 6667 -u root -pw root
```
Create a database
```bash
create database root.Vehicles
```
Create desired timeseries

```bash
create timeseries root.Vehicles.Vehicle_TraveledDistance WITH DATATYPE=FLOAT, ENCODING=RLE
create timeseries root.Vehicles.Vehicle_Speed WITH DATATYPE=FLOAT, ENCODING=RLE
```

### Start router

Build the router image
```bash
docker build -t router .
```
Run the router
```bash
# Docker
docker run --rm --name router -p 8080:8080 -e HANDLER_TYPE=iotdb -e IOTDB_HOST=host.docker.internal router
# OR natively
npm install
HANDLER_TYPE=iotdb IOTDB_HOST=localhost npm start
```

## Backend Option 2: RealmDB


### Prepare cloud

- Ensure that in your [ATLAS cloud](https://cloud.mongodb.com/) app there is a vehicle _document_ with an `Vehicle_VehicleIdentification_VIN` in a collection named _`Vehicles`_.
- Ensure that this document as well contains VSS data. Here you can see the data supported in this repository for a vehicle document within _Vehicles_ that should be reflected in ATLAS:

```
_id: "<SOME_STRING>" (String)
Vehicle_Speed: <SOME_DOUBLE> (Double)
Vehicle_TraveledDistance: "<SOME_DOUBLE>" (Double)
```

### Start router

Build the router image
```bash
docker build -t router .
```
Run the router
```bash
# Docker
docker run --rm --name router -p 8080:8080 -e HANDLER_TYPE=realmdb -e VERSION_REALMDB_SCHEMA=0 -e REALM_APP_ID=<YOUR-APP-ID> -e REALM_API_KEY=<YOUR-API-KEY> router
# OR natively
npm install
HANDLER_TYPE=realmdb VERSION_REALMDB_SCHEMA=0 REALM_APP_ID=<YOUR-APP-ID> REALM_API_KEY=<YOUR-API-KEY> npm start
```

## Usage

See [api](#api) how to interact with the router.

# API

Connect your own websocket client by connecting to `ws://localhost:8080`.

The examples use [websocat](https://github.com/vi/websocat) and [jq](https://github.com/jqlang/jq)

## Read

Schema:
```jsonc
{
"type": "read",
"tree": "VSS",
"id": "123", // The VIN
"uuid": "testClient", // The unique client ID
// For reading one
"node": { "name": "Vehicle_Speed" },
Copy link
Collaborator

@slawr slawr Nov 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An early review observation is that in your IoTDB implementation you have chosen to replace VSS dot notation in VSS node/leaf names with underscores to (I assume) integrate and avoid conflicts with the dot notation of the IoTDB data model. Whilst a valid approach (I considered the same when creating the Playground) it is different to the one I choose which quotes the VSS name and which is used in various places in the Playground codebase. For example, the RemotiveLabs feeder, the VISSR integration, examples and in the online documentation. See https://covesa.github.io/cdsp/manuals/apache-iotdb/#integrating-vss-data-into-the-iotdb-data-model

So we need to have an alignment discussion to resolve this.

// For reading N
"nodes": [{ "name": "Vehicle_Speed" },{ "name": "Vehicle_TraveledDistance" }]
}
```

Example:
```bash
echo '{ "type": "read", "tree": "VSS", "id": "123", "uuid": "testClient", "node": { "name": "Vehicle.Speed" } }' | websocat ws://localhost:8080 | jq
```
```json
{
"type": "update",
"tree": "VSS",
"id": "123",
"dateTime": "2024-10-16T12:09:13.084Z",
"uuid": "test",
"node": {
"name": "Vehicle.Speed",
"value": 300
}
}
```

## Write

Schema:
```jsonc
{
"type": "write",
"tree": "VSS",
"id": "123", // The VIN
"uuid": "testClient", // The unique client ID
// For writing one
"node": { "name": "Vehicle_Speed", "value": 300 },
// For writing N
"nodes": [{ "name": "Vehicle_Speed", "value": 300 },{ "name": "Vehicle_TraveledDistance", "value": 100000 }]
}
```
Example:
```bash
echo '{ "type": "write", "tree": "VSS", "id": "123", "uuid": "testClient", "node": { "name": "Vehicle.Speed", "value": 300 } }' | websocat ws://localhost:8080 | jq
```
```json
{
"type": "update",
"tree": "VSS",
"id": "123",
"dateTime": "2024-10-16T12:09:13.084Z",
"uuid": "test",
"node": {
"name": "Vehicle.Speed",
"value": 300
}
}
```

## Subscribe (Realm Only)

Schema:
```json
{
"type": "subscribe",
"tree": "VSS",
"id": "123",
"uuid": "testClient"
}
```

On success:
```json
{
"type": "subscribe:status",
"tree": "VSS",
"id": "123",
"dateTime": "2024-09-12T15:50:17.232Z",
"uuid": "testClient",
"status": "succeed"
}
```
## Unsubscribe

```json
{
"type": "unsubscribe",
"tree": "VSS",
"id": "123",
"uuid": "testClient"
}
```

On success:
```json
{
"type": "unsubscribe:status",
"tree": "VSS",
"id": "123",
"dateTime": "2024-09-12T17:40:00.754Z",
"uuid": "testClient",
"status": "succeed"
}
```

38 changes: 38 additions & 0 deletions cdsp/information-layer/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// @ts-check

import eslint from "@eslint/js";
import pluginPrettier from "eslint-plugin-prettier";
import prettierConfig from "eslint-config-prettier";
import tseslint, { parser } from "typescript-eslint";

export default tseslint.config(
{
ignores: ["coverage/**", "**/dist/**", "node_modules/**"],
},
{
files: ["./**/*.{ts,tsx}"],
extends: [eslint.configs.recommended, ...tseslint.configs.strict],
plugins: {
prettier: pluginPrettier,
//"@typescript-eslint": ESLintPlugin,
},
languageOptions: {
parser: parser,
parserOptions: {
project: "./tsconfig.json", // Ensure it points to your tsconfig
},
},
rules: {
"max-depth": ["error", 3],
"@/no-console": "error",
"@typescript-eslint/no-unnecessary-condition": "error",
"@typescript-eslint/no-floating-promises": "error",
"no-shadow": "off",
"@typescript-eslint/no-shadow": "error",
"@typescript-eslint/naming-convention": "error",
"@no-nested-ternary": "warn",
"prettier/prettier": "error",
...prettierConfig.rules,
},
}
);
18 changes: 18 additions & 0 deletions cdsp/information-layer/handlers/config/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Configuration Handler for supported Data Points

This module is responsible for handling the configuration of supported data points in the application. It supports JSON, YAML, or YML formats for defining the data points.

The `vss_data_points.yaml` and `vss_data_points.json` files in the `./schema-files` directory contain the same data point definition (only one of them is necessary to build) and based on that, the system will configure the data schema used during the Database configuration.

> [!WARNING]
>
> - Before starting the application, ensure that the desired YAML, YML or JSON file is correctly placed in the `./schema-files` directory. This file should contain the definitions of the supported data points. The name and extension to use can be configured in the `/docker/.env` file, it uses the ENV variable named `DATA_POINTS_SCHEMA_FILE`. If it is not specified, it uses `vss_data_points.yaml` by default, which is one of the files contained in this repository. .
> - Ensure that the used file is correctly formatted and contains valid data points definitions.
> - **The application will not function correctly if the data points file is missing or incorrectly placed.**

## File: `config.js`

### Description

The `config.js` file contains the logic to retrieve the data defined in the ENV variables and the full path to the data points schema configuration file (`./schema-files/vss_data_points.yaml` in this case). This file is crucial for the application to understand which data points are supported and how they should be handled.

39 changes: 39 additions & 0 deletions cdsp/information-layer/handlers/config/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import path from "path";
import dotenv from "dotenv";
import { logMessage } from "../../utils/logger";

// Load environment variables from the .env file
dotenv.config();

/**
* This file contains the description of the supported data points.
* It supports JSON, YAML or YML format.
*/
const ENDPOINTS_FILE: string = "vss_data_points.yaml";

/**
* Retrieves the value of an environment variable.
*
* @param envVar - The environment variable to retrieve.
* @returns The value of the environment variable or null if not set.
*/
export const getEnvValue = (envVar: string): string | null => {
if (!process.env[envVar]) {
logMessage(`${envVar} environment variable is not set in .env file.`);
return null;
}
return process.env[envVar]!;
};

/**
* Retrieves the full path to the data points file.
*
* This function resolves the schema-files directory path of the current module
* and joins it with the ENDPOINTS_FILE constant to form the full path.
*
* @returns The full path to the data points file.
*/
export const getDataPointsPath = (): string => {
const rootPath = path.resolve(`${__dirname}/schema-files`);
return path.join(rootPath, ENDPOINTS_FILE);
};
Loading
Loading