Merge branch 'master' of https://git.eclipse.org/r/basyx/basyx
# Conflicts:
# .gitignore
diff --git a/.gitignore b/.gitignore
index 7053dde..caa84fe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+.lck
*.class
/components/basys.components/WebContent/WEB-INF/lib/jdbc/postgresql-42.2.2.jar
/components/basys.components/WebContent/WEB-INF/lib/jersey/ext/aopalliance-repackaged-2.5.0-b42.jar
@@ -58,6 +59,6 @@
/.vs
/sdks/dotnet/.vs/BaSyx
launchSettings.json
+.project
*.pubxml
-/sdks/dotnet/basyx-components/NewtonsoftJsonAdapter
Properties
diff --git a/CONTRIBUTING b/CONTRIBUTING
new file mode 100644
index 0000000..23bef6e
--- /dev/null
+++ b/CONTRIBUTING
@@ -0,0 +1,62 @@
+# Contributing to Eclipse Basyx
+
+Thanks for your interest in this project.
+
+## Project description
+
+Eclipse BaSyx collects the implementation results of the research project BaSys
+4.0. An essential goal of BaSys 4.0 is the use of IT technology for production
+systems to enable the concepts of the new Industrie 4.0 paradigm. It develops a
+middleware that integrates traditional production systems (e.g. PLC controllers)
+and state-of-the art IT technology (BPMN engine, SOA) to enable next generation
+of production automation.
+
+* https://projects.eclipse.org/projects/technology.basyx
+
+## Developer resources
+
+Information regarding source code management, builds, coding standards, and
+more.
+
+* https://projects.eclipse.org/projects/technology.basyx/developer
+
+The project maintains the following source code repositories
+
+* https://git.eclipse.org/r/plugins/gitiles/basyx/basyx
+* https://git.eclipse.org/r/plugins/gitiles/basyx/basyx.website
+
+This project uses Bugzilla to track ongoing development and issues.
+
+* Search for issues: https://bugs.eclipse.org/bugs/buglist.cgi?product=Basyx
+* Create a new report:
+ https://bugs.eclipse.org/bugs/enter_bug.cgi?product=Basyx
+
+Be sure to search for existing bugs before you create another one. Remember that
+contributions are always welcome!
+
+## Eclipse Development Process
+
+This Eclipse Foundation open project is governed by the Eclipse Foundation
+Development Process and operates under the terms of the Eclipse IP Policy.
+
+## Eclipse Contributor Agreement
+
+Before your contribution can be accepted by the project team contributors must
+electronically sign the Eclipse Contributor Agreement (ECA).
+
+* http://www.eclipse.org/legal/ECA.php
+
+Commits that are provided by non-committers must have a Signed-off-by field in
+the footer indicating that the author is aware of the terms by which the
+contribution has been provided to the project. The non-committer must
+additionally have an Eclipse Foundation account and must have a signed Eclipse
+Contributor Agreement (ECA) on file.
+
+For more information, please see the Eclipse Committer Handbook:
+https://www.eclipse.org/projects/handbook/#resources-commit
+
+## Contact
+
+Contact the project developers via the project's "dev" list.
+
+* https://dev.eclipse.org/mailman/listinfo/basyx-dev
diff --git a/Jenkinsfile_Cpp b/Jenkinsfile_Cpp
new file mode 100644
index 0000000..b1e0a7f
--- /dev/null
+++ b/Jenkinsfile_Cpp
@@ -0,0 +1,37 @@
+pipeline {
+ agent {
+ kubernetes {
+ label 'basyx-' + env.BRANCH_NAME + '-' + env.BUILD_NUMBER
+ yaml """
+apiVersion: v1
+kind: Pod
+spec:
+ containers:
+ - name: cpp
+ image: iesetps/basyx-ci-cpp:latest
+ resources:
+ requests:
+ memory: "4Gi"
+ cpu: "2.00"
+ limits:
+ memory: "4Gi"
+ cpu: "2.00"
+ command:
+ - cat
+ tty: true
+"""
+ }
+ }
+ stages {
+ stage('C++ SDK Tests') {
+ steps {
+ container('cpp') {
+ sh '''
+ chmod +x ./ci/build_cpp.sh
+ ./ci/build_cpp.sh
+ '''
+ }
+ }
+ }
+ }
+}
diff --git a/Jenkinsfile_Java b/Jenkinsfile_Java
new file mode 100644
index 0000000..2f513c0
--- /dev/null
+++ b/Jenkinsfile_Java
@@ -0,0 +1,69 @@
+pipeline {
+ agent {
+ kubernetes {
+ label 'basyx-' + env.BRANCH_NAME + '-' + env.BUILD_NUMBER
+ yaml """
+apiVersion: v1
+kind: Pod
+spec:
+ containers:
+ - name: postgresql
+ image: postgres:latest
+ resources:
+ requests:
+ memory: "2Gi"
+ cpu: "0.5"
+ limits:
+ memory: "2Gi"
+ cpu: "0.5"
+ command:
+ - cat
+ tty: true
+ env:
+ - name: POSTGRES_PASSWORD
+ value: admin
+ - name: PGDATA
+ value: /run/postgresql/data
+ - name: java
+ image: maven:3.6-jdk-8
+ resources:
+ requests:
+ memory: "4Gi"
+ cpu: "1.5"
+ limits:
+ memory: "4Gi"
+ cpu: "1.5"
+ command:
+ - cat
+ tty: true
+ env:
+ - name: MAVEN_CONFIG
+ value: /home/jenkins/agent/.m2
+"""
+ }
+ }
+ stages {
+ stage('Setup PostgreSQL') {
+ steps {
+ container('postgresql') {
+ sh '''
+ chmod +x ./ci/init_postgres.sh
+ ./ci/init_postgres.sh postgres
+ pg_ctl start
+ '''
+ }
+ }
+ }
+ stage('Java SDK Tests') {
+ steps {
+ container('java') {
+ sh '''
+ mkdir /home/jenkins/agent/.m2
+ chmod +x ./ci/build_java.sh
+ ./ci/build_java.sh
+ '''
+ }
+ }
+ }
+ }
+}
diff --git a/NOTICE b/NOTICE
index de0fa23..41bc327 100644
--- a/NOTICE
+++ b/NOTICE
@@ -19,4 +19,79 @@
## Third-party Content
-TBD
\ No newline at end of file
+Eclipse Milo
+
+ * License: EPL 2.0
+
+javax.servlet-api
+
+ * License: CDDL
+
+javax.ws.rs-api
+
+ * License: EPL 2.0
+
+jersey-client
+
+ * License: EPL 2.0
+
+jersey-hk2
+
+ * License: EPL 2.0
+
+Tomcat-catalina
+
+ * License: Apache License 2.0
+
+Apache poi-ooxml
+
+ * License: Apache License 2.0
+
+Logback
+
+ * License: EPL 1.0
+
+Janino
+
+ * License: BSD 3
+
+Eclipse Paho
+
+ * License: EPL 2.0
+
+Postgres
+
+ * License: PostgreSQL Licence
+
+GSON
+
+ * License: Apache License 2.0
+
+HikariCP
+
+ * License: EPL 1.0
+
+mongodb-driver-sync
+
+ * License: Apache License 2.0
+
+spring-data-mongodb
+
+ * License: Apache License 2.0
+
+Moquette
+
+ * License: Apache License 2.0
+
+
+To be extended
+
+
+## Cryptography
+
+Content may contain encryption software. The country in which you are currently
+may have restrictions on the import, possession, and use, and/or re-export to
+another country, of encryption software. BEFORE using any encryption software,
+please check the country's laws, regulations and policies concerning the import,
+possession, or use, and re-export of encryption software, to see if this is
+permitted.
\ No newline at end of file
diff --git a/ci/build_cpp.sh b/ci/build_cpp.sh
index 055161a..dfa60bc 100644
--- a/ci/build_cpp.sh
+++ b/ci/build_cpp.sh
@@ -13,7 +13,7 @@
mkdir build && cd build
cmake ../sdks/c++/basys.sdk.cc -DBASYX_UTILITY_PROJECTS=OFF -DBUILD_SHARED_LIBS=ON
- make all
+ make -j2 all
ctest
else
echo "No files changed in C++ SDK."
diff --git a/components/basys.components/.mvn/wrapper/MavenWrapperDownloader.java b/components/basys.components/.mvn/wrapper/MavenWrapperDownloader.java
new file mode 100644
index 0000000..e76d1f3
--- /dev/null
+++ b/components/basys.components/.mvn/wrapper/MavenWrapperDownloader.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2007-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import java.net.*;
+import java.io.*;
+import java.nio.channels.*;
+import java.util.Properties;
+
+public class MavenWrapperDownloader {
+
+ private static final String WRAPPER_VERSION = "0.5.6";
+ /**
+ * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
+ */
+ private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
+ + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
+
+ /**
+ * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
+ * use instead of the default one.
+ */
+ private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
+ ".mvn/wrapper/maven-wrapper.properties";
+
+ /**
+ * Path where the maven-wrapper.jar will be saved to.
+ */
+ private static final String MAVEN_WRAPPER_JAR_PATH =
+ ".mvn/wrapper/maven-wrapper.jar";
+
+ /**
+ * Name of the property which should be used to override the default download url for the wrapper.
+ */
+ private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
+
+ public static void main(String args[]) {
+ System.out.println("- Downloader started");
+ File baseDirectory = new File(args[0]);
+ System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
+
+ // If the maven-wrapper.properties exists, read it and check if it contains a custom
+ // wrapperUrl parameter.
+ File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
+ String url = DEFAULT_DOWNLOAD_URL;
+ if(mavenWrapperPropertyFile.exists()) {
+ FileInputStream mavenWrapperPropertyFileInputStream = null;
+ try {
+ mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
+ Properties mavenWrapperProperties = new Properties();
+ mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
+ url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
+ } catch (IOException e) {
+ System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
+ } finally {
+ try {
+ if(mavenWrapperPropertyFileInputStream != null) {
+ mavenWrapperPropertyFileInputStream.close();
+ }
+ } catch (IOException e) {
+ // Ignore ...
+ }
+ }
+ }
+ System.out.println("- Downloading from: " + url);
+
+ File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
+ if(!outputFile.getParentFile().exists()) {
+ if(!outputFile.getParentFile().mkdirs()) {
+ System.out.println(
+ "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
+ }
+ }
+ System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
+ try {
+ downloadFileFromURL(url, outputFile);
+ System.out.println("Done");
+ System.exit(0);
+ } catch (Throwable e) {
+ System.out.println("- Error downloading");
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ private static void downloadFileFromURL(String urlString, File destination) throws Exception {
+ if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
+ String username = System.getenv("MVNW_USERNAME");
+ char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
+ Authenticator.setDefault(new Authenticator() {
+ @Override
+ protected PasswordAuthentication getPasswordAuthentication() {
+ return new PasswordAuthentication(username, password);
+ }
+ });
+ }
+ URL website = new URL(urlString);
+ ReadableByteChannel rbc;
+ rbc = Channels.newChannel(website.openStream());
+ FileOutputStream fos = new FileOutputStream(destination);
+ fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
+ fos.close();
+ rbc.close();
+ }
+
+}
diff --git a/components/basys.components/.mvn/wrapper/maven-wrapper.properties b/components/basys.components/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 0000000..642d572
--- /dev/null
+++ b/components/basys.components/.mvn/wrapper/maven-wrapper.properties
@@ -0,0 +1,2 @@
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/Dockerfile b/components/basys.components/basyx.components.docker/basyx.components.AASServer/Dockerfile
index 3628774..e199c91 100644
--- a/components/basys.components/basyx.components.docker/basyx.components.AASServer/Dockerfile
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/Dockerfile
@@ -5,11 +5,25 @@
ARG JAR_FILE
COPY target/${JAR_FILE} /usr/share/basyxExecutable.jar
COPY target/lib /usr/share/lib
-COPY src/main/resources/context.properties /usr/share/context.properties
+COPY src/main/resources/aas.properties /usr/share/config/aas.properties
+COPY src/main/resources/context.properties /usr/share/config/context.properties
+COPY src/test/resources/dockerMongodb.properties /usr/share/config/mongodb.properties
# Expose the appropriate port. In case of Tomcat, this is 8080.
ARG PORT
EXPOSE ${PORT}
+# Set the path for the aas configuration file
+ARG AAS_CONFIG_KEY
+ENV ${AAS_CONFIG_KEY} "/usr/share/config/aas.properties"
+
+# Set the path for the context configuration file
+ARG CONTEXT_CONFIG_KEY
+ENV ${CONTEXT_CONFIG_KEY} "/usr/share/config/context.properties"
+
+# Set the path for the mongodb configuration file
+ARG MONGODB_CONFIG_KEY
+ENV ${MONGODB_CONFIG_KEY} "/usr/share/config/mongodb.properties"
+
# Start the jar
-CMD java -jar "/usr/share/basyxExecutable.jar" "/usr/share/context.properties"
\ No newline at end of file
+CMD java -jar "/usr/share/basyxExecutable.jar"
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/build.bat b/components/basys.components/basyx.components.docker/basyx.components.AASServer/build.bat
new file mode 100644
index 0000000..64f74e3
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/build.bat
@@ -0,0 +1 @@
+../.././mvnw clean install -U -Pdocker -DskipTests
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/build.sh b/components/basys.components/basyx.components.docker/basyx.components.AASServer/build.sh
new file mode 100755
index 0000000..6820ccc
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/build.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+../../mvnw clean install -U -Pdocker -DskipTests
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/docker-compose.yml b/components/basys.components/basyx.components.docker/basyx.components.AASServer/docker-compose.yml
new file mode 100644
index 0000000..b55d107
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/docker-compose.yml
@@ -0,0 +1,26 @@
+version: '2.1'
+services:
+
+ aas:
+ image: ${BASYX_IMAGE_NAME}:${BASYX_IMAGE_TAG}
+ container_name: ${BASYX_CONTAINER_NAME}
+ ports:
+ - ${BASYX_HOST_PORT}:${BASYX_CONTAINER_PORT}
+ depends_on:
+ mongodb:
+ condition: service_healthy
+ links:
+ - mongodb
+
+ mongodb:
+ image: mongo:latest
+ container_name: mongodb
+ healthcheck:
+ test: echo 'db.runCommand("ping").ok' | mongo mongodb:27017/test --quiet
+ interval: 3s
+ timeout: 3s
+ retries: 5
+# Possibility to enable authentication
+# environment:
+# MONGO_INITDB_ROOT_USERNAME: root
+# MONGO_INITDB_ROOT_PASSWORD: example
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/pom.xml b/components/basys.components/basyx.components.docker/basyx.components.AASServer/pom.xml
index ca9308f..d73f236 100644
--- a/components/basys.components/basyx.components.docker/basyx.components.AASServer/pom.xml
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/pom.xml
@@ -5,12 +5,21 @@
<parent>
<groupId>org.eclipse.basyx</groupId>
<artifactId>basyx.components.docker</artifactId>
- <version>0.0.1-SNAPSHOT</version>
+ <version>1.0.0</version>
</parent>
<artifactId>basyx.components.AASServer</artifactId>
<name>AAS Server</name>
-<packaging>jar</packaging>
+
+ <properties>
+ <!--
+ basyx.components.executable is the executable class with the definition of the public void main(String[]).
+ It is needed when building the jar in the maven-jar-plugin (see basyx.components.docker/pom.xml)
+ -->
+ <basyx.components.executable>org.eclipse.basyx.components.aas.executable.AASServerExecutable</basyx.components.executable>
+ </properties>
+
+ <packaging>jar</packaging>
<!-- Define additional plugins that are not included by default -->
<!-- Plugin configuration is done in parent project(s) -->
@@ -24,6 +33,37 @@
</plugins>
</build>
+ <dependencies>
+ <!-- Use MongoDB Java Drivers for db connections -->
+ <dependency>
+ <groupId>org.mongodb</groupId>
+ <artifactId>mongodb-driver-sync</artifactId>
+ <version>4.0.5</version>
+ </dependency>
+
+ <!-- Use Spring Data MongoDB for db data management -->
+ <dependency>
+ <groupId>org.springframework.data</groupId>
+ <artifactId>spring-data-mongodb</artifactId>
+ <version>3.0.1.RELEASE</version>
+ </dependency>
+
+ <!-- Adds additional classes of the BaSys SDK for tests -->
+ <dependency>
+ <groupId>org.eclipse.basyx</groupId>
+ <artifactId>basyx.sdk</artifactId>
+ <classifier>tests</classifier>
+ </dependency>
+
+ <!-- Used for reading .aasx files -->
+ <dependency>
+ <groupId>org.apache.poi</groupId>
+ <artifactId>poi-ooxml</artifactId>
+ <version>4.1.2</version>
+ </dependency>
+
+ </dependencies>
+
<profiles>
<profile>
<!--
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/basyx/components/AASServer/AASServerComponent.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/basyx/components/AASServer/AASServerComponent.java
deleted file mode 100644
index ea57c18..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/basyx/components/AASServer/AASServerComponent.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package org.basyx.components.AASServer;
-
-import java.io.IOException;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.basyx.components.AASServer.servlet.AASServerServlet;
-import org.eclipse.basyx.vab.protocol.http.server.AASHTTPServer;
-import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.xml.sax.SAXException;
-
-/**
- * Component providing an empty AAS server that is able to receive AAS/SMs from
- * remote. It uses the Aggregator API, i.e. AAS should be pushed to
- * ${URL}/aasList
- *
- * @author schnicke
- *
- */
-public class AASServerComponent {
- private static Logger logger = LoggerFactory.getLogger(AASServerComponent.class);
-
- // The server with the servlet that will be created
- private AASHTTPServer server;
-
- private String hostName;
- private int port;
- private String path;
- private String docBasePath;
-
- /**
- * Constructs an empty AAS server using the passed arguments
- *
- * @param hostName
- * @param port
- * @param path
- * @param docBasePath
- */
- public AASServerComponent(String hostName, int port, String path, String docBasePath) {
- // Sets the server context
- this.hostName = hostName;
- this.port = port;
- this.path = path;
- this.docBasePath = docBasePath;
- }
-
- /**
- * Starts the AASX component at http://${hostName}:${port}/${path}
- *
- * @param hostName
- * @param port
- * @param path
- * @param docBasePath
- * @throws IOException
- * @throws SAXException
- * @throws ParserConfigurationException
- */
- public void startComponent() {
- logger.info("Create the server...");
- // Init HTTP context and add an XMLAAServlet according to the configuration
- BaSyxContext context = new BaSyxContext(path, docBasePath, hostName, port);
- // Create the Servlet for aas
- context.addServletMapping("/*", new AASServerServlet());
- server = new AASHTTPServer(context);
-
- logger.info("Start the server...");
- server.start();
- }
-
- /**
- * Retrieves the URL on which the component is providing its HTTP server
- *
- * @return
- */
- public String getURL() {
- return "http://" + hostName + ":" + port + "/" + path;
- }
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/basyx/components/AASServer/executable/AASServerExecutable.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/basyx/components/AASServer/executable/AASServerExecutable.java
deleted file mode 100644
index 9d4f9ab..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/basyx/components/AASServer/executable/AASServerExecutable.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package org.basyx.components.AASServer.executable;
-
-import java.io.IOException;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.basyx.components.AASServer.AASServerComponent;
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.xml.sax.SAXException;
-
-/**
- * Starts an HTTP server that is able to receive AAS and submodels pushed from
- * remote <br />
- * They are made available at
- * <i>localhost:4000/aasServer/aasList/${aasId}/aas</i>. Submodels are available
- * at
- * <i>localhost:4000/aasServer/aasList/${aasId}/submodels/${submodelId}/submodel</i><br
- * />
- *
- * @author schnicke
- */
-public class AASServerExecutable {
- // Creates a Logger based on the current class
- private static Logger logger = LoggerFactory.getLogger(AASServerExecutable.class);
-
- public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
- // Load configuration
- BaSyxContextConfiguration config = new BaSyxContextConfiguration();
- if (args.length > 0 && args[0] instanceof String) {
- // file path available? => load configs from file
- config.loadFromFile(args[0]);
- } else {
- // fallback: load default configs (in resources)
- config.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
- }
-
- AASServerComponent component = new AASServerComponent(config.getHostname(), config.getPort(), config.getContextPath(), config.getDocBasePath());
- component.startComponent();
-
- logger.info("BaSyx AAS Server component started");
- }
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/basyx/components/AASServer/servlet/AASServerServlet.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/basyx/components/AASServer/servlet/AASServerServlet.java
deleted file mode 100644
index d2796ad..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/basyx/components/AASServer/servlet/AASServerServlet.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.basyx.components.AASServer.servlet;
-
-import org.eclipse.basyx.aas.aggregator.AASAggregator;
-import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
-import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
-
-/**
- * A servlet containing the empty infrastructure needed to support receiving
- * AAS/Submodels by clients and hosting them
- *
- * @author schnicke
- *
- */
-public class AASServerServlet extends VABHTTPInterface<AASAggregatorProvider> {
- private static final long serialVersionUID = 1244938902937878401L;
-
- public AASServerServlet() {
- super(new AASAggregatorProvider(new AASAggregator()));
- }
-
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/AASServerComponent.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/AASServerComponent.java
new file mode 100644
index 0000000..19efa27
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/AASServerComponent.java
@@ -0,0 +1,347 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.aas;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Collection;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.catalina.servlets.DefaultServlet;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.eclipse.basyx.aas.aggregator.AASAggregator;
+import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
+import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.aas.restapi.api.IAASAPIFactory;
+import org.eclipse.basyx.aas.restapi.vab.VABAASAPIFactory;
+import org.eclipse.basyx.components.IComponent;
+import org.eclipse.basyx.components.aas.aasx.AASXPackageManager;
+import org.eclipse.basyx.components.aas.aasx.SubmodelFileEndpointLoader;
+import org.eclipse.basyx.components.aas.configuration.AASServerBackend;
+import org.eclipse.basyx.components.aas.configuration.BaSyxAASServerConfiguration;
+import org.eclipse.basyx.components.aas.mongodb.MongoDBAASAggregator;
+import org.eclipse.basyx.components.aas.mqtt.MqttSubmodelAPIFactory;
+import org.eclipse.basyx.components.aas.servlet.AASAggregatorServlet;
+import org.eclipse.basyx.components.configuration.BaSyxConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxMongoDBConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxMqttConfiguration;
+import org.eclipse.basyx.components.json.JSONAASBundleFactory;
+import org.eclipse.basyx.components.xml.XMLAASBundleFactory;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPIFactory;
+import org.eclipse.basyx.support.bundle.AASBundle;
+import org.eclipse.basyx.support.bundle.AASBundleDescriptorFactory;
+import org.eclipse.basyx.support.bundle.AASBundleHelper;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxHTTPServer;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.SAXException;
+
+/**
+ * Component providing an empty AAS server that is able to receive AAS/SMs from
+ * remote. It uses the Aggregator API, i.e. AAS should be pushed to
+ * ${URL}/shells
+ *
+ * @author schnicke, espen
+ *
+ */
+public class AASServerComponent implements IComponent {
+ private static Logger logger = LoggerFactory.getLogger(AASServerComponent.class);
+
+ // The server with the servlet that will be created
+ private BaSyxHTTPServer server;
+ private IAASRegistry registry;
+
+ // Configurations
+ private BaSyxContextConfiguration contextConfig;
+ private BaSyxAASServerConfiguration aasConfig;
+ private BaSyxMongoDBConfiguration mongoDBConfig;
+ private BaSyxMqttConfiguration mqttConfig;
+
+ // Initial AASBundle
+ protected Collection<AASBundle> aasBundles;
+
+ /**
+ * Constructs an empty AAS server using the passed context
+ */
+ public AASServerComponent(BaSyxContextConfiguration contextConfig) {
+ this.contextConfig = contextConfig;
+ this.aasConfig = new BaSyxAASServerConfiguration();
+ }
+
+ /**
+ * Constructs an empty AAS server using the passed configuration
+ */
+ public AASServerComponent(BaSyxContextConfiguration contextConfig, BaSyxAASServerConfiguration aasConfig) {
+ this.contextConfig = contextConfig;
+ this.aasConfig = aasConfig;
+ }
+
+ /**
+ * Constructs an empty AAS server using the passed configuration
+ */
+ public AASServerComponent(BaSyxContextConfiguration contextConfig, BaSyxAASServerConfiguration aasConfig,
+ BaSyxMongoDBConfiguration mongoDBConfig) {
+ this.contextConfig = contextConfig;
+ this.aasConfig = aasConfig;
+ this.aasConfig.setAASBackend(AASServerBackend.MONGODB);
+ this.mongoDBConfig = mongoDBConfig;
+ }
+
+ /**
+ * Sets and enables mqtt connection configuration for this component. Has to be called before the component is
+ * started. Currently only works for InMemory backend.
+ *
+ * @param configuration
+ */
+ public void enableMQTT(BaSyxMqttConfiguration configuration) {
+ this.mqttConfig = configuration;
+ }
+
+ /**
+ * Disables mqtt configuration. Has to be called before the component is started.
+ */
+ public void disableMQTT() {
+ this.mqttConfig = null;
+ }
+
+ /**
+ * Sets a registry service for registering AAS that are created during startup
+ *
+ * @param registry
+ */
+ public void setRegistry(IAASRegistry registry) {
+ this.registry = registry;
+ }
+
+ /**
+ * Starts the AASX component at http://${hostName}:${port}/${path}
+ */
+ @Override
+ public void startComponent() {
+ logger.info("Create the server...");
+ // Load the aggregator servlet
+ createRegistryFromUrl();
+ AASAggregatorServlet aggregatorServlet = loadAggregatorServlet();
+
+ // Init HTTP context and add an XMLAASServlet according to the configuration
+ BaSyxContext context = contextConfig.createBaSyxContext();
+ context.addServletMapping("/*", aggregatorServlet);
+
+
+ // An initial AAS has been loaded from the drive?
+ if (aasBundles != null) {
+ // 1. Also provide the files
+ context.addServletMapping("/files/*", new DefaultServlet());
+
+ // 2. Fix the file paths according to the servlet configuration
+ modifyFilePaths(contextConfig.getHostname(), contextConfig.getPort(), contextConfig.getContextPath());
+
+ // 3. Register the initial AAS
+ registerAAS();
+ }
+
+ logger.info("Start the server");
+ server = new BaSyxHTTPServer(context);
+ server.start();
+ }
+
+ /**
+ * Retrieves the URL on which the component is providing its HTTP server
+ *
+ * @return
+ */
+ public String getURL() {
+ return contextConfig.getUrl();
+ }
+
+ @Override
+ public void stopComponent() {
+
+ // Remove all AASs/SMs that were registered on startup
+ AASBundleHelper.deregister(registry, aasBundles);
+
+ server.shutdown();
+ }
+
+ private String loadBundleString(String filePath) throws IOException {
+ String content;
+ try {
+ content = new String(Files.readAllBytes(Paths.get(filePath)));
+ } catch (IOException e) {
+ logger.info("Could not find a corresponding file. Loading from default resource.");
+ content = BaSyxConfiguration.getResourceString(filePath);
+ }
+ return content;
+ }
+
+ private void loadBundleFromXML(String xmlPath) throws IOException, ParserConfigurationException, SAXException {
+ logger.info("Loading aas from xml \"" + xmlPath + "\"");
+ String xmlContent = loadBundleString(xmlPath);
+ this.aasBundles = new XMLAASBundleFactory(xmlContent).create();
+ }
+
+ private void loadBundleFromJSON(String jsonPath) throws IOException {
+ logger.info("Loading aas from json \"" + jsonPath + "\"");
+ String jsonContent = loadBundleString(jsonPath);
+ this.aasBundles = new JSONAASBundleFactory(jsonContent).create();
+ }
+
+ private void loadBundleFromAASX(String aasxPath)
+ throws IOException, ParserConfigurationException, SAXException, URISyntaxException, InvalidFormatException {
+ logger.info("Loading aas from aasx \"" + aasxPath + "\"");
+
+ // Instantiate the aasx package manager
+ AASXPackageManager packageManager = new AASXPackageManager(aasxPath);
+
+ // Unpack the files referenced by the aas
+ packageManager.unzipRelatedFiles();
+
+ // Retrieve the aas from the package
+ this.aasBundles = packageManager.retrieveAASBundles();
+ }
+
+ private AASAggregatorServlet loadAggregatorServlet() {
+ // Load the initial AAS bundles from given source
+ loadAASFromSource(aasConfig.getAASSource());
+
+ // Load the aggregator
+ IAASAggregator aggregator = loadAASAggregator();
+
+ // Integrate the loaded bundles into the aggregator
+ if (aasBundles != null) {
+ AASBundleHelper.integrate(aggregator, aasBundles);
+ }
+
+ // Return the servlet for the resulting aggregator
+ return new AASAggregatorServlet(aggregator);
+ }
+
+ private void loadAASFromSource(String aasSource) {
+ if (aasSource.isEmpty()) {
+ return;
+ }
+
+ try {
+ if (aasSource.endsWith(".aasx")) {
+ loadBundleFromAASX(aasSource);
+ } else if (aasSource.endsWith(".json")) {
+ loadBundleFromJSON(aasSource);
+ } else if (aasSource.endsWith(".xml")) {
+ loadBundleFromXML(aasSource);
+ }
+ } catch (IOException | ParserConfigurationException | SAXException | URISyntaxException | InvalidFormatException e) {
+ logger.error("Could not load initial AAS from source '" + aasSource + "'");
+ logger.info("Starting empty server instead");
+ }
+ }
+
+ /**
+ * Only creates the registry, if it hasn't been set explicitly before
+ */
+ private void createRegistryFromUrl() {
+ if (this.registry != null) {
+ // Do not overwrite an explicitly set registry
+ return;
+ }
+ // Load registry url from config
+ String registryUrl = this.aasConfig.getRegistry();
+ if (registryUrl != null && !registryUrl.isEmpty()) {
+ registry = new AASRegistryProxy(registryUrl);
+ logger.info("Registry loaded at \"" + registryUrl + "\"");
+ }
+ }
+
+ private void registerAAS() {
+ if (registry != null) {
+ Set<AASDescriptor> descriptors = retrieveDescriptors(contextConfig.getUrl());
+ descriptors.stream().forEach(registry::register);
+ } else {
+ logger.info("No registry specified, skipped registration");
+ }
+ }
+
+ /**
+ * Returns the set of AAS descriptors for the AAS contained in the AASX
+ *
+ * @param hostBasePath
+ * the path to the server; helper method for e.g. virtualization
+ * environments
+ * @return
+ */
+ private Set<AASDescriptor> retrieveDescriptors(String hostBasePath) {
+ // Base path + aggregator accessor
+ final String fullBasePath = hostBasePath + "/" + AASAggregatorProvider.PREFIX;
+
+ return aasBundles.stream().map(b -> AASBundleDescriptorFactory.createAASDescriptor(b, fullBasePath))
+ .collect(Collectors.toSet());
+ }
+
+ /**
+ * Fixes the File submodel element value paths according to the given endpoint configuration
+ */
+ private void modifyFilePaths(String hostName, int port, String rootPath) {
+ rootPath = rootPath + "/files";
+ for (AASBundle bundle : aasBundles) {
+ Set<ISubmodel> submodels = bundle.getSubmodels();
+ for (ISubmodel sm : submodels) {
+ SubmodelFileEndpointLoader.setRelativeFileEndpoints(sm, hostName, port, rootPath);
+ }
+ }
+ }
+
+ /**
+ * Loads a aas aggregator servlet with a backend according to the configuration
+ *
+ * @return
+ */
+ private IAASAggregator loadAASAggregator() {
+ // Get aggregator according to backend config
+ AASServerBackend backendType = aasConfig.getAASBackend();
+ IAASAggregator aggregator = null;
+ if (backendType == AASServerBackend.INMEMORY && mqttConfig == null) {
+ logger.info("Using InMemory backend");
+ aggregator = new AASAggregator(registry);
+ } else if (backendType == AASServerBackend.INMEMORY && mqttConfig != null) {
+ logger.info("Using InMemory backend with MQTT providers");
+ IAASAPIFactory aasApiProvider = new VABAASAPIFactory();
+ ISubmodelAPIFactory smApiProvider = new MqttSubmodelAPIFactory(mqttConfig);
+ aggregator = new AASAggregator(aasApiProvider, smApiProvider, registry);
+ } else if ( backendType == AASServerBackend.MONGODB ) {
+ logger.info("Using MongoDB backend");
+ aggregator = loadMongoDBAggregator();
+ }
+
+ return aggregator;
+ }
+
+ private IAASAggregator loadMongoDBAggregator() {
+ BaSyxMongoDBConfiguration config;
+ if (this.mongoDBConfig == null) {
+ config = new BaSyxMongoDBConfiguration();
+ config.loadFromDefaultSource();
+ } else {
+ config = this.mongoDBConfig;
+ }
+ MongoDBAASAggregator aggregator = new MongoDBAASAggregator(config);
+ aggregator.setRegistry(registry);
+ return aggregator;
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/aasx/AASXPackageManager.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/aasx/AASXPackageManager.java
new file mode 100644
index 0000000..4f8179b
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/aasx/AASXPackageManager.java
@@ -0,0 +1,285 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.aas.aasx;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
+import org.apache.poi.openxml4j.opc.PackagingURIHelper;
+import org.eclipse.basyx.components.configuration.BaSyxConfiguration;
+import org.eclipse.basyx.components.xml.XMLAASBundleFactory;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IFile;
+import org.eclipse.basyx.support.bundle.AASBundle;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.SAXException;
+
+/**
+ * The AASX package converter converts a aasx package into a list of aas, a list
+ * of submodels a list of assets, a list of Concept descriptions
+ *
+ * The aas provides the references to the submodels and assets
+ *
+ * @author zhangzai, conradi
+ *
+ */
+public class AASXPackageManager {
+
+
+ private static final String XML_TYPE = "http://www.admin-shell.io/aasx/relationships/aas-spec";
+ private static final String AASX_ORIGIN = "/aasx/aasx-origin";
+
+
+ /**
+ * Path to the AASX package
+ */
+ private String aasxPath;
+
+ /**
+ * AAS bundle factory
+ */
+ private XMLAASBundleFactory bundleFactory;
+
+ /**
+ * Cache for generated Bundles
+ */
+ private Set<AASBundle> bundles;
+
+ /**
+ * Logger
+ */
+ private static Logger logger = LoggerFactory.getLogger(AASXPackageManager.class);
+
+ /**
+ * Constructor
+ */
+ public AASXPackageManager(String path) {
+ aasxPath = path;
+ }
+
+ public Set<AASBundle> retrieveAASBundles() throws IOException, ParserConfigurationException, SAXException, InvalidFormatException {
+
+ // If the XML was already parsed return cached Bundles
+ if(bundles != null) {
+ return bundles;
+ }
+
+ OPCPackage aasxRoot = OPCPackage.open(getInputStream(aasxPath));
+
+ bundleFactory = new XMLAASBundleFactory(getXMLResourceString(aasxRoot));
+
+ bundles = bundleFactory.create();
+
+ return bundles;
+ }
+
+ /**
+ * Return the Content of the xml file in the aasx-package as String
+ *
+ * @param aasxPackage - the root package of the AASX
+ * @return Content of XML as String
+ * @throws InvalidFormatException
+ * @throws IOException
+ */
+ private String getXMLResourceString(OPCPackage aasxPackage) throws InvalidFormatException, IOException {
+
+ // Get the "/aasx/aasx-origin" Part. It is Relationship source for the XML-Document
+ PackagePart originPart = aasxPackage.getPart(PackagingURIHelper.createPartName(AASX_ORIGIN));
+
+ // Get the Relation to the XML Document
+ PackageRelationshipCollection originRelationships = originPart.getRelationshipsByType(XML_TYPE);
+
+
+ // If there is more than one or no XML-Document that is an error
+ if(originRelationships.size() > 1) {
+ throw new RuntimeException("More than one 'aasx-spec' document found in .aasx");
+ } else if(originRelationships.size() == 0) {
+ throw new RuntimeException("No 'aasx-spec' document found in .aasx");
+ }
+
+ // Get the PackagePart of the XML-Document
+ PackagePart xmlPart = originPart.getRelatedPart(originRelationships.getRelationship(0));
+
+ // Read the content from the PackagePart
+ InputStream stream = xmlPart.getInputStream();
+ StringWriter writer = new StringWriter();
+ IOUtils.copy(stream, writer, StandardCharsets.UTF_8);
+ return writer.toString();
+ }
+
+ /**
+ * Load the referenced filepaths in the submodels such as PDF, PNG files from
+ * the package
+ *
+ * @return a map of the folder name and folder path, the folder holds the files
+ * @throws IOException
+ * @throws SAXException
+ * @throws ParserConfigurationException
+ * @throws InvalidFormatException
+ *
+ */
+ private List<String> parseReferencedFilePathsFromAASX()
+ throws IOException, ParserConfigurationException, SAXException, InvalidFormatException {
+
+ Set<AASBundle> bundles = retrieveAASBundles();
+
+ List<ISubmodel> submodels = new ArrayList<>();
+
+ // Get the Submodels from all AASBundles
+ for(AASBundle bundle: bundles) {
+ submodels.addAll(bundle.getSubmodels());
+ }
+
+ List<String> paths = new ArrayList<String>();
+
+ for(ISubmodel sm: submodels) {
+ paths.addAll(parseElements(sm.getSubmodelElements().values()));
+ }
+ return paths;
+ }
+
+ /**
+ * Gets the paths from a collection of ISubmodelElement
+ *
+ * @param elements
+ * @return the Paths from the File elements
+ */
+ private List<String> parseElements(Collection<ISubmodelElement> elements) {
+ List<String> paths = new ArrayList<String>();
+
+ for(ISubmodelElement element: elements) {
+ if(element instanceof IFile) {
+ IFile file = (IFile) element;
+ // If the path contains a "://", we can assume, that the Path is a link to an other server
+ // e.g. http://localhost:8080/aasx/...
+ if(!file.getValue().contains("://")) {
+ paths.add(file.getValue());
+ }
+ }
+ else if(element instanceof ISubmodelElementCollection) {
+ ISubmodelElementCollection collection = (ISubmodelElementCollection) element;
+ paths.addAll(parseElements(collection.getSubmodelElements().values()));
+ }
+ }
+ return paths;
+ }
+
+ /**
+ * Unzips all files referenced by the aasx file according to its relationships
+ *
+ *
+ * @throws IOException
+ * @throws SAXException
+ * @throws ParserConfigurationException
+ * @throws URISyntaxException
+ * @throws InvalidFormatException
+ */
+ public void unzipRelatedFiles()
+ throws IOException, ParserConfigurationException, SAXException, URISyntaxException, InvalidFormatException {
+ // load folder which stores the files
+ List<String> files = parseReferencedFilePathsFromAASX();
+ OPCPackage aasxRoot = OPCPackage.open(getInputStream(aasxPath));
+ for (String filePath : files) {
+ // name of the folder
+ unzipFile(filePath, aasxRoot);
+ }
+ }
+
+ /**
+ * Create a folder to hold the unpackaged files The folder has the path
+ * \target\classes\docs
+ *
+ * @throws IOException
+ * @throws URISyntaxException
+ */
+ private Path getRootFolder() throws IOException, URISyntaxException {
+ URI uri = AASXPackageManager.class.getProtectionDomain().getCodeSource().getLocation().toURI();
+ URI parent = new File(uri).getParentFile().toURI();
+ return Paths.get(parent);
+ }
+
+ /**
+ * unzip the file folders
+ *
+ * @param filePath - path of the file in the aasx to unzip
+ * @param aasxPath - aasx path
+ * @throws IOException
+ * @throws URISyntaxException
+ * @throws InvalidFormatException
+ */
+ private void unzipFile(String filePath, OPCPackage aasxRoot) throws IOException, URISyntaxException, InvalidFormatException {
+ // Create destination directory
+ if (filePath.startsWith("/")) {
+ filePath = filePath.substring(1);
+ }
+ if(filePath.isEmpty()) {
+ logger.warn("A file with empty path can not be unzipped.");
+ return;
+ }
+ logger.info("Unzipping " + filePath + " to root folder:");
+ String relativePath = "files/" + VABPathTools.getParentPath(filePath);
+ Path rootPath = getRootFolder();
+ Path destDir = rootPath.resolve(relativePath);
+ logger.info("Unzipping to " + destDir);
+ Files.createDirectories(destDir);
+
+ PackagePart part = aasxRoot.getPart(PackagingURIHelper.createPartName("/" + filePath));
+
+ if(part == null) {
+ logger.warn("File '" + filePath + "' could not be unzipped. It does not exist in .aasx.");
+ return;
+ }
+
+ String targetPath = destDir.toString() + "/" + VABPathTools.getLastElement(filePath);
+ InputStream stream = part.getInputStream();
+ FileUtils.copyInputStreamToFile(stream, new File(targetPath));
+ }
+
+ private InputStream getInputStream(String aasxFilePath) throws IOException {
+ InputStream stream = BaSyxConfiguration.getResourceStream(aasxFilePath);
+ if(stream != null) {
+ return stream;
+ } else {
+ // Alternativ, if resource has not been found: load from a file
+ try {
+ return new FileInputStream(aasxFilePath);
+ } catch (FileNotFoundException e) {
+ logger.error("File '" + aasxFilePath + "' to be loaded was not found.");
+ throw e;
+ }
+ }
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/aasx/SubmodelFileEndpointLoader.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/aasx/SubmodelFileEndpointLoader.java
new file mode 100644
index 0000000..b539ade
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/aasx/SubmodelFileEndpointLoader.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.aas.aasx;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Map;
+
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
+
+/**
+ * A utility class for configuring file endpoints in submodels
+ *
+ * @author espen
+ *
+ */
+public class SubmodelFileEndpointLoader {
+ /**
+ * Sets all file and blob submodelElements inside of the submodel to an endpoint at a given host relative
+ * to its original path.
+ *
+ * @param submodel
+ * @param host e.g. localhost
+ * @param port port for the host
+ * @param path path at which the files are hosted on the host (e.g. "/files")
+ */
+ public static void setRelativeFileEndpoints(ISubmodel submodel, String host, int port, String path) {
+ String fileRoot = "http://" + host + ":" + port + path;
+ setRelativeFileEndpoints(submodel, fileRoot);
+ }
+
+ /**
+ * Sets all file and blob submodelElements inside of the submodel to an endpoint at a given host relative
+ * to its original path.
+ *
+ * @param submodel
+ * @param fileRoot the full root path for the files (e.g. "http://localhost:1234/myFiles")
+ */
+ public static void setRelativeFileEndpoints(ISubmodel submodel, String fileRoot) {
+ Map<String, ISubmodelElement> elements = submodel.getSubmodelElements();
+ setMapEndpoints(elements, fileRoot);
+ }
+
+ /**
+ * Fixes endpoints in a Map of submodel elements (applicable for Submodels and SubmodelElementCollections)
+ *
+ * @param elements
+ * @param fileRoot
+ */
+ private static void setMapEndpoints(Map<String, ISubmodelElement> elements, String fileRoot) {
+ elements.values().stream().forEach(e -> {
+ if (e instanceof File) {
+ File file = (File) e;
+ setFileEndpoint(file, fileRoot);
+ } else if (e instanceof ISubmodelElementCollection) {
+ SubmodelElementCollection col = (SubmodelElementCollection) e;
+ setMapEndpoints(col.getSubmodelElements(), fileRoot);
+ }
+ });
+ }
+
+ /**
+ * Modifies the file value endpoint in a single given file according to a new file root path
+ *
+ * @param file
+ * @param fileRoot
+ */
+ private static void setFileEndpoint(File file, String fileRoot) {
+ String relativePath = file.getValue();
+ URL url;
+ try {
+ url = new URL(file.getValue());
+ relativePath = url.getPath();
+ } catch (MalformedURLException e1) {
+ // assume that the file value is already a relative path
+ }
+ String newEndpoint = fileRoot + relativePath;
+ file.setValue(newEndpoint);
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/configuration/AASEventBackend.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/configuration/AASEventBackend.java
new file mode 100644
index 0000000..45b60bc
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/configuration/AASEventBackend.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.aas.configuration;
+
+import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnumHelper;
+
+import com.google.common.base.Strings;
+
+/**
+ * Possible types for AAS event backends.
+ *
+ * @author espen
+ *
+ */
+public enum AASEventBackend {
+ /**
+ * Enum values of KeyElements
+ */
+ NONE("NONE"), MQTT("MQTT");
+
+ private String literal;
+
+ private AASEventBackend(String literal) {
+ this.literal = literal;
+ }
+
+ @Override
+ public String toString() {
+ return literal;
+ }
+
+ /**
+ * Method to transform string literal to AAS event enum.
+ *
+ * @see StandardizedLiteralEnumHelper StandardizedLiteralEnumHelper
+ *
+ * @param literal
+ * @return
+ */
+ public static AASEventBackend fromString(String literal) {
+ if (Strings.isNullOrEmpty(literal)) {
+ return null;
+ }
+
+ AASEventBackend[] enumConstants = AASEventBackend.class.getEnumConstants();
+ for (AASEventBackend constant : enumConstants) {
+ if (constant.toString().equals(literal)) {
+ return constant;
+ }
+ }
+ throw new IllegalArgumentException("The literal '" + literal + "' is not a valid EventBackend");
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/configuration/AASServerBackend.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/configuration/AASServerBackend.java
new file mode 100644
index 0000000..30c0d36
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/configuration/AASServerBackend.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.aas.configuration;
+
+import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnumHelper;
+
+import com.google.common.base.Strings;
+
+/**
+ * Possible types for AAS backends.
+ *
+ * @author espen
+ *
+ */
+public enum AASServerBackend {
+ /**
+ * Enum values of KeyElements
+ */
+ INMEMORY("InMemory"),
+ MONGODB("MongoDB");
+
+ private String literal;
+
+ private AASServerBackend(String literal) {
+ this.literal = literal;
+ }
+
+ @Override
+ public String toString() {
+ return literal;
+ }
+
+ /**
+ * Method to transform string literal to AASBackend enum.
+ *
+ * @see StandardizedLiteralEnumHelper StandardizedLiteralEnumHelper
+ *
+ * @param literal
+ * @return
+ */
+ public static AASServerBackend fromString(String literal) {
+ if (Strings.isNullOrEmpty(literal)) {
+ return null;
+ }
+
+ AASServerBackend[] enumConstants = AASServerBackend.class.getEnumConstants();
+ for (AASServerBackend constant : enumConstants) {
+ if (constant.toString().equals(literal)) {
+ return constant;
+ }
+ }
+ throw new IllegalArgumentException("The literal '" + literal + "' is not a valid RegistryBackend");
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/configuration/BaSyxAASServerConfiguration.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/configuration/BaSyxAASServerConfiguration.java
new file mode 100644
index 0000000..df49876
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/configuration/BaSyxAASServerConfiguration.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.aas.configuration;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.basyx.components.configuration.BaSyxConfiguration;
+
+/**
+ * Represents a BaSyx server configuration for an AAS Server with any backend,
+ * that can be loaded from a properties file.
+ *
+ * @author espen
+ *
+ */
+public class BaSyxAASServerConfiguration extends BaSyxConfiguration {
+ // Prefix for environment variables
+ public static final String ENV_PREFIX = "BaSyxAAS_";
+
+ // Default BaSyx AAS configuration
+ public static final String DEFAULT_BACKEND = AASServerBackend.INMEMORY.toString();
+ public static final String DEFAULT_SOURCE = "";
+ public static final String DEFAULT_REGISTRY = "";
+ public static final String DEFAULT_EVENTS = AASEventBackend.NONE.toString();
+
+ // Configuration keys
+ public static final String REGISTRY = "registry.path";
+ public static final String BACKEND = "aas.backend";
+ public static final String SOURCE = "aas.source";
+ public static final String EVENTS = "aas.events";
+
+ // The default path for the context properties file
+ public static final String DEFAULT_CONFIG_PATH = "aas.properties";
+
+ // The default key for variables pointing to the configuration file
+ public static final String DEFAULT_FILE_KEY = "BASYX_AAS";
+
+ public static Map<String, String> getDefaultProperties() {
+ Map<String, String> defaultProps = new HashMap<>();
+ defaultProps.put(BACKEND, DEFAULT_BACKEND);
+ defaultProps.put(SOURCE, DEFAULT_SOURCE);
+ defaultProps.put(REGISTRY, DEFAULT_REGISTRY);
+ defaultProps.put(EVENTS, DEFAULT_EVENTS);
+ return defaultProps;
+ }
+
+ /**
+ * Empty Constructor - use default values
+ */
+ public BaSyxAASServerConfiguration() {
+ super(getDefaultProperties());
+ }
+
+ /**
+ * Constructor with initial configuration
+ *
+ * @param backend
+ * The backend for the AASServer
+ * @param source
+ * The file source for the AASServer (e.g. an .aasx file)
+ */
+ public BaSyxAASServerConfiguration(AASServerBackend backend, String source) {
+ super(getDefaultProperties());
+ setAASBackend(backend);
+ setAASSource(source);
+ }
+
+ /**
+ * Constructor with initial configuration values
+ *
+ * @param backend
+ * The backend for the AASServer
+ * @param source
+ * The file source for the AASServer (e.g. an .aasx file)
+ * @param registryUrl
+ * The url to the registry
+ */
+ public BaSyxAASServerConfiguration(AASServerBackend backend, String source, String registryUrl) {
+ super(getDefaultProperties());
+ setAASBackend(backend);
+ setAASSource(source);
+ setRegistry(registryUrl);
+ }
+
+ /**
+ * Constructor with predefined value map
+ */
+ public BaSyxAASServerConfiguration(Map<String, String> values) {
+ super(values);
+ }
+
+ public void loadFromEnvironmentVariables() {
+ String[] properties = { REGISTRY, BACKEND, SOURCE, EVENTS };
+ loadFromEnvironmentVariables(ENV_PREFIX, properties);
+ }
+
+ public void loadFromDefaultSource() {
+ loadFileOrDefaultResource(DEFAULT_FILE_KEY, DEFAULT_CONFIG_PATH);
+ loadFromEnvironmentVariables();
+ }
+
+ public AASServerBackend getAASBackend() {
+ return AASServerBackend.fromString(getProperty(BACKEND));
+ }
+
+ public void setAASBackend(AASServerBackend backend) {
+ setProperty(BACKEND, backend.toString());
+ }
+
+ public AASEventBackend getAASEvents() {
+ return AASEventBackend.fromString(getProperty(EVENTS));
+ }
+
+ public void setAASEvents(AASEventBackend events) {
+ setProperty(EVENTS, events.toString());
+ }
+
+ public String getAASSource() {
+ return getProperty(SOURCE);
+ }
+
+ public void setAASSource(String source) {
+ setProperty(SOURCE, source);
+ }
+
+ public String getRegistry() {
+ return getProperty(REGISTRY);
+ }
+
+ public void setRegistry(String registryPath) {
+ setProperty(REGISTRY, registryPath);
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/executable/AASServerExecutable.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/executable/AASServerExecutable.java
new file mode 100644
index 0000000..58527c2
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/executable/AASServerExecutable.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.aas.executable;
+
+import java.io.File;
+import java.net.URISyntaxException;
+
+import org.eclipse.basyx.components.aas.AASServerComponent;
+import org.eclipse.basyx.components.aas.configuration.AASEventBackend;
+import org.eclipse.basyx.components.aas.configuration.BaSyxAASServerConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxMqttConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Starts an HTTP server that is able to receive AAS and submodels pushed from
+ * remote <br />
+ * They are made available at
+ * <i>localhost:4000/aasServer/shells/${aasId}/aas</i>. Submodels are available
+ * at
+ * <i>localhost:4000/aasServer/shells/${aasId}/submodels/${submodelId}/submodel</i><br
+ * />
+ *
+ * @author schnicke, espen
+ */
+public class AASServerExecutable {
+ // Creates a Logger based on the current class
+ private static Logger logger = LoggerFactory.getLogger(AASServerExecutable.class);
+
+ public static void main(String[] args) throws URISyntaxException {
+ logger.info("Starting BaSyx AASServer component...");
+ // Load context configuration
+ BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
+ contextConfig.loadFromDefaultSource();
+
+ // Load aas configuration
+ BaSyxAASServerConfiguration aasConfig = new BaSyxAASServerConfiguration();
+ aasConfig.loadFromDefaultSource();
+
+ // Load the additional file path relative to the executed jar file
+ String rootPath = new File(AASServerExecutable.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getParentFile().getPath();
+ String docBasePath = rootPath;
+ contextConfig.setDocBasePath(docBasePath);
+
+ AASServerComponent component = new AASServerComponent(contextConfig, aasConfig);
+
+ // If enabled, load mqtt configuration
+ if (aasConfig.getAASEvents().equals(AASEventBackend.MQTT)) {
+ BaSyxMqttConfiguration mqttConfig = new BaSyxMqttConfiguration();
+ mqttConfig.loadFromDefaultSource();
+ component.enableMQTT(mqttConfig);
+ }
+
+ component.startComponent();
+
+ logger.info("BaSyx AAS Server component started");
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/mongodb/MongoDBAASAPI.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/mongodb/MongoDBAASAPI.java
new file mode 100644
index 0000000..6ae87c1
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/mongodb/MongoDBAASAPI.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.aas.mongodb;
+
+import static org.springframework.data.mongodb.core.query.Criteria.where;
+import static org.springframework.data.mongodb.core.query.Query.query;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.restapi.api.IAASAPI;
+import org.eclipse.basyx.components.configuration.BaSyxMongoDBConfiguration;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Query;
+
+import com.mongodb.client.MongoClient;
+import com.mongodb.client.MongoClients;
+
+/**
+ * Implements the IAASAPI for a mongoDB backend.
+ *
+ * @author espen
+ */
+public class MongoDBAASAPI implements IAASAPI {
+ private static final String DEFAULT_CONFIG_PATH = "mongodb.properties";
+ private static final String AASIDPATH = Identifiable.IDENTIFICATION + "." + Identifier.ID;
+
+ protected BaSyxMongoDBConfiguration config;
+ protected MongoOperations mongoOps;
+ protected String collection;
+ protected String aasId;
+
+ /**
+ * Receives the path of the configuration.properties file in it's constructor.
+ *
+ * @param configFilePath
+ */
+ public MongoDBAASAPI(BaSyxMongoDBConfiguration config, String aasId) {
+ this.setConfiguration(config);
+ this.setAASId(aasId);
+ }
+
+ /**
+ * Receives the path of the .properties file in it's constructor from a resource.
+ */
+ public MongoDBAASAPI(String resourceConfigPath, String aasId) {
+ config = new BaSyxMongoDBConfiguration();
+ config.loadFromResource(resourceConfigPath);
+ this.setConfiguration(config);
+ this.setAASId(aasId);
+ }
+
+ /**
+ * Constructor using default sql connections
+ */
+ public MongoDBAASAPI(String aasId) {
+ this(DEFAULT_CONFIG_PATH, aasId);
+ }
+
+ public void setConfiguration(BaSyxMongoDBConfiguration config) {
+ this.config = config;
+ MongoClient client = MongoClients.create(config.getConnectionUrl());
+ this.mongoOps = new MongoTemplate(client, config.getDatabase());
+ this.collection = config.getAASCollection();
+ }
+
+ /**
+ * Sets the aas id, so that this API points to the aas with aasId. Can be changed
+ * to point to a different aas in the database.
+ *
+ * @param smId
+ */
+ public void setAASId(String aasId) {
+ this.aasId = aasId;
+ }
+
+ /**
+ * Depending on whether the model is already in the db, this method inserts or replaces the existing data.
+ * The new aas id for this API is taken from the given aas.
+ *
+ * @param sm
+ */
+ public void setAAS(AssetAdministrationShell aas) {
+ String id = aas.getIdentification().getId();
+ this.setAASId(id);
+
+ Query hasId = query(where(AASIDPATH).is(aasId));
+ // Try to replace if already present - otherwise: insert it
+ Object replaced = mongoOps.findAndReplace(hasId, aas, collection);
+ if (replaced == null) {
+ mongoOps.insert(aas, collection);
+ }
+ }
+
+ @Override
+ public IAssetAdministrationShell getAAS() {
+ Query hasId = query(where(AASIDPATH).is(aasId));
+ AssetAdministrationShell aas = mongoOps.findOne(hasId, AssetAdministrationShell.class, collection);
+ if (aas == null) {
+ throw new ResourceNotFoundException("The AAS " + aasId + " could not be found in the database.");
+ }
+ // Remove mongoDB-specific map attribute from AASDescriptor
+ aas.remove("_id");
+ return aas;
+ }
+
+ @Override
+ public void addSubmodel(IReference submodel) {
+ // Get AAS from db
+ Query hasId = query(where(AASIDPATH).is(aasId));
+ AssetAdministrationShell aas = mongoOps.findOne(hasId, AssetAdministrationShell.class, collection);
+ if (aas == null) {
+ throw new ResourceNotFoundException("The AAS " + aasId + " could not be found in the database.");
+ }
+ // Add reference
+ aas.addSubmodelReference(submodel);
+ // Update db entry
+ mongoOps.findAndReplace(hasId, aas, collection);
+ }
+
+ @Override
+ public void removeSubmodel(String id) {
+ // Get AAS from db
+ Query hasId = query(where(AASIDPATH).is(aasId));
+ AssetAdministrationShell aas = mongoOps.findOne(hasId, AssetAdministrationShell.class, collection);
+ if (aas == null) {
+ throw new ResourceNotFoundException("The AAS " + aasId + " could not be found in the database.");
+ }
+ // Remove reference
+ Collection<IReference> smReferences = aas.getSubmodelReferences();
+ // Reference to submodel could be either by idShort (=> local) or directly via
+ // its identifier
+ for (Iterator<IReference> iterator = smReferences.iterator(); iterator.hasNext();) {
+ IReference ref = iterator.next();
+ List<IKey> keys = ref.getKeys();
+ IKey lastKey = keys.get(keys.size() - 1);
+ String idValue = lastKey.getValue();
+ // remove this reference, if the last key points to the submodel
+ if (idValue.equals(id)) {
+ iterator.remove();
+ break;
+ }
+ }
+ // Update db entry
+ mongoOps.findAndReplace(hasId, aas, collection);
+ }
+
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/mongodb/MongoDBAASAggregator.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/mongodb/MongoDBAASAggregator.java
new file mode 100644
index 0000000..4d3ead9
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/mongodb/MongoDBAASAggregator.java
@@ -0,0 +1,286 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.aas.mongodb;
+
+import static org.springframework.data.mongodb.core.query.Criteria.where;
+import static org.springframework.data.mongodb.core.query.Query.query;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.eclipse.basyx.aas.aggregator.AASAggregator;
+import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.restapi.AASModelProvider;
+import org.eclipse.basyx.aas.restapi.MultiSubmodelProvider;
+import org.eclipse.basyx.aas.restapi.api.IAASAPI;
+import org.eclipse.basyx.aas.restapi.api.IAASAPIFactory;
+import org.eclipse.basyx.components.configuration.BaSyxMongoDBConfiguration;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
+import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI;
+import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPIFactory;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Query;
+
+import com.mongodb.client.MongoClient;
+import com.mongodb.client.MongoClients;
+
+/**
+ * An IAASAggregator for persistent storage in a MongoDB.
+ *
+ * @see AASAggregator AASAggregator for the "InMemory"-variant
+ *
+ * @author espen
+ *
+ */
+public class MongoDBAASAggregator implements IAASAggregator {
+ private static Logger logger = LoggerFactory.getLogger(MongoDBAASAggregator.class);
+
+ private static final String DEFAULT_CONFIG_PATH = "mongodb.properties";
+ private static final String IDSHORTPATH = Referable.IDSHORT;
+ private static final String IDPATH = Identifiable.IDENTIFICATION + "." + Identifier.ID;
+
+ protected Map<String, MultiSubmodelProvider> aasProviderMap = new HashMap<>();
+ protected BaSyxMongoDBConfiguration config;
+ protected MongoOperations mongoOps;
+ protected String aasCollection;
+ protected String smCollection;
+
+ private IAASRegistry registry;
+
+ /**
+ * Store AAS API Provider. By default, uses the MongoDB API Provider
+ */
+ protected IAASAPIFactory aasApiProvider;
+
+ /**
+ * Store Submodel API Provider. By default, uses a MongoDB Submodel Provider
+ */
+ protected ISubmodelAPIFactory smApiProvider;
+
+ /**
+ * Receives the path of the configuration.properties file in it's constructor.
+ *
+ * @param configFilePath
+ */
+ public MongoDBAASAggregator(BaSyxMongoDBConfiguration config) {
+ this.setConfiguration(config);
+ init();
+ }
+
+ public void setRegistry(IAASRegistry registry) {
+ this.registry = registry;
+ }
+
+ /**
+ * Receives the path of the .properties file in it's constructor from a resource.
+ */
+ public MongoDBAASAggregator(String resourceConfigPath) {
+ config = new BaSyxMongoDBConfiguration();
+ config.loadFromResource(resourceConfigPath);
+ this.setConfiguration(config);
+ init();
+ }
+
+ /**
+ * Constructor using default connections
+ */
+ public MongoDBAASAggregator() {
+ this(DEFAULT_CONFIG_PATH);
+ }
+
+ /**
+ * Sets the db configuration for this Aggregator.
+ *
+ * @param config
+ */
+ public void setConfiguration(BaSyxMongoDBConfiguration config) {
+ // set mongoDB configuration
+ this.config = config;
+ MongoClient client = MongoClients.create(config.getConnectionUrl());
+ this.mongoOps = new MongoTemplate(client, config.getDatabase());
+ this.aasCollection = config.getAASCollection();
+ this.smCollection = config.getSubmodelCollection();
+
+ // Create API factories with the given configuration
+ this.aasApiProvider = aas -> {
+ MongoDBAASAPI api = new MongoDBAASAPI(config, aas.getIdentification().getId());
+ api.setAAS(aas);
+ return api;
+ };
+ this.smApiProvider = sm -> {
+ MongoDBSubmodelAPI api = new MongoDBSubmodelAPI(config, sm.getIdentification().getId());
+ api.setSubmodel(sm);
+ return api;
+ };
+ }
+
+ /**
+ * Removes all persistent AAS and submodels
+ */
+ public void reset() {
+ mongoOps.dropCollection(aasCollection);
+ mongoOps.dropCollection(smCollection);
+ aasProviderMap.clear();
+ }
+
+ private void init() {
+ List<AssetAdministrationShell> data = mongoOps.findAll(AssetAdministrationShell.class, aasCollection);
+ for (AssetAdministrationShell aas : data) {
+ String aasId = aas.getIdentification().getId();
+ logger.info("Adding AAS from DB: " + aasId);
+ MongoDBAASAPI aasApi = new MongoDBAASAPI(config, aasId);
+ MultiSubmodelProvider provider = initMultiSubmodelProvider(aasApi);
+ addSubmodelsFromDB(provider, aas);
+ aasProviderMap.put(aas.getIdentification().getId(), provider);
+ }
+ }
+
+ /**
+ * Initializes and returns a VABMultiSubmodelProvider with only the AssetAdministrationShell
+ */
+ private MultiSubmodelProvider initMultiSubmodelProvider(IAASAPI aasApi) {
+ AASModelProvider aasProvider = new AASModelProvider(aasApi);
+ IConnectorFactory connProvider = new HTTPConnectorFactory();
+ MultiSubmodelProvider provider = new MultiSubmodelProvider(aasProvider, registry, connProvider,
+ smApiProvider, aasApiProvider);
+ provider.setAssetAdministrationShell(aasProvider);
+ return provider;
+ }
+
+ /**
+ * Adds submodel providers for submodels in the MongoDB
+ */
+ private void addSubmodelsFromDB(MultiSubmodelProvider provider, AssetAdministrationShell aas) {
+ // Get ids and idShorts from aas
+ Collection<IReference> submodelRefs = aas.getSubmodelReferences();
+ List<String> smIds = new ArrayList<>();
+ List<String> smIdShorts = new ArrayList<>();
+ for (IReference ref : submodelRefs) {
+ List<IKey> keys = ref.getKeys();
+ IKey lastKey = keys.get(keys.size() - 1);
+ if (lastKey.getIdType() == KeyType.IDSHORT) {
+ smIdShorts.add(lastKey.getValue());
+ } else {
+ smIds.add(lastKey.getValue());
+ }
+ }
+
+ // Add submodel ids by id shorts
+ for (String idShort : smIdShorts) {
+ String id = getSubmodelId(idShort);
+ if (id != null) {
+ smIds.add(id);
+ }
+ }
+
+ // Create a provider for each submodel
+ for (String id : smIds) {
+ logger.info("Adding Submodel from DB: " + id);
+ addSubmodelProvidersById(id, provider);
+ }
+ }
+
+ private String getSubmodelId(String idShort) {
+ Submodel sm = mongoOps.findOne(query(where(IDSHORTPATH).is(idShort)), Submodel.class);
+ if ( sm != null ) {
+ return sm.getIdentification().getId();
+ }
+ return null;
+ }
+
+ private void addSubmodelProvidersById(String smId, MultiSubmodelProvider provider) {
+ ISubmodelAPI smApi = new MongoDBSubmodelAPI(smId);
+ SubmodelProvider smProvider = new SubmodelProvider(smApi);
+ provider.addSubmodel(smProvider);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Collection<IAssetAdministrationShell> getAASList() {
+ return aasProviderMap.values().stream().map(p -> {
+ try {
+ return p.getValue("/aas");
+ } catch (Exception e1) {
+ e1.printStackTrace();
+ throw new RuntimeException();
+ }
+ }).map(m -> {
+ AssetAdministrationShell aas = new AssetAdministrationShell();
+ aas.putAll((Map<? extends String, ? extends Object>) m);
+ return aas;
+ }).collect(Collectors.toList());
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public IAssetAdministrationShell getAAS(IIdentifier aasId) {
+ IModelProvider aasProvider = getAASProvider(aasId);
+
+ // get all Elements from provider
+ Map<String, Object> aasMap = (Map<String, Object>) aasProvider.getValue("/aas");
+ return AssetAdministrationShell.createAsFacade(aasMap);
+ }
+
+ @Override
+ public void createAAS(AssetAdministrationShell aas) {
+ IAASAPI aasApi = this.aasApiProvider.getAASApi(aas);
+ MultiSubmodelProvider provider = initMultiSubmodelProvider(aasApi);
+ aasProviderMap.put(aas.getIdentification().getId(), provider);
+ }
+
+ @Override
+ public void updateAAS(AssetAdministrationShell aas) {
+ createAAS(aas);
+ }
+
+ @Override
+ public void deleteAAS(IIdentifier aasId) {
+ Query hasId = query(where(IDPATH).is(aasId));
+ mongoOps.remove(hasId, aasCollection);
+ aasProviderMap.remove(aasId.getId());
+ }
+
+ public MultiSubmodelProvider getProviderForAASId(String aasId) {
+ return aasProviderMap.get(aasId);
+ }
+
+ @Override
+ public IModelProvider getAASProvider(IIdentifier aasId) {
+ MultiSubmodelProvider provider = aasProviderMap.get(aasId.getId());
+
+ if (provider == null) {
+ throw new ResourceNotFoundException("AAS with Id " + aasId.getId() + " does not exist");
+ }
+
+ return provider;
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/mongodb/MongoDBSubmodelAPI.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/mongodb/MongoDBSubmodelAPI.java
new file mode 100644
index 0000000..bdc4b53
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/mongodb/MongoDBSubmodelAPI.java
@@ -0,0 +1,428 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.aas.mongodb;
+
+import static org.springframework.data.mongodb.core.query.Criteria.where;
+import static org.springframework.data.mongodb.core.query.Query.query;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.basyx.components.configuration.BaSyxMongoDBConfiguration;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
+import org.eclipse.basyx.submodel.metamodel.facade.submodelelement.SubmodelElementFacadeFactory;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI;
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Query;
+
+import com.mongodb.client.MongoClient;
+import com.mongodb.client.MongoClients;
+
+/**
+ * Implements the ISubmodelAPI for a mongoDB backend.
+ *
+ * @author espen
+ */
+public class MongoDBSubmodelAPI implements ISubmodelAPI {
+ private static final String DEFAULT_CONFIG_PATH = "mongodb.properties";
+ private static final String SMIDPATH = Identifiable.IDENTIFICATION + "." + Identifier.ID;
+
+ protected BaSyxMongoDBConfiguration config;
+ protected MongoOperations mongoOps;
+ protected String collection;
+ protected String smId;
+
+ /**
+ * Receives the path of the configuration.properties file in it's constructor.
+ *
+ * @param configFilePath
+ */
+ public MongoDBSubmodelAPI(BaSyxMongoDBConfiguration config, String smId) {
+ this.setConfiguration(config);
+ this.setSubmodelId(smId);
+ }
+
+ /**
+ * Receives the path of the .properties file in it's constructor from a resource.
+ */
+ public MongoDBSubmodelAPI(String resourceConfigPath, String smId) {
+ config = new BaSyxMongoDBConfiguration();
+ config.loadFromResource(resourceConfigPath);
+ this.setConfiguration(config);
+ this.setSubmodelId(smId);
+ }
+
+ /**
+ * Constructor using default sql connections
+ */
+ public MongoDBSubmodelAPI(String smId) {
+ this(DEFAULT_CONFIG_PATH, smId);
+ }
+
+ /**
+ * Sets the db configuration for the submodel API.
+ *
+ * @param config
+ */
+ public void setConfiguration(BaSyxMongoDBConfiguration config) {
+ this.config = config;
+ MongoClient client = MongoClients.create(config.getConnectionUrl());
+ this.mongoOps = new MongoTemplate(client, config.getDatabase());
+ this.collection = config.getSubmodelCollection();
+ }
+
+ /**
+ * Sets the submodel id, so that this API points to the submodel with smId. Can be changed
+ * to point to a different submodel in the database.
+ *
+ * @param smId
+ */
+ public void setSubmodelId(String smId) {
+ this.smId = smId;
+ }
+
+ /**
+ * Depending on whether the model is already in the db, this method inserts or replaces the existing data.
+ * The new submodel id for this API is taken from the given submodel.
+ *
+ * @param sm
+ */
+ public void setSubmodel(Submodel sm) {
+ String id = sm.getIdentification().getId();
+ this.setSubmodelId(id);
+
+ Query hasId = query(where(SMIDPATH).is(smId));
+ Object replaced = mongoOps.findAndReplace(hasId, sm, collection);
+ if (replaced == null) {
+ mongoOps.insert(sm, collection);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public ISubmodel getSubmodel() {
+ // Query Submodel from MongoDB
+ Query hasId = query(where(SMIDPATH).is(smId));
+ Submodel result = mongoOps.findOne(hasId, Submodel.class, collection);
+ if (result == null) {
+ throw new ResourceNotFoundException("The submodel " + smId + " could not be found in the database.");
+ }
+
+ // Remove mongoDB-specific map attribute from AASDescriptor
+ result.remove("_id");
+
+ // Cast all SubmodelElement maps to ISubmodelElements before returning the submodel
+ Map<String, ISubmodelElement> elements = new HashMap<>();
+ Map<String, Map<String, Object>> elemMaps = (Map<String, Map<String, Object>>) result
+ .get(Submodel.SUBMODELELEMENT);
+ for (Entry<String, Map<String, Object>> entry : elemMaps.entrySet()) {
+ String shortId = entry.getKey();
+ Map<String, Object> elemMap = entry.getValue();
+ ISubmodelElement element = SubmodelElementFacadeFactory.createSubmodelElement(elemMap);
+ elements.put(shortId, element);
+ }
+ // Replace the element map in the submodel
+ result.put(Submodel.SUBMODELELEMENT, elements);
+ // Return the "fixed" submodel
+ return result;
+ }
+
+ @Override
+ public void addSubmodelElement(ISubmodelElement elem) {
+ // Get sm from db
+ Submodel sm = (Submodel) getSubmodel();
+ // Add element
+ sm.addSubmodelElement(elem);
+ // Replace db entry
+ Query hasId = query(where(SMIDPATH).is(smId));
+ mongoOps.findAndReplace(hasId, sm, collection);
+ }
+
+ private ISubmodelElement getTopLevelSubmodelElement(String idShort) {
+ Submodel sm = (Submodel) getSubmodel();
+ Map<String, ISubmodelElement> submodelElements = sm.getSubmodelElements();
+ ISubmodelElement element = submodelElements.get(idShort);
+ if (element == null) {
+ throw new ResourceNotFoundException("The element \"" + idShort + "\" could not be found");
+ }
+ return convertSubmodelElement(element);
+ }
+
+ @SuppressWarnings("unchecked")
+ private ISubmodelElement convertSubmodelElement(ISubmodelElement element) {
+ // FIXME: Convert internal data structure of ISubmodelElement
+ Map<String, Object> elementMap = (Map<String, Object>) element;
+ IModelProvider elementProvider = new SubmodelElementProvider(new VABMapProvider(elementMap));
+ Object elementVABObj = elementProvider.getValue("");
+ return SubmodelElement.createAsFacade((Map<String, Object>) elementVABObj);
+ }
+
+ private void deleteTopLevelSubmodelElement(String idShort) {
+ // Get sm from db
+ Submodel sm = (Submodel) getSubmodel();
+ // Remove element
+ sm.getSubmodelElements().remove(idShort);
+ // Replace db entry
+ Query hasId = query(where(SMIDPATH).is(smId));
+ mongoOps.findAndReplace(hasId, sm, collection);
+ }
+
+ @Override
+ public Collection<IOperation> getOperations() {
+ Submodel sm = (Submodel) getSubmodel();
+ return sm.getOperations().values();
+ }
+
+
+ private void addNestedSubmodelElement(List<String> idShorts, ISubmodelElement elem) {
+ Submodel sm = (Submodel) getSubmodel();
+ // > 1 idShorts => add new sm element to an existing sm element
+ if (idShorts.size() > 1) {
+ idShorts = idShorts.subList(0, idShorts.size() - 1);
+ // Get parent SM element if more than 1 idShort
+ ISubmodelElement parentElement = getNestedSubmodelElement(sm, idShorts);
+ if (parentElement instanceof SubmodelElementCollection) {
+ ((SubmodelElementCollection) parentElement).addSubmodelElement(elem);
+ // Replace db entry
+ Query hasId = query(where(SMIDPATH).is(smId));
+ mongoOps.findAndReplace(hasId, sm, collection);
+ }
+ } else {
+ // else => directly add it to the submodel
+ sm.addSubmodelElement(elem);
+ // Replace db entry
+ Query hasId = query(where(SMIDPATH).is(smId));
+ mongoOps.findAndReplace(hasId, sm, collection);
+ }
+ }
+
+ @Override
+ public Collection<ISubmodelElement> getSubmodelElements() {
+ Submodel sm = (Submodel) getSubmodel();
+ return sm.getSubmodelElements().values();
+ }
+
+ private void updateTopLevelSubmodelElement(String idShort, Object newValue) {
+ // Get sm from db
+ Submodel sm = (Submodel) getSubmodel();
+ // Unwrap value
+ newValue = unwrapParameter(newValue);
+ // Get and update property value
+ getElementProvider(sm, idShort).setValue(Property.VALUE, newValue);
+ // Replace db entry
+ Query hasId = query(where(SMIDPATH).is(smId));
+ mongoOps.findAndReplace(hasId, sm, collection);
+ }
+
+ @SuppressWarnings("unchecked")
+ private void updateNestedSubmodelElement(List<String> idShorts, Object newValue) {
+ Submodel sm = (Submodel) getSubmodel();
+
+ // Get parent SM element
+ ISubmodelElement element = getNestedSubmodelElement(sm, idShorts);
+
+ // Update value
+ IModelProvider mapProvider = new VABMapProvider((Map<String, Object>) element);
+ IModelProvider elemProvider = SubmodelElementProvider.getElementProvider(mapProvider);
+ elemProvider.setValue(Property.VALUE, newValue);
+
+ // Replace db entry
+ Query hasId = query(where(SMIDPATH).is(smId));
+ mongoOps.findAndReplace(hasId, sm, collection);
+ }
+
+ private Object getTopLevelSubmodelElementValue(String idShort) {
+ Submodel sm = (Submodel) getSubmodel();
+ return getElementProvider(sm, idShort).getValue("/value");
+ }
+
+ @SuppressWarnings("unchecked")
+ private Object getNestedSubmodelElementValue(List<String> idShorts) {
+ ISubmodelElement lastElement = getNestedSubmodelElement(idShorts);
+ IModelProvider mapProvider = new VABMapProvider((Map<String, Object>) lastElement);
+ return SubmodelElementProvider.getElementProvider(mapProvider).getValue("/value");
+ }
+
+ @SuppressWarnings("unchecked")
+ protected Object unwrapParameter(Object parameter) {
+ if (parameter instanceof Map<?, ?>) {
+ Map<String, Object> map = (Map<String, Object>) parameter;
+ // Parameters have a strictly defined order and may not be omitted at all.
+ // Enforcing the structure with valueType is ok, but we should unwrap null values, too.
+ if (map.get("valueType") != null && map.containsKey("value")) {
+ return map.get("value");
+ }
+ }
+ return parameter;
+ }
+
+ @SuppressWarnings("unchecked")
+ private IModelProvider getElementProvider(Submodel sm, String idShort) {
+ ISubmodelElement elem = sm.getSubmodelElements().get(idShort);
+ IModelProvider mapProvider = new VABMapProvider((Map<String, Object>) elem);
+ return SubmodelElementProvider.getElementProvider(mapProvider);
+ }
+
+ private ISubmodelElement getNestedSubmodelElement(Submodel sm, List<String> idShorts) {
+ Map<String, ISubmodelElement> elemMap = sm.getSubmodelElements();
+ // Get last nested submodel element
+ for (int i = 0; i < idShorts.size() - 1; i++) {
+ String idShort = idShorts.get(i);
+ ISubmodelElement elem = elemMap.get(idShort);
+ if (elem instanceof SubmodelElementCollection) {
+ elemMap = ((SubmodelElementCollection) elem).getSubmodelElements();
+ } else {
+ throw new ResourceNotFoundException(
+ idShort + " in the nested submodel element path could not be resolved.");
+ }
+ }
+ String lastIdShort = idShorts.get(idShorts.size() - 1);
+ if (!elemMap.containsKey(lastIdShort)) {
+ throw new ResourceNotFoundException(lastIdShort
+ + " in the nested submodel element path could not be resolved.");
+ }
+ return elemMap.get(lastIdShort);
+ }
+
+ private ISubmodelElement getNestedSubmodelElement(List<String> idShorts) {
+ // Get sm from db
+ Submodel sm = (Submodel) getSubmodel();
+ // Get nested sm element from this sm
+ return convertSubmodelElement(getNestedSubmodelElement(sm, idShorts));
+ }
+
+ private Object invokeTopLevelOperation(String idShort, Object... params) {
+ // not possible to invoke operations on a submodel that is stored in a db
+ throw new MalformedRequestException("Invoke not supported by this backend");
+ }
+
+ private void deleteNestedSubmodelElement(List<String> idShorts) {
+ if ( idShorts.size() == 1 ) {
+ deleteSubmodelElement(idShorts.get(0));
+ return;
+ }
+
+ // Get sm from db
+ Submodel sm = (Submodel) getSubmodel();
+ // Get parent collection
+ List<String> parentIds = idShorts.subList(0, idShorts.size() - 1);
+ ISubmodelElement parentElement = getNestedSubmodelElement(sm, parentIds);
+ // Remove element
+ SubmodelElementCollection coll = (SubmodelElementCollection) parentElement;
+ coll.deleteSubmodelElement(idShorts.get(idShorts.size() - 1));
+ // Replace db entry
+ Query hasId = query(where(SMIDPATH).is(smId));
+ mongoOps.findAndReplace(hasId, sm, collection);
+ }
+
+ private Object invokeNestedOperation(List<String> idShorts, Object... params) {
+ // not possible to invoke operations on a submodel that is stored in a db
+ throw new MalformedRequestException("Invoke not supported by this backend");
+ }
+
+ private Object invokeNestedOperationAsync(List<String> idShorts, Object... params) {
+ // not possible to invoke operations on a submodel that is stored in a db
+ throw new MalformedRequestException("Invoke not supported by this backend");
+ }
+
+ @Override
+ public Object getOperationResult(String idShort, String requestId) {
+ // not possible to invoke operations on a submodel that is stored in a db
+ throw new MalformedRequestException("Invoke not supported by this backend");
+ }
+
+ @Override
+ public ISubmodelElement getSubmodelElement(String idShortPath) {
+ if(idShortPath.contains("/")) {
+ String[] splitted = VABPathTools.splitPath(idShortPath);
+ List<String> idShorts = Arrays.asList(splitted);
+ return getNestedSubmodelElement(idShorts);
+ }else {
+ return getTopLevelSubmodelElement(idShortPath);
+ }
+ }
+
+ @Override
+ public void deleteSubmodelElement(String idShortPath) {
+ if(idShortPath.contains("/")) {
+ String[] splitted = VABPathTools.splitPath(idShortPath);
+ List<String> idShorts = Arrays.asList(splitted);
+ deleteNestedSubmodelElement(idShorts);
+ }else {
+ deleteTopLevelSubmodelElement(idShortPath);
+ }
+ }
+
+ @Override
+ public void updateSubmodelElement(String idShortPath, Object newValue) {
+ if(idShortPath.contains("/")) {
+ String[] splitted = VABPathTools.splitPath(idShortPath);
+ List<String> idShorts = Arrays.asList(splitted);
+ updateNestedSubmodelElement(idShorts, newValue);
+ }else {
+ updateTopLevelSubmodelElement(idShortPath, newValue);
+ }
+ }
+
+ @Override
+ public Object getSubmodelElementValue(String idShortPath) {
+ if(idShortPath.contains("/")) {
+ String[] splitted = VABPathTools.splitPath(idShortPath);
+ List<String> idShorts = Arrays.asList(splitted);
+ return getNestedSubmodelElementValue(idShorts);
+ }else {
+ return getTopLevelSubmodelElementValue(idShortPath);
+ }
+ }
+
+ @Override
+ public Object invokeOperation(String idShortPath, Object... params) {
+ if(idShortPath.contains("/")) {
+ String[] splitted = VABPathTools.splitPath(idShortPath);
+ List<String> idShorts = Arrays.asList(splitted);
+ return invokeNestedOperation(idShorts, params);
+ }else {
+ return invokeTopLevelOperation(idShortPath, params);
+ }
+ }
+
+ @Override
+ public Object invokeAsync(String idShortPath, Object... params) {
+ String[] splitted = VABPathTools.splitPath(idShortPath);
+ List<String> idShorts = Arrays.asList(splitted);
+ return invokeNestedOperationAsync(idShorts, params);
+ }
+
+ @Override
+ public void addSubmodelElement(String idShortPath, ISubmodelElement elem) {
+ String[] splitted = VABPathTools.splitPath(idShortPath);
+ List<String> idShorts = Arrays.asList(splitted);
+ addNestedSubmodelElement(idShorts, elem);
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/mqtt/MqttSubmodelAPIFactory.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/mqtt/MqttSubmodelAPIFactory.java
new file mode 100644
index 0000000..742e033
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/mqtt/MqttSubmodelAPIFactory.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.aas.mqtt;
+
+import java.util.Set;
+
+import org.eclipse.basyx.components.configuration.BaSyxMqttConfiguration;
+import org.eclipse.basyx.extensions.submodel.mqtt.MqttSubmodelAPI;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI;
+import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPIFactory;
+import org.eclipse.basyx.submodel.restapi.vab.VABSubmodelAPI;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
+import org.eclipse.paho.client.mqttv3.MqttException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Api provider for constructing a new Submodel API that emits MQTT events
+ *
+ * @author espen
+ */
+public class MqttSubmodelAPIFactory implements ISubmodelAPIFactory {
+ private static Logger logger = LoggerFactory.getLogger(MqttSubmodelAPIFactory.class);
+
+ private BaSyxMqttConfiguration config;
+
+ /**
+ * Constructor with MQTT configuration for providing submodel APIs
+ *
+ * @param config
+ */
+ public MqttSubmodelAPIFactory(BaSyxMqttConfiguration config) {
+ this.config = config;
+ }
+
+ @Override
+ public ISubmodelAPI getSubmodelAPI(Submodel sm) {
+ // Get the submodel's id from the given provider
+ String smId = sm.getIdentification().getId();
+
+ // Create the API
+ IModelProvider provider = new VABLambdaProvider(sm);
+ VABSubmodelAPI observedApi = new VABSubmodelAPI(provider);
+
+ // Configure the API according to the given configs
+ String brokerEndpoint = config.getServer();
+ String clientId = smId;
+ MqttSubmodelAPI api;
+ try {
+ if (config.getUser() != null) {
+ String user = config.getUser();
+ String pass = config.getPass();
+ api = new MqttSubmodelAPI(observedApi, brokerEndpoint, clientId, user, pass.toCharArray());
+ } else {
+ api = new MqttSubmodelAPI(observedApi, brokerEndpoint, clientId);
+ }
+ setWhitelist(api, smId);
+ } catch (MqttException e) {
+ logger.error("Could not create MqttSubmodelApi", e);
+ return observedApi;
+ }
+ return api;
+ }
+
+ private void setWhitelist(MqttSubmodelAPI api, String smId) {
+ if (!config.isWhitelistEnabled(smId)) {
+ // Do not use the whitelist if it has been disabled
+ api.disableWhitelist();
+ return;
+ }
+
+ // Read whitelist from configuration
+ Set<String> whitelist = config.getWhitelist(smId);
+
+ logger.info("Set MQTT whitelist for " + smId + " with " + whitelist.size() + " entries");
+ api.setWhitelist(whitelist);
+ api.enableWhitelist();
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/servlet/AASAggregatorServlet.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/servlet/AASAggregatorServlet.java
new file mode 100644
index 0000000..d3c7a17
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/servlet/AASAggregatorServlet.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.aas.servlet;
+
+import org.eclipse.basyx.aas.aggregator.AASAggregator;
+import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
+import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
+import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
+
+/**
+ * A servlet containing the empty infrastructure needed to support receiving
+ * AAS/Submodels by clients and hosting them
+ *
+ * @author schnicke
+ *
+ */
+public class AASAggregatorServlet extends VABHTTPInterface<AASAggregatorProvider> {
+ private static final long serialVersionUID = 1244938902937878401L;
+
+ public AASAggregatorServlet() {
+ super(new AASAggregatorProvider(new AASAggregator()));
+ }
+
+ public AASAggregatorServlet(IAASAggregator aggregator) {
+ super(new AASAggregatorProvider(aggregator));
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/aas.properties b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/aas.properties
new file mode 100644
index 0000000..5fb6126
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/aas.properties
@@ -0,0 +1,45 @@
+# #############################
+# AAS Server configuration file
+# #############################
+
+# #############################
+# Backend
+# #############################
+# Specifies the backend that loads the AAS and Submodels
+
+# InMemory - does not persist AAS or submodels
+aas.backend=InMemory
+
+# MongoDB - persists data within a MongoDB
+# See connection configuration in mongodb.properties
+# aas.backend=MongoDB
+
+# #############################
+# Source
+# #############################
+# Possible to load an AAS Environment from a file
+
+aas.source=
+
+# Other examples (Currently supported: *.xml, *.json and *.aasx):
+# aas.source=aasx/myAAS.aasx
+# aas.source=aasx/myAAS.xml
+# aas.source=aasx/myAAS.json
+# Or when encapsulated in the docker volume for this container:
+# aas.source=/usr/share/config/myAAS.aasx
+
+# #############################
+# MQTT
+# #############################
+# Possible to enable MQTT events
+
+aas.events=NONE
+# aas.events=MQTT
+
+
+# #############################
+# Registry
+# #############################
+# If specified, can directly registers the AAS that has been loaded from the source file
+
+# registry.path=http://localhost:4000/registry/
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/resources/aasx/01_Festo.aasx b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/aasx/01_Festo.aasx
similarity index 100%
rename from components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/resources/aasx/01_Festo.aasx
rename to components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/aasx/01_Festo.aasx
Binary files differ
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/context.properties b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/context.properties
index a723466..65f2a94 100644
--- a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/context.properties
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/context.properties
@@ -1,3 +1,24 @@
+# ###############################
+# HTTP Context configuration file
+# ###############################
+
+# ###############################
+# Context Path
+# ###############################
+# Specifies the subpath in the url for this server context
+
contextPath=/aasServer
+
+# ###############################
+# Hostname
+# ###############################
+# Specifies the hostname for this server context
+
contextHostname=localhost
-contextPort=4000
\ No newline at end of file
+
+# ###############################
+# Port
+# ###############################
+# Specifies the port for this server context
+
+contextPort=4001
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/json/aas.json b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/json/aas.json
new file mode 100644
index 0000000..afa70e0
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/json/aas.json
@@ -0,0 +1,570 @@
+{
+ "assetAdministrationShells": [
+ {
+ "asset": {
+ "keys": [
+ {
+ "type": "Asset",
+ "local": true,
+ "value": "http://customer.com/assets/KHBVZJSQKIY",
+ "idType": "IRI"
+ }
+ ],
+ "kind": "Type",
+ "idShort": "assetId1",
+ "identification": {
+ "idType": "IRI",
+ "id": "assetId1"
+ }
+ },
+ "submodels": [
+ {
+ "keys": [
+ {
+ "type": "Submodel",
+ "local": true,
+ "value": "http.//i40.customer.com/type/1/1/7A7104BDAB57E184",
+ "idType": "IRI"
+ }
+ ],
+ "idShort": "submodelId1",
+ "identification": {
+ "idType": "IRI",
+ "id": "submodelId1"
+ }
+ },
+ {
+ "keys": [
+ {
+ "type": "Submodel",
+ "local": true,
+ "value": "http://i40.customer.com/instance/1/1/AC69B1CB44F07935",
+ "idType": "IRI"
+ }
+ ],
+ "idShort": "submodelId2",
+ "identification": {
+ "idType": "IRI",
+ "id": "submodelId2"
+ }
+ },
+ {
+ "keys": [
+ {
+ "type": "Submodel",
+ "local": true,
+ "value": "http://i40.customer.com/type/1/1/1A7B62B529F19152",
+ "idType": "IRI"
+ }
+ ],
+ "idShort": "submodelId3",
+ "identification": {
+ "idType": "IRI",
+ "id": "submodelId3"
+ }
+ }
+ ],
+ "conceptDictionaries": [],
+ "identification": {
+ "idType": "IRI",
+ "id": "http://customer.com/aas/9175_7013_7091_9168"
+ },
+ "idShort": "ExampleMotor",
+ "category": "CONSTANT",
+ "modelType": {
+ "name": "AssetAdministrationShell"
+ }
+ }
+ ],
+ "assets": [
+ {
+ "assetIdentificationModelRef": {
+ "keys": [
+ {
+ "type": "Submodel",
+ "local": true,
+ "value": "i40.customer.com/type/1/1/F13E8576F6488342",
+ "idType": "IRI"
+ }
+ ]
+ },
+ "identification": {
+ "idType": "IRI",
+ "id": "http://customer.com/assets/KHBVZJSQKIY"
+ },
+ "idShort": "ServoDCMotor",
+ "category": "",
+ "modelType": {
+ "name": "Asset"
+ },
+ "kind": "Instance"
+ }
+ ],
+ "submodels": [
+ {
+ "semanticId": {
+ "keys": [
+ {
+ "type": "GlobalReference",
+ "local": false,
+ "value": "0173-1#01-AFZ615#016",
+ "idType": "IRDI"
+ }
+ ]
+ },
+ "identification": {
+ "idType": "IRI",
+ "id": "http.//i40.customer.com/type/1/1/7A7104BDAB57E184"
+ },
+ "idShort": "TechnicalData",
+ "category": "CONSTANT",
+ "modelType": {
+ "name": "Submodel"
+ },
+ "kind": "Instance",
+ "submodelElements": [
+ {
+ "value": "5000",
+ "semanticId": {
+ "keys": [
+ {
+ "type": "ConceptDescription",
+ "local": true,
+ "value": "0173-1#02-BAA120#008",
+ "idType": "IRDI"
+ }
+ ]
+ },
+ "constraints": [],
+ "idShort": "MaxRotationSpeed",
+ "category": "PARAMETER",
+ "modelType": {
+ "name": "Property"
+ },
+ "valueType": "integer",
+ "kind": "Instance"
+ }
+ ]
+ },
+ {
+ "semanticId": {
+ "keys": []
+ },
+ "identification": {
+ "idType": "IRI",
+ "id": "http://i40.customer.com/type/1/1/1A7B62B529F19152"
+ },
+ "idShort": "Documentation",
+ "category": "CONSTANT",
+ "modelType": {
+ "name": "Submodel"
+ },
+ "kind": "Instance",
+ "submodelElements": [
+ {
+ "ordered": false,
+ "allowDuplicates": false,
+ "semanticId": {
+ "keys": [
+ {
+ "type": "ConceptDescription",
+ "local": true,
+ "value": "www.vdi2770.com/blatt1/Entwurf/Okt18/cd/Document",
+ "idType": "IRI"
+ }
+ ]
+ },
+ "constraints": [],
+ "idShort": "OperatingManual",
+ "category": "",
+ "modelType": {
+ "name": "SubmodelElementCollection"
+ },
+ "value": [
+ {
+ "value": "Operating Manual",
+ "semanticId": {
+ "keys": [
+ {
+ "type": "ConceptDescription",
+ "local": true,
+ "value": "www.vdi2770.com/blatt1/Entwurf/Okt18/cd/Description/Title",
+ "idType": "IRI"
+ }
+ ]
+ },
+ "constraints": [],
+ "idShort": "Title",
+ "modelType": {
+ "name": "Property"
+ },
+ "valueType": "langString",
+ "kind": "Instance"
+ },
+ {
+ "mimeType": "application/pdf",
+ "value": "/aasx/OperatingManual.pdf",
+ "semanticId": {
+ "keys": [
+ {
+ "type": "ConceptDescription",
+ "local": true,
+ "value": "www.vdi2770.com/blatt1/Entwurf/Okt18/cd/StoredDocumentRepresentation/DigitalFile",
+ "idType": "IRI"
+ }
+ ]
+ },
+ "constraints": [],
+ "idShort": "DigitalFile_PDF",
+ "category": "PARAMETER",
+ "modelType": {
+ "name": "File"
+ },
+ "kind": "Instance"
+ }
+ ],
+ "kind": "Instance"
+ }
+ ]
+ },
+ {
+ "semanticId": {
+ "keys": []
+ },
+ "qualifiers": [],
+ "identification": {
+ "idType": "IRI",
+ "id": "http://i40.customer.com/instance/1/1/AC69B1CB44F07935"
+ },
+ "idShort": "OperationalData",
+ "category": "VARIABLE",
+ "modelType": {
+ "name": "Submodel"
+ },
+ "kind": "Instance",
+ "submodelElements": [
+ {
+ "value": "4370",
+ "hasDataSpecification": {
+ "reference": []
+ },
+ "semanticId": {
+ "keys": [
+ {
+ "type": "ConceptDescription",
+ "local": true,
+ "value": "http://customer.com/cd/1/1/18EBD56F6B43D895",
+ "idType": "IRI"
+ }
+ ]
+ },
+ "constraints": [],
+ "idShort": "RotationSpeed",
+ "category": "VARIABLE",
+ "modelType": {
+ "name": "Property"
+ },
+ "valueType": "integer",
+ "kind": "Instance"
+ }
+ ]
+ }
+ ],
+ "conceptDescriptions": [
+ {
+ "identification": {
+ "idType": "IRI",
+ "id": "www.vdi2770.com/blatt1/Entwurf/Okt18/cd/Description/Title"
+ },
+ "idShort": "Title",
+ "category": "CONSTANT",
+ "modelType": {
+ "name": "ConceptDescription"
+ },
+ "embeddedDataSpecifications": [
+ {
+ "dataSpecification": {
+ "keys": [
+ {
+ "type": "GlobalReference",
+ "local": false,
+ "value": "http://admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360",
+ "idType": "IRI"
+ }
+ ]
+ },
+ "dataSpecificationContent": {
+ "preferredName": [
+ {
+ "language": "EN",
+ "text": "Title"
+ },
+ {
+ "language": "DE",
+ "text": "Titel"
+ }
+ ],
+ "shortName": [
+ {
+ "language": "EN",
+ "text": "Title"
+ },
+ {
+ "language": "DE",
+ "text": "Titel"
+ }
+ ],
+ "unit": "",
+ "sourceOfDefinition": "",
+ "dataType": "STRING_TRANSLATABLE",
+ "definition": [
+ {
+ "language": "DE",
+ "text": "Sprachabhängiger Titel des Dokuments."
+ }
+ ]
+ }
+ }
+ ],
+ "isCaseOf": []
+ },
+ {
+ "identification": {
+ "idType": "IRI",
+ "id": "www.vdi2770.com/blatt1/Entwurf/Okt18/cd/StoredDocumentRepresentation/DigitalFile"
+ },
+ "idShort": "DigitalFile",
+ "modelType": {
+ "name": "ConceptDescription"
+ },
+ "embeddedDataSpecifications": [
+ {
+ "dataSpecification": {
+ "keys": [
+ {
+ "type": "GlobalReference",
+ "local": false,
+ "value": "http://admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360",
+ "idType": "IRI"
+ }
+ ]
+ },
+ "dataSpecificationContent": {
+ "preferredName": [
+ {
+ "language": "EN",
+ "text": "Digital File"
+ },
+ {
+ "language": "DE",
+ "text": "Digitale Datei"
+ }
+ ],
+ "shortName": [
+ {
+ "language": "EN",
+ "text": "DigitalFile"
+ },
+ {
+ "language": "DE",
+ "text": "DigitaleDatei"
+ }
+ ],
+ "unit": "",
+ "sourceOfDefinition": "",
+ "dataType": "STRING",
+ "definition": [
+ {
+ "language": "DE",
+ "text": "Eine Datei, die die DocumentVersion repräsentiert. Neben der obligatorischen PDF/A Datei können weitere Dateien angegeben werden."
+ }
+ ]
+ }
+ }
+ ],
+ "isCaseOf": []
+ },
+ {
+ "identification": {
+ "idType": "IRDI",
+ "id": "0173-1#02-BAA120#008"
+ },
+ "administration": {
+ "version": "",
+ "revision": "2"
+ },
+ "idShort": "MaxRotationSpeed",
+ "category": "PROPERTY",
+ "modelType": {
+ "name": "ConceptDescription"
+ },
+ "embeddedDataSpecifications": [
+ {
+ "dataSpecification": {
+ "keys": []
+ },
+ "dataSpecificationContent": {
+ "preferredName": [
+ {
+ "language": "de",
+ "text": "max. Drehzahl"
+ },
+ {
+ "language": "en",
+ "text": "Max. rotation speed"
+ }
+ ],
+ "shortName": [],
+ "unit": "1/min",
+ "unitId": {
+ "keys": [
+ {
+ "type": "GlobalReference",
+ "local": false,
+ "value": "0173-1#05-AAA650#002",
+ "idType": "IRDI"
+ }
+ ]
+ },
+ "sourceOfDefinition": "",
+ "dataType": "REAL_MEASURE",
+ "definition": [
+ {
+ "language": "de",
+ "text": "Höchste zulässige Drehzahl, mit welcher der Motor oder die Speiseinheit betrieben werden darf"
+ },
+ {
+ "language": "en",
+ "text": "Greatest permissible rotation speed with which the motor or feeding unit may be operated"
+ }
+ ]
+ }
+ }
+ ],
+ "isCaseOf": [
+ {
+ "keys": []
+ }
+ ]
+ },
+ {
+ "identification": {
+ "idType": "IRI",
+ "id": "http://customer.com/cd/1/1/18EBD56F6B43D895"
+ },
+ "idShort": "RotationSpeed",
+ "category": "PROPERTY",
+ "modelType": {
+ "name": "ConceptDescription"
+ },
+ "embeddedDataSpecifications": [
+ {
+ "dataSpecification": {
+ "keys": [
+ {
+ "type": "GlobalReference",
+ "local": false,
+ "value": "http://admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360",
+ "idType": "IRI"
+ }
+ ]
+ },
+ "dataSpecificationContent": {
+ "preferredName": [
+ {
+ "language": "DE",
+ "text": "Aktuelle Drehzahl"
+ },
+ {
+ "language": "EN",
+ "text": "Actual rotation speed"
+ }
+ ],
+ "shortName": [
+ {
+ "language": "DE",
+ "text": "AktuelleDrehzahl"
+ },
+ {
+ "language": "EN",
+ "text": "ActualRotationSpeed"
+ }
+ ],
+ "unit": "1/min",
+ "unitId": {
+ "keys": [
+ {
+ "type": "GlobalReference",
+ "local": false,
+ "value": "0173-1#05-AAA650#002",
+ "idType": "IRDI"
+ }
+ ]
+ },
+ "sourceOfDefinition": "",
+ "dataType": "REAL_MEASURE",
+ "definition": [
+ {
+ "language": "DE",
+ "text": "Aktuelle Drehzahl, mit welcher der Motor oder die Speiseinheit betrieben wird"
+ },
+ {
+ "language": "EN",
+ "text": "Actual rotation speed with which the motor or feeding unit is operated"
+ }
+ ]
+ }
+ }
+ ],
+ "isCaseOf": []
+ },
+ {
+ "identification": {
+ "idType": "IRI",
+ "id": "www.vdi2770.com/blatt1/Entwurf/Okt18/cd/Document"
+ },
+ "idShort": "Document",
+ "modelType": {
+ "name": "ConceptDescription"
+ },
+ "embeddedDataSpecifications": [
+ {
+ "dataSpecification": {
+ "keys": [
+ {
+ "type": "GlobalReference",
+ "local": false,
+ "value": "http://admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360",
+ "idType": "IRI"
+ }
+ ]
+ },
+ "dataSpecificationContent": {
+ "preferredName": [],
+ "shortName": [
+ {
+ "language": "EN",
+ "text": "Document"
+ },
+ {
+ "language": "DE",
+ "text": "Dokument"
+ }
+ ],
+ "unit": "",
+ "sourceOfDefinition": "[ISO 15519-1:2010]",
+ "dataType": "STRING",
+ "definition": [
+ {
+ "language": "DE",
+ "text": "Feste und geordnete Menge von für die Verwendung durch Personen bestimmte Informationen, die verwaltet und als Einheit zwischen Benutzern und System ausgetauscht werden kann."
+ }
+ ]
+ }
+ }
+ ],
+ "isCaseOf": [],
+ "descriptions": []
+ }
+ ]
+}
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/mongodb.properties b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/mongodb.properties
new file mode 100644
index 0000000..2b3c79d
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/mongodb.properties
@@ -0,0 +1,32 @@
+# #############################
+# MongoDB Backend configuration
+# #############################
+
+# #############################
+# Database Name
+# #############################
+# The database in the MongoDB that hold the data
+
+dbname=admin
+
+# #############################
+# Connection String
+# #############################
+# MongoDB connection string for connecting to the MongoDB endpoint
+
+dbconnectionstring=mongodb://localhost:27017/
+
+# #############################
+# AAS collections
+# #############################
+# Collection names that are used for storing the AAS and Submodels
+
+dbcollectionAAS=assetadministrationshells
+dbcollectionSubmodels=submodels
+
+# #############################
+# Registry Collections
+# #############################
+# Collection name that is used for storing registry data
+
+dbcollectionRegistry=registry
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/mqtt.properties b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/mqtt.properties
new file mode 100644
index 0000000..7762dc9
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/mqtt.properties
@@ -0,0 +1,35 @@
+# ##################
+# MQTT configuration
+# ##################
+
+# ##################
+# Credentials
+# ##################
+# The credentials for connecting to the MQTT broker
+
+# user=
+# pass=
+
+# ##################
+# Server location
+# ##################
+# Broker address to connect to
+
+server=tcp://localhost:1883
+
+# ##################
+# QoS
+# ##################
+# QoS level for the mqtt messages (0, 1 or 2). Default is 1.
+
+# qos=2
+
+# ##################
+# Filtered whitelist
+# ##################
+# Whitelist for filtering mqtt events for specific submodels / submodelelements
+
+whitelist.patientTemplate=true
+whitelist.element.patientTemplate.active=true
+# whitelist.element.{mySmIdentifier}.{elementIdShort}=true
+
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/xml/aas.xml b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/xml/aas.xml
new file mode 100644
index 0000000..2c75def
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/xml/aas.xml
@@ -0,0 +1,586 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<aas:aasenv xmlns:aas="http://www.admin-shell.io/aas/2/0"
+ xmlns:IEC61360="http://www.admin-shell.io/IEC61360/2/0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.admin-shell.io/aas/2/0 AAS.xsd
+ http://www.admin-shell.io/IEC61360/2/0 IEC61360.xsd">
+ <aas:assetAdministrationShells>
+ <!-- This AAS is populated with all possible fields -->
+ <aas:assetAdministrationShell>
+ <aas:idShort>aas1</aas:idShort>
+ <aas:category>test_category</aas:category>
+ <aas:description>
+ <aas:langString lang="EN">aas_Description</aas:langString>
+ <aas:langString lang="DE">Beschreibung Verwaltungsschale</aas:langString>
+ </aas:description>
+ <aas:parent>
+ <!-- Parent is currently a String in the Schema. But it should be a Reference. -->
+ <aas:keys>
+ <aas:key idType="IRI" local="false" type="AssetAdministrationShell">aas_parent_id</aas:key>
+ </aas:keys>
+ </aas:parent>
+ <aas:identification idType="IRI">www.admin-shell.io/aas-sample/2/0</aas:identification>
+ <aas:administration>
+ <aas:version>1</aas:version>
+ <aas:revision>0</aas:revision>
+ </aas:administration>
+ <aas:embeddedDataSpecification>
+ <aas:dataSpecificationContent>
+ <aas:dataSpecificationIEC61360>
+ <IEC61360:preferredName>
+ <IEC61360:langString lang="DE">Drehzahl</IEC61360:langString>
+ <IEC61360:langString lang="EN">Rotation Speed</IEC61360:langString>
+ </IEC61360:preferredName>
+ <IEC61360:shortName>
+ <IEC61360:langString lang="DE">N</IEC61360:langString>
+ </IEC61360:shortName>
+ <IEC61360:unit>1/min</IEC61360:unit>
+ <IEC61360:unitId>
+ <IEC61360:keys>
+ <IEC61360:key idType="IRDI" local="false" type="GlobalReference">
+ 0173-1#05-AAA650#002
+ </IEC61360:key>
+ </IEC61360:keys>
+ </IEC61360:unitId>
+ <IEC61360:valueFormat>NR1..5</IEC61360:valueFormat>
+ </aas:dataSpecificationIEC61360>
+ </aas:dataSpecificationContent>
+ <aas:dataSpecification>
+ <aas:keys>
+ <aas:key idType="IRI" local="false" type="GlobalReference">www.admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360</aas:key>
+ </aas:keys>
+ </aas:dataSpecification>
+ </aas:embeddedDataSpecification>
+ <aas:derivedFrom>
+ <aas:keys>
+ <aas:key type="ReferenceElement" local="false" idType="IRI">http://pk.festo.com/3s7plfdrs35</aas:key>
+ </aas:keys>
+ </aas:derivedFrom>
+ <aas:assetRef>
+ <aas:keys>
+ <aas:key type="Asset" local="false" idType="IRI">http://pk.festo.com/3s7plfdrs35</aas:key>
+ </aas:keys>
+ </aas:assetRef>
+ <aas:submodelRefs>
+ <aas:submodelRef>
+ <aas:keys>
+ <aas:key type="Submodel" local="true" idType="IRI">http://www.zvei.de/demo/submodel/12345679</aas:key>
+ </aas:keys>
+ </aas:submodelRef>
+ </aas:submodelRefs>
+ <aas:views>
+ <!-- This View is populated with all possible fields -->
+ <aas:view>
+ <aas:idShort>SampleView</aas:idShort>
+ <aas:category>test_categogy</aas:category>
+ <aas:description>
+ <aas:langString lang="EN">View_Description</aas:langString>
+ </aas:description>
+ <aas:parent>
+ <!-- Parent is currently a String in the Schema. But it should be a Reference. -->
+ <aas:keys>
+ <aas:key idType="IRI" local="false" type="Submodel">view_parent_id</aas:key>
+ </aas:keys>
+ </aas:parent>
+ <aas:semanticId>
+ <aas:keys>
+ <aas:key idType="IRI" local="false" type="Submodel">view_semantic_id</aas:key>
+ </aas:keys>
+ </aas:semanticId>
+ <aas:embeddedDataSpecification>
+ <aas:dataSpecificationContent>
+ <aas:dataSpecificationIEC61360>
+ <IEC61360:preferredName>
+ <IEC61360:langString lang="DE">Drehzahl</IEC61360:langString>
+ <IEC61360:langString lang="EN">Rotation Speed</IEC61360:langString>
+ </IEC61360:preferredName>
+ <IEC61360:shortName>
+ <IEC61360:langString lang="DE">N</IEC61360:langString>
+ </IEC61360:shortName>
+ <IEC61360:unit>1/min</IEC61360:unit>
+ <IEC61360:unitId>
+ <IEC61360:keys>
+ <IEC61360:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</IEC61360:key>
+ </IEC61360:keys>
+ </IEC61360:unitId>
+ <IEC61360:valueFormat>NR1..5</IEC61360:valueFormat>
+ </aas:dataSpecificationIEC61360>
+ </aas:dataSpecificationContent>
+ <aas:dataSpecification>
+ <aas:keys>
+ <aas:key idType="IRI" local="false" type="GlobalReference">www.admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360</aas:key>
+ </aas:keys>
+ </aas:dataSpecification>
+ </aas:embeddedDataSpecification>
+ <aas:containedElements>
+ <aas:containedElementRef>
+ <aas:keys>
+ <aas:key type="Submodel" local="true" idType="IRI">"http://www.zvei.de/demo/submodel/12345679"</aas:key>
+ <aas:key type="Property" local="true" idType="IdShort">rotationSpeed</aas:key>
+ </aas:keys>
+ </aas:containedElementRef>
+ </aas:containedElements>
+ </aas:view>
+ <!-- This is a View with only the minimal required information in it. To test for Nullpointers and such. -->
+ <aas:view>
+ <aas:idShort>EmptyView</aas:idShort>
+ <aas:containedElements></aas:containedElements>
+ </aas:view>
+ </aas:views>
+ <aas:conceptDictionaries>
+ <aas:conceptDictionary>
+ <aas:idShort>SampleDic</aas:idShort>
+ <aas:conceptDescriptionRefs>
+ <aas:conceptDescriptionRef>
+ <aas:keys>
+ <aas:key type="ConceptDescription" local="true" idType="IRI">www.festo.com/dic/08111234</aas:key>
+ </aas:keys>
+ </aas:conceptDescriptionRef>
+ </aas:conceptDescriptionRefs>
+ </aas:conceptDictionary>
+ </aas:conceptDictionaries>
+ </aas:assetAdministrationShell>
+ <!-- This is an AAS with only the minimal required information in it. To test for Nullpointers and such. -->
+ <aas:assetAdministrationShell>
+ <aas:idShort>asset_admin_shell</aas:idShort>
+ <aas:identification idType="IRI">www.admin-shell.io/aas-sample/1/1</aas:identification>
+ <aas:assetRef>
+ <aas:keys>
+ <aas:key type="Asset" local="false" idType="IRI">http://pk.festo.com/3s7plfdrs35</aas:key>
+ </aas:keys>
+ </aas:assetRef>
+ </aas:assetAdministrationShell>
+ </aas:assetAdministrationShells>
+ <aas:assets>
+ <!-- This Asset is populated with all possible fields -->
+ <aas:asset>
+ <aas:idShort>3s7plfdrs35_asset1</aas:idShort>
+ <aas:category>asset1_categogy</aas:category>
+ <aas:description>
+ <aas:langString lang="EN">asset1_Description</aas:langString>
+ </aas:description>
+ <aas:parent>
+ <!-- Parent is currently a String in the Schema. But it should be a Reference. -->
+ <aas:keys>
+ <aas:key idType="IRI" local="false" type="Asset">asset_parent_id</aas:key>
+ </aas:keys>
+ </aas:parent>
+ <aas:identification idType="IRI">http://pk.festo.com/3s7plfdrs35</aas:identification>
+ <aas:administration>
+ <aas:version>1</aas:version>
+ <aas:revision>0</aas:revision>
+ </aas:administration>
+ <aas:embeddedDataSpecification>
+ <aas:dataSpecificationContent>
+ <aas:dataSpecificationIEC61360>
+ <IEC61360:preferredName>
+ <IEC61360:langString lang="DE">Drehzahl</IEC61360:langString>
+ <IEC61360:langString lang="EN">Rotation Speed</IEC61360:langString>
+ </IEC61360:preferredName>
+ <IEC61360:shortName>
+ <IEC61360:langString lang="DE">N</IEC61360:langString>
+ </IEC61360:shortName>
+ <IEC61360:unit>1/min</IEC61360:unit>
+ <IEC61360:unitId>
+ <IEC61360:keys>
+ <IEC61360:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</IEC61360:key>
+ </IEC61360:keys>
+ </IEC61360:unitId>
+ <IEC61360:valueFormat>NR1..5</IEC61360:valueFormat>
+ </aas:dataSpecificationIEC61360>
+ </aas:dataSpecificationContent>
+ <aas:dataSpecification>
+ <aas:keys>
+ <aas:key idType="IRI" local="false" type="GlobalReference">www.admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360</aas:key>
+ </aas:keys>
+ </aas:dataSpecification>
+ </aas:embeddedDataSpecification>
+ <aas:assetIdentificationModelRef>
+ <aas:keys>
+ <aas:key type="ConceptDescription" local="true" idType="IRI">www.festo.com/dic/08111234</aas:key>
+ </aas:keys>
+ </aas:assetIdentificationModelRef>
+ <aas:kind>Instance</aas:kind>
+ </aas:asset>
+ <aas:asset>
+ <aas:idShort>emptyAsset</aas:idShort>
+ <aas:identification idType="IRI">http://pk.festo.com/q30j38dlajx</aas:identification>
+ <aas:kind>Instance</aas:kind>
+ </aas:asset>
+ </aas:assets>
+ <aas:submodels>
+ <!-- This Submodel is populated with all possible fields -->
+ <aas:submodel>
+ <aas:idShort>submodel1</aas:idShort>
+ <aas:category>submodel1_categogy</aas:category>
+ <aas:description>
+ <aas:langString lang="EN">submode1_decription</aas:langString>
+ </aas:description>
+ <aas:parent>
+ <!-- Parent is currently a String in the Schema. But it should be a Reference. -->
+ <aas:keys>
+ <aas:key idType="IRI" local="false" type="Submodel">submodel_parent_id</aas:key>
+ </aas:keys>
+ </aas:parent>
+ <aas:identification idType="IRI">http://www.zvei.de/demo/submodel/12345679</aas:identification>
+ <aas:administration>
+ <aas:version>1</aas:version>
+ <aas:revision>0</aas:revision>
+ </aas:administration>
+ <aas:kind>Instance</aas:kind>
+ <aas:semanticId>
+ <aas:keys>
+ <aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+ </aas:keys>
+ </aas:semanticId>
+ <aas:qualifier>
+ <aas:qualifiers>
+ <aas:formula>
+ <aas:dependsOnRefs>
+ <aas:reference>
+ <aas:keys>
+ <aas:key local="false" type="GlobalReference" idType="IRDI">qualifier_reference</aas:key>
+ </aas:keys>
+ </aas:reference>
+ </aas:dependsOnRefs>
+ </aas:formula>
+ </aas:qualifiers>
+ <aas:qualifiers>
+ <aas:qualifier>
+ <aas:valueId>
+ <aas:keys>
+ <aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+ </aas:keys>
+ </aas:valueId>
+ <aas:value>qualifierValue</aas:value>
+ <aas:type>qualifierType</aas:type>
+ <aas:valueType>anyType</aas:valueType>
+ <aas:semanticId>
+ <aas:keys>
+ <aas:key idType="IRI" local="false" type="GlobalReference">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+ </aas:keys>
+ </aas:semanticId>
+ </aas:qualifier>
+ </aas:qualifiers>
+ </aas:qualifier>
+ <aas:embeddedDataSpecification>
+ <aas:dataSpecificationContent>
+ <aas:dataSpecificationIEC61360>
+ <IEC61360:preferredName>
+ <IEC61360:langString lang="DE">Drehzahl</IEC61360:langString>
+ <IEC61360:langString lang="EN">Rotation Speed</IEC61360:langString>
+ </IEC61360:preferredName>
+ <IEC61360:shortName>
+ <IEC61360:langString lang="DE">N</IEC61360:langString>
+ </IEC61360:shortName>
+ <IEC61360:unit>1/min</IEC61360:unit>
+ <IEC61360:unitId>
+ <IEC61360:keys>
+ <IEC61360:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</IEC61360:key>
+ </IEC61360:keys>
+ </IEC61360:unitId>
+ <IEC61360:valueFormat>NR1..5</IEC61360:valueFormat>
+ </aas:dataSpecificationIEC61360>
+ </aas:dataSpecificationContent>
+ <aas:dataSpecification>
+ <aas:keys>
+ <aas:key idType="IRI" local="false" type="GlobalReference">www.admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360</aas:key>
+ </aas:keys>
+ </aas:dataSpecification>
+ </aas:embeddedDataSpecification>
+ <aas:submodelElements>
+ <aas:submodelElement>
+ <aas:property>
+ <aas:idShort>rotationSpeed</aas:idShort>
+ <aas:category>VARIABLE</aas:category>
+ <aas:semanticId>
+ <aas:keys>
+ <aas:key idType="IRI" type="ConceptDescription" local="true">www.festo.com/dic/08111234</aas:key>
+ </aas:keys>
+ </aas:semanticId>
+ <aas:qualifier>
+ <aas:qualifiers>
+ <aas:qualifier>
+ <aas:valueId>
+ <aas:keys>
+ <aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+ </aas:keys>
+ </aas:valueId>
+ <aas:value>qualifierValue</aas:value>
+ <aas:type>qualifierType</aas:type>
+ <aas:valueType>anyType</aas:valueType>
+ <aas:semanticId>
+ <aas:keys>
+ <aas:key idType="IRI" local="false" type="GlobalReference">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+ </aas:keys>
+ </aas:semanticId>
+ </aas:qualifier>
+ </aas:qualifiers>
+ </aas:qualifier>
+ <aas:embeddedDataSpecification>
+ <aas:dataSpecificationContent>
+ <aas:dataSpecificationIEC61360>
+ <IEC61360:preferredName>
+ <IEC61360:langString lang="DE">Drehzahl</IEC61360:langString>
+ <IEC61360:langString lang="EN">Rotation Speed</IEC61360:langString>
+ </IEC61360:preferredName>
+ <IEC61360:shortName>
+ <IEC61360:langString lang="DE">N</IEC61360:langString>
+ </IEC61360:shortName>
+ <IEC61360:unit>1/min</IEC61360:unit>
+ <IEC61360:unitId>
+ <IEC61360:keys>
+ <IEC61360:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</IEC61360:key>
+ </IEC61360:keys>
+ </IEC61360:unitId>
+ <IEC61360:valueFormat>NR1..5</IEC61360:valueFormat>
+ </aas:dataSpecificationIEC61360>
+ </aas:dataSpecificationContent>
+ <aas:dataSpecification>
+ <aas:keys>
+ <aas:key idType="IRI" local="false" type="GlobalReference">www.admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360</aas:key>
+ </aas:keys>
+ </aas:dataSpecification>
+ </aas:embeddedDataSpecification>
+ <aas:value>2000</aas:value>
+ <aas:valueType>double</aas:valueType>
+ </aas:property>
+ </aas:submodelElement>
+ <aas:submodelElement>
+ <aas:property>
+ <aas:idShort>emptyDouble</aas:idShort>
+ <aas:valueType>double</aas:valueType>
+ </aas:property>
+ </aas:submodelElement>
+ <aas:submodelElement>
+ <aas:basicEvent>
+ <aas:idShort>basic_event_id</aas:idShort>
+ <aas:observed>
+ <aas:keys>
+ <aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+ </aas:keys>
+ </aas:observed>
+ </aas:basicEvent>
+ </aas:submodelElement>
+ <aas:submodelElement>
+ <aas:entity>
+ <aas:idShort>entity_id</aas:idShort>
+ <aas:assetRef>
+ <aas:keys>
+ <aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+ </aas:keys>
+ </aas:assetRef>
+ <aas:entityType>CoManagedEntity</aas:entityType>
+ <aas:statements>
+ <!-- XML Schema currently supports only one statement, but multiple should be supported -->
+ <aas:submodelElement>
+ <aas:file>
+ <aas:idShort>file_ID</aas:idShort>
+ <aas:mimeType>file_mimetype</aas:mimeType>
+ <aas:value>file_value</aas:value>
+ </aas:file>
+ </aas:submodelElement>
+ <aas:submodelElement>
+ <aas:range>
+ <aas:idShort>range_id</aas:idShort>
+ <aas:min>10</aas:min>
+ <aas:valueType>int</aas:valueType>
+ </aas:range>
+ </aas:submodelElement>
+ </aas:statements>
+ </aas:entity>
+ </aas:submodelElement>
+ <aas:submodelElement>
+ <aas:multiLanguageProperty>
+ <aas:idShort>multi_language_property_id</aas:idShort>
+ <aas:valueId>
+ <aas:keys>
+ <aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</aas:key>
+ </aas:keys>
+ </aas:valueId>
+ <aas:value>
+ <aas:langString lang="DE">Eine Beschreibung auf deutsch</aas:langString>
+ <aas:langString lang="EN">A description in english</aas:langString>
+ </aas:value>
+ </aas:multiLanguageProperty>
+ </aas:submodelElement>
+ <aas:submodelElement>
+ <aas:range>
+ <aas:idShort>range_id</aas:idShort>
+ <aas:max>10</aas:max>
+ <aas:min>1</aas:min>
+ <aas:valueType>int</aas:valueType>
+ </aas:range>
+ </aas:submodelElement>
+ <aas:submodelElement>
+ <aas:file>
+ <aas:idShort>file_id</aas:idShort>
+ <aas:mimeType>file_mimetype</aas:mimeType>
+ <aas:value>file_value</aas:value>
+ </aas:file>
+ </aas:submodelElement>
+ <aas:submodelElement>
+ <aas:blob>
+ <aas:idShort>blob_id</aas:idShort>
+ <aas:value>YmxvYit2YWx1ZQ==</aas:value>
+ <aas:mimeType>blob_mimetype</aas:mimeType>
+ </aas:blob>
+ </aas:submodelElement>
+ <aas:submodelElement>
+ <aas:referenceElement>
+ <aas:idShort>reference_ELE_ID</aas:idShort>
+ <aas:value>
+ <aas:keys>
+ <aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</aas:key>
+ </aas:keys>
+ </aas:value>
+ </aas:referenceElement>
+ </aas:submodelElement>
+ <aas:submodelElement>
+ <aas:submodelElementCollection>
+ <aas:idShort>submodelElementCollection_ID</aas:idShort>
+ <aas:allowDuplicates>true</aas:allowDuplicates>
+ <aas:ordered>false</aas:ordered>
+ <aas:value>
+ <aas:submodelElement>
+ <aas:file>
+ <aas:idShort>file_ID</aas:idShort>
+ <aas:mimeType>file_mimetype</aas:mimeType>
+ <aas:value>file_value</aas:value>
+ </aas:file>
+ </aas:submodelElement>
+ <aas:submodelElement>
+ <aas:blob>
+ <aas:idShort>blob_id</aas:idShort>
+ <aas:value>YmxvYit2YWx1ZQ==</aas:value>
+ <aas:mimeType>blob_mimetype</aas:mimeType>
+ </aas:blob>
+ </aas:submodelElement>
+ </aas:value>
+ </aas:submodelElementCollection>
+ </aas:submodelElement>
+ <aas:submodelElement>
+ <aas:relationshipElement>
+ <aas:idShort>relationshipElement_ID</aas:idShort>
+ <aas:first>
+ <aas:keys>
+ <aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#001</aas:key>
+ </aas:keys>
+ </aas:first>
+ <aas:second>
+ <aas:keys>
+ <aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</aas:key>
+ </aas:keys>
+ </aas:second>
+ </aas:relationshipElement>
+ </aas:submodelElement>
+ <aas:submodelElement>
+ <aas:operation>
+ <aas:idShort>operation_ID</aas:idShort>
+ <aas:inoutputVariable>
+ <aas:operationVariable>
+ <aas:value>
+ <aas:referenceElement>
+ <aas:idShort>reference_ELE_ID2</aas:idShort>
+ <aas:value>
+ <aas:keys>
+ <aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#003</aas:key>
+ </aas:keys>
+ </aas:value>
+ </aas:referenceElement>
+ </aas:value>
+ </aas:operationVariable>
+ </aas:inoutputVariable>
+ <aas:inputVariable>
+ <!-- The schema only allows one opVar in inputVariable, one in outputVariable and one in inoutputVariable. The Metamodel allows 0..* in each -->
+ <!-- To be able to have multiple Vars they are surrounded by <aas:operationVariable>. This is also violating the Schema. -->
+ <aas:operationVariable>
+ <aas:value>
+ <aas:file>
+ <aas:idShort>file_ID</aas:idShort>
+ <aas:mimeType>file_mimetype</aas:mimeType>
+ <aas:value>file_value</aas:value>
+ </aas:file>
+ </aas:value>
+ </aas:operationVariable>
+ <aas:operationVariable>
+ <aas:value>
+ <aas:blob>
+ <aas:idShort>blob_ID</aas:idShort>
+ <aas:value>YmxvYit2YWx1ZQ==</aas:value>
+ <aas:mimeType>blob_mimetype</aas:mimeType>
+ </aas:blob>
+ </aas:value>
+ </aas:operationVariable>
+ </aas:inputVariable>
+ <aas:outputVariable>
+ <aas:operationVariable>
+ <aas:value>
+ <aas:referenceElement>
+ <aas:idShort>reference_ELE_ID</aas:idShort>
+ <aas:value>
+ <aas:keys>
+ <aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</aas:key>
+ </aas:keys>
+ </aas:value>
+ </aas:referenceElement>
+ </aas:value>
+ </aas:operationVariable>
+ </aas:outputVariable>
+ </aas:operation>
+ </aas:submodelElement>
+ </aas:submodelElements>
+ </aas:submodel>
+ </aas:submodels>
+ <aas:conceptDescriptions>
+ <!-- This ConceptDescription is populated with all possible fields -->
+ <aas:conceptDescription>
+ <aas:idShort>conceptDescription1</aas:idShort>
+ <aas:category>cs_category</aas:category>
+ <aas:description>
+ <aas:langString lang="EN">conceptDescription_Description</aas:langString>
+ </aas:description>
+ <aas:parent>
+ <!-- Parent is currently a String in the Schema. But it should be a Reference. -->
+ <aas:keys>
+ <aas:key idType="IRI" local="false" type="ConceptDescription">cs_parent_id</aas:key>
+ </aas:keys>
+ </aas:parent>
+ <aas:identification idType="IRI">www.festo.com/dic/08111234</aas:identification>
+ <aas:administration>
+ <aas:version>1</aas:version>
+ <aas:revision>0</aas:revision>
+ </aas:administration>
+ <aas:embeddedDataSpecification>
+ <aas:dataSpecificationContent>
+ <aas:dataSpecificationIEC61360>
+ <IEC61360:preferredName>
+ <IEC61360:langString lang="DE">Drehzahl</IEC61360:langString>
+ <IEC61360:langString lang="EN">Rotation Speed</IEC61360:langString>
+ </IEC61360:preferredName>
+ <IEC61360:shortName>
+ <IEC61360:langString lang="DE">N</IEC61360:langString>
+ </IEC61360:shortName>
+ <IEC61360:unit>1/min</IEC61360:unit>
+ <IEC61360:unitId>
+ <IEC61360:keys>
+ <IEC61360:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</IEC61360:key>
+ </IEC61360:keys>
+ </IEC61360:unitId>
+ <IEC61360:valueFormat>NR1..5</IEC61360:valueFormat>
+ </aas:dataSpecificationIEC61360>
+ </aas:dataSpecificationContent>
+ <aas:dataSpecification>
+ <aas:keys>
+ <aas:key idType="IRI" local="false" type="GlobalReference">www.admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360</aas:key>
+ </aas:keys>
+ </aas:dataSpecification>
+ </aas:embeddedDataSpecification>
+ <aas:isCaseOf>
+ <aas:keys>
+ <aas:key idType="IRI" type="ConceptDescription" local="true">www.festo.com/dic/08111234</aas:key>
+ <aas:key idType="IRI" type="ConceptDescription" local="true">www.festo.com/dic/08111234_2</aas:key>
+ </aas:keys>
+ </aas:isCaseOf>
+ </aas:conceptDescription>
+ </aas:conceptDescriptions>
+</aas:aasenv>
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/basyx/components/AASServer/AASServerSuite.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/basyx/components/AASServer/AASServerSuite.java
deleted file mode 100644
index 10e3826..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/basyx/components/AASServer/AASServerSuite.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package org.basyx.components.AASServer;
-
-import static org.junit.Assert.assertEquals;
-
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
-import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.vab.protocol.api.IConnectorProvider;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Suite for testing that the AAS Server component is set up correctly. The
- * tests here can be used by the component test itself and the integration test
- *
- * @author schnicke
- *
- */
-public abstract class AASServerSuite {
- protected IAASRegistryService aasRegistry;
- private ConnectedAssetAdministrationShellManager manager;
-
- private String aasId = "testId";
-
- protected abstract String getURL();
-
- @Before
- public void setUp() {
- // Create a dummy registry to test integration of XML AAS
- aasRegistry = new InMemoryRegistry();
-
- // Create ConnectedAASManager
- IConnectorProvider connectorProvider = new HTTPConnectorProvider();
- manager = new ConnectedAssetAdministrationShellManager(aasRegistry, connectorProvider);
- }
-
- @Test
- public void testAddAAS() throws Exception {
- AssetAdministrationShell shell = new AssetAdministrationShell();
- IIdentifier identifier = new ModelUrn(aasId);
- shell.setIdentification(identifier);
- shell.setIdShort("aasIdShort");
-
- manager.createAAS(shell, identifier, getURL());
-
- IAssetAdministrationShell remote = manager.retrieveAAS(identifier);
- assertEquals(shell.getIdShort(), remote.getIdShort());
- }
-
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/basyx/components/AASServer/ITAASServer.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/basyx/components/AASServer/ITAASServer.java
deleted file mode 100644
index 0b165a4..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/basyx/components/AASServer/ITAASServer.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package org.basyx.components.AASServer;
-
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.eclipse.basyx.components.configuration.BaSyxDockerConfiguration;
-import org.junit.BeforeClass;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Tests the docker container using the test suite
- *
- * @author schnicke
- *
- */
-public class ITAASServer extends AASServerSuite {
-
- private static String URL;
-
- @Override
- protected String getURL() {
- return URL;
- }
-
- private static Logger logger = LoggerFactory.getLogger(AASServerSuite.class);
-
- @BeforeClass
- public static void setUpClass() {
- logger.info("Running integration test...");
-
- logger.info("Loading servlet configuration");
- // Load the servlet configuration inside of the docker configuration from
- // properties file
- BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
- contextConfig.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
-
- // Load the docker environment configuration from properties file
- logger.info("Loading docker configuration");
- BaSyxDockerConfiguration dockerConfig = new BaSyxDockerConfiguration();
- dockerConfig.loadFromResource(BaSyxDockerConfiguration.DEFAULT_CONFIG_PATH);
-
- URL = "http://localhost:" + dockerConfig.getHostPort() + contextConfig.getContextPath();
- }
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/basyx/components/AASServer/TestAASServer.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/basyx/components/AASServer/TestAASServer.java
deleted file mode 100644
index 758237e..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/basyx/components/AASServer/TestAASServer.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package org.basyx.components.AASServer;
-
-import java.io.IOException;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.junit.BeforeClass;
-import org.xml.sax.SAXException;
-
-/**
- * Tests the component using the test suite
- *
- * @author schnicke
- *
- */
-public class TestAASServer extends AASServerSuite {
-
- private static AASServerComponent component;
-
- @Override
- protected String getURL() {
- return component.getURL();
- }
-
- @BeforeClass
- public static void setUpClass() throws ParserConfigurationException, SAXException, IOException {
- BaSyxContextConfiguration config = new BaSyxContextConfiguration();
- config.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
-
- component = new AASServerComponent(config.getHostname(), config.getPort(), config.getContextPath(), config.getDocBasePath());
- component.startComponent();
- }
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/AASServerComponentTest.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/AASServerComponentTest.java
new file mode 100644
index 0000000..9f7bf2b
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/AASServerComponentTest.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.AASServer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
+import org.eclipse.basyx.components.aas.AASServerComponent;
+import org.eclipse.basyx.components.aas.configuration.AASServerBackend;
+import org.eclipse.basyx.components.aas.configuration.BaSyxAASServerConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Tests if AASServerComponent correctly deregisteres automatically registered AASs/SMs
+ *
+ * @author conradi
+ *
+ */
+public class AASServerComponentTest {
+
+
+ private static AASServerComponent component;
+ private static InMemoryRegistry registry;
+
+ @BeforeClass
+ public static void setUp() {
+ // Setup component's test configuration
+ BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration(8080, "");
+ BaSyxAASServerConfiguration aasConfig = new BaSyxAASServerConfiguration(AASServerBackend.INMEMORY, "xml/aas.xml");
+
+ // Create and start AASServer component
+ component = new AASServerComponent(contextConfig, aasConfig);
+ registry = new InMemoryRegistry();
+ component.setRegistry(registry);
+ component.startComponent();
+ }
+
+ /**
+ * Tests if AASServerComponent deregisters all AASs/SMs that it registered automatically on startup
+ */
+ @Test
+ public void testServerCleanup() {
+
+ List<AASDescriptor> aasDescriptors = registry.lookupAll();
+ assertEquals(2, aasDescriptors.size());
+
+ component.stopComponent();
+
+ // Try to lookup all previously registered AASs
+ for(AASDescriptor aasDescriptor: aasDescriptors) {
+ try {
+ registry.lookupAAS(aasDescriptor.getIdentifier());
+ fail();
+ } catch (ResourceNotFoundException e) {
+ }
+
+ // Try to lookup all previously registered SMs
+ for(SubmodelDescriptor smDescriptor: aasDescriptor.getSubmodelDescriptors()) {
+ try {
+ registry.lookupSubmodel(aasDescriptor.getIdentifier(), smDescriptor.getIdentifier());
+ fail();
+ } catch (ResourceNotFoundException e) {
+ }
+ }
+ }
+
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/AASServerSuite.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/AASServerSuite.java
new file mode 100644
index 0000000..0ad88d7
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/AASServerSuite.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.AASServer;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Suite for testing that the AAS Server component is set up correctly. The
+ * tests here can be used by the component test itself and the integration test
+ *
+ * @author espen
+ *
+ */
+public abstract class AASServerSuite {
+ protected IAASRegistry aasRegistry;
+ protected ConnectedAssetAdministrationShellManager manager;
+
+ protected String aasId = "testId";
+
+ protected abstract String getURL();
+
+ @Before
+ public void setUp() {
+ // Create a dummy registry to test integration of XML AAS
+ aasRegistry = new InMemoryRegistry();
+
+ // Create ConnectedAASManager
+ IConnectorFactory connectorFactory = new HTTPConnectorFactory();
+ manager = new ConnectedAssetAdministrationShellManager(aasRegistry, connectorFactory);
+ }
+
+ @Test
+ public void testAddAAS() throws Exception {
+ AssetAdministrationShell shell = new AssetAdministrationShell();
+ IIdentifier identifier = new ModelUrn(aasId);
+ shell.setIdentification(identifier);
+ shell.setIdShort("aasIdShort");
+ manager.createAAS(shell, getURL());
+
+ IAssetAdministrationShell remote = manager.retrieveAAS(identifier);
+ assertEquals(shell.getIdShort(), remote.getIdShort());
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/AASXSuite.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/AASXSuite.java
new file mode 100644
index 0000000..2890927
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/AASXSuite.java
@@ -0,0 +1,185 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.AASServer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.Response;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.connected.ConnectedAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IFile;
+import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.ConnectedSubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedFile;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Suite for testing that the XMLAAS servlet is set up correctly. The tests here
+ * can be used by the servlet test itself and the integration test
+ *
+ * @author schnicke, espen
+ *
+ */
+public abstract class AASXSuite {
+ private static Logger logger = LoggerFactory.getLogger(AASXSuite.class);
+
+ protected IAASRegistry aasRegistry;
+
+ protected static final String aasShortId = "Festo_3S7PM0CP4BD";
+ protected static final ModelUrn aasId = new ModelUrn("smart.festo.com/demo/aas/1/1/454576463545648365874");
+ protected static final ModelUrn smId = new ModelUrn("www.company.com/ids/sm/4343_5072_7091_3242");
+ protected static final String smShortId = "Nameplate";
+
+ // Has to be individualized by each test inheriting from this suite
+ protected static String aasEndpoint;
+ protected static String smEndpoint;
+ protected static String rootEndpoint;
+
+ private ConnectedAssetAdministrationShellManager manager;
+
+ // create a REST client
+ private Client client = ClientBuilder.newClient();
+
+ /**
+ * Before each test, a dummy registry is created and an AAS is added in the
+ * registry
+ */
+ @Before
+ public void setUp() {
+ // Create a dummy registry to test integration of XML AAS
+ aasRegistry = new InMemoryRegistry();
+ AASDescriptor descriptor = new AASDescriptor(aasShortId, aasId, aasEndpoint);
+ descriptor.addSubmodelDescriptor(new SubmodelDescriptor(smShortId, smId, smEndpoint));
+ aasRegistry.register(descriptor);
+
+ // Create a ConnectedAssetAdministrationShell using a
+ // ConnectedAssetAdministrationShellManager
+ IConnectorFactory connectorFactory = new HTTPConnectorFactory();
+ manager = new ConnectedAssetAdministrationShellManager(aasRegistry, connectorFactory);
+ }
+
+ @Test
+ public void testGetSingleAAS() throws Exception {
+ ConnectedAssetAdministrationShell connectedAssetAdministrationShell = getConnectedAssetAdministrationShell();
+ assertEquals(aasShortId, connectedAssetAdministrationShell.getIdShort());
+ }
+
+ @Test
+ public void testGetSingleSubmodel() throws Exception {
+ ISubmodel subModel = getConnectedSubmodel();
+ assertEquals(smShortId, subModel.getIdShort());
+ }
+
+ @Test
+ public void testGetSingleModule() throws Exception {
+ final String FILE_ENDING = "files/aasx/Nameplate/marking_rcm.jpg";
+ final String FILE_PATH = rootEndpoint + "files/aasx/Nameplate/marking_rcm.jpg";
+ checkFile(FILE_PATH);
+
+ // Get the submdoel nameplate
+ ISubmodel nameplate = getConnectedSubmodel();
+ // Get the submodel element collection marking_rcm
+ ConnectedSubmodelElementCollection marking_rcm = (ConnectedSubmodelElementCollection) nameplate.getSubmodelElements().get("Marking_RCM");
+ Collection<ISubmodelElement> values = marking_rcm.getValue();
+
+ // navigate to the File element
+ Iterator<ISubmodelElement> iter = values.iterator();
+ while (iter.hasNext()) {
+ ISubmodelElement element = iter.next();
+ if (element instanceof ConnectedFile) {
+ ConnectedFile connectedFile = (ConnectedFile) element;
+ // get value of the file element
+
+ String fileurl = connectedFile.getValue();
+ assertTrue(fileurl.endsWith(FILE_ENDING));
+ }
+ }
+ }
+
+ @Test
+ public void testAllFiles() throws Exception {
+ logger.info("Checking all files");
+ ConnectedAssetAdministrationShell aas = getConnectedAssetAdministrationShell();
+ logger.info("AAS idShort: " + aas.getIdShort());
+ logger.info("AAS identifier: " + aas.getIdentification().getId());
+ Map<String, ISubmodel> submodels = aas.getSubmodels();
+ logger.info("# Submodels: " + submodels.size());
+ for (ISubmodel sm : submodels.values()) {
+ logger.info("Checking submodel: " + sm.getIdShort());
+ checkElementCollectionFiles(sm.getSubmodelElements().values());
+ }
+
+ }
+
+ private void checkElementCollectionFiles(Collection<ISubmodelElement> elements) {
+ for (ISubmodelElement element : elements) {
+ if (element instanceof IFile) {
+ String fileUrl = ((IFile) element).getValue();
+ checkFile(fileUrl);
+ } else if (element instanceof ISubmodelElementCollection) {
+ ISubmodelElementCollection col = (ISubmodelElementCollection) element;
+ checkElementCollectionFiles(col.getSubmodelElements().values());
+ }
+ }
+ }
+
+ private void checkFile(String absolutePath) {
+ // connect to the url of the aas
+ WebTarget webTarget = client.target(absolutePath);
+ logger.info("Checking file: " + absolutePath);
+ Invocation.Builder invocationBuilder = webTarget.request();
+ Response response = invocationBuilder.get();
+
+ // validate the response
+ assertEquals("Path check failed: " + absolutePath, 200, response.getStatus());
+ }
+
+ /**
+ * Gets the connected Asset Administration Shell
+ *
+ * @return connected AAS
+ * @throws Exception
+ */
+ private ConnectedAssetAdministrationShell getConnectedAssetAdministrationShell() throws Exception {
+ return manager.retrieveAAS(aasId);
+ }
+
+ /**
+ * Gets the connected Submodel
+ *
+ * @return connected SM
+ * @throws Exception
+ */
+ private ISubmodel getConnectedSubmodel() {
+ return manager.retrieveSubmodel(aasId, smId);
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/SimpleNoOpAASSubmodel.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/SimpleNoOpAASSubmodel.java
new file mode 100644
index 0000000..b115f5c
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/SimpleNoOpAASSubmodel.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.AASServer;
+
+import java.util.Map;
+
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.testsuite.regression.submodel.restapi.SimpleAASSubmodel;
+
+public class SimpleNoOpAASSubmodel extends SimpleAASSubmodel {
+
+ public SimpleNoOpAASSubmodel() {
+ this("SimpleAASSubmodel");
+ }
+
+ public SimpleNoOpAASSubmodel(String idShort) {
+ super(idShort);
+
+ // Remove operations
+ deleteSubmodelElement("complex");
+ deleteSubmodelElement("simple");
+ deleteSubmodelElement("exception1");
+ deleteSubmodelElement("exception2");
+
+ Map<String, ISubmodelElement> elems = this.getSubmodelElements();
+ SubmodelElementCollection root = (SubmodelElementCollection) elems.get("containerRoot");
+ SubmodelElementCollection opContainer = (SubmodelElementCollection) root.getSubmodelElement("container");
+ opContainer.deleteSubmodelElement("operationId");
+ Operation opReplacement = new Operation("operationId");
+ opContainer.addSubmodelElement(opReplacement);
+ }
+
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestAASXAASServer.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestAASXAASServer.java
new file mode 100644
index 0000000..5286a05
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestAASXAASServer.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.AASServer;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+
+import javax.servlet.ServletException;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
+import org.eclipse.basyx.components.aas.AASServerComponent;
+import org.eclipse.basyx.components.aas.configuration.AASServerBackend;
+import org.eclipse.basyx.components.aas.configuration.BaSyxAASServerConfiguration;
+import org.eclipse.basyx.components.aas.executable.AASServerExecutable;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.SAXException;
+/**
+ * Test accessing to AAS using basys aas SDK
+ *
+ * @author zhangzai
+ *
+ */
+public class TestAASXAASServer extends AASXSuite {
+ private static Logger logger = LoggerFactory.getLogger(TestAASXAASServer.class);
+ private static AASServerComponent component;
+
+ @BeforeClass
+ public static void setUpClass() throws ParserConfigurationException, SAXException, IOException, URISyntaxException, ServletException {
+ // Setup component's test configuration
+ BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
+ contextConfig.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
+ BaSyxAASServerConfiguration aasConfig = new BaSyxAASServerConfiguration(AASServerBackend.INMEMORY, "aasx/01_Festo.aasx");
+
+ // Load the additional file path relative to the executed jar file
+ String rootPath = new File(AASServerExecutable.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getParentFile().getPath();
+ String docBasePath = rootPath;
+ contextConfig.setDocBasePath(docBasePath);
+
+ // Start the component
+ component = new AASServerComponent(contextConfig, aasConfig);
+ component.startComponent();
+
+ rootEndpoint = "http://" + contextConfig.getHostname() + ":" + contextConfig.getPort() + "/"
+ + contextConfig.getContextPath() + "/";
+ aasEndpoint = rootEndpoint + "/" + AASAggregatorProvider.PREFIX + "/" + aasId.getEncodedURN() + "/aas";
+ smEndpoint = aasEndpoint + "/submodels/" + smShortId + "/submodel";
+ logger.info("AAS URL for servlet test: " + aasEndpoint);
+ }
+
+ @AfterClass
+ public static void tearDownClass() {
+ component.stopComponent();
+ }
+}
+
+
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestAASXPackageManager.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestAASXPackageManager.java
new file mode 100644
index 0000000..6f14e3f
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestAASXPackageManager.java
@@ -0,0 +1,389 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.AASServer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.eclipse.basyx.aas.factory.aasx.AASXFactory;
+import org.eclipse.basyx.aas.factory.aasx.InMemoryFile;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.components.aas.aasx.AASXPackageManager;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.parts.IConceptDescription;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.support.bundle.AASBundle;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.xml.sax.SAXException;
+
+/**
+ * J-Unit tests for AASx package explorer. This test checks the parsing of aas,
+ * submodels, assets and concept-descriptions. it also checks whether the aas
+ * have correct references to the asets and submodels
+ *
+ * @author zhangzai, conradi
+ *
+ */
+public class TestAASXPackageManager {
+ /**
+ * path to the aasx package
+ */
+ private static final String aasxPath = "aasx/01_Festo.aasx";
+
+ private static final String CREATED_AASX_PATH = "test.aasx";
+
+ /**
+ * the aasx package converter
+ */
+ private static AASXPackageManager packageConverter;
+
+ /**
+ * this string array is used to check the refs to submodels of aas
+ */
+ private String[] submodelids = { "www.company.com/ids/sm/6053_5072_7091_5102", "smart.festo.com/demo/sm/instance/1/1/13B7CCD9BF7A3F24", "www.company.com/ids/sm/4343_5072_7091_3242", "www.company.com/ids/sm/2543_5072_7091_2660",
+ "www.company.com/ids/sm/6563_5072_7091_4267"
+
+ };
+
+ /**
+ * Files that are unzipped
+ */
+ private static String[] unzipFiles = { "target/files/aasx/Document/docu.pdf", "target/files/icon.png"
+ };
+
+ /**
+ * AAS bundle which will be generated by the XMLAASBundleFactory
+ */
+ private Set<AASBundle> aasBundles;
+
+ /**
+ * Submodels parsed by the converter
+ */
+ private Set<ISubmodel> submodels;
+
+ /**
+ * Initialize the AASX package converter
+ */
+ @BeforeClass
+ public static void setup() {
+ // Create the aasx package converter with the path to the aasx package
+ packageConverter = new AASXPackageManager(aasxPath);
+ }
+
+ /**
+ * Test parsing of aas, assets, submodels and concept-descriptions
+ */
+ @Test
+ public void testCheckAasxConverter() {
+ // Parse aas from the XML and create the AAS Bundle with refs to submodels
+ try {
+ aasBundles = packageConverter.retrieveAASBundles();
+ } catch (ParserConfigurationException | SAXException | IOException | InvalidFormatException e) {
+ e.printStackTrace();
+ }
+
+ // check the information in the aas bundles
+ checkAASs(aasBundles);
+
+ // Check the submodels
+ checkSubmodels(submodels);
+ }
+
+
+ /**
+ * Creates a new .aasx using the AASXFactory and tries to parse it
+ */
+ @Test
+ public void testLoadGeneratedAASX()
+ throws InvalidFormatException, IOException, ParserConfigurationException, SAXException, TransformerException, URISyntaxException {
+
+ List<IAssetAdministrationShell> aasList = new ArrayList<>();
+ List<ISubmodel> submodelList = new ArrayList<>();
+ List<IAsset> assetList = new ArrayList<>();
+ List<IConceptDescription> conceptDescriptionList = new ArrayList<>();
+
+ List<InMemoryFile> fileList = new ArrayList<>();
+
+ Asset asset = new Asset("asset-id", new ModelUrn("ASSET_IDENTIFICATION"), AssetKind.INSTANCE);
+ AssetAdministrationShell aas = new AssetAdministrationShell("aasIdShort", new ModelUrn("aasId"), asset);
+ aas.setAssetReference((Reference) asset.getReference());
+
+ Submodel sm = new Submodel("smIdShort", new ModelUrn("smId"));
+
+ // Create File SubmodelElements
+ File file1 = new File("/icon.png", "image/png");
+ file1.setIdShort("file1");
+ File file2 = new File("/aasx/Document/docu.pdf", "application/pdf");
+ file2.setIdShort("file2");
+
+ SubmodelElementCollection collection = new SubmodelElementCollection("Marking_RCM");
+ collection.addSubmodelElement(file1);
+
+ sm.addSubmodelElement(collection);
+ sm.addSubmodelElement(file2);
+ aas.addSubmodel(sm);
+
+ aasList.add(aas);
+ submodelList.add(sm);
+ assetList.add(asset);
+
+ // Build InMemoryFiles for .aasx
+ byte[] content1 = {5,6,7,8,9};
+ InMemoryFile file = new InMemoryFile(content1, "/icon.png");
+ fileList.add(file);
+
+ byte[] content2 = {10,11,12,13,14};
+ file = new InMemoryFile(content2, "aasx/Document/docu.pdf");
+ fileList.add(file);
+
+ // Build AASX
+ FileOutputStream out = new FileOutputStream(CREATED_AASX_PATH);
+ AASXFactory.buildAASX(aasList, assetList, conceptDescriptionList, submodelList, fileList, out);
+
+ AASXPackageManager packageManager = new AASXPackageManager(CREATED_AASX_PATH);
+
+ checkBundle(packageManager.retrieveAASBundles(), aas, sm);
+
+ // Unzip files from the .aasx
+ packageManager.unzipRelatedFiles();
+
+ // Check if all expected files are present
+ for(String path: unzipFiles) {
+ assertTrue(new java.io.File(path).exists());
+ }
+
+ }
+
+ private void checkBundle(Set<AASBundle> bundles, IAssetAdministrationShell aas, ISubmodel sm) {
+ assertEquals(1, bundles.size());
+ AASBundle bundle = bundles.stream().findFirst().get();
+
+ IAssetAdministrationShell parsedAAS = bundle.getAAS();
+ assertEquals(aas.getIdShort(), parsedAAS.getIdShort());
+ assertEquals(aas.getIdentification().getId(), parsedAAS.getIdentification().getId());
+
+ assertEquals(1, bundle.getSubmodels().size());
+ ISubmodel parsedSubmodel = bundle.getSubmodels().stream().findFirst().get();
+ assertEquals(sm.getIdShort(), parsedSubmodel.getIdShort());
+ assertEquals(sm.getIdentification().getId(), parsedSubmodel.getIdentification().getId());
+ assertEquals(sm.getSubmodelElements().size(), parsedSubmodel.getSubmodelElements().size());
+ }
+
+
+ /**
+ * Check the parsed aas with expected ones
+ *
+ * @param aasList
+ */
+ private void checkAASs(Set<AASBundle> aasBundles) {
+ assertEquals(2, aasBundles.size());
+
+ IAssetAdministrationShell aas = null;
+
+ // select the AAS with a specific ID from the list
+ Optional<AASBundle> testAASBundleOptional = aasBundles.stream().filter(b -> b.getAAS().getIdShort().equals("Festo_3S7PM0CP4BD")).findFirst();
+ // verify there exist one aas with this ID
+ assertTrue(testAASBundleOptional.isPresent());
+
+ // Get the aasbundle from the filtered results
+ AASBundle testAASBundle = testAASBundleOptional.get();
+ aas = testAASBundle.getAAS();
+
+ // get submodels of this aas
+ submodels = testAASBundle.getSubmodels();
+
+ // verify short id
+ assertEquals("Festo_3S7PM0CP4BD", aas.getIdShort());
+ assertEquals("CONSTANT", aas.getCategory());
+
+ // verify id and id-type
+ assertEquals("smart.festo.com/demo/aas/1/1/454576463545648365874", aas.getIdentification().getId());
+ assertEquals(IdentifierType.IRI, aas.getIdentification().getIdType());
+
+
+ // Get submodel references
+ Collection<IReference> references = aas.getSubmodelReferences();
+
+ // this aas has 5 submodels
+ assertEquals(5, references.size());
+ List<IReference> referencelist = new ArrayList<>();
+ referencelist.addAll(references);
+
+ // sort the list for later assertion
+ // list is sorted by the last two characters of the id
+ referencelist.sort((x, y) -> {
+ String idx = x.getKeys().get(0).getValue();
+ String idy = y.getKeys().get(0).getValue();
+
+ String idx_end = idx.substring(idx.length() - 2);
+ int idxint = Integer.parseInt(idx_end);
+ String idy_end = idy.substring(idy.length() - 2);
+ int idyint = Integer.parseInt(idy_end);
+
+ return idxint - idyint;
+
+ });
+
+ // get First submodel reference
+ for (int i = 0; i < referencelist.size(); i++) {
+ IReference ref = referencelist.get(i);
+ List<IKey> refKeys = ref.getKeys();
+
+ // assert the submodel id
+ assertEquals(submodelids[i], refKeys.get(0).getValue());
+ // assert the id type
+ assertEquals("IRI", refKeys.get(0).getIdType().name());
+ // assert the model type
+ assertEquals("SUBMODEL", refKeys.get(0).getType().name());
+ // submodels are local
+ assertEquals(true, refKeys.get(0).isLocal());
+ }
+
+ }
+
+ /**
+ * Check parsed submodels with expected ones
+ *
+ * @param submodels
+ */
+ private void checkSubmodels(Set<ISubmodel> submodels) {
+ assertEquals(5, submodels.size());
+
+ // filter the submodel with id "Nameplate"
+ Optional<ISubmodel> sm1Optional = submodels.stream().filter(s -> s.getIdShort().equals("Nameplate")).findFirst();
+ assertTrue(sm1Optional.isPresent());
+ ISubmodel sm1 = sm1Optional.get();
+
+ // verify short id, id-type, id and model-kind of the submodel
+ assertEquals("Nameplate", sm1.getIdShort());
+ assertEquals("IRI", sm1.getIdentification().getIdType().name());
+ assertEquals("www.company.com/ids/sm/4343_5072_7091_3242", sm1.getIdentification().getId());
+ assertEquals("Instance", sm1.getModelingKind().toString());
+
+ // ---------------------------------------------
+ // get 1st submodel element
+ // Get submodel elements
+ Map<String, ISubmodelElement> smElements = sm1.getSubmodelElements();
+
+ // get element manufacturing name
+ ISubmodelElement sele = smElements.get("ManufacturerName");
+
+ // verify short id
+ assertEquals("ManufacturerName", sele.getIdShort());
+
+ // verify category and model-kind, value and value-type
+ assertEquals("PARAMETER", sele.getCategory());
+ assertTrue(sele.getModelingKind().name().equalsIgnoreCase("Instance"));
+ Property prop = (Property) sele;
+ assertEquals("Festo AG & Co. KG", prop.getValue());
+ assertEquals(ValueType.String, prop.getValueType());
+
+ // get semantic id
+ IReference semantic = sele.getSemanticId();
+
+ IKey semanticKey = semantic.getKeys().get(0);
+ assertTrue(semanticKey.getType().name().equalsIgnoreCase("ConceptDescription"));
+ assertEquals("IRDI", semanticKey.getIdType().name());
+ assertEquals("0173-1#02-AAO677#002", semanticKey.getValue());
+ assertEquals(true, semanticKey.isLocal());
+
+ /// ---------------------------------------------
+ // get 2nd submodel element
+ // Get submodel elements
+ sele = smElements.get("ManufacturerProductDesignation");
+ assertEquals("ManufacturerProductDesignation", sele.getIdShort());
+ assertEquals("PARAMETER", sele.getCategory());
+ assertTrue(sele.getModelingKind().name().equalsIgnoreCase("Instance"));
+ prop = (Property) sele;
+ assertEquals("OVEL Vacuum generator", prop.getValue());
+ assertEquals(ValueType.String, prop.getValueType());
+
+ // get semantic id
+ semantic = sele.getSemanticId();
+ semanticKey = semantic.getKeys().get(0);
+ assertTrue(semanticKey.getType().name().equalsIgnoreCase("ConceptDescription"));
+ assertEquals("IRDI", semanticKey.getIdType().name());
+ assertEquals("0173-1#02-AAW338#001", semanticKey.getValue());
+ assertEquals(true, semanticKey.isLocal());
+
+ // ---------------------------------------------
+ // get 3rd submodel element
+ // Get submodel elements
+ sele = smElements.get("PhysicalAddress");
+ assertEquals("PhysicalAddress", sele.getIdShort());
+ assertEquals("PARAMETER", sele.getCategory());
+ assertTrue(sele.getModelingKind().name().equalsIgnoreCase("Instance"));
+
+ // get semantic id
+ semantic = sele.getSemanticId();
+ semanticKey = semantic.getKeys().get(0);
+ assertTrue(semanticKey.getType().name().equalsIgnoreCase("ConceptDescription"));
+ assertEquals("IRI", semanticKey.getIdType().name());
+ assertEquals("https://www.hsu-hh.de/aut/aas/physicaladdress", semanticKey.getValue());
+ assertEquals(true, semanticKey.isLocal());
+
+ // get values
+ assertTrue(sele.getModelType().equalsIgnoreCase("SubmodelElementCollection"));
+ SubmodelElementCollection collection = (SubmodelElementCollection) sele;
+ Map<String, ISubmodelElement> smElemMap = collection.getSubmodelElements();
+
+ assertEquals(5, smElemMap.size());
+ Property prop1 = (Property) smElemMap.get("CountryCode");
+ assertEquals("CountryCode", prop1.getIdShort());
+ assertEquals("DE", prop1.getValue());
+
+ Property prop2 = (Property) smElemMap.get("Street");
+ assertEquals("Street", prop2.getIdShort());
+ assertEquals("Ruiter Straße 82", prop2.getValue());
+ }
+
+
+ /**
+ * Delete created files
+ */
+ @AfterClass
+ public static void cleanUp() {
+ for(String path: unzipFiles) {
+ new java.io.File(path).delete();
+ }
+ new java.io.File(CREATED_AASX_PATH).delete();
+ }
+
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestFileEndpointLoader.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestFileEndpointLoader.java
new file mode 100644
index 0000000..4a49cdf
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestFileEndpointLoader.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.AASServer;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Map;
+
+import org.eclipse.basyx.components.aas.aasx.SubmodelFileEndpointLoader;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IFile;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests the SubmodelFileEndpointLoader
+ *
+ * @author espen
+ *
+ */
+public class TestFileEndpointLoader {
+ private Submodel submodel;
+ private final String relativePath = "/file/root/text.txt";
+ private final String absolutePath = "http://localhost:1234/file/root/text.txt";
+ private final String relativeTargetPath = "http://localhost:4321/new/file/root/text.txt";
+
+ @Before
+ public void setup() {
+ File fRel = new File(relativePath, "application/json");
+ fRel.setIdShort("fRel");
+ File fAbs = new File(absolutePath, "application/json");
+ fAbs.setIdShort("fAbs");
+ SubmodelElementCollection col = new SubmodelElementCollection();
+ col.setIdShort("fileCollection");
+ File fCol = new File(relativePath, "application/json");
+ fCol.setIdShort("fInside");
+ col.addSubmodelElement(fCol);
+ submodel = new Submodel("FileTestSubmodel", new Identifier(IdentifierType.IRDI, "FileTestSubmodel"));
+ submodel.addSubmodelElement(fRel);
+ submodel.addSubmodelElement(fAbs);
+ submodel.addSubmodelElement(col);
+ }
+
+ /**
+ * Tests setting a static string endpoint (relative to the given path in the existing value)
+ */
+ @Test
+ public void testRelativePaths1() {
+ SubmodelFileEndpointLoader.setRelativeFileEndpoints(submodel, "http://localhost:4321/new");
+ checkRelativeTargetPaths();
+ }
+
+ /**
+ * Tests setting a endpoint via host, port and root path (relative to the given path in the existing value)
+ */
+ @Test
+ public void testRelativePaths2() {
+ SubmodelFileEndpointLoader.setRelativeFileEndpoints(submodel, "localhost", 4321, "/new");
+ checkRelativeTargetPaths();
+ }
+
+ /**
+ * Tests elements inside of collections
+ */
+ @Test
+ public void testCollections() {
+ SubmodelFileEndpointLoader.setRelativeFileEndpoints(submodel, "localhost", 4321, "/new");
+
+ Map<String, ISubmodelElement> elements = submodel.getSubmodelElements();
+ SubmodelElementCollection col = (SubmodelElementCollection) elements.get("fileCollection");
+ IFile file = (IFile) col.getSubmodelElements().get("fInside");
+ assertEquals(relativeTargetPath, file.getValue());
+ }
+
+ private void checkRelativeTargetPaths() {
+ Map<String, ISubmodelElement> elements = submodel.getSubmodelElements();
+
+ String fromRelative = ((IFile) elements.get("fRel")).getValue();
+ assertEquals(relativeTargetPath, fromRelative);
+
+ String fromAbsolute = ((IFile) elements.get("fAbs")).getValue();
+ assertEquals(relativeTargetPath, fromAbsolute);
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestInMemoryAASServer.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestInMemoryAASServer.java
new file mode 100644
index 0000000..06531f3
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestInMemoryAASServer.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.AASServer;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.eclipse.basyx.components.aas.AASServerComponent;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.xml.sax.SAXException;
+
+/**
+ * Tests the component using the test suite
+ *
+ * @author schnicke
+ *
+ */
+public class TestInMemoryAASServer extends AASServerSuite {
+
+ private static AASServerComponent component;
+
+ @Override
+ protected String getURL() {
+ return component.getURL() + "/shells";
+ }
+
+ @BeforeClass
+ public static void setUpClass() throws ParserConfigurationException, SAXException, IOException {
+ BaSyxContextConfiguration config = new BaSyxContextConfiguration();
+ config.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
+
+ component = new AASServerComponent(config);
+ component.startComponent();
+ }
+
+ @AfterClass
+ public static void tearDownClass() {
+ component.stopComponent();
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestJSONAASServer.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestJSONAASServer.java
new file mode 100644
index 0000000..b74b9b3
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestJSONAASServer.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.AASServer;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Map;
+
+import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.connected.ConnectedAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
+import org.eclipse.basyx.components.aas.AASServerComponent;
+import org.eclipse.basyx.components.aas.configuration.AASServerBackend;
+import org.eclipse.basyx.components.aas.configuration.BaSyxAASServerConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Suite for testing that the JSONAAS servlet is set up correctly. The tests here
+ * can be used by the servlet test itself and the integration test
+ *
+ * @author JSON
+ *
+ */
+public class TestJSONAASServer {
+ private static Logger logger = LoggerFactory.getLogger(TestJSONAASServer.class);
+
+ protected static final String aasShortId = "ExampleMotor";
+ protected static final ModelUrn aasId = new ModelUrn("http://customer.com/aas/9175_7013_7091_9168");
+ protected static final ModelUrn smId = new ModelUrn("http.//i40.customer.com/type/1/1/7A7104BDAB57E184");
+ protected static final String smShortId = "TechnicalData";
+ protected static final String smShortId2 = "Documentation";
+ protected static final String smShortId3 = "OperationalData";
+
+ // Has to be individualized by each test inheriting from this suite
+ protected static String aasEndpoint;
+ protected static String smEndpoint;
+
+ // Registry and AAS component
+ protected static IAASRegistry registry;
+ protected static AASServerComponent component;
+ protected static ConnectedAssetAdministrationShellManager manager;
+
+ @BeforeClass
+ public static void setUp() {
+ // Setup component's test configuration
+ BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
+ contextConfig.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
+ BaSyxAASServerConfiguration aasConfig = new BaSyxAASServerConfiguration(AASServerBackend.INMEMORY,
+ "json/aas.json");
+
+ // Setup endpoints
+ String rootEndpoint = "http://" + contextConfig.getHostname() + ":" + contextConfig.getPort() + "/"
+ + contextConfig.getContextPath() + "/";
+ aasEndpoint = rootEndpoint + "/" + AASAggregatorProvider.PREFIX + "/" + aasId.getEncodedURN() + "/aas";
+ smEndpoint = aasEndpoint + "/submodels/" + smShortId + "/submodel";
+ logger.info("AAS URL for servlet test: " + aasEndpoint);
+
+ // Create and start AASServer component
+ component = new AASServerComponent(contextConfig, aasConfig);
+ registry = new InMemoryRegistry();
+ component.setRegistry(registry);
+ component.startComponent();
+
+ // Create a ConnectedAssetAdministrationShell using a
+ // ConnectedAssetAdministrationShellManager
+ IConnectorFactory connectorFactory = new HTTPConnectorFactory();
+ manager = new ConnectedAssetAdministrationShellManager(registry, connectorFactory);
+ }
+
+
+ @AfterClass
+ public static void tearDown() {
+ component.stopComponent();
+ }
+
+ @Test
+ public void testGetSingleAAS() throws Exception {
+ ConnectedAssetAdministrationShell connectedAssetAdministrationShell = getConnectedAssetAdministrationShell();
+ assertEquals(aasShortId, connectedAssetAdministrationShell.getIdShort());
+ }
+
+ @Test
+ public void testGetSingleSubmodel() throws Exception {
+ ISubmodel subModel = getConnectedSubmodel();
+ assertEquals(smShortId, subModel.getIdShort());
+ }
+
+ @Test
+ public void testGetAllSubmodels() throws Exception {
+ Map<String, ISubmodel> subModels = getAllConnectedSubmodels();
+ assertEquals(3, subModels.size());
+ assertEquals(smShortId, subModels.get(smShortId).getIdShort());
+ assertEquals(smShortId2, subModels.get(smShortId2).getIdShort());
+ assertEquals(smShortId3, subModels.get(smShortId3).getIdShort());
+ }
+
+ /**
+ * Gets the connected Asset Administration Shell
+ *
+ * @return connected AAS
+ * @throws Exception
+ */
+ private ConnectedAssetAdministrationShell getConnectedAssetAdministrationShell() throws Exception {
+ return manager.retrieveAAS(aasId);
+ }
+
+ /**
+ * Gets the connected Submodel
+ *
+ * @return connected SM
+ * @throws Exception
+ */
+ private ISubmodel getConnectedSubmodel() {
+ return manager.retrieveSubmodel(aasId, smId);
+ }
+
+ /**
+ * Gets all connected Submodels
+ *
+ * @return connected SM
+ * @throws Exception
+ */
+ private Map<String, ISubmodel> getAllConnectedSubmodels() {
+ return manager.retrieveSubmodels(aasId);
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestMongoDBAggregator.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestMongoDBAggregator.java
new file mode 100644
index 0000000..0295aa6
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestMongoDBAggregator.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.AASServer;
+
+import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
+import org.eclipse.basyx.components.aas.mongodb.MongoDBAASAggregator;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.testsuite.regression.aas.aggregator.AASAggregatorSuite;
+
+public class TestMongoDBAggregator extends AASAggregatorSuite {
+
+ @Override
+ protected IAASAggregator getAggregator() {
+ MongoDBAASAggregator aggregator = new MongoDBAASAggregator(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
+ aggregator.reset();
+
+ return aggregator;
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestMongoDBServer.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestMongoDBServer.java
new file mode 100644
index 0000000..c014157
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestMongoDBServer.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.AASServer;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.components.aas.AASServerComponent;
+import org.eclipse.basyx.components.aas.configuration.AASServerBackend;
+import org.eclipse.basyx.components.aas.configuration.BaSyxAASServerConfiguration;
+import org.eclipse.basyx.components.aas.mongodb.MongoDBAASAggregator;
+import org.eclipse.basyx.components.aas.mongodb.MongoDBSubmodelAPI;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxMongoDBConfiguration;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.xml.sax.SAXException;
+
+/**
+ * Tests the component using the test suite
+ *
+ * @author espen
+ *
+ */
+public class TestMongoDBServer extends AASServerSuite {
+
+ private static AASServerComponent component;
+ private static BaSyxMongoDBConfiguration mongoDBConfig;
+
+ @Override
+ protected String getURL() {
+ return component.getURL() + "/shells";
+ }
+
+ @BeforeClass
+ public static void setUpClass() throws ParserConfigurationException, SAXException, IOException {
+ // just reset the data with this default db configuration
+ new MongoDBAASAggregator(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH).reset();
+
+ // Setup component configuration
+ BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
+ contextConfig.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
+ mongoDBConfig = new BaSyxMongoDBConfiguration();
+ BaSyxAASServerConfiguration aasConfig = new BaSyxAASServerConfiguration(AASServerBackend.MONGODB, "");
+
+ // Start component
+ component = new AASServerComponent(contextConfig, aasConfig, mongoDBConfig);
+ component.startComponent();
+ }
+
+ @Test
+ public void testAddSubmodelPersistency() throws Exception {
+ testAddAAS();
+
+ Submodel sm = new Submodel("MongoDB", new Identifier(IdentifierType.CUSTOM, "MongoDBId"));
+ manager.createSubmodel(new ModelUrn(aasId), sm);
+
+ MongoDBSubmodelAPI api = new MongoDBSubmodelAPI(mongoDBConfig, sm.getIdentification().getId());
+ ISubmodel persistentSM = api.getSubmodel();
+ assertEquals("MongoDB", persistentSM.getIdShort());
+ }
+
+ @AfterClass
+ public static void tearDownClass() {
+ component.stopComponent();
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestMongoDBSubmodelProvider.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestMongoDBSubmodelProvider.java
new file mode 100644
index 0000000..6004fd0
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestMongoDBSubmodelProvider.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.AASServer;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.basyx.components.aas.mongodb.MongoDBAASAggregator;
+import org.eclipse.basyx.components.aas.mongodb.MongoDBSubmodelAPI;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
+import org.eclipse.basyx.testsuite.regression.submodel.restapi.SubmodelProviderTest;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.TestsuiteDirectory;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.protocol.api.ConnectorFactory;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class TestMongoDBSubmodelProvider extends SubmodelProviderTest {
+ private VABConnectionManager connManager;
+
+ @BeforeClass
+ public static void setUpClass() {
+ // just reset the data with this default db configuration
+ new MongoDBAASAggregator(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH).reset();
+ }
+
+ @Override
+ protected VABConnectionManager getConnectionManager() {
+ if (connManager == null) {
+ connManager = new VABConnectionManager(new TestsuiteDirectory(), new ConnectorFactory() {
+ @Override
+ protected IModelProvider createProvider(String addr) {
+ SimpleNoOpAASSubmodel submodel = new SimpleNoOpAASSubmodel();
+ MongoDBSubmodelAPI api = new MongoDBSubmodelAPI("mySubmodelId");
+ api.setSubmodel(submodel);
+ IModelProvider smProvider = new SubmodelProvider(api);
+ // Simple submodel for testing specific mappings for submodels
+ return smProvider;
+ }
+ });
+ }
+ return connManager;
+ }
+
+ /**
+ * Operations are not supported
+ */
+ @Override
+ @Test
+ public void testDeleteOperation() {
+ }
+
+ /**
+ * Operations are not supported
+ */
+ @Override
+ @Test
+ public void testInvokeOperation() {
+ }
+
+ /**
+ * Operations are not supported
+ */
+ @Override
+ @Test
+ public void testInvokeOperationInCollection() {
+ }
+
+ /**
+ * Operations are not supported
+ */
+ @Override
+ @Test
+ public void testInvokeAsync() throws Exception {
+ }
+
+ /**
+ * Operations are not supported
+ */
+ @Override
+ @Test
+ public void testInvokeAsyncException() throws Exception {
+ }
+
+ /**
+ * Now 4 instead of 8 elements
+ */
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testReadSubmodelElements() {
+ VABElementProxy submodel = getConnectionManager().connectToVABElement(submodelAddr);
+ Collection<Map<String, Object>> set = (Collection<Map<String, Object>>) submodel
+ .getValue("/submodel/submodelElements");
+ assertEquals(4, set.size());
+ }
+
+ /**
+ * Operations are not supported
+ */
+ @Test
+ public void testReadSingleOperation() {
+ }
+
+ /**
+ * testReadOperations
+ */
+ @Test
+ public void testReadOperations() {
+ }
+
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestXMLAASServer.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestXMLAASServer.java
new file mode 100644
index 0000000..a5d00bf
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestXMLAASServer.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.AASServer;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.connected.ConnectedAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
+import org.eclipse.basyx.components.aas.AASServerComponent;
+import org.eclipse.basyx.components.aas.configuration.AASServerBackend;
+import org.eclipse.basyx.components.aas.configuration.BaSyxAASServerConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Suite for testing that the XMLAAS servlet is set up correctly. The tests here
+ * can be used by the servlet test itself and the integration test
+ *
+ * @author schnicke
+ *
+ */
+public class TestXMLAASServer {
+ private static Logger logger = LoggerFactory.getLogger(TestXMLAASServer.class);
+
+ protected static final String aasShortId = "aas1";
+ protected static final ModelUrn aasId = new ModelUrn("www.admin-shell.io/aas-sample/2/0");
+ protected static final ModelUrn smId = new ModelUrn("http://www.zvei.de/demo/submodel/12345679");
+ protected static final String smShortId = "submodel1";
+
+ // Has to be individualized by each test inheriting from this suite
+ protected static String aasEndpoint;
+ protected static String smEndpoint;
+
+ // Registry and AAS component
+ protected static IAASRegistry registry;
+ protected static AASServerComponent component;
+ protected static ConnectedAssetAdministrationShellManager manager;
+
+ @BeforeClass
+ public static void setUp() {
+ // Setup component's test configuration
+ BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
+ contextConfig.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
+ BaSyxAASServerConfiguration aasConfig = new BaSyxAASServerConfiguration(AASServerBackend.INMEMORY, "xml/aas.xml");
+
+ // Setup endpoints
+ String rootEndpoint = "http://" + contextConfig.getHostname() + ":" + contextConfig.getPort() + "/"
+ + contextConfig.getContextPath() + "/";
+ aasEndpoint = rootEndpoint + "/" + AASAggregatorProvider.PREFIX + "/" + aasId.getEncodedURN() + "/aas";
+ smEndpoint = aasEndpoint + "/submodels/" + smShortId + "/submodel";
+ logger.info("AAS URL for servlet test: " + aasEndpoint);
+
+ // Create and start AASServer component
+ component = new AASServerComponent(contextConfig, aasConfig);
+ registry = new InMemoryRegistry();
+ component.setRegistry(registry);
+ component.startComponent();
+
+ // Create a ConnectedAssetAdministrationShell using a
+ // ConnectedAssetAdministrationShellManager
+ IConnectorFactory connectorFactory = new HTTPConnectorFactory();
+ manager = new ConnectedAssetAdministrationShellManager(registry, connectorFactory);
+ }
+
+
+ @AfterClass
+ public static void tearDown() {
+ component.stopComponent();
+ }
+
+ @Test
+ public void testGetSingleAAS() throws Exception {
+ ConnectedAssetAdministrationShell connectedAssetAdministrationShell = getConnectedAssetAdministrationShell();
+ assertEquals(aasShortId, connectedAssetAdministrationShell.getIdShort());
+ }
+
+ @Test
+ public void testGetSingleSubmodel() throws Exception {
+ ISubmodel subModel = getConnectedSubmodel();
+ assertEquals(smShortId, subModel.getIdShort());
+ }
+
+ /**
+ * Gets the connected Asset Administration Shell
+ *
+ * @return connected AAS
+ * @throws Exception
+ */
+ private ConnectedAssetAdministrationShell getConnectedAssetAdministrationShell() throws Exception {
+ return manager.retrieveAAS(aasId);
+ }
+
+ /**
+ * Gets the connected Submodel
+ *
+ * @return connected SM
+ * @throws Exception
+ */
+ private ISubmodel getConnectedSubmodel() {
+ return manager.retrieveSubmodel(aasId, smId);
+ }
+
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/resources/.env b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/resources/.env
new file mode 100644
index 0000000..dc2072c
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/resources/.env
@@ -0,0 +1,38 @@
+# ##################
+# Docker Environment
+# ##################
+
+# ##################
+# Host Port
+# ##################
+# Specifies the port for the Docker HOST the container port is mapped to
+
+BASYX_HOST_PORT=8082
+
+# ##################
+# Container Port
+# ##################
+# Specifies the port for the Docker CONTAINER that is be mapped for the host
+
+BASYX_CONTAINER_PORT=4001
+
+# ##################
+# Image Name
+# ##################
+# The image of the image that is build for this component
+
+BASYX_IMAGE_NAME=eclipsebasyx/aas-server
+
+# ##################
+# Image Tag
+# ##################
+# The image tag of the image that is build for this component
+
+BASYX_IMAGE_TAG=1.0.0
+
+# ##################
+# Container Name
+# ##################
+# The name of the container used for the default environment
+
+BASYX_CONTAINER_NAME=aas
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/resources/dockerMongodb.properties b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/resources/dockerMongodb.properties
new file mode 100644
index 0000000..7e9af7f
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/resources/dockerMongodb.properties
@@ -0,0 +1,34 @@
+# #############################
+# MongoDB Backend configuration
+# #############################
+
+# #############################
+# Database Name
+# #############################
+# The database in the MongoDB that hold the data
+
+dbname=admin
+
+# #############################
+# Connection String
+# #############################
+# MongoDB connection string for connecting to the MongoDB endpoint
+# Here it is not localhost, because the container has to address the mongodb
+# container in the default docker environment used in this component
+
+dbconnectionstring=mongodb://mongodb:27017/
+
+# #############################
+# AAS collections
+# #############################
+# Collection names that are used for storing the AAS and Submodels
+
+dbcollectionAAS=assetadministrationshells
+dbcollectionSubmodels=submodels
+
+# #############################
+# Registry Collections
+# #############################
+# Collection name that is used for storing registry data
+
+dbcollectionRegistry=registry
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/start.bat b/components/basys.components/basyx.components.docker/basyx.components.AASServer/start.bat
new file mode 100644
index 0000000..f0ff9e1
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/start.bat
@@ -0,0 +1,3 @@
+cd src/test/resources
+docker-compose up
+cd ../../..
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/start.sh b/components/basys.components/basyx.components.docker/basyx.components.AASServer/start.sh
new file mode 100755
index 0000000..4b9b54a
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/start.sh
@@ -0,0 +1,4 @@
+#!/usr/bin/env sh
+cd src/test/resources
+docker-compose up
+cd ../../..
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/stop.bat b/components/basys.components/basyx.components.docker/basyx.components.AASServer/stop.bat
new file mode 100644
index 0000000..b645246
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/stop.bat
@@ -0,0 +1,3 @@
+cd src/test/resources
+docker-compose down
+cd ../../..
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/stop.sh b/components/basys.components/basyx.components.docker/basyx.components.AASServer/stop.sh
new file mode 100755
index 0000000..e11a931
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/stop.sh
@@ -0,0 +1,4 @@
+#!/usr/bin/env sh
+cd src/test/resources
+docker-compose down
+cd ../../..
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/Dockerfile b/components/basys.components/basyx.components.docker/basyx.components.AASX/Dockerfile
deleted file mode 100644
index 3628774..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASX/Dockerfile
+++ /dev/null
@@ -1,15 +0,0 @@
-# Add java runtime environment for execution
-FROM java:8-jdk-alpine
-
-# Copy built jar to image using the jar name specified in the pom.xml (JAR_FILE)
-ARG JAR_FILE
-COPY target/${JAR_FILE} /usr/share/basyxExecutable.jar
-COPY target/lib /usr/share/lib
-COPY src/main/resources/context.properties /usr/share/context.properties
-
-# Expose the appropriate port. In case of Tomcat, this is 8080.
-ARG PORT
-EXPOSE ${PORT}
-
-# Start the jar
-CMD java -jar "/usr/share/basyxExecutable.jar" "/usr/share/context.properties"
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/docker-compose.yml b/components/basys.components/basyx.components.docker/basyx.components.AASX/docker-compose.yml
deleted file mode 100644
index 7e029c5..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASX/docker-compose.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-version: '3'
-services:
-
- registry:
- image: ${BASYX_IMAGE_NAME}:${BASYX_IMAGE_TAG}
- container_name: ${BASYX_CONTAINER_NAME}
- ports:
- - ${BASYX_HOST_PORT}:${BASYX_CONTAINER_PORT}
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/pom.xml b/components/basys.components/basyx.components.docker/basyx.components.AASX/pom.xml
deleted file mode 100644
index 2e985e6..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASX/pom.xml
+++ /dev/null
@@ -1,89 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
-
- <parent>
- <groupId>org.eclipse.basyx</groupId>
- <artifactId>basyx.components.docker</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- </parent>
-
- <artifactId>basyx.components.AASX</artifactId>
- <name>BaSyx AASX Docker Component</name>
-
- <properties>
- <!--
- basyx.components.executable is the executable class with the definition of the public void main(String[]).
- It is needed when building the jar in the maven-jar-plugin (see basyx.components.docker/pom.xml)
- -->
- <basyx.components.executable>org.eclipse.basyx.components.executable.AASXExecutable</basyx.components.executable>
- </properties>
-
- <packaging>jar</packaging>
-
- <!-- Define additional plugins that are not included by default -->
- <!-- Plugin configuration is done in parent project(s) -->
- <build>
- <plugins>
- <!-- Attach sources to jar file -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-
- <dependencies>
- <!-- This component is based on the xmlAAS component -->
- <dependency>
- <groupId>org.eclipse.basyx</groupId>
- <artifactId>basyx.components.xmlAAS</artifactId>
- <version>${project.version}</version>
- </dependency>
- </dependencies>
-
- <profiles>
- <profile>
- <!--
- "Docker" profile - do not build & install docker images by default
- Run "mvn install -Pdocker" in order to include docker
- -->
- <id>docker</id>
- <build>
- <plugins>
- <!-- Read maven properties from file -->
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>properties-maven-plugin</artifactId>
- </plugin>
-
- <!-- Copy the dependencies necessary to run the jar -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-dependency-plugin</artifactId>
- </plugin>
-
- <!-- Build the docker image -->
- <plugin>
- <groupId>com.spotify</groupId>
- <artifactId>dockerfile-maven-plugin</artifactId>
- </plugin>
-
- <!-- Create integration test environment -->
- <plugin>
- <groupId>com.dkanejs.maven.plugins</groupId>
- <artifactId>docker-compose-maven-plugin</artifactId>
- </plugin>
-
- <!-- Run integration tests -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-failsafe-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
- </profile>
- </profiles>
-</project>
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/java/org/eclipse/basyx/components/AASXComponent.java b/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/java/org/eclipse/basyx/components/AASXComponent.java
deleted file mode 100644
index f2abd28..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/java/org/eclipse/basyx/components/AASXComponent.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package org.eclipse.basyx.components;
-
-
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.util.Set;
-
-import javax.servlet.ServletException;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.apache.catalina.servlets.DefaultServlet;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
-import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
-import org.eclipse.basyx.components.aasx.AASXPackageManager;
-import org.eclipse.basyx.components.servlet.aas.AASBundleServlet;
-import org.eclipse.basyx.support.bundle.AASBundle;
-import org.eclipse.basyx.vab.protocol.http.server.AASHTTPServer;
-import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
-import org.xml.sax.SAXException;
-
-/**
- * A component that takes an AASX file and provides it via an HTTP server
- *
- * @author schnicke, espen
- *
- */
-public class AASXComponent extends XMLAASComponent {
- public AASXComponent(String hostName, int port, String path, String docBasePath, String aasxPath,
- String registryUrl) throws IOException, ParserConfigurationException, SAXException, URISyntaxException {
- super(hostName, port, path, docBasePath);
-
- // Instantiate the aasx package manager
- AASXPackageManager packageManager = new AASXPackageManager(aasxPath);
-
- // Unpack the files referenced by the aas
- packageManager.unzipRelatedFiles(aasxPath);
-
- // Retrieve the aas from the package
- Set<AASBundle> aasBundles = packageManager.retrieveAASBundles();
-
- setAASBundle(aasBundles);
- setRegistryUrl(registryUrl);
- }
-
- /**
- * Starts the AASX component at http://${hostName}:${port}/${path}
- *
- * @param hostName
- * @param port
- * @param path
- * @param docBasePath
- * @throws ServletException
- * @throws IOException
- * @throws SAXException
- * @throws ParserConfigurationException
- */
- @Override
- public void startComponent() {
- // Init HTTP context and add an XMLAAServlet according to the configuration
-
- BaSyxContext context = new BaSyxContext(path, docBasePath, hostName, port);
- // Create the Servlet for aas
- context.addServletMapping("/*", new AASBundleServlet(aasBundles));
- context.addServletMapping("/aasx/*", new DefaultServlet());
- server = new AASHTTPServer(context);
-
- // logger.info("Start the server...");
- server.start();
-
- if (registryUrl != null && !registryUrl.isEmpty()) {
- // logger.info("Registering AAS at registry \"" + registryUrl + "\"...");
- AASRegistryProxy registryProxy = new AASRegistryProxy(registryUrl);
- Set<AASDescriptor> descriptors = retrieveDescriptors();
- descriptors.stream().forEach(registryProxy::register);
- } else {
- // logger.info("No registry specified, skipped registration");
- }
- }
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/java/org/eclipse/basyx/components/aasx/AASXPackageManager.java b/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/java/org/eclipse/basyx/components/aasx/AASXPackageManager.java
deleted file mode 100644
index 485b391..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/java/org/eclipse/basyx/components/aasx/AASXPackageManager.java
+++ /dev/null
@@ -1,376 +0,0 @@
-package org.eclipse.basyx.components.aasx;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.apache.commons.io.IOUtils;
-import org.eclipse.basyx.components.configuration.BaSyxConfiguration;
-import org.eclipse.basyx.components.xml.XMLAASBundleFactory;
-import org.eclipse.basyx.support.bundle.AASBundle;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
-/**
- * The AASX package converter converts a aasx package into a list of aas, a list
- * of submodels a list of assets, a list of Concept descriptions
- *
- * The aas provides the references to the submodels and assets
- *
- * @author zhangzai
- *
- */
-public class AASXPackageManager {
-
-
- /**
- * Path to the AASX package
- */
- private String aasxPath;
-
- /**
- * AAS bundle factory
- */
- private XMLAASBundleFactory bundleFactory;
-
- /**
- * Logger
- */
- private static Logger logger = LoggerFactory.getLogger(AASXPackageManager.class);
-
- /**
- * Constructor
- */
- public AASXPackageManager(String path) {
- aasxPath = path;
- }
-
- public Set<AASBundle> retrieveAASBundles() throws IOException, ParserConfigurationException, SAXException {
- bundleFactory = new XMLAASBundleFactory(getXMLResourceString(aasxPath));
-
- return bundleFactory.create();
- }
-
- /**
- * Find the path of the aas-xml file
- *
- * @param stream - Stream of the aasx package
- * @return Path of the aas xml file, empty string if not found
- * @throws IOException
- * @throws ParserConfigurationException
- * @throws SAXException
- */
- private String findAASXml(ZipInputStream stream) throws IOException, ParserConfigurationException, SAXException {
- String path = "";
- // find the entry of the aasx
- for (ZipEntry entry; (entry = stream.getNextEntry()) != null;) {
-
- // get name of the entry
- String name = entry.getName();
-
- // find the relationship file in the directory /aasx/_rels/aas_origin.rels
- if (!entry.isDirectory() && name.startsWith("aasx/_rels")) {
- // find the file aasx-origin.rels
- if (name.endsWith("aasx-origin.rels")) {
- // Get path of the aas xml
- String aasXmlPath = findAASXMLAddress(stream);
- if (!aasXmlPath.isEmpty()) {
- path = aasXmlPath;
- break;
- }
- }
- }
- }
- return path;
- }
-
- /**
- * Get entry of a file
- *
- * @param filename - name of a file with path
- * @return a file entry
- * @throws IOException
- */
- private ZipInputStream returnFileEntryStream(String filename, ZipInputStream stream) throws IOException {
- ZipInputStream str = null;
- if (filename.startsWith("/")) {
- filename = filename.substring(1);
- }
-
- // get all entries of the aasx
- for (ZipEntry e; (e = stream.getNextEntry()) != null;) {
- // get name of the entry
- String name = e.getName();
- if (name.equals(filename)) {
- str = stream;
- break;
- }
- }
- return str;
- }
-
- /**
- * Parse the relationship file and find the path of the aas-XML file describing
- * the aas
- *
- * @param ins - input stream of this relationship file
- * @return path of the aas-xml file
- * @throws ParserConfigurationException
- * @throws SAXException
- * @throws IOException
- */
- private String findAASXMLAddress(InputStream ins) throws ParserConfigurationException, SAXException, IOException {
- String path = "";
-
- // create the XML document parser
- DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
- DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
- Document doc = dBuilder.parse(ins);
- doc.getDocumentElement().normalize();
-
- // Get the tag with "Relationships"
- logger.info("Root element :" + doc.getDocumentElement().getNodeName());
- NodeList relList = doc.getElementsByTagName("Relationship");
-
- // If there is only 1 relationship pointing to the aas-xml file, this should be
- // the case
- if (relList.getLength() == 1) {
- Node first = relList.item(0);
-
- if (first.getNodeType() == Node.ELEMENT_NODE) {
- logger.info("\nCurrent Element :" + first.getNodeName());
- // get the target file path
- String targetFile = ((Element) first).getAttribute("Target");
- String type = ((Element) first).getAttribute("Type");
-
- // validate the relationship type
- if (type.endsWith("aas-spec")) {
- logger.info("target file name : " + targetFile);
- path = targetFile;
- }
- }
- }
- return path;
- }
-
- /**
- * Return the Content of the xml file in the aasx-package as String
- *
- * @param filePath - path to the aasx package
- * @return Content of XML as String
- * @throws IOException
- * @throws ParserConfigurationException
- * @throws SAXException
- */
- private String getXMLResourceString(String filePath) throws IOException, ParserConfigurationException, SAXException {
- String aasXmlPath;
- // Create the zip input stream
- try (ZipInputStream stream = new ZipInputStream(BaSyxConfiguration.getResourceStream(filePath))) {
-
- // find the path of the aas xml
- aasXmlPath = this.findAASXml(stream);
- }
-
- try (ZipInputStream stream = new ZipInputStream(BaSyxConfiguration.getResourceStream(filePath))) {
- // Find the entry of the aas xml
- ZipInputStream streamPointingToEntry = this.returnFileEntryStream(aasXmlPath, stream);
-
- // create the xml-converter with the input stream
- String text = IOUtils.toString(streamPointingToEntry, StandardCharsets.UTF_8.name());
- return text;
- }
- }
-
- /**
- * Load the referenced filepaths in the submodels such as PDF, PNG files from
- * the package
- *
- * @return a map of the folder name and folder path, the folder holds the files
- * @throws IOException
- * @throws SAXException
- * @throws ParserConfigurationException
- *
- */
- private List<String> parseReferencedFilePathsFromAASX(String aasxFilePath)
- throws IOException, ParserConfigurationException, SAXException {
- String xmlPath;
- logger.info("AASX filepath: " + aasxFilePath);
- try (ZipInputStream stream = new ZipInputStream(BaSyxConfiguration.getResourceStream(aasxFilePath))) {
- // find the aasx xml file
- xmlPath = this.findAASXml(stream);
- }
-
- try (ZipInputStream stream = new ZipInputStream(BaSyxConfiguration.getResourceStream(aasxFilePath))) {
- // find the relationship file next to the aas xml file
- String[] xmlPathParts = xmlPath.split("/");
- String relPath = xmlPath.substring(0, xmlPath.lastIndexOf("/")) + "/_rels/" + xmlPathParts[xmlPathParts.length - 1] + ".rels";
-
- // Find the entry of the xml .rel file
- ZipInputStream streamPointingToEntry = this.returnFileEntryStream(relPath, stream);
-
- // Return all files referenced in this relationship file
- return parseReferencedFilePathsFromRelationship(streamPointingToEntry);
- }
- }
-
- /**
- * Unzips all files referenced by the aasx file according to its relationships
- *
- * @param filePath - path the AASX
- *
- * @throws IOException
- * @throws SAXException
- * @throws ParserConfigurationException
- * @throws URISyntaxException
- */
- public void unzipRelatedFiles(String aasxFilePath)
- throws IOException, ParserConfigurationException, SAXException, URISyntaxException {
- // load folder which stores the files
- List<String> files = parseReferencedFilePathsFromAASX(aasxFilePath);
- for (String filePath : files) {
- // name of the folder
- unzipFile(filePath, aasxPath);
- }
- }
-
- /**
- * Create a folder to hold the unpackaged files The folder has the path
- * \target\classes\docs
- *
- * @throws IOException
- * @throws URISyntaxException
- */
- private Path getRootFolder() throws IOException, URISyntaxException {
- URI uri = AASXPackageManager.class.getProtectionDomain().getCodeSource().getLocation().toURI();
- URI parent = new File(uri).getParentFile().toURI();
- return Paths.get(parent);
- }
-
- /**
- * unzip the file folders
- *
- * @param filePath - path of the file in the aasx to unzip
- * @param aasxPath - aasx path
- * @throws IOException
- * @throws URISyntaxException
- */
- private void unzipFile(String filePath, String aasxPath)
- throws IOException, URISyntaxException {
- // Create destination directory
- if (filePath.startsWith("/")) {
- filePath = filePath.substring(1);
- }
- logger.info("Unzipping " + filePath + " to root folder:");
- String relativePath = filePath.substring(0, filePath.lastIndexOf("/"));
- Path rootPath = getRootFolder();
- Path destDir = rootPath.resolve(relativePath);
- logger.info("Unzipping to " + destDir);
- Files.createDirectories(destDir);
-
- // create buffer for the folder binary
- byte[] buffer = new byte[1024];
-
- // Find the file with the "filePath"
- try (ZipInputStream stream = new ZipInputStream(BaSyxConfiguration.getResourceStream(aasxPath))) {
- ZipEntry zipEntry = stream.getNextEntry();
- while (zipEntry != null) {
- if (!zipEntry.isDirectory() && zipEntry.getName().contains(filePath)) {
- // Create the file object in the destination directory
- File newFile = newFile(destDir.toFile(), zipEntry);
-
- // Create the file output stream
- try (FileOutputStream fos = new FileOutputStream(newFile)) {
- int len;
- // Write the binary to the file
- while ((len = stream.read(buffer)) > 0) {
- fos.write(buffer, 0, len);
- }
- }
- return;
- }
- zipEntry = stream.getNextEntry();
- }
- }
- }
-
- /**
- * Preventing Zip Slip, create a file
- *
- * @param destinationDir
- * @param zipEntry
- * @return
- * @throws IOException
- */
- private File newFile(File destinationDir, ZipEntry zipEntry) throws IOException {
- int i = zipEntry.getName().lastIndexOf("/");
- String filename = zipEntry.getName().substring(i);
-
- File destFile = new File(destinationDir, filename);
-
- String destDirPath = destinationDir.getCanonicalPath();
- String destFilePath = destFile.getCanonicalPath();
-
- if (!destFilePath.startsWith(destDirPath + File.separator)) {
- throw new IOException("Entry is outside of the target dir: " + zipEntry.getName());
- }
-
- return destFile;
- }
-
- /**
- * Find path of the referenced file with reference type aas-suppl
- *
- * @param insRelFile - the input stream of the relationship file
- * @return
- * @throws ParserConfigurationException
- * @throws SAXException
- * @throws IOException
- */
- private List<String> parseReferencedFilePathsFromRelationship(InputStream insRelFile)
- throws ParserConfigurationException, SAXException, IOException {
- List<String> files = new ArrayList<>();
-
- // create the XML document parser
- DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
- DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
- Document doc = dBuilder.parse(insRelFile);
- doc.getDocumentElement().normalize();
-
- // Get the tag with "Relationships"
- NodeList relList = doc.getElementsByTagName("Relationship");
- for (int i = 0; i < relList.getLength(); i++) {
- Node node = relList.item(i);
- if (node.getNodeType() == Node.ELEMENT_NODE) {
- // get the target file path
- String targetFile = ((Element) node).getAttribute("Target");
- String type = ((Element) node).getAttribute("Type");
-
- // validate the relationship type
- if (type.endsWith("aas-suppl")) {
- files.add(targetFile);
- }
- }
- }
- return files;
- }
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/java/org/eclipse/basyx/components/executable/AASXExecutable.java b/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/java/org/eclipse/basyx/components/executable/AASXExecutable.java
deleted file mode 100644
index 8e1e137..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/java/org/eclipse/basyx/components/executable/AASXExecutable.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package org.eclipse.basyx.components.executable;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URISyntaxException;
-
-import javax.servlet.ServletException;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.eclipse.basyx.components.AASXComponent;
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.xml.sax.SAXException;
-
-/**
- * Starts an HTTP server providing multiple AAS and submodels as described in
- * the AASX package file specified in the properties file <br />
- * They are made available at <i>localhost:4000/aasx/$aasId/aas</i><br />
- * <br />
- * <b>Please note:</b> Neither the AASs nor the Submodels are added to the
- * registry. Additionally, the Submodel descriptors inside the AAS are missing.
- * <br />
- * There reason for this is, that the executable does not know about the outside
- * context (e.g. docker, ...)!
- *
- * @author zhang
- */
-public class AASXExecutable {
- private static Logger logger = LoggerFactory.getLogger(AASXExecutable.class);
-
- public static void main(String[] args) throws IOException, ParserConfigurationException, SAXException, URISyntaxException, ServletException {
- logger.info("Starting BaSyx AASX component");
-
- // Load configuration
- BaSyxContextConfiguration config = new BaSyxContextConfiguration();
- if (args.length > 0 && args[0] instanceof String) {
- // file path available? => load configs from file
- config.loadFromFile(args[0]);
- } else {
- // fallback: load default configs (in resources)
- config.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
- }
-
- // In addition to the context for the AAS, also the registryUrl can be specified
- String registryUrl = config.getProperty("registry");
-
- String rootPath = new File(AASXExecutable.class.getProtectionDomain().getCodeSource().getLocation().toURI())
- .getParentFile().getPath();
- String docPath = rootPath + config.getDocBasePath();
- // Get the path to the doc base path
- AASXComponent component = new AASXComponent(config.getHostname(), config.getPort(), config.getContextPath(),
- docPath, config.getProperty("aasxPath"), registryUrl);
- component.startComponent();
- }
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/java/org/eclipse/basyx/components/servlets/AASXAASServlet.java b/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/java/org/eclipse/basyx/components/servlets/AASXAASServlet.java
deleted file mode 100644
index 75e7b67..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/java/org/eclipse/basyx/components/servlets/AASXAASServlet.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package org.eclipse.basyx.components.servlets;
-
-import java.io.IOException;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.eclipse.basyx.components.aasx.AASXPackageManager;
-import org.eclipse.basyx.components.servlet.aas.AASBundleServlet;
-import org.xml.sax.SAXException;
-
-/**
- * It generates the AAS-bundle using AASX package manager. It also maps the AAS
- * to servlet and adds the submodels, assets and concept descriptors to the AAS.
- *
- *
- * @author zhangzai
- */
-public class AASXAASServlet extends AASBundleServlet {
- private static final long serialVersionUID = -3487515646027982620L;
-
-
-
- public AASXAASServlet(String filePath) throws ParserConfigurationException, SAXException, IOException {
- super(new AASXPackageManager(filePath).retrieveAASBundles());
-
- }
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/resources/context.properties b/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/resources/context.properties
deleted file mode 100644
index 309a541..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/resources/context.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-contextPath=/
-contextHostname=localhost
-contextPort=4000
-aasxPath=aasx/01_Festo.aasx
-contextDocPath=/
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/resources/logback.xml b/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/resources/logback.xml
deleted file mode 100644
index 86341d6..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/resources/logback.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<configuration>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
-
- <!-- Example for a filter, which removes all entries not containing "[TEST]" in the message. -->
-
- <!--<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
- <evaluator>
- <expression>return message.contains("[TEST]");</expression>
- </evaluator>
- <OnMismatch>DENY</OnMismatch>
- <OnMatch>NEUTRAL</OnMatch>
- </filter>-->
-
- <encoder>
- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="INFO">
- <appender-ref ref="STDOUT" />
- </root>
-
-</configuration>
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/java/org/eclipse/basyx/regression/aasx/AASXSuite.java b/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/java/org/eclipse/basyx/regression/aasx/AASXSuite.java
deleted file mode 100644
index bd2c82e..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/java/org/eclipse/basyx/regression/aasx/AASXSuite.java
+++ /dev/null
@@ -1,176 +0,0 @@
-package org.eclipse.basyx.regression.aasx;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Map;
-
-import javax.ws.rs.client.Client;
-import javax.ws.rs.client.ClientBuilder;
-import javax.ws.rs.client.Invocation;
-import javax.ws.rs.client.WebTarget;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.metamodel.connected.ConnectedAssetAdministrationShell;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
-import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IFile;
-import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.ConnectedSubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedFile;
-import org.eclipse.basyx.vab.protocol.api.IConnectorProvider;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.Before;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Suite for testing that the XMLAAS servlet is set up correctly. The tests here
- * can be used by the servlet test itself and the integration test
- *
- * @author schnicke, espen
- *
- */
-public class AASXSuite {
- private static Logger logger = LoggerFactory.getLogger(AASXSuite.class);
-
- protected IAASRegistryService aasRegistry;
-
- protected static final String aasShortId = "Festo_3S7PM0CP4BD";
- protected static final IIdentifier aasId = new ModelUrn("smart.festo.com/demo/aas/1/1/454576463545648365874");
- protected static final IIdentifier smId = new ModelUrn("www.company.com/ids/sm/4343_5072_7091_3242");
- protected static final String smShortId = "Nameplate";
-
- // Has to be individualized by each test inheriting from this suite
- protected static String aasEndpoint;
- protected static String smEndpoint;
- protected static String rootEndpoint;
-
- private ConnectedAssetAdministrationShellManager manager;
-
- // create a REST client
- private Client client = ClientBuilder.newClient();
-
- /**
- * Before each test, a dummy registry is created and an AAS is added in the
- * registry
- */
- @Before
- public void setUp() {
- // Create a dummy registry to test integration of XML AAS
- aasRegistry = new InMemoryRegistry();
- AASDescriptor descriptor = new AASDescriptor(aasShortId, aasId, aasEndpoint);
- descriptor.addSubmodelDescriptor(new SubmodelDescriptor(smShortId, smId, smEndpoint));
- aasRegistry.register(descriptor);
-
- // Create a ConnectedAssetAdministrationShell using a
- // ConnectedAssetAdministrationShellManager
- IConnectorProvider connectorProvider = new HTTPConnectorProvider();
- manager = new ConnectedAssetAdministrationShellManager(aasRegistry, connectorProvider);
- }
-
- @Test
- public void testGetSingleAAS() throws Exception {
- ConnectedAssetAdministrationShell connectedAssetAdministrationShell = getConnectedAssetAdministrationShell();
- assertEquals(aasShortId, connectedAssetAdministrationShell.getIdShort());
- }
-
- @Test
- public void testGetSingleSubmodel() throws Exception {
- ISubModel subModel = getConnectedSubmodel();
- assertEquals(smShortId, subModel.getIdShort());
- }
-
- @Test
- public void testGetSingleModule() throws Exception {
- checkFile("aasx/Nameplate/marking_rcm.jpg");
-
- // Get the submdoel nameplate
- ISubModel nameplate = getConnectedSubmodel();
- // Get the submodel element collection marking_rcm
- ConnectedSubmodelElementCollection marking_rcm = (ConnectedSubmodelElementCollection) nameplate.getSubmodelElements().get("Marking_RCM");
- Collection<ISubmodelElement> values = marking_rcm.getValue();
-
- // navigate to the File element
- Iterator<ISubmodelElement> iter = values.iterator();
- while (iter.hasNext()) {
- ISubmodelElement element = iter.next();
- if (element instanceof ConnectedFile) {
- ConnectedFile connectedFile = (ConnectedFile) element;
- // get value of the file element
-
- String fileurl = connectedFile.getValue();
- assertEquals("http://localhost:4000/aasx/docs/marking_rcm.jpg", fileurl);
- }
- }
- }
-
- @Test
- public void testAllFiles() throws Exception {
- logger.info("Checking all files");
- ConnectedAssetAdministrationShell aas = getConnectedAssetAdministrationShell();
- logger.info("AAS idShort: " + aas.getIdShort());
- logger.info("AAS identifier: " + aas.getIdentification().getId());
- Map<String, ISubModel> submodels = aas.getSubModels();
- logger.info("# Submodels: " + submodels.size());
- for (ISubModel sm : submodels.values()) {
- logger.info("Checking submodel: " + sm.getIdShort());
- checkElementCollectionFiles(sm.getSubmodelElements().values());
- }
-
- }
-
- private void checkElementCollectionFiles(Collection<ISubmodelElement> elements) {
- for (ISubmodelElement element : elements) {
- if (element instanceof IFile) {
- String fileUrl = ((IFile) element).getValue();
- checkFile(fileUrl);
- } else if (element instanceof ISubmodelElementCollection) {
- ISubmodelElementCollection col = (ISubmodelElementCollection) element;
- checkElementCollectionFiles(col.getValue());
- }
- }
- }
-
- private void checkFile(String relativePath) {
- // connect to the url of the aas
- WebTarget webTarget = client.target(rootEndpoint);
- // go to the path of the file
- WebTarget fileTarget = webTarget.path(relativePath);
- logger.info("Checking file: " + relativePath);
- Invocation.Builder invocationBuilder = fileTarget.request(MediaType.APPLICATION_JSON);
- Response response = invocationBuilder.get();
- // validate the response
- assertEquals(200, response.getStatus());
- }
-
- /**
- * Gets the connected Asset Administration Shell
- *
- * @return connected AAS
- * @throws Exception
- */
- private ConnectedAssetAdministrationShell getConnectedAssetAdministrationShell() throws Exception {
- return manager.retrieveAAS(aasId);
- }
-
- /**
- * Gets the connected Submodel
- *
- * @return connected SM
- * @throws Exception
- */
- private ISubModel getConnectedSubmodel() {
- return manager.retrieveSubModel(aasId, smId);
- }
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/java/org/eclipse/basyx/regression/aasx/ITInAASX.java b/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/java/org/eclipse/basyx/regression/aasx/ITInAASX.java
deleted file mode 100644
index 8d417ae..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/java/org/eclipse/basyx/regression/aasx/ITInAASX.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package org.eclipse.basyx.regression.aasx;
-
-import javax.ws.rs.ProcessingException;
-import javax.ws.rs.client.Client;
-import javax.ws.rs.client.ClientBuilder;
-import javax.ws.rs.client.Invocation;
-import javax.ws.rs.client.WebTarget;
-import javax.ws.rs.core.MediaType;
-
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.eclipse.basyx.components.configuration.BaSyxDockerConfiguration;
-import org.junit.BeforeClass;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A Test case for accessing an element of an aas which is hosted on Docker
- *
- *
- */
-public class ITInAASX extends AASXSuite {
- private static Logger logger = LoggerFactory.getLogger(ITInAASX.class);
-
- @BeforeClass
- public static void setUpClass() {
- logger.info("Running integration test...");
-
- logger.info("Loading servlet configuration");
- // Load the servlet configuration inside of the docker configuration from
- // properties file
- BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
- contextConfig.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
-
- // Load the docker environment configuration from properties file
- logger.info("Loading docker configuration");
- BaSyxDockerConfiguration dockerConfig = new BaSyxDockerConfiguration();
- dockerConfig.loadFromResource(BaSyxDockerConfiguration.DEFAULT_CONFIG_PATH);
-
- rootEndpoint = "http://localhost:" + dockerConfig.getHostPort() + contextConfig.getContextPath() + "/";
- aasEndpoint = rootEndpoint + aasShortId + "/aas";
- smEndpoint = rootEndpoint + aasShortId + "/aas/submodels/" + smShortId + "/submodel";
-
- waitUntilReady();
-
- logger.info("AAS URL for integration test: " + aasEndpoint);
- }
-
- /**
- * Waits for at most 4s until the container is ready
- */
- private static void waitUntilReady() {
- Client client = ClientBuilder.newClient();
- WebTarget webTarget = client.target(rootEndpoint);
- Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON);
- for (int i = 0; i < 20; i++) {
- try {
- invocationBuilder.get();
- return;
- } catch (ProcessingException e) {
- // retry
- try {
- Thread.sleep(200);
- } catch (InterruptedException e1) {
- e1.printStackTrace();
- }
- }
- }
- }
-
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/java/org/eclipse/basyx/regression/aasx/TestAASX.java b/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/java/org/eclipse/basyx/regression/aasx/TestAASX.java
deleted file mode 100644
index 71d3eab..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/java/org/eclipse/basyx/regression/aasx/TestAASX.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package org.eclipse.basyx.regression.aasx;
-
-import java.io.IOException;
-import java.net.URISyntaxException;
-
-import javax.servlet.ServletException;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.eclipse.basyx.components.executable.AASXExecutable;
-import org.junit.BeforeClass;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.xml.sax.SAXException;
-
-/**
- * Test accessing to AAS using basys aas SDK
- *
- * @author zhangzai
- *
- */
-public class TestAASX extends AASXSuite {
- private static Logger logger = LoggerFactory.getLogger(TestAASX.class);
-
- @BeforeClass
- public static void setUpClass() throws ParserConfigurationException, SAXException, IOException, URISyntaxException, ServletException {
- AASXExecutable.main(new String[] {});
-
- BaSyxContextConfiguration config = new BaSyxContextConfiguration();
- config.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
-
- rootEndpoint = "http://" + config.getHostname() + ":" + config.getPort() + "/" + config.getContextPath() + "/";
- aasEndpoint = rootEndpoint + aasShortId + "/aas";
- smEndpoint = rootEndpoint + aasShortId + "/aas/submodels/" + smShortId + "/submodel";
- logger.info("AAS URL for servlet test: " + aasEndpoint);
- }
-}
-
-
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/java/org/eclipse/basyx/regression/aasx/TestAASXPackageManager.java b/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/java/org/eclipse/basyx/regression/aasx/TestAASXPackageManager.java
deleted file mode 100644
index 89225de..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/java/org/eclipse/basyx/regression/aasx/TestAASXPackageManager.java
+++ /dev/null
@@ -1,267 +0,0 @@
-package org.eclipse.basyx.regression.aasx;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
-import org.eclipse.basyx.components.aasx.AASXPackageManager;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
-import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
-import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.support.bundle.AASBundle;
-import org.junit.Before;
-import org.junit.Test;
-import org.xml.sax.SAXException;
-
-/**
- * J-Unit tests for AASx package explorer. This test checks the parsing of aas,
- * submodels, assets and concept-descriptions. it also checks whether the aas
- * have correct references to the asets and submodels
- *
- * @author zhangzai
- *
- */
-public class TestAASXPackageManager {
- /**
- * path to the aasx package
- */
- private String aasxPath = "aasx/01_Festo.aasx";
-
- /**
- * the aasx package converter
- */
- private AASXPackageManager packageConverter;
-
- /**
- * this string array is used to check the refs to submodels of aas
- */
- private String[] submodelids = { "www.company.com/ids/sm/6053_5072_7091_5102", "smart.festo.com/demo/sm/instance/1/1/13B7CCD9BF7A3F24", "www.company.com/ids/sm/4343_5072_7091_3242", "www.company.com/ids/sm/2543_5072_7091_2660",
- "www.company.com/ids/sm/6563_5072_7091_4267"
-
- };
-
- /**
- * AAS bundle which will be generated by the XMLAASBundleFactory
- */
- private Set<AASBundle> aasBundles;
-
- /**
- * Submodels parsed by the converter
- */
- private Set<ISubModel> submodels;
-
- /**
- * Initialize the AASX package converter
- */
- @Before
- public void setup() {
- // Create the aasx package converter with the path to the aasx package
- packageConverter = new AASXPackageManager(aasxPath);
- }
-
- /**
- * Test parsing of aas, assets, submodels and concept-descriptions
- */
- @Test
- public void testCheckAasxConverter() {
- // Parse aas from the XML and create the AAS Bundle with refs to submodels
- try {
- aasBundles = packageConverter.retrieveAASBundles();
- } catch (ParserConfigurationException | SAXException | IOException e) {
- e.printStackTrace();
- }
-
- // check the information in the aas bundles
- checkAASs(aasBundles);
-
- // Check the submodels
- checkSubmodels(submodels);
- }
-
- /**
- * Check the parsed aas with expected ones
- *
- * @param aasList
- */
- private void checkAASs(Set<AASBundle> aasBundles) {
- assertEquals(2, aasBundles.size());
-
- IAssetAdministrationShell aas = null;
-
- // select the AAS with a specific ID from the list
- Optional<AASBundle> testAASBundleOptional = aasBundles.stream().filter(b -> b.getAAS().getIdShort().equals("Festo_3S7PM0CP4BD")).findFirst();
- // verify there exist one aas with this ID
- assertTrue(testAASBundleOptional.isPresent());
-
- // Get the aasbundle from the filtered results
- AASBundle testAASBundle = testAASBundleOptional.get();
- aas = testAASBundle.getAAS();
-
- // get submodels of this aas
- submodels = testAASBundle.getSubmodels();
-
- // verify short id
- assertEquals("Festo_3S7PM0CP4BD", aas.getIdShort());
- assertEquals("CONSTANT", aas.getCategory());
-
- assertEquals("", aas.getDescription().get("EN"));
- assertEquals("", aas.getDescription().get("DE"));
-
- // verify id and id-type
- assertEquals("smart.festo.com/demo/aas/1/1/454576463545648365874", aas.getIdentification().getId());
- assertEquals(IdentifierType.IRI, aas.getIdentification().getIdType());
-
-
- // Get submodel references
- Collection<IReference> references = aas.getSubmodelReferences();
-
- // this aas has 5 submodels
- assertEquals(5, references.size());
- List<IReference> referencelist = new ArrayList<>();
- referencelist.addAll(references);
-
- // sort the list for later assertion
- // list is sorted by the last two characters of the id
- referencelist.sort((x, y) -> {
- String idx = x.getKeys().get(0).getValue();
- String idy = y.getKeys().get(0).getValue();
-
- String idx_end = idx.substring(idx.length() - 2);
- int idxint = Integer.parseInt(idx_end);
- String idy_end = idy.substring(idy.length() - 2);
- int idyint = Integer.parseInt(idy_end);
-
- return idxint - idyint;
-
- });
-
- // get First submodel reference
- for (int i = 0; i < referencelist.size(); i++) {
- IReference ref = referencelist.get(i);
- List<IKey> refKeys = ref.getKeys();
-
- // assert the submodel id
- assertEquals(submodelids[i], refKeys.get(0).getValue());
- // assert the id type
- assertEquals("IRI", refKeys.get(0).getIdType().name());
- // assert the model type
- assertEquals("SUBMODEL", refKeys.get(0).getType().name());
- // submodels are local
- assertEquals(true, refKeys.get(0).isLocal());
- }
-
- }
-
- /**
- * Check parsed submodels with expected ones
- *
- * @param submodels
- */
- private void checkSubmodels(Set<ISubModel> submodels) {
- assertEquals(5, submodels.size());
-
- // filter the submodel with id "Nameplate"
- Optional<ISubModel> sm1Optional = submodels.stream().filter(s -> s.getIdShort().equals("Nameplate")).findFirst();
- assertTrue(sm1Optional.isPresent());
- ISubModel sm1 = sm1Optional.get();
-
- // verify short id, id-type, id and model-kind of the submodel
- assertEquals("Nameplate", sm1.getIdShort());
- assertEquals("IRI", sm1.getIdentification().getIdType().name());
- assertEquals("www.company.com/ids/sm/4343_5072_7091_3242", sm1.getIdentification().getId());
- assertEquals("Instance", sm1.getModelingKind().toString());
-
- // ---------------------------------------------
- // get 1st submodel element
- // Get submodel elements
- Map<String, ISubmodelElement> smElements = sm1.getSubmodelElements();
-
- // get element manufacturing name
- ISubmodelElement sele = smElements.get("ManufacturerName");
-
- // verify short id
- assertEquals("ManufacturerName", sele.getIdShort());
-
- // verify category and model-kind, value and value-type
- assertEquals("PARAMETER", sele.getCategory());
- assertTrue(sele.getModelingKind().name().equalsIgnoreCase("Instance"));
- Property prop = (Property) sele;
- assertEquals("Festo AG & Co. KG", prop.get());
- assertEquals("string", prop.getValueType());
-
- // get semantic id
- IReference semantic = sele.getSemanticId();
-
- IKey semanticKey = semantic.getKeys().get(0);
- assertTrue(semanticKey.getType().name().equalsIgnoreCase("ConceptDescription"));
- assertEquals("IRDI", semanticKey.getIdType().name());
- assertEquals("0173-1#02-AAO677#002", semanticKey.getValue());
- assertEquals(true, semanticKey.isLocal());
-
- /// ---------------------------------------------
- // get 2nd submodel element
- // Get submodel elements
- sele = smElements.get("ManufacturerProductDesignation");
- assertEquals("ManufacturerProductDesignation", sele.getIdShort());
- assertEquals("PARAMETER", sele.getCategory());
- assertTrue(sele.getModelingKind().name().equalsIgnoreCase("Instance"));
- prop = (Property) sele;
- assertEquals("OVEL Vacuum generator", prop.get());
- assertEquals("string", prop.getValueType());
-
- // get semantic id
- semantic = sele.getSemanticId();
- semanticKey = semantic.getKeys().get(0);
- assertTrue(semanticKey.getType().name().equalsIgnoreCase("ConceptDescription"));
- assertEquals("IRDI", semanticKey.getIdType().name());
- assertEquals("0173-1#02-AAW338#001", semanticKey.getValue());
- assertEquals(true, semanticKey.isLocal());
-
- // ---------------------------------------------
- // get 3rd submodel element
- // Get submodel elements
- sele = smElements.get("PhysicalAddress");
- assertEquals("PhysicalAddress", sele.getIdShort());
- assertEquals("PARAMETER", sele.getCategory());
- assertTrue(sele.getModelingKind().name().equalsIgnoreCase("Instance"));
-
- // get semantic id
- semantic = sele.getSemanticId();
- semanticKey = semantic.getKeys().get(0);
- assertTrue(semanticKey.getType().name().equalsIgnoreCase("ConceptDescription"));
- assertEquals("IRI", semanticKey.getIdType().name());
- assertEquals("https://www.hsu-hh.de/aut/aas/physicaladdress", semanticKey.getValue());
- assertEquals(true, semanticKey.isLocal());
-
- // get values
- assertTrue(sele.getModelType().equalsIgnoreCase("SubmodelElementCollection"));
- SubmodelElementCollection collection = (SubmodelElementCollection) sele;
- Collection<ISubmodelElement> subelements = collection.getValue();
-
- assertEquals(5, subelements.size());
- Iterator<ISubmodelElement> iterator = subelements.iterator();
- Property prop1 = (Property) (iterator.next());
- assertEquals("CountryCode", prop1.getIdShort());
- assertEquals("DE", prop1.get());
-
- Property prop2 = (Property) (iterator.next());
- assertEquals("Street", prop2.getIdShort());
- assertEquals("Ruiter Straße 82", prop2.get());
- }
-
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/resources/.env b/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/resources/.env
deleted file mode 100644
index 0eea4b9..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/resources/.env
+++ /dev/null
@@ -1,5 +0,0 @@
-BASYX_HOST_PORT=8082
-BASYX_CONTAINER_PORT=4000
-BASYX_IMAGE_NAME=basys/aasx
-BASYX_CONTAINER_NAME=aasx
-BASYX_IMAGE_TAG=0.0.1-SNAPSHOT
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/Dockerfile b/components/basys.components/basyx.components.docker/basyx.components.registry/Dockerfile
new file mode 100644
index 0000000..c9f4b78
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/Dockerfile
@@ -0,0 +1,34 @@
+# Add java runtime environment for execution
+FROM java:8-jdk-alpine
+
+# Copy built jar to image using the jar name specified in the pom.xml (JAR_FILE)
+ARG JAR_FILE
+COPY target/${JAR_FILE} /usr/share/basyxExecutable.jar
+COPY target/lib /usr/share/lib
+COPY src/main/resources/context.properties /usr/share/config/context.properties
+COPY src/main/resources/registry.properties /usr/share/config/registry.properties
+COPY src/test/resources/dockerSQL.properties /usr/share/config/sql.properties
+COPY src/test/resources/dockerMongodb.properties /usr/share/config/mongodb.properties
+
+# Expose the appropriate port. In case of Tomcat, this is 8080.
+ARG PORT
+EXPOSE ${PORT}
+
+# Set the path for the registry configuration file
+ARG REGISTRY_CONFIG_KEY
+ENV ${REGISTRY_CONFIG_KEY} "/usr/share/config/registry.properties"
+
+# Set the path for the context configuration file
+ARG CONTEXT_CONFIG_KEY
+ENV ${CONTEXT_CONFIG_KEY} "/usr/share/config/context.properties"
+
+# Set the path for the sql configuration file
+ARG SQL_CONFIG_KEY
+ENV ${SQL_CONFIG_KEY} "/usr/share/config/sql.properties"
+
+# Set the path for the mongodb configuration file
+ARG MONGODB_CONFIG_KEY
+ENV ${MONGODB_CONFIG_KEY} "/usr/share/config/mongodb.properties"
+
+# Start the jar
+CMD java -jar "/usr/share/basyxExecutable.jar"
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/build.bat b/components/basys.components/basyx.components.docker/basyx.components.registry/build.bat
new file mode 100644
index 0000000..64f74e3
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/build.bat
@@ -0,0 +1 @@
+../.././mvnw clean install -U -Pdocker -DskipTests
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/build.sh b/components/basys.components/basyx.components.docker/basyx.components.registry/build.sh
new file mode 100644
index 0000000..6820ccc
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/build.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+../../mvnw clean install -U -Pdocker -DskipTests
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/docker-compose.yml b/components/basys.components/basyx.components.docker/basyx.components.registry/docker-compose.yml
new file mode 100644
index 0000000..717a3e3
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/docker-compose.yml
@@ -0,0 +1,25 @@
+version: '2.1'
+services:
+ registry:
+ image: ${BASYX_IMAGE_NAME}:${BASYX_IMAGE_TAG}
+ container_name: ${BASYX_CONTAINER_NAME}
+ ports:
+ - ${BASYX_HOST_PORT}:${BASYX_CONTAINER_PORT}
+# depends_on:
+# mongodb:
+# condition: service_healthy
+# links:
+# - mongodb
+
+# mongodb:
+# image: mongo:latest
+# container_name: mongodb
+# Possibility to enable authentication
+# environment:
+# MONGO_INITDB_ROOT_USERNAME: root
+# MONGO_INITDB_ROOT_PASSWORD: example
+# healthcheck:
+# test: echo 'db.runCommand("ping").ok' | mongo mongodb:27017/test --quiet
+# interval: 3s
+# timeout: 3s
+# retries: 5
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/pom.xml b/components/basys.components/basyx.components.docker/basyx.components.registry/pom.xml
new file mode 100644
index 0000000..0185e3f
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/pom.xml
@@ -0,0 +1,95 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.eclipse.basyx</groupId>
+ <artifactId>basyx.components.docker</artifactId>
+ <version>1.0.0</version>
+ </parent>
+
+ <artifactId>basyx.components.registry</artifactId>
+ <name>BaSyx Registry</name>
+ <version>1.0.2</version>
+
+ <properties>
+ <basyx.components.executable>org.eclipse.basyx.components.registry.executable.RegistryExecutable</basyx.components.executable>
+ </properties>
+
+ <packaging>jar</packaging>
+
+ <build>
+ <!-- Define additional plugins that are not included by default -->
+ <!-- Plugin configuration is done in parent project(s) -->
+ <plugins>
+ <!-- Attach sources to jar file -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <!-- Use MongoDB Java Drivers for db connections -->
+ <dependency>
+ <groupId>org.mongodb</groupId>
+ <artifactId>mongodb-driver-sync</artifactId>
+ <version>4.0.5</version>
+ </dependency>
+
+ <!-- Use Spring Data MongoDB for db data management -->
+ <dependency>
+ <groupId>org.springframework.data</groupId>
+ <artifactId>spring-data-mongodb</artifactId>
+ <version>3.0.2.RELEASE</version>
+ </dependency>
+
+ <!-- Adds additional classes of the BaSys SDK for tests (for TestRegistryProvider) -->
+ <dependency>
+ <groupId>org.eclipse.basyx</groupId>
+ <artifactId>basyx.sdk</artifactId>
+ <classifier>tests</classifier>
+ </dependency>
+ </dependencies>
+
+ <profiles>
+ <profile>
+ <id>docker</id>
+ <build>
+ <plugins>
+ <!-- Read maven properties from file -->
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>properties-maven-plugin</artifactId>
+ </plugin>
+
+ <!-- Copy the dependencies necessary to run the jar -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ </plugin>
+
+ <!-- Build the docker image -->
+ <plugin>
+ <groupId>com.spotify</groupId>
+ <artifactId>dockerfile-maven-plugin</artifactId>
+ </plugin>
+
+ <!-- Create integration test environment -->
+ <plugin>
+ <groupId>com.dkanejs.maven.plugins</groupId>
+ <artifactId>docker-compose-maven-plugin</artifactId>
+ </plugin>
+
+ <!-- Run integration tests -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/RegistryComponent.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/RegistryComponent.java
new file mode 100644
index 0000000..1070cd9
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/RegistryComponent.java
@@ -0,0 +1,190 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.registry;
+
+import javax.servlet.http.HttpServlet;
+
+import org.eclipse.basyx.components.IComponent;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxMongoDBConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxSQLConfiguration;
+import org.eclipse.basyx.components.registry.configuration.BaSyxRegistryConfiguration;
+import org.eclipse.basyx.components.registry.configuration.RegistryBackend;
+import org.eclipse.basyx.components.registry.servlet.InMemoryRegistryServlet;
+import org.eclipse.basyx.components.registry.servlet.MongoDBRegistryServlet;
+import org.eclipse.basyx.components.registry.servlet.SQLRegistryServlet;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxHTTPServer;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Generic registry that can start and stop a registry with different kinds of backends.
+ * Currently supports MongoDB and SQL. For development purposes, the component can also start a
+ * registry without a backend and without persistency.
+ *
+ * @author espen
+ *
+ */
+public class RegistryComponent implements IComponent {
+ private static Logger logger = LoggerFactory.getLogger(RegistryComponent.class);
+
+ // The server with the servlet that will be created
+ private BaSyxHTTPServer server;
+
+ // The component configuration
+ private BaSyxContextConfiguration contextConfig;
+ private BaSyxRegistryConfiguration registryConfig;
+
+ // The backend configuration
+ private BaSyxMongoDBConfiguration mongoDBConfig;
+ private BaSyxSQLConfiguration sqlConfig;
+
+ /**
+ * Default constructor that loads default configurations
+ */
+ public RegistryComponent() {
+ contextConfig = new BaSyxContextConfiguration();
+ registryConfig = new BaSyxRegistryConfiguration();
+ }
+
+ /**
+ * Constructor with given configuration for the registry and its server context. This constructor will create an
+ * InMemory registry.
+ *
+ * @param contextConfig The context configuration
+ */
+ public RegistryComponent(BaSyxContextConfiguration contextConfig) {
+ this.contextConfig = contextConfig;
+ this.registryConfig = new BaSyxRegistryConfiguration(RegistryBackend.INMEMORY);
+ }
+
+ /**
+ * Constructor with given configuration for the registry and its server context. This constructor will create a
+ * registry with a MongoDB backend.
+ *
+ * @param contextConfig The context configuration
+ * @param mongoDBConfig The mongoDB configuration
+ */
+ public RegistryComponent(BaSyxContextConfiguration contextConfig, BaSyxMongoDBConfiguration mongoDBConfig) {
+ this.contextConfig = contextConfig;
+ this.registryConfig = new BaSyxRegistryConfiguration(RegistryBackend.MONGODB);
+ this.mongoDBConfig = mongoDBConfig;
+ }
+
+ /**
+ * Constructor with given configuration for the registry and its server context. This constructor will create a
+ * registry with an SQL backend.
+ *
+ * @param contextConfig The context configuration
+ * @param sqlConfig The sql configuration
+ */
+ public RegistryComponent(BaSyxContextConfiguration contextConfig, BaSyxSQLConfiguration sqlConfig) {
+ this.contextConfig = contextConfig;
+ this.registryConfig = new BaSyxRegistryConfiguration(RegistryBackend.SQL);
+ this.sqlConfig = sqlConfig;
+ }
+
+ /**
+ * Constructor with given configuration for the registry and its server context.
+ * Will load the backend configuration using the default load process.
+ *
+ * @param contextConfig The context configuration
+ * @param registryConfig The registry configuration
+ */
+ public RegistryComponent(BaSyxContextConfiguration contextConfig, BaSyxRegistryConfiguration registryConfig) {
+ this.contextConfig = contextConfig;
+ this.registryConfig = registryConfig;
+ }
+
+ /**
+ * Starts the context at http://${hostName}:${port}/${path}
+ */
+ @Override
+ public void startComponent() {
+ BaSyxContext context = contextConfig.createBaSyxContext();
+ context.addServletMapping("/*", loadRegistryServlet());
+ server = new BaSyxHTTPServer(context);
+ server.start();
+ logger.info("Registry server started");
+ }
+
+ /**
+ * Loads a registry with a backend according to the registryConfig
+ *
+ * @return
+ */
+ private HttpServlet loadRegistryServlet() {
+ HttpServlet registryServlet = null;
+ RegistryBackend backendType = registryConfig.getRegistryBackend();
+ switch(backendType) {
+ case MONGODB:
+ registryServlet = loadMongoDBRegistryServlet();
+ break;
+ case SQL:
+ registryServlet = loadSQLRegistryServlet();
+ break;
+ case INMEMORY:
+ registryServlet = loadInMemoryRegistryServlet();
+ break;
+ }
+ return registryServlet;
+ }
+
+ /**
+ * Creates a registry servlet with an sql backend
+ *
+ * @return
+ */
+ private HttpServlet loadSQLRegistryServlet() {
+ logger.info("Loading SQLRegistry");
+ BaSyxSQLConfiguration config;
+ if (this.sqlConfig == null) {
+ config = new BaSyxSQLConfiguration();
+ config.loadFromDefaultSource();
+ } else {
+ config = this.sqlConfig;
+ }
+ return new SQLRegistryServlet(config);
+ }
+
+ /**
+ * Creates a registry servlet with an mongodb backend
+ *
+ * @return
+ */
+ private HttpServlet loadMongoDBRegistryServlet() {
+ logger.info("Loading MongoDBRegistry");
+ BaSyxMongoDBConfiguration config;
+ if (this.mongoDBConfig == null) {
+ config = new BaSyxMongoDBConfiguration();
+ config.loadFromDefaultSource();
+ } else {
+ config = this.mongoDBConfig;
+ }
+ return new MongoDBRegistryServlet(config);
+ }
+
+ /**
+ * Creates an registry servlet with in memory data (=> not persistent)
+ *
+ * @return
+ */
+ private HttpServlet loadInMemoryRegistryServlet() {
+ logger.info("Loading InMemoryRegistry");
+ return new InMemoryRegistryServlet();
+ }
+
+ @Override
+ public void stopComponent() {
+ server.shutdown();
+ logger.info("Registry server stopped");
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/configuration/BaSyxRegistryConfiguration.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/configuration/BaSyxRegistryConfiguration.java
new file mode 100644
index 0000000..418daaa
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/configuration/BaSyxRegistryConfiguration.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.registry.configuration;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.basyx.components.configuration.BaSyxConfiguration;
+
+/**
+ * Represents a BaSyx registry configuration for a BaSyx Registry with any backend,
+ * that can be loaded from a properties file.
+ *
+ * @author espen
+ *
+ */
+public class BaSyxRegistryConfiguration extends BaSyxConfiguration {
+ // Prefix for environment variables
+ public static final String ENV_PREFIX = "BaSyxRegistry_";
+
+ // Default BaSyx Context configuration
+ public static final String DEFAULT_BACKEND = RegistryBackend.INMEMORY.toString();
+
+ // Configuration keys
+ public static final String BACKEND = "registry.backend";
+
+ // The default path for the context properties file
+ public static final String DEFAULT_CONFIG_PATH = "registry.properties";
+
+ // The default key for variables pointing to the configuration file
+ public static final String DEFAULT_FILE_KEY = "BASYX_REGISTRY";
+
+ public static Map<String, String> getDefaultProperties() {
+ Map<String, String> defaultProps = new HashMap<>();
+ defaultProps.put(BACKEND, DEFAULT_BACKEND);
+ return defaultProps;
+ }
+
+ public BaSyxRegistryConfiguration() {
+ super(getDefaultProperties());
+ }
+
+ public BaSyxRegistryConfiguration(RegistryBackend backend) {
+ super(getDefaultProperties());
+ setRegistryBackend(backend);
+ }
+
+ public BaSyxRegistryConfiguration(Map<String, String> values) {
+ super(values);
+ }
+
+ public void loadFromEnvironmentVariables() {
+ loadFromEnvironmentVariables(ENV_PREFIX, BACKEND);
+ }
+
+ public void loadFromDefaultSource() {
+ loadFileOrDefaultResource(DEFAULT_FILE_KEY, DEFAULT_CONFIG_PATH);
+ loadFromEnvironmentVariables();
+ }
+
+ public RegistryBackend getRegistryBackend() {
+ return RegistryBackend.fromString(getProperty(BACKEND));
+ }
+
+ public void setRegistryBackend(RegistryBackend backend) {
+ setProperty(BACKEND, backend.toString());
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/configuration/RegistryBackend.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/configuration/RegistryBackend.java
new file mode 100644
index 0000000..cec5be6
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/configuration/RegistryBackend.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.registry.configuration;
+
+import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnumHelper;
+
+import com.google.common.base.Strings;
+
+/**
+ * Possible types for registry backends.
+ *
+ * @author espen
+ *
+ */
+public enum RegistryBackend {
+ /**
+ * Enum values of KeyElements
+ */
+ INMEMORY("InMemory"),
+ SQL("SQL"),
+ MONGODB("MongoDB");
+
+ private String literal;
+
+ private RegistryBackend(String literal) {
+ this.literal = literal;
+ }
+
+ @Override
+ public String toString() {
+ return literal;
+ }
+
+ /**
+ * Method to transform string literal to RegistryBackend enum.
+ *
+ * @see StandardizedLiteralEnumHelper StandardizedLiteralEnumHelper
+ *
+ * @param literal
+ * @return
+ */
+ public static RegistryBackend fromString(String literal) {
+ if (Strings.isNullOrEmpty(literal)) {
+ return null;
+ }
+
+ RegistryBackend[] enumConstants = RegistryBackend.class.getEnumConstants();
+ for (RegistryBackend constant : enumConstants) {
+ if (constant.toString().equals(literal)) {
+ return constant;
+ }
+ }
+ throw new IllegalArgumentException("The literal '" + literal + "' is not a valid RegistryBackend");
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/executable/RegistryExecutable.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/executable/RegistryExecutable.java
new file mode 100644
index 0000000..57e6dec
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/executable/RegistryExecutable.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.registry.executable;
+
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.components.registry.RegistryComponent;
+import org.eclipse.basyx.components.registry.configuration.BaSyxRegistryConfiguration;
+
+/**
+ * A registry executable for a registry with any backend.
+ *
+ * @author espen
+ */
+public class RegistryExecutable {
+ private RegistryExecutable() {
+ }
+
+ public static void main(String[] args) {
+ // Load context configuration from default source
+ BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
+ contextConfig.loadFromDefaultSource();
+
+ // Load registry configuration from default source
+ BaSyxRegistryConfiguration registryConfig = new BaSyxRegistryConfiguration();
+ registryConfig.loadFromDefaultSource();
+
+ // Create and start component according to the configuration
+ RegistryComponent component = new RegistryComponent(contextConfig, registryConfig);
+ component.startComponent();
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/mongodb/MongoDBRegistryHandler.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/mongodb/MongoDBRegistryHandler.java
new file mode 100644
index 0000000..acb080e
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/mongodb/MongoDBRegistryHandler.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.registry.mongodb;
+
+import static org.springframework.data.mongodb.core.query.Criteria.where;
+import static org.springframework.data.mongodb.core.query.Query.query;
+
+import java.util.List;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.registration.memory.IRegistryHandler;
+import org.eclipse.basyx.components.configuration.BaSyxMongoDBConfiguration;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+
+import com.mongodb.client.MongoClient;
+import com.mongodb.client.MongoClients;
+
+/**
+ * A registry handler based on MongoDB
+ *
+ * @author espen
+ */
+public class MongoDBRegistryHandler implements IRegistryHandler {
+ private static final String DEFAULT_CONFIG_PATH = "mongodb.properties";
+
+ protected BaSyxMongoDBConfiguration config;
+ protected MongoOperations mongoOps;
+ protected String collection;
+
+ private static final String AASID = Identifiable.IDENTIFICATION + "." + Identifier.ID;
+ private static final String ASSETID = AASDescriptor.ASSET + "." + Identifiable.IDENTIFICATION + "." + Identifier.ID;
+
+ /**
+ * Receives the path of the configuration.properties file in it's constructor.
+ *
+ * @param configFilePath
+ */
+ public MongoDBRegistryHandler(BaSyxMongoDBConfiguration config) {
+ this.setConfiguration(config);
+ }
+
+ /**
+ * Receives the path of the .properties file in it's constructor from a resource.
+ */
+ public MongoDBRegistryHandler(String resourceConfigPath) {
+ config = new BaSyxMongoDBConfiguration();
+ config.loadFromResource(resourceConfigPath);
+ this.setConfiguration(config);
+ }
+
+ /**
+ * Constructor using default sql connections
+ */
+ public MongoDBRegistryHandler() {
+ this(DEFAULT_CONFIG_PATH);
+ }
+
+ public void setConfiguration(BaSyxMongoDBConfiguration config) {
+ this.config = config;
+ MongoClient client = MongoClients.create(config.getConnectionUrl());
+ this.mongoOps = new MongoTemplate(client, config.getDatabase());
+ this.collection = config.getRegistryCollection();
+ }
+
+ @Override
+ public boolean contains(IIdentifier identifier) {
+ String id = identifier.getId();
+ Criteria hasId = new Criteria();
+ hasId.orOperator(where(AASID).is(id), where(ASSETID).is(id));
+ return mongoOps.exists(query(hasId), collection);
+ }
+
+ @Override
+ public void remove(IIdentifier identifier) {
+ String id = identifier.getId();
+ Criteria hasId = new Criteria();
+ hasId.orOperator(where(AASID).is(id), where(ASSETID).is(id));
+ mongoOps.remove(query(hasId), collection);
+ }
+
+ @Override
+ public void insert(AASDescriptor descriptor) {
+ mongoOps.insert(descriptor, collection);
+ }
+
+ @Override
+ public void update(AASDescriptor descriptor) {
+ String aasId = descriptor.getIdentifier().getId();
+ Object result = mongoOps.findAndReplace(query(where(AASID).is(aasId)), descriptor, collection);
+ if (result == null) {
+ insert(descriptor);
+ }
+ }
+
+ @Override
+ public AASDescriptor get(IIdentifier identifier) {
+ String id = identifier.getId();
+ Criteria hasId = new Criteria();
+ hasId.orOperator(where(AASID).is(id), where(ASSETID).is(id));
+ AASDescriptor result = mongoOps.findOne(query(hasId), AASDescriptor.class, collection);
+ if (result != null) {
+ // Remove mongoDB-specific map attribute from AASDescriptor
+ result.remove("_id");
+ }
+ return result;
+ }
+
+ @Override
+ public List<AASDescriptor> getAll() {
+ List<AASDescriptor> result = mongoOps.findAll(AASDescriptor.class, collection);
+ // Remove mongoDB-specific map attribute from AASDescriptor
+ result.forEach(desc -> desc.remove("_id"));
+ return result;
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/InMemoryRegistryServlet.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/InMemoryRegistryServlet.java
new file mode 100644
index 0000000..6a040fa
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/InMemoryRegistryServlet.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.registry.servlet;
+
+import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
+import org.eclipse.basyx.aas.registration.restapi.AASRegistryModelProvider;
+import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
+
+/**
+ * A registry servlet based on an InMemory Registry. The servlet therefore provides an implementation
+ * for the IAASRegistryService interface without a permanent storage capability.
+ *
+ * Do not use this registry in a productive environment - the entries are not persistent!
+ *
+ * @author espen
+ */
+public class InMemoryRegistryServlet extends VABHTTPInterface<AASRegistryModelProvider> {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructor with ModelProvider based on an InMemoryRegistry
+ */
+ public InMemoryRegistryServlet() {
+ super(new AASRegistryModelProvider(new InMemoryRegistry()));
+
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/MongoDBRegistryServlet.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/MongoDBRegistryServlet.java
new file mode 100644
index 0000000..73cff45
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/MongoDBRegistryServlet.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.registry.servlet;
+
+import org.eclipse.basyx.aas.registration.memory.AASRegistry;
+import org.eclipse.basyx.aas.registration.restapi.AASRegistryModelProvider;
+import org.eclipse.basyx.components.configuration.BaSyxMongoDBConfiguration;
+import org.eclipse.basyx.components.registry.mongodb.MongoDBRegistryHandler;
+import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
+
+/**
+ * A registry servlet based on an SQL database. The servlet therefore provides an implementation
+ * for the IAASRegistryService interface with a permanent storage solution.
+ *
+ * @author espen
+ */
+public class MongoDBRegistryServlet extends VABHTTPInterface<AASRegistryModelProvider> {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Provide HTTP interface with JSONProvider to handle serialization and
+ * SQLDirectoryProvider as backend
+ */
+ public MongoDBRegistryServlet() {
+ super(new AASRegistryModelProvider(new AASRegistry(new MongoDBRegistryHandler())));
+ }
+
+ public MongoDBRegistryServlet(BaSyxMongoDBConfiguration config) {
+ super(new AASRegistryModelProvider(new AASRegistry(new MongoDBRegistryHandler(config))));
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/SQLRegistryServlet.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/SQLRegistryServlet.java
new file mode 100644
index 0000000..2033adf
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/SQLRegistryServlet.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.registry.servlet;
+
+import org.eclipse.basyx.aas.registration.restapi.AASRegistryModelProvider;
+import org.eclipse.basyx.components.configuration.BaSyxSQLConfiguration;
+import org.eclipse.basyx.components.registry.sql.SQLRegistry;
+import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
+
+/**
+ * A registry servlet based on an SQL database. The servlet therefore provides an implementation
+ * for the IAASRegistryService interface with a permanent storage solution.
+ *
+ * @author kuhn, pschorn, espen
+ */
+public class SQLRegistryServlet extends VABHTTPInterface<AASRegistryModelProvider> {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Provide HTTP interface with JSONProvider to handle serialization and
+ * SQLDirectoryProvider as backend
+ */
+ public SQLRegistryServlet() {
+ super(new AASRegistryModelProvider(new SQLRegistry()));
+ }
+
+ public SQLRegistryServlet(BaSyxSQLConfiguration sqlConfig) {
+ super(new AASRegistryModelProvider(new SQLRegistry(sqlConfig)));
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/sql/AASDescriptorMap.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/sql/AASDescriptorMap.java
new file mode 100644
index 0000000..87cfc7e
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/sql/AASDescriptorMap.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.registry.sql;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+
+/**
+ * This is a map implementation for a <String, AASDescriptor> map which is needed
+ * by map registries. It is based on an arbitrary <String, Object> map and provides a proxy
+ * access to that map by assuming AASDescriptor entries.
+ *
+ * @author espen
+ *
+ */
+public class AASDescriptorMap implements Map<String, AASDescriptor> {
+ /**
+ * The map all operations of this map are based on
+ */
+ private Map<String, Object> baseMap;
+
+ /**
+ * Default constructor taking the base map
+ *
+ * @param baseMap
+ */
+ public AASDescriptorMap(Map<String, Object> baseMap) {
+ this.baseMap = baseMap;
+ }
+
+ @Override
+ public int size() {
+ return baseMap.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return baseMap.isEmpty();
+ }
+
+ @Override
+ public boolean containsKey(Object key) {
+ return baseMap.containsKey(key);
+ }
+
+ @Override
+ public boolean containsValue(Object value) {
+ return baseMap.containsValue(value);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public AASDescriptor get(Object key) {
+ Map<String, Object> mapEntry = (Map<String, Object>) baseMap.get(key);
+ if (mapEntry == null) {
+ return null;
+ } else {
+ return new AASDescriptor(mapEntry);
+ }
+ }
+
+ @Override
+ public AASDescriptor put(String key, AASDescriptor value) {
+ return (AASDescriptor) baseMap.put(key, value);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public AASDescriptor remove(Object key) {
+ Map<String, Object> result = (Map<String, Object>) baseMap.remove(key);
+ if (result == null) {
+ return null;
+ } else {
+ return new AASDescriptor(result);
+ }
+ }
+
+ @Override
+ public void putAll(Map<? extends String, ? extends AASDescriptor> m) {
+ baseMap.putAll(m);
+ }
+
+ @Override
+ public void clear() {
+ baseMap.clear();
+ }
+
+ @Override
+ public Set<String> keySet() {
+ return baseMap.keySet();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Collection<AASDescriptor> values() {
+ return baseMap.values().stream()
+ .map(o -> new AASDescriptor((Map<String, Object>) o))
+ .collect(Collectors.toList());
+ }
+
+ @Override
+ public Set<Entry<String, AASDescriptor>> entrySet() {
+ return baseMap.entrySet().stream()
+ .map(e -> new Entry<String, AASDescriptor>() {
+ @Override
+ public AASDescriptor setValue(AASDescriptor value) {
+ return (AASDescriptor) e.setValue(value);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public AASDescriptor getValue() {
+ if (e.getValue() == null) {
+ return null;
+ } else {
+ return new AASDescriptor((Map<String, Object>) e.getValue());
+ }
+ }
+
+ @Override
+ public String getKey() {
+ return e.getKey();
+ }
+ }).collect(Collectors.toSet());
+ }
+
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/sql/SQLRegistry.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/sql/SQLRegistry.java
new file mode 100644
index 0000000..3b9733a
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/sql/SQLRegistry.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.registry.sql;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Map;
+
+import javax.servlet.ServletException;
+
+import org.eclipse.basyx.aas.registration.memory.AASRegistry;
+import org.eclipse.basyx.aas.registration.memory.MapRegistryHandler;
+import org.eclipse.basyx.components.configuration.BaSyxSQLConfiguration;
+import org.eclipse.basyx.tools.sqlproxy.SQLRootElement;
+
+/**
+ * Implements a local registry based on an SQL database
+ *
+ * @author espen
+ *
+ */
+public class SQLRegistry extends AASRegistry {
+ public final static String TABLE_ID = "root_registry";
+
+ /**
+ * Constructor using default sql connection
+ */
+ public SQLRegistry() {
+ super(new MapRegistryHandler(new AASDescriptorMap(createRootMap(new BaSyxSQLConfiguration()))));
+ }
+
+ /**
+ * Creates a SQLRegistry from a sql configuration
+ */
+ public SQLRegistry(BaSyxSQLConfiguration configuration) {
+ super(new MapRegistryHandler(new AASDescriptorMap(createRootMap(configuration))));
+ }
+
+ private static Map<String, Object> createRootMap(BaSyxSQLConfiguration config) {
+ SQLRootElement sqlRootElement = initSQLConnection(config);
+ sqlRootElement.createRootTableIfNotExists();
+ return sqlRootElement.retrieveRootMap();
+ }
+
+ /**
+ * Initialize sqlDriver
+ *
+ * @throws IOException
+ * @throws FileNotFoundException
+ *
+ * @throws ServletException
+ */
+ private static final SQLRootElement initSQLConnection(BaSyxSQLConfiguration config) {
+ // SQL parameter
+ String path = config.getPath();
+ String user = config.getUser();
+ String pass = config.getPass();
+ String qryPfx = config.getPrefix();
+ String qDrvCls = config.getDriver();
+
+ // Create SQL driver instance
+ return new SQLRootElement(user, pass, path, qDrvCls, qryPfx, TABLE_ID);
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/context.properties b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/context.properties
new file mode 100644
index 0000000..9ff1ad2
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/context.properties
@@ -0,0 +1,24 @@
+# ###############################
+# HTTP Context configuration file
+# ###############################
+
+# ###############################
+# Context Path
+# ###############################
+# Specifies the subpath in the url for this server context
+
+contextPath=/registry
+
+# ###############################
+# Hostname
+# ###############################
+# Specifies the hostname for this server context
+
+contextHostname=localhost
+
+# ###############################
+# Port
+# ###############################
+# Specifies the port for this server context
+
+contextPort=4000
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/resources/logback.xml b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/logback.xml
similarity index 100%
rename from components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/resources/logback.xml
rename to components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/logback.xml
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/mongodb.properties b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/mongodb.properties
new file mode 100644
index 0000000..76dd4e4
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/mongodb.properties
@@ -0,0 +1,32 @@
+# #############################
+# MongoDB Backend configuration
+# #############################
+
+# #############################
+# Database Name
+# #############################
+# The database in the MongoDB that hold the data
+
+dbname=admin
+
+# #############################
+# Connection String
+# #############################
+# MongoDB connection string for connecting to the MongoDB endpoint
+
+dbconnectionstring=mongodb://localhost:27017/
+
+# #############################
+# Registry Collections
+# #############################
+# Collection name that is used for storing registry data
+
+dbcollectionRegistry=registry
+
+# #############################
+# AAS collections
+# #############################
+# Collection names that are used for storing the AAS and Submodels
+
+# dbcollectionAAS=assetadministrationshells
+# dbcollectionSubmodels=submodels
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/registry.properties b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/registry.properties
new file mode 100644
index 0000000..f0657a6
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/registry.properties
@@ -0,0 +1,19 @@
+# ###########################
+# Registry configuration file
+# ###########################
+
+# ###########################
+# Backend
+# ###########################
+# Specifies the backend that loads the AAS and Submodels
+
+# InMemory - does not persist AAS or submodels
+registry.backend=InMemory
+
+# MongoDB - persists data within a MongoDB
+# See connection configuration in mongodb.properties
+# registry.backend=MongoDB
+
+# SQL - persists data within an SQL database
+# See connection configuration in sql.properties
+# registry.backend=SQL
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/sql.properties b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/sql.properties
new file mode 100644
index 0000000..5199325
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/sql.properties
@@ -0,0 +1,36 @@
+# ###############################
+# SQL database configuration file
+# ###############################
+
+# ###############################
+# Credentials
+# ###############################
+# Specifies the credentials for connecting to the SQL database
+
+dbuser=postgres
+dbpass=admin
+
+# ###############################
+# Database URL
+# ###############################
+# The direct SQL database url for connection
+
+dburl=//localhost:5432/basyx-directory?
+
+# ###############################
+# SQL driver information
+# ###############################
+# Java Driver and connection prefix for using the driver
+
+sqlDriver=org.postgresql.Driver
+sqlPrefix=jdbc:postgresql:
+
+
+# ###############################
+# Microsoft SQL Server Example
+# ###############################
+# dburl=//localhost:1234;databaseName=mydb
+# sqlDriver=com.microsoft.sqlserver.jdbc.SQLServerDriver
+# sqlPrefix=jdbc:sqlserver:
+
+
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/ITRegistry.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/ITRegistry.java
new file mode 100644
index 0000000..ec16c95
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/ITRegistry.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.registry;
+
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxDockerConfiguration;
+import org.eclipse.basyx.testsuite.regression.aas.registration.TestRegistryProviderSuite;
+import org.junit.BeforeClass;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ITRegistry extends TestRegistryProviderSuite {
+ private static Logger logger = LoggerFactory.getLogger(ITRegistry.class);
+
+ private static String registryUrl;
+
+ @BeforeClass
+ public static void setUpClass() {
+ logger.info("Running integration test...");
+
+ logger.info("Loading servlet configuration");
+ // Load the servlet configuration inside of the docker configuration from properties file
+ BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
+ contextConfig.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
+
+ // Load the docker environment configuration from properties file
+ logger.info("Loading docker configuration");
+ BaSyxDockerConfiguration dockerConfig = new BaSyxDockerConfiguration();
+ dockerConfig.loadFromResource(BaSyxDockerConfiguration.DEFAULT_CONFIG_PATH);
+
+ registryUrl = "http://localhost:" + dockerConfig.getHostPort() + contextConfig.getContextPath();
+ logger.info("Registry URL for integration test: " + registryUrl);
+ }
+
+ @Override
+ protected IAASRegistry getRegistryService() {
+ return new AASRegistryProxy(registryUrl);
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/ITRegistryRaw.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/ITRegistryRaw.java
new file mode 100644
index 0000000..354ca28
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/ITRegistryRaw.java
@@ -0,0 +1,233 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.registry;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.Collection;
+import java.util.Map;
+
+import javax.ws.rs.NotFoundException;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxDockerConfiguration;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.tools.webserviceclient.WebServiceRawClient;
+import org.eclipse.basyx.vab.coder.json.metaprotocol.MetaprotocolHandler;
+import org.eclipse.basyx.vab.coder.json.serialization.DefaultTypeFactory;
+import org.eclipse.basyx.vab.coder.json.serialization.GSONTools;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Test raw http queries to SQL directory provider.
+ *
+ * @author espen
+ *
+ */
+public class ITRegistryRaw {
+ private static Logger logger = LoggerFactory.getLogger(ITRegistryRaw.class);
+
+ /**
+ * Serialization
+ */
+ private static final GSONTools serializer = new GSONTools(new DefaultTypeFactory());
+ private static final MetaprotocolHandler handler = new MetaprotocolHandler();
+
+ /**
+ * Invoke BaSyx service calls via web services
+ */
+ private static final WebServiceRawClient client = new WebServiceRawClient();
+ private static String registryUrl;
+
+ /**
+ * AASDescriptor to test
+ */
+ private static final IIdentifier id1 = new ModelUrn("urn:de.FHG:es.iese:aas:0.98:5:lab:microscope#A-166");
+ private static final String endpoint1 = "www.endpoint.de";
+ private static final AASDescriptor aasDescriptor1 = new AASDescriptor(id1, endpoint1);
+ private static final String serializedDescriptor1 = serializer.serialize(aasDescriptor1);
+ private static final IIdentifier id2 = new ModelUrn("urn:de.FHG:es.iese:aas:0.98:5:lab:microscope#A-167");
+ private static final String endpoint2 = "www.endpoint2.de";
+ private static final String endpoint2b = "www.endpoint2.de";
+ private static final AASDescriptor aasDescriptor2 = new AASDescriptor(id2, endpoint2);
+ private static final AASDescriptor aasDescriptor2b = new AASDescriptor(id2, endpoint2b);
+ private static final String serializedDescriptor2 = serializer.serialize(aasDescriptor2);
+ private static final String serializedDescriptor2b = serializer.serialize(aasDescriptor2b);
+ private static final IIdentifier idUnknown = new ModelUrn("urn:de.FHG:es.iese:aas:0.98:5:lab:microscope#A-168");
+ private static String aasUrl1, aasUrl2, aasUrlUnknown;
+
+ @BeforeClass
+ public static void setUpClass() throws UnsupportedEncodingException {
+ logger.info("Running integration test...");
+
+ logger.info("Loading servlet configuration");
+ // Load the servlet configuration inside of the docker configuration from properties file
+ BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
+ contextConfig.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
+
+ // Load the docker environment configuration from properties file
+ logger.info("Loading docker configuration");
+ BaSyxDockerConfiguration dockerConfig = new BaSyxDockerConfiguration();
+ dockerConfig.loadFromResource(BaSyxDockerConfiguration.DEFAULT_CONFIG_PATH);
+
+ registryUrl = "http://localhost:" + dockerConfig.getHostPort() + contextConfig.getContextPath()
+ + "/api/v1/registry/";
+ logger.info("Registry URL for integration test: " + registryUrl);
+ aasUrl1 = registryUrl + URLEncoder.encode(id1.getId(), "UTF-8");
+ aasUrl2 = registryUrl + URLEncoder.encode(id2.getId(), "UTF-8");
+ aasUrlUnknown = registryUrl + URLEncoder.encode(idUnknown.getId(), "UTF-8");
+
+ logger.info("Registry URL for integration test: " + registryUrl);
+ }
+
+ @Before
+ public void setUp() {
+ // Put serialized descriptor to register it
+ client.put(aasUrl1, serializedDescriptor1);
+ client.put(aasUrl2, serializedDescriptor2);
+ }
+
+ @After
+ public void tearDown() throws UnsupportedEncodingException {
+ // Delete AAS registration
+ try {
+ client.delete(aasUrl1);
+ } catch(NotFoundException e) {}
+ try {
+ client.delete(aasUrl2);
+ } catch(NotFoundException e) {}
+ }
+
+ /**
+ * Execute test case that test working calls
+ */
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testGetterCalls() {
+ // First test - get all locally registered AAS
+ {
+ // Get all locally registered AAS
+ Collection<AASDescriptor> result = getResult(client.get(registryUrl));
+
+ // Check if all AAS are contained in result
+ assertEquals(2, result.size());
+ }
+
+ // Get a specific AAS (1)
+ try {
+ // Get a known AAS by its ID
+ AASDescriptor result = new AASDescriptor((Map<String, Object>) getResult(client.get(aasUrl1)));
+
+ // Check if all AAS are contained in result
+ assertEquals(id1.getId(), result.getIdentifier().getId());
+ } catch (Exception e) {
+ fail("Get specific AAS test case did throw exception:" + e);
+ }
+
+ // Get a specific AAS (2)
+ try {
+ // Get a known AAS by its ID
+ AASDescriptor result = new AASDescriptor((Map<String, Object>) getResult(client.get(aasUrl2)));
+
+ // Check if all AAS are contained in result
+ assertEquals(id2.getId(), result.getIdentifier().getId());
+ } catch (Exception e) {
+ fail("Get specific AAS test case did throw exception:" + e);
+ }
+ }
+
+ /**
+ * Execute update test case
+ *
+ * @throws UnsupportedEncodingException
+ */
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testUpdateCall() throws UnsupportedEncodingException {
+ // Update a specific AAS
+ // Update AAS registration
+ client.put(aasUrl2, serializedDescriptor2b);
+
+ // Get a known AAS by its ID
+ AASDescriptor result = new AASDescriptor((Map<String, Object>) getResult(client.get(aasUrl2)));
+ // - Check updated registration
+ assertEquals(endpoint2b, result.getFirstEndpoint());
+ }
+
+ /**
+ * Execute create/Delete test cases
+ *
+ * @throws UnsupportedEncodingException
+ */
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testCreateDeleteCall() throws UnsupportedEncodingException {
+ // Update a specific AAS
+ // Delete AAS registration (make sure tests work also if previous test suite
+ // did fail)
+ client.delete(aasUrl2);
+
+ // Try to get deleted AAS, has to throw exception
+ try {
+ getResult(client.get(aasUrl2));
+ fail();
+ } catch(NotFoundException e) {}
+
+ // Create new AAS registration
+ client.put(aasUrl2, serializedDescriptor2);
+
+ // Get a known AAS by its ID
+ AASDescriptor result2 = new AASDescriptor((Map<String, Object>) getResult(client.get(aasUrl2)));
+
+ assertEquals(endpoint2, result2.getFirstEndpoint()); // need deep json string compare here
+
+ // Delete AAS registration
+ client.delete(aasUrl2);
+
+ // Try to get deleted AAS, has to throw exception
+ try {
+ getResult(client.get(aasUrl2));
+ fail();
+ } catch(NotFoundException e) {}
+ }
+
+ /**
+ * Execute test case that test non-working calls
+ *
+ * @throws UnsupportedEncodingException
+ */
+ @Test(expected = NotFoundException.class)
+ public void testNonWorkingCalls() throws UnsupportedEncodingException {
+ // Get unknown AAS ID, has to throw exception
+ getResult(client.get(aasUrlUnknown));
+ fail();
+ }
+
+ @SuppressWarnings("unchecked")
+ private <T> T getResult(String res) {
+ try {
+ return (T) handler.deserialize(res);
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new RuntimeException();
+ }
+ }
+
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/TestMongoDBRegistry.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/TestMongoDBRegistry.java
new file mode 100644
index 0000000..93ef1d8
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/TestMongoDBRegistry.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.registry;
+
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.memory.AASRegistry;
+import org.eclipse.basyx.components.registry.mongodb.MongoDBRegistryHandler;
+import org.eclipse.basyx.testsuite.regression.aas.registration.TestRegistryProviderSuite;
+
+/**
+ * Test class for a local registry provider based on SQL tables
+ *
+ * @author espen
+ *
+ */
+public class TestMongoDBRegistry extends TestRegistryProviderSuite {
+
+ @Override
+ protected IAASRegistry getRegistryService() {
+ return new AASRegistry(new MongoDBRegistryHandler("mongodb.properties"));
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/TestSQLRegistryProvider.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/TestSQLRegistryProvider.java
new file mode 100644
index 0000000..1541805
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/TestSQLRegistryProvider.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.registry;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.components.configuration.BaSyxSQLConfiguration;
+import org.eclipse.basyx.components.registry.sql.SQLRegistry;
+import org.eclipse.basyx.testsuite.regression.aas.registration.TestRegistryProviderSuite;
+import org.eclipse.basyx.tools.sqlproxy.SQLRootElement;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test class for a local registry provider based on SQL tables
+ *
+ * @author espen
+ *
+ */
+public class TestSQLRegistryProvider extends TestRegistryProviderSuite {
+
+ @BeforeClass
+ public static void setUpClass() {
+ SQLRootElement root = getSQLRootElement();
+ root.drop();
+ }
+
+ @AfterClass
+ public static void tearDownClass() {
+ SQLRootElement root = getSQLRootElement();
+ root.drop();
+ }
+
+ protected static SQLRootElement getSQLRootElement() {
+ // Load config
+ BaSyxSQLConfiguration config = new BaSyxSQLConfiguration();
+ config.loadFromResource("sql.properties");
+
+ // Create SQL driver instance
+ String path = config.getPath();
+ String user = config.getUser();
+ String pass = config.getPass();
+ String qryPfx = config.getPrefix();
+ String qDrvCls = config.getDriver();
+ return new SQLRootElement(user, pass, path, qDrvCls, qryPfx, SQLRegistry.TABLE_ID);
+ }
+
+ @Override
+ protected IAASRegistry getRegistryService() {
+ BaSyxSQLConfiguration sqlConfig = new BaSyxSQLConfiguration();
+ sqlConfig.loadFromResource("sql.properties");
+ return new SQLRegistry(sqlConfig);
+ }
+
+ /**
+ * Tests, if the data has been persisted by creating a new registry with the same settings
+ */
+ @Test
+ public void testPersistency() {
+ // Create new SQLRegistry with same configuration
+ BaSyxSQLConfiguration sqlConfig = new BaSyxSQLConfiguration();
+ sqlConfig.loadFromResource("sql.properties");
+ IAASRegistry registry = new SQLRegistry(sqlConfig);
+
+ // Try to "overwrite" data
+ AASDescriptor aasDesc2 = new AASDescriptor(aasIdShort2, aasId2, asset2, aasEndpoint2);
+ proxy.register(aasDesc2);
+
+ // Retrieve and check the first AAS
+ AASDescriptor descriptor = registry.lookupAAS(aasId1);
+ super.validateDescriptor1(descriptor);
+
+ // Retrieve and check the second AAS
+ AASDescriptor descriptor2 = registry.lookupAAS(aasId2);
+ super.validateDescriptor2(descriptor2);
+ }
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/resources/.env b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/resources/.env
new file mode 100644
index 0000000..36083e8
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/resources/.env
@@ -0,0 +1,39 @@
+# ##################
+# Docker Environment
+# ##################
+
+# ##################
+# Host Port
+# ##################
+# Specifies the port for the Docker HOST the container port is mapped to
+
+BASYX_HOST_PORT=8082
+
+# ##################
+# Container Port
+# ##################
+# Specifies the port for the Docker CONTAINER that is be mapped for the host
+
+BASYX_CONTAINER_PORT=4000
+
+# ##################
+# Image Name
+# ##################
+# The image of the image that is build for this component
+
+BASYX_IMAGE_NAME=eclipsebasyx/aas-registry
+
+# ##################
+# Image Tag
+# ##################
+# The image tag of the image that is build for this component
+
+BASYX_IMAGE_TAG=1.0.2
+
+# ##################
+# Container Name
+# ##################
+# The name of the container used for the default environment
+
+BASYX_CONTAINER_NAME=registry
+
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/resources/dockerMongodb.properties b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/resources/dockerMongodb.properties
new file mode 100644
index 0000000..e2caf5b
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/resources/dockerMongodb.properties
@@ -0,0 +1,34 @@
+# #############################
+# MongoDB Backend configuration
+# #############################
+
+# #############################
+# Database Name
+# #############################
+# The database in the MongoDB that hold the data
+
+dbname=admin
+
+# #############################
+# Connection String
+# #############################
+# MongoDB connection string for connecting to the MongoDB endpoint
+# Here it is not localhost, because the container has to address the mongodb
+# container in the default docker environment used in this component
+
+dbconnectionstring=mongodb://mongodb:27017/
+
+# #############################
+# Registry Collections
+# #############################
+# Collection name that is used for storing registry data
+
+dbcollectionRegistry=registry
+
+# #############################
+# AAS collections
+# #############################
+# Collection names that are used for storing the AAS and Submodels
+
+# dbcollectionAAS=assetadministrationshells
+# dbcollectionSubmodels=submodels
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/resources/dockerSQL.properties b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/resources/dockerSQL.properties
new file mode 100644
index 0000000..3871d94
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/resources/dockerSQL.properties
@@ -0,0 +1,37 @@
+# ###############################
+# SQL database configuration file
+# ###############################
+
+# ###############################
+# Credentials
+# ###############################
+# Specifies the credentials for connecting to the SQL database
+
+dbuser=postgres
+dbpass=admin
+
+# ###############################
+# Database URL
+# ###############################
+# The direct SQL database url for connection
+# Here it is not localhost, because the container has to address the postgreSQL
+# container in the default docker environment used in this component
+
+dburl=//postgres:5432/basyx-directory?
+
+# ###############################
+# SQL driver information
+# ###############################
+# Java Driver and connection prefix for using the driver
+
+sqlDriver=org.postgresql.Driver
+sqlPrefix=jdbc:postgresql:
+
+
+# ###############################
+# Microsoft SQL Server Example
+# ###############################
+# dburl=//localhost:1234;databaseName=mydb
+# sqlDriver=com.microsoft.sqlserver.jdbc.SQLServerDriver
+# sqlPrefix=jdbc:sqlserver:
+
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/start.bat b/components/basys.components/basyx.components.docker/basyx.components.registry/start.bat
new file mode 100644
index 0000000..f0ff9e1
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/start.bat
@@ -0,0 +1,3 @@
+cd src/test/resources
+docker-compose up
+cd ../../..
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/start.sh b/components/basys.components/basyx.components.docker/basyx.components.registry/start.sh
new file mode 100644
index 0000000..4b9b54a
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/start.sh
@@ -0,0 +1,4 @@
+#!/usr/bin/env sh
+cd src/test/resources
+docker-compose up
+cd ../../..
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/stop.bat b/components/basys.components/basyx.components.docker/basyx.components.registry/stop.bat
new file mode 100644
index 0000000..b645246
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/stop.bat
@@ -0,0 +1,3 @@
+cd src/test/resources
+docker-compose down
+cd ../../..
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/stop.sh b/components/basys.components/basyx.components.docker/basyx.components.registry/stop.sh
new file mode 100644
index 0000000..e11a931
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/stop.sh
@@ -0,0 +1,4 @@
+#!/usr/bin/env sh
+cd src/test/resources
+docker-compose down
+cd ../../..
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.simple/Dockerfile b/components/basys.components/basyx.components.docker/basyx.components.simple/Dockerfile
deleted file mode 100644
index 3628774..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.simple/Dockerfile
+++ /dev/null
@@ -1,15 +0,0 @@
-# Add java runtime environment for execution
-FROM java:8-jdk-alpine
-
-# Copy built jar to image using the jar name specified in the pom.xml (JAR_FILE)
-ARG JAR_FILE
-COPY target/${JAR_FILE} /usr/share/basyxExecutable.jar
-COPY target/lib /usr/share/lib
-COPY src/main/resources/context.properties /usr/share/context.properties
-
-# Expose the appropriate port. In case of Tomcat, this is 8080.
-ARG PORT
-EXPOSE ${PORT}
-
-# Start the jar
-CMD java -jar "/usr/share/basyxExecutable.jar" "/usr/share/context.properties"
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.simple/docker-compose.yml b/components/basys.components/basyx.components.docker/basyx.components.simple/docker-compose.yml
deleted file mode 100644
index aca4d1b..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.simple/docker-compose.yml
+++ /dev/null
@@ -1,31 +0,0 @@
-version: '3'
-services:
-
- registry:
- image: ${BASYX_IMAGE_NAME}:${BASYX_IMAGE_TAG}
- container_name: ${BASYX_CONTAINER_NAME}
- ports:
- - ${BASYX_HOST_PORT}:${BASYX_CONTAINER_PORT}
-# depends_on:
-# - postgres
-# volumes:
-# - .\WebContent\WEB-INF\config\directory\sqldirectory\directory.properties:/basys/directory.properties
-# links:
-# - postgres
-
-# postgres:
-# image: postgres:9.4
-# container_name: postgres
-# environment:
-# - POSTGRES_USER:'postgres'
-# - POSTGRES_PASSWORD:'admin'
-# - POSTGRES_DB=basyx-directory
-# volumes:
-# - ./WebContent/WEB-INF/config/postgres/init.sql:/docker-entrypoint-initdb.d/init.sql
-# ports:
-# - 5433:5432
-# expose:
-# - 5432
-
-
-
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.simple/pom.xml b/components/basys.components/basyx.components.docker/basyx.components.simple/pom.xml
deleted file mode 100644
index 78b6354..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.simple/pom.xml
+++ /dev/null
@@ -1,95 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <!--
- Simple Docker Component
-
- Serves as a template for simple docker components that do not depend on other docker containers.
- Do NOT use the included in-memory registry in a productive environment - the entries are not stored permanently
- -->
-
- <parent>
- <groupId>org.eclipse.basyx</groupId>
- <artifactId>basyx.components.docker</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- </parent>
-
- <artifactId>basyx.components.simple</artifactId>
- <name>BaSyx Simple Docker Component</name>
-
- <properties>
- <!--
- basyx.components.executable is the executable class with the definition of the public void main(String[]).
- It is needed when building the jar in the maven-jar-plugin (see basyx.components.docker/pom.xml)
- -->
- <basyx.components.executable>org.eclipse.basyx.components.executable.InMemoryRegistryExecutable</basyx.components.executable>
- </properties>
-
- <packaging>jar</packaging>
-
- <!-- Define additional plugins that are not included by default -->
- <!-- Plugin configuration is done in parent project(s) -->
- <build>
- <plugins>
- <!-- Attach sources to jar file -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-
- <profiles>
- <profile>
- <!--
- "Docker" profile - do not build & install docker images by default
- Run "mvn install -Pdocker" in order to include docker
- -->
- <id>docker</id>
- <build>
- <plugins>
- <!-- Read maven properties from file -->
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>properties-maven-plugin</artifactId>
- </plugin>
-
- <!-- Copy the dependencies necessary to run the jar -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-dependency-plugin</artifactId>
- </plugin>
-
- <!-- Build the docker image -->
- <plugin>
- <groupId>com.spotify</groupId>
- <artifactId>dockerfile-maven-plugin</artifactId>
- </plugin>
-
- <!-- Create integration test environment -->
- <plugin>
- <groupId>com.dkanejs.maven.plugins</groupId>
- <artifactId>docker-compose-maven-plugin</artifactId>
- </plugin>
-
- <!-- Run integration tests -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-failsafe-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
- </profile>
- </profiles>
-
- <dependencies>
- <!-- Adds additional classes of the BaSys SDK for tests (for TestRegistryProvider) -->
- <dependency>
- <groupId>org.eclipse.basyx</groupId>
- <artifactId>basyx.sdk</artifactId>
- <classifier>tests</classifier>
- </dependency>
- </dependencies>
-</project>
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/java/org/eclipse/basyx/components/InMemoryRegistryComponent.java b/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/java/org/eclipse/basyx/components/InMemoryRegistryComponent.java
deleted file mode 100644
index 972d21e..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/java/org/eclipse/basyx/components/InMemoryRegistryComponent.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package org.eclipse.basyx.components;
-
-import org.eclipse.basyx.components.servlets.InMemoryRegistryServlet;
-import org.eclipse.basyx.vab.protocol.http.server.AASHTTPServer;
-import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A Registry component based on an InMemory Registry.
- *
- * Do not use this registry in a productive environment - the entries are not persistent!
- *
- * @author espen
- */
-public class InMemoryRegistryComponent {
- private static Logger logger = LoggerFactory.getLogger(InMemoryRegistryComponent.class);
-
- // BaSyx context information
- private String hostName;
- private int port;
- private String path;
- private String docBasePath;
-
- // The server with the servlet that will be created
- private AASHTTPServer server;
-
- public InMemoryRegistryComponent(String hostName, int port, String path, String docBasePath) {
- // Sets the server context
- this.hostName = hostName;
- this.port = port;
- this.path = path;
- this.docBasePath = docBasePath;
- }
-
- /**
- * Starts the InMemoryRegistry at http://${hostName}:${port}/${path}
- */
- public void startComponent() {
- logger.info("Create the server...");
- // Init HTTP context and add an InMemoryRegistryServlet according to the configuration
- BaSyxContext context = new BaSyxContext(path, docBasePath, hostName, port);
- context.addServletMapping("/*", new InMemoryRegistryServlet());
- server = new AASHTTPServer(context);
-
- logger.info("Start the server...");
- server.start();
- }
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/java/org/eclipse/basyx/components/executable/InMemoryRegistryExecutable.java b/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/java/org/eclipse/basyx/components/executable/InMemoryRegistryExecutable.java
deleted file mode 100644
index eb7191d..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/java/org/eclipse/basyx/components/executable/InMemoryRegistryExecutable.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package org.eclipse.basyx.components.executable;
-
-import org.eclipse.basyx.components.InMemoryRegistryComponent;
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A registry servlet based on an InMemory Registry. The servlet therefore provides an implementation
- * for the IAASRegistryService interface without a permanent storage capability.
- *
- * Do not use this registry in a productive environment - the entries are not persistent!
- *
- * @author espen
- */
-public class InMemoryRegistryExecutable {
- private static Logger logger = LoggerFactory.getLogger(InMemoryRegistryExecutable.class);
-
- private InMemoryRegistryExecutable() {
- }
-
- public static void main(String[] args) {
- logger.info("Starting BaSyx InMemory registry");
-
- // Load configuration
- BaSyxContextConfiguration config = new BaSyxContextConfiguration();
- if (args.length > 0 && args[0] instanceof String) {
- // file path available? => load configs from file
- config.loadFromFile(args[0]);
- } else {
- // fallback: load default configs (in resources)
- config.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
- }
-
- InMemoryRegistryComponent component = new InMemoryRegistryComponent(config.getHostname(), config.getPort(),
- config.getContextPath(), config.getDocBasePath());
- component.startComponent();
- }
-}
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/java/org/eclipse/basyx/components/servlets/InMemoryRegistryServlet.java b/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/java/org/eclipse/basyx/components/servlets/InMemoryRegistryServlet.java
deleted file mode 100644
index 933577b..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/java/org/eclipse/basyx/components/servlets/InMemoryRegistryServlet.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.eclipse.basyx.components.servlets;
-
-import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
-import org.eclipse.basyx.aas.registration.restapi.DirectoryModelProvider;
-import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
-
-/**
- * A registry servlet based on an InMemory Registry. The servlet therefore provides an implementation
- * for the IAASRegistryService interface without a permanent storage capability.
- *
- * Do not use this registry in a productive environment - the entries are not persistent!
- *
- * @author espen
- */
-public class InMemoryRegistryServlet extends VABHTTPInterface<DirectoryModelProvider> {
- private static final long serialVersionUID = 1L;
-
- /**
- * Constructor with ModelProvider based on an InMemoryRegistry
- */
- public InMemoryRegistryServlet() {
- super(new DirectoryModelProvider(new InMemoryRegistry()));
-
- }
-}
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/resources/context.properties b/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/resources/context.properties
deleted file mode 100644
index 7e933a3..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/resources/context.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-contextPath=/registry
-contextHostname=localhost
-contextPort=4000
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/resources/logback.xml b/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/resources/logback.xml
deleted file mode 100644
index 86341d6..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/resources/logback.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<configuration>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
-
- <!-- Example for a filter, which removes all entries not containing "[TEST]" in the message. -->
-
- <!--<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
- <evaluator>
- <expression>return message.contains("[TEST]");</expression>
- </evaluator>
- <OnMismatch>DENY</OnMismatch>
- <OnMatch>NEUTRAL</OnMatch>
- </filter>-->
-
- <encoder>
- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="INFO">
- <appender-ref ref="STDOUT" />
- </root>
-
-</configuration>
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.simple/src/test/java/org/eclipse/basyx/regression/docker/ITInMemoryRegistry.java b/components/basys.components/basyx.components.docker/basyx.components.simple/src/test/java/org/eclipse/basyx/regression/docker/ITInMemoryRegistry.java
deleted file mode 100644
index 0dbb7bf..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.simple/src/test/java/org/eclipse/basyx/regression/docker/ITInMemoryRegistry.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package org.eclipse.basyx.regression.docker;
-
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
-import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.eclipse.basyx.components.configuration.BaSyxDockerConfiguration;
-import org.eclipse.basyx.testsuite.regression.aas.registration.TestRegistryProviderSuite;
-import org.junit.BeforeClass;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ITInMemoryRegistry extends TestRegistryProviderSuite {
- private static Logger logger = LoggerFactory.getLogger(ITInMemoryRegistry.class);
-
- private static String registryUrl;
-
- @BeforeClass
- public static void setUpClass() {
- logger.info("Running integration test...");
-
- logger.info("Loading servlet configuration");
- // Load the servlet configuration inside of the docker configuration from properties file
- BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
- contextConfig.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
-
- // Load the docker environment configuration from properties file
- logger.info("Loading docker configuration");
- BaSyxDockerConfiguration dockerConfig = new BaSyxDockerConfiguration();
- dockerConfig.loadFromResource(BaSyxDockerConfiguration.DEFAULT_CONFIG_PATH);
-
- registryUrl = "http://localhost:" + dockerConfig.getHostPort() + contextConfig.getContextPath();
- logger.info("Registry URL for integration test: " + registryUrl);
- }
-
- @Override
- protected IAASRegistryService getRegistryService() {
- return new AASRegistryProxy(registryUrl);
- }
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.simple/src/test/resources/.env b/components/basys.components/basyx.components.docker/basyx.components.simple/src/test/resources/.env
deleted file mode 100644
index 21cc7e8..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.simple/src/test/resources/.env
+++ /dev/null
@@ -1,5 +0,0 @@
-BASYX_HOST_PORT=8082
-BASYX_CONTAINER_PORT=4000
-BASYX_IMAGE_NAME=basys/registry-inmemory
-BASYX_CONTAINER_NAME=registry
-BASYX_IMAGE_TAG=0.0.1-SNAPSHOT
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/Dockerfile b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/Dockerfile
deleted file mode 100644
index 3628774..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/Dockerfile
+++ /dev/null
@@ -1,15 +0,0 @@
-# Add java runtime environment for execution
-FROM java:8-jdk-alpine
-
-# Copy built jar to image using the jar name specified in the pom.xml (JAR_FILE)
-ARG JAR_FILE
-COPY target/${JAR_FILE} /usr/share/basyxExecutable.jar
-COPY target/lib /usr/share/lib
-COPY src/main/resources/context.properties /usr/share/context.properties
-
-# Expose the appropriate port. In case of Tomcat, this is 8080.
-ARG PORT
-EXPOSE ${PORT}
-
-# Start the jar
-CMD java -jar "/usr/share/basyxExecutable.jar" "/usr/share/context.properties"
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/docker-compose.yml b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/docker-compose.yml
deleted file mode 100644
index f6add3e..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/docker-compose.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-version: '2.1'
-services:
- registry:
- image: ${BASYX_IMAGE_NAME}:${BASYX_IMAGE_TAG}
- container_name: ${BASYX_CONTAINER_NAME}
- ports:
- - ${BASYX_HOST_PORT}:${BASYX_CONTAINER_PORT}
- depends_on:
- postgres:
- condition: service_healthy
-# Possibility to embed user-configuration into the docker container
-# volumes:
-# - ./myConfig/myConfigs.properties:/usr/share/dockerRegistry.properties
- links:
- - postgres
-
- postgres:
- image: postgres:12.1
- container_name: postgres
- environment:
- - POSTGRES_USER:'postgres'
- - POSTGRES_PASSWORD:'admin'
- - POSTGRES_DB=basyx-directory
- healthcheck:
- test: ["CMD-SHELL", "pg_isready -U postgres"]
- interval: 3s
- timeout: 3s
- retries: 5
-# Possibility to configure postgres-config into docker container
-# volumes:
-# - ./WebContent/WEB-INF/config/postgres/init.sql:/docker-entrypoint-initdb.d/init.sql
-# ports:
-# - 5433:5432
-# expose:
-# - 5432
-
-
-
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/pom.xml b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/pom.xml
deleted file mode 100644
index 3664f36..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/pom.xml
+++ /dev/null
@@ -1,80 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.eclipse.basyx</groupId>
- <artifactId>basyx.components.docker</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- </parent>
-
- <artifactId>basyx.components.sqlregistry</artifactId>
- <name>BaSyx SQL Registry</name>
-
- <properties>
- <basyx.components.executable>org.eclipse.basyx.components.executable.SQLRegistryExecutable</basyx.components.executable>
- </properties>
-
- <packaging>jar</packaging>
-
- <build>
- <!-- Define additional plugins that are not included by default -->
- <!-- Plugin configuration is done in parent project(s) -->
- <plugins>
- <!-- Attach sources to jar file -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-
- <dependencies>
- <!-- Adds additional classes of the BaSys SDK for tests (for TestRegistryProvider) -->
- <dependency>
- <groupId>org.eclipse.basyx</groupId>
- <artifactId>basyx.sdk</artifactId>
- <classifier>tests</classifier>
- </dependency>
- </dependencies>
-
- <profiles>
- <profile>
- <id>docker</id>
- <build>
- <plugins>
- <!-- Read maven properties from file -->
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>properties-maven-plugin</artifactId>
- </plugin>
-
- <!-- Copy the dependencies necessary to run the jar -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-dependency-plugin</artifactId>
- </plugin>
-
- <!-- Build the docker image -->
- <plugin>
- <groupId>com.spotify</groupId>
- <artifactId>dockerfile-maven-plugin</artifactId>
- </plugin>
-
- <!-- Create integration test environment -->
- <plugin>
- <groupId>com.dkanejs.maven.plugins</groupId>
- <artifactId>docker-compose-maven-plugin</artifactId>
- </plugin>
-
- <!-- Run integration tests -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-failsafe-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
- </profile>
- </profiles>
-</project>
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/SQLRegistryComponent.java b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/SQLRegistryComponent.java
deleted file mode 100644
index 3f70a6e..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/SQLRegistryComponent.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package org.eclipse.basyx.components;
-
-import org.eclipse.basyx.components.servlet.SQLRegistryServlet;
-import org.eclipse.basyx.vab.protocol.http.server.AASHTTPServer;
-import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A registry component based on an SQL database.
- *
- * @author espen
- */
-public class SQLRegistryComponent {
- private static Logger logger = LoggerFactory.getLogger(SQLRegistryComponent.class);
-
- // BaSyx context information
- private String hostName;
- private int port;
- private String path;
- private String docBasePath;
- private String sqlPropertyPath;
-
- // The server with the servlet that will be created
- private AASHTTPServer server;
-
- public SQLRegistryComponent(String hostName, int port, String path, String docBasePath, String sqlPropertyPath) {
- this.sqlPropertyPath = sqlPropertyPath;
- // Sets the server context
- this.hostName = hostName;
- this.port = port;
- this.path = path;
- this.docBasePath = docBasePath;
- }
-
- /**
- * Starts the SQLRegistry at http://${hostName}:${port}/${path}
- */
- public void startComponent() {
- logger.info("Create the server...");
- // Init HTTP context and add an InMemoryRegistryServlet according to the configuration
- BaSyxContext context = new BaSyxContext(path, docBasePath, hostName, port);
- context.addServletMapping("/*", new SQLRegistryServlet(sqlPropertyPath));
- server = new AASHTTPServer(context);
-
- logger.info("Start the server...");
- server.start();
- }
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/executable/SQLRegistryExecutable.java b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/executable/SQLRegistryExecutable.java
deleted file mode 100644
index 67a1d4a..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/executable/SQLRegistryExecutable.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package org.eclipse.basyx.components.executable;
-
-import org.eclipse.basyx.components.SQLRegistryComponent;
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A registry servlet based on an SQL database. The servlet therefore provides an implementation
- * for the IAASRegistryService interface with a permanent storage solution. The properties for the
- * SQL connection will be read from executables.properties in the resource folder.
- *
- * @author espen
- */
-public class SQLRegistryExecutable {
- private static Logger logger = LoggerFactory.getLogger(SQLRegistryExecutable.class);
-
- private SQLRegistryExecutable() {
- }
-
- public static void main(String[] args) {
- logger.info("Starting BaSyx SQL registry");
-
- // Load configuration
- BaSyxContextConfiguration config = new BaSyxContextConfiguration();
- if (args.length > 0 && args[0] instanceof String) {
- // file path available? => load configs from file
- config.loadFromFile(args[0]);
- } else {
- // fallback: load default configs (in resources)
- config.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
- }
-
- SQLRegistryComponent component = new SQLRegistryComponent(config.getHostname(), config.getPort(),
- config.getContextPath(), config.getDocBasePath(), "dockerRegistry.properties");
- component.startComponent();
- }
-}
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/servlet/SQLRegistryServlet.java b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/servlet/SQLRegistryServlet.java
deleted file mode 100644
index ff69ac7..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/servlet/SQLRegistryServlet.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package org.eclipse.basyx.components.servlet;
-
-import org.eclipse.basyx.aas.registration.restapi.DirectoryModelProvider;
-import org.eclipse.basyx.components.sqlregistry.SQLRegistry;
-import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
-
-/**
- * A registry servlet based on an SQL database. The servlet therefore provides an implementation
- * for the IAASRegistryService interface with a permanent storage solution.
- *
- * @author kuhn, pschorn, espen
- */
-public class SQLRegistryServlet extends VABHTTPInterface<DirectoryModelProvider> {
- private static final long serialVersionUID = 1L;
-
- /**
- * Provide HTTP interface with JSONProvider to handle serialization and
- * SQLDirectoryProvider as backend
- */
- public SQLRegistryServlet() {
- super(new DirectoryModelProvider(new SQLRegistry()));
- }
-
- public SQLRegistryServlet(String customConfigFilePath) {
- super(new DirectoryModelProvider(new SQLRegistry(customConfigFilePath)));
- }
-}
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/sqlregistry/AASDescriptorMap.java b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/sqlregistry/AASDescriptorMap.java
deleted file mode 100644
index d754f4c..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/sqlregistry/AASDescriptorMap.java
+++ /dev/null
@@ -1,129 +0,0 @@
-package org.eclipse.basyx.components.sqlregistry;
-
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
-
-/**
- * This is a map implementation for a <String, AASDescriptor> map which is needed
- * by map registries. It is based on an arbitrary <String, Object> map and provides a proxy
- * access to that map by assuming AASDescriptor entries.
- *
- * @author espen
- *
- */
-public class AASDescriptorMap implements Map<String, AASDescriptor> {
- /**
- * The map all operations of this map are based on
- */
- private Map<String, Object> baseMap;
-
- /**
- * Default constructor taking the base map
- *
- * @param baseMap
- */
- public AASDescriptorMap(Map<String, Object> baseMap) {
- this.baseMap = baseMap;
- }
-
- @Override
- public int size() {
- return baseMap.size();
- }
-
- @Override
- public boolean isEmpty() {
- return baseMap.isEmpty();
- }
-
- @Override
- public boolean containsKey(Object key) {
- return baseMap.containsKey(key);
- }
-
- @Override
- public boolean containsValue(Object value) {
- return baseMap.containsValue(value);
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public AASDescriptor get(Object key) {
- Map<String, Object> mapEntry = (Map<String, Object>) baseMap.get(key);
- if (mapEntry == null) {
- return null;
- } else {
- return new AASDescriptor(mapEntry);
- }
- }
-
- @Override
- public AASDescriptor put(String key, AASDescriptor value) {
- return (AASDescriptor) baseMap.put(key, value);
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public AASDescriptor remove(Object key) {
- Map<String, Object> result = (Map<String, Object>) baseMap.remove(key);
- if (result == null) {
- return null;
- } else {
- return new AASDescriptor(result);
- }
- }
-
- @Override
- public void putAll(Map<? extends String, ? extends AASDescriptor> m) {
- baseMap.putAll(m);
- }
-
- @Override
- public void clear() {
- baseMap.clear();
- }
-
- @Override
- public Set<String> keySet() {
- return baseMap.keySet();
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public Collection<AASDescriptor> values() {
- return baseMap.values().stream()
- .map(o -> new AASDescriptor((Map<String, Object>) o))
- .collect(Collectors.toList());
- }
-
- @Override
- public Set<Entry<String, AASDescriptor>> entrySet() {
- return baseMap.entrySet().stream()
- .map(e -> new Entry<String, AASDescriptor>() {
- @Override
- public AASDescriptor setValue(AASDescriptor value) {
- return (AASDescriptor) e.setValue(value);
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public AASDescriptor getValue() {
- if (e.getValue() == null) {
- return null;
- } else {
- return new AASDescriptor((Map<String, Object>) e.getValue());
- }
- }
-
- @Override
- public String getKey() {
- return e.getKey();
- }
- }).collect(Collectors.toSet());
- }
-
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/sqlregistry/SQLRegistry.java b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/sqlregistry/SQLRegistry.java
deleted file mode 100644
index 17f2729..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/sqlregistry/SQLRegistry.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package org.eclipse.basyx.components.sqlregistry;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.Map;
-
-import javax.servlet.ServletException;
-
-import org.eclipse.basyx.aas.registration.memory.MapRegistry;
-import org.eclipse.basyx.components.configuration.BaSyxSQLConfiguration;
-import org.eclipse.basyx.tools.sqlproxy.SQLRootElement;
-
-/**
- * Implements a local registry based on an SQL database
- *
- * @author espen
- *
- */
-public class SQLRegistry extends MapRegistry {
- private static final String DEFAULT_SQL_CONFIG_PATH = "registry.properties";
-
- /**
- * Receives the path of the configuration.properties file in it's constructor.
- *
- * @param configFilePath
- */
- public SQLRegistry(String configFilePath) {
- super(new AASDescriptorMap(createRootMap(configFilePath)));
- }
-
- /**
- * Constructor using default sql connections
- */
- public SQLRegistry() {
- this(DEFAULT_SQL_CONFIG_PATH);
- }
-
- /**
- * Creates a SQLRegistry from a sql configuration
- */
- public SQLRegistry(BaSyxSQLConfiguration configuration) {
- super(new AASDescriptorMap(createRootMap(configuration)));
- }
-
- private static Map<String, Object> createRootMap(String configFilePath) {
- BaSyxSQLConfiguration config = new BaSyxSQLConfiguration();
- config.loadFromResource(configFilePath);
- return createRootMap(config);
- }
-
- private static Map<String, Object> createRootMap(BaSyxSQLConfiguration config) {
- SQLRootElement sqlRootElement = initSQLConnection(config);
- sqlRootElement.drop();
- sqlRootElement.create();
-
- return sqlRootElement.createMap(sqlRootElement.getNextIdentifier());
- }
-
- /**
- * Initialize sqlDriver
- *
- * @throws IOException
- * @throws FileNotFoundException
- *
- * @throws ServletException
- */
- private static final SQLRootElement initSQLConnection(BaSyxSQLConfiguration config) {
- // SQL parameter
- String path = config.getPath();
- String user = config.getUser();
- String pass = config.getPass();
- String qryPfx = config.getPrefix();
- String qDrvCls = config.getDrv();
-
- // Create SQL driver instance
- return new SQLRootElement(user, pass, path, qDrvCls, qryPfx, "root_registry");
- }
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/resources/context.properties b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/resources/context.properties
deleted file mode 100644
index 7e933a3..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/resources/context.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-contextPath=/registry
-contextHostname=localhost
-contextPort=4000
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/resources/dockerRegistry.properties b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/resources/dockerRegistry.properties
deleted file mode 100644
index 3464cd4..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/resources/dockerRegistry.properties
+++ /dev/null
@@ -1,43 +0,0 @@
-# ##############################################################
-# Directory configuration file
-# ##############################################################
-
-
-
-
-# ##############################################################
-# Directory server configuration
-
-
-# URL and type of uplink server. Forward all requests that we cannot satisfy here to uplink
-# - URL of uplink directory server
-# - Type of uplink server. Currently supported is BASYS (BaSys registry API) or DNS (DNS server processing legalBody tag)
-cfg.uplink =
-cfg.uplink.type = DNS
-
-
-# Downlink servers, forward matching URI patterns to downlink servers
-# - Match all subunits that end with "is.iese", including "is.iese"
-cfg.downlink.is.pattern = is.iese
-cfg.downlink.is.directory = http://wherever1
-
-# - Match all subunits that end with "pm.iese", including "pm.iese"
-cfg.downlink.pm.pattern = pm.iese
-cfg.downlink.pm.directory = http://wherever2
-
-# - Match all subunits that end with ".es.iese", but not "es.iese"
-cfg.downlink.es.pattern = .es.iese
-cfg.downlink.es.directory = http://wherever3
-
-
-
-
-# ##############################################################
-# SQL database configuration
-
-dbuser = postgres
-dbpass = admin
-dburl = //postgres:5432/basyx-directory?
-
-sqlDriver = org.postgresql.Driver
-sqlPrefix = jdbc:postgresql:
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/java/org/eclipse/basyx/regression/registry/ITSQLRegistry.java b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/java/org/eclipse/basyx/regression/registry/ITSQLRegistry.java
deleted file mode 100644
index 34afc09..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/java/org/eclipse/basyx/regression/registry/ITSQLRegistry.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package org.eclipse.basyx.regression.registry;
-
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
-import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.eclipse.basyx.components.configuration.BaSyxDockerConfiguration;
-import org.eclipse.basyx.testsuite.regression.aas.registration.TestRegistryProviderSuite;
-import org.junit.BeforeClass;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ITSQLRegistry extends TestRegistryProviderSuite {
- private static Logger logger = LoggerFactory.getLogger(ITSQLRegistry.class);
-
- private static String registryUrl;
-
- @BeforeClass
- public static void setUpClass() {
- logger.info("Running integration test...");
-
- logger.info("Loading servlet configuration");
- // Load the servlet configuration inside of the docker configuration from properties file
- BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
- contextConfig.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
-
- // Load the docker environment configuration from properties file
- logger.info("Loading docker configuration");
- BaSyxDockerConfiguration dockerConfig = new BaSyxDockerConfiguration();
- dockerConfig.loadFromResource(BaSyxDockerConfiguration.DEFAULT_CONFIG_PATH);
-
- registryUrl = "http://localhost:" + dockerConfig.getHostPort() + contextConfig.getContextPath()
- + "/api/v1/registry";
- logger.info("Registry URL for integration test: " + registryUrl);
- }
-
- @Override
- protected IAASRegistryService getRegistryService() {
- // Create a registry proxy directly pointing to the servlet
- return new AASRegistryProxy(registryUrl);
- }
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/java/org/eclipse/basyx/regression/registry/ITSQLRegistryRaw.java b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/java/org/eclipse/basyx/regression/registry/ITSQLRegistryRaw.java
deleted file mode 100644
index 2c5ed04..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/java/org/eclipse/basyx/regression/registry/ITSQLRegistryRaw.java
+++ /dev/null
@@ -1,224 +0,0 @@
-package org.eclipse.basyx.regression.registry;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-import java.util.Collection;
-import java.util.Map;
-
-import javax.ws.rs.NotFoundException;
-
-import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.eclipse.basyx.components.configuration.BaSyxDockerConfiguration;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.tools.webserviceclient.WebServiceRawClient;
-import org.eclipse.basyx.vab.coder.json.metaprotocol.MetaprotocolHandler;
-import org.eclipse.basyx.vab.coder.json.serialization.DefaultTypeFactory;
-import org.eclipse.basyx.vab.coder.json.serialization.GSONTools;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Test raw http queries to SQL directory provider.
- *
- * @author espen
- *
- */
-public class ITSQLRegistryRaw {
- private static Logger logger = LoggerFactory.getLogger(ITSQLRegistry.class);
-
- /**
- * Serialization
- */
- private static final GSONTools serializer = new GSONTools(new DefaultTypeFactory());
- private static final MetaprotocolHandler handler = new MetaprotocolHandler();
-
- /**
- * Invoke BaSyx service calls via web services
- */
- private static final WebServiceRawClient client = new WebServiceRawClient();
- private static String registryUrl;
-
- /**
- * AASDescriptor to test
- */
- private static final IIdentifier id1 = new ModelUrn("urn:de.FHG:es.iese:aas:0.98:5:lab:microscope#A-166");
- private static final String endpoint1 = "www.endpoint.de";
- private static final AASDescriptor aasDescriptor1 = new AASDescriptor(id1, endpoint1);
- private static final String serializedDescriptor1 = serializer.serialize(aasDescriptor1);
- private static final IIdentifier id2 = new ModelUrn("urn:de.FHG:es.iese:aas:0.98:5:lab:microscope#A-167");
- private static final String endpoint2 = "www.endpoint2.de";
- private static final String endpoint2b = "www.endpoint2.de";
- private static final AASDescriptor aasDescriptor2 = new AASDescriptor(id2, endpoint2);
- private static final AASDescriptor aasDescriptor2b = new AASDescriptor(id2, endpoint2b);
- private static final String serializedDescriptor2 = serializer.serialize(aasDescriptor2);
- private static final String serializedDescriptor2b = serializer.serialize(aasDescriptor2b);
- private static final IIdentifier idUnknown = new ModelUrn("urn:de.FHG:es.iese:aas:0.98:5:lab:microscope#A-168");
- private static String aasUrl1, aasUrl2, aasUrlUnknown;
-
- @BeforeClass
- public static void setUpClass() throws UnsupportedEncodingException {
- logger.info("Running integration test...");
-
- logger.info("Loading servlet configuration");
- // Load the servlet configuration inside of the docker configuration from properties file
- BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
- contextConfig.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
-
- // Load the docker environment configuration from properties file
- logger.info("Loading docker configuration");
- BaSyxDockerConfiguration dockerConfig = new BaSyxDockerConfiguration();
- dockerConfig.loadFromResource(BaSyxDockerConfiguration.DEFAULT_CONFIG_PATH);
-
- registryUrl = "http://localhost:" + dockerConfig.getHostPort() + contextConfig.getContextPath()
- + "/api/v1/registry/";
- logger.info("Registry URL for integration test: " + registryUrl);
- aasUrl1 = registryUrl + URLEncoder.encode(id1.getId(), "UTF-8");
- aasUrl2 = registryUrl + URLEncoder.encode(id2.getId(), "UTF-8");
- aasUrlUnknown = registryUrl + URLEncoder.encode(idUnknown.getId(), "UTF-8");
-
- logger.info("Registry URL for integration test: " + registryUrl);
- }
-
- @Before
- public void setUp() {
- // Post serialized descriptor to register it
- client.post(registryUrl, serializedDescriptor1);
- client.post(registryUrl, serializedDescriptor2);
- }
-
- @After
- public void tearDown() throws UnsupportedEncodingException {
- // Delete AAS registration
- try {
- client.delete(aasUrl1);
- } catch(NotFoundException e) {}
- try {
- client.delete(aasUrl2);
- } catch(NotFoundException e) {}
- }
-
- /**
- * Execute test case that test working calls
- */
- @SuppressWarnings("unchecked")
- @Test
- public void testGetterCalls() {
- // First test - get all locally registered AAS
- {
- // Get all locally registered AAS
- Collection<AASDescriptor> result = getResult(client.get(registryUrl));
-
- // Check if all AAS are contained in result
- assertEquals(2, result.size());
- }
-
- // Get a specific AAS (1)
- try {
- // Get a known AAS by its ID
- AASDescriptor result = new AASDescriptor((Map<String, Object>) getResult(client.get(aasUrl1)));
-
- // Check if all AAS are contained in result
- assertEquals(id1.getId(), result.getIdentifier().getId());
- } catch (Exception e) {
- fail("Get specific AAS test case did throw exception:" + e);
- }
-
- // Get a specific AAS (2)
- try {
- // Get a known AAS by its ID
- AASDescriptor result = new AASDescriptor((Map<String, Object>) getResult(client.get(aasUrl2)));
-
- // Check if all AAS are contained in result
- assertEquals(id2.getId(), result.getIdentifier().getId());
- } catch (Exception e) {
- fail("Get specific AAS test case did throw exception:" + e);
- }
- }
-
- /**
- * Execute update test case
- *
- * @throws UnsupportedEncodingException
- */
- @SuppressWarnings("unchecked")
- @Test
- public void testUpdateCall() throws UnsupportedEncodingException {
- // Update a specific AAS
- // Update AAS registration
- client.put(aasUrl2, serializedDescriptor2b);
-
- // Get a known AAS by its ID
- AASDescriptor result = new AASDescriptor((Map<String, Object>) getResult(client.get(aasUrl2)));
- // - Check updated registration
- assertEquals(endpoint2b, result.getFirstEndpoint());
- }
-
- /**
- * Execute create/Delete test cases
- *
- * @throws UnsupportedEncodingException
- */
- @SuppressWarnings("unchecked")
- @Test
- public void testCreateDeleteCall() throws UnsupportedEncodingException {
- // Update a specific AAS
- // Delete AAS registration (make sure tests work also if previous test suite
- // did fail)
- client.delete(aasUrl2);
-
- // Try to get deleted AAS, has to throw exception
- try {
- getResult(client.get(aasUrl2));
- fail();
- } catch(NotFoundException e) {}
-
- // Create new AAS registration
- client.post(registryUrl, serializedDescriptor2);
-
- // Get a known AAS by its ID
- AASDescriptor result2 = new AASDescriptor((Map<String, Object>) getResult(client.get(aasUrl2)));
-
- assertEquals(endpoint2, result2.getFirstEndpoint()); // need deep json string compare here
-
- // Delete AAS registration
- client.delete(aasUrl2);
-
- // Try to get deleted AAS, has to throw exception
- try {
- getResult(client.get(aasUrl2));
- fail();
- } catch(NotFoundException e) {}
- }
-
- /**
- * Execute test case that test non-working calls
- *
- * @throws UnsupportedEncodingException
- */
- @Test(expected = NotFoundException.class)
- public void testNonWorkingCalls() throws UnsupportedEncodingException {
- // Get unknown AAS ID, has to throw exception
- getResult(client.get(aasUrlUnknown));
- fail();
- }
-
- @SuppressWarnings("unchecked")
- private <T> T getResult(String res) {
- try {
- return (T) handler.deserialize(res);
- } catch (Exception e) {
- e.printStackTrace();
- throw new RuntimeException();
- }
- }
-
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/java/org/eclipse/basyx/regression/registry/TestSQLRegistryProvider.java b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/java/org/eclipse/basyx/regression/registry/TestSQLRegistryProvider.java
deleted file mode 100644
index b1e8613..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/java/org/eclipse/basyx/regression/registry/TestSQLRegistryProvider.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.eclipse.basyx.regression.registry;
-
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
-import org.eclipse.basyx.components.sqlregistry.SQLRegistry;
-import org.eclipse.basyx.testsuite.regression.aas.registration.TestRegistryProviderSuite;
-
-/**
- * Test class for a local registry provider based on SQL tables
- *
- * @author espen
- *
- */
-public class TestSQLRegistryProvider extends TestRegistryProviderSuite {
-
- @Override
- protected IAASRegistryService getRegistryService() {
- return new SQLRegistry("localRegistry.properties");
- }
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/resources/.env b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/resources/.env
deleted file mode 100644
index c6adcc2..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/resources/.env
+++ /dev/null
@@ -1,5 +0,0 @@
-BASYX_HOST_PORT=8082
-BASYX_CONTAINER_PORT=4000
-BASYX_IMAGE_NAME=basys/registry-sql
-BASYX_CONTAINER_NAME=registry
-BASYX_IMAGE_TAG=0.0.1-SNAPSHOT
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/resources/localRegistry.properties b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/resources/localRegistry.properties
deleted file mode 100644
index ffec021..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/resources/localRegistry.properties
+++ /dev/null
@@ -1,43 +0,0 @@
-# ##############################################################
-# Directory configuration file
-# ##############################################################
-
-
-
-
-# ##############################################################
-# Directory server configuration
-
-
-# URL and type of uplink server. Forward all requests that we cannot satisfy here to uplink
-# - URL of uplink directory server
-# - Type of uplink server. Currently supported is BASYS (BaSys registry API) or DNS (DNS server processing legalBody tag)
-cfg.uplink =
-cfg.uplink.type = DNS
-
-
-# Downlink servers, forward matching URI patterns to downlink servers
-# - Match all subunits that end with "is.iese", including "is.iese"
-cfg.downlink.is.pattern = is.iese
-cfg.downlink.is.directory = http://wherever1
-
-# - Match all subunits that end with "pm.iese", including "pm.iese"
-cfg.downlink.pm.pattern = pm.iese
-cfg.downlink.pm.directory = http://wherever2
-
-# - Match all subunits that end with ".es.iese", but not "es.iese"
-cfg.downlink.es.pattern = .es.iese
-cfg.downlink.es.directory = http://wherever3
-
-
-
-
-# ##############################################################
-# SQL database configuration
-
-dbuser = postgres
-dbpass = admin
-dburl = //localhost:5432/basyx-directory?
-
-sqlDriver = org.postgresql.Driver
-sqlPrefix = jdbc:postgresql:
diff --git a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/Dockerfile b/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/Dockerfile
deleted file mode 100644
index 3628774..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/Dockerfile
+++ /dev/null
@@ -1,15 +0,0 @@
-# Add java runtime environment for execution
-FROM java:8-jdk-alpine
-
-# Copy built jar to image using the jar name specified in the pom.xml (JAR_FILE)
-ARG JAR_FILE
-COPY target/${JAR_FILE} /usr/share/basyxExecutable.jar
-COPY target/lib /usr/share/lib
-COPY src/main/resources/context.properties /usr/share/context.properties
-
-# Expose the appropriate port. In case of Tomcat, this is 8080.
-ARG PORT
-EXPOSE ${PORT}
-
-# Start the jar
-CMD java -jar "/usr/share/basyxExecutable.jar" "/usr/share/context.properties"
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/docker-compose.yml b/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/docker-compose.yml
deleted file mode 100644
index aca4d1b..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/docker-compose.yml
+++ /dev/null
@@ -1,31 +0,0 @@
-version: '3'
-services:
-
- registry:
- image: ${BASYX_IMAGE_NAME}:${BASYX_IMAGE_TAG}
- container_name: ${BASYX_CONTAINER_NAME}
- ports:
- - ${BASYX_HOST_PORT}:${BASYX_CONTAINER_PORT}
-# depends_on:
-# - postgres
-# volumes:
-# - .\WebContent\WEB-INF\config\directory\sqldirectory\directory.properties:/basys/directory.properties
-# links:
-# - postgres
-
-# postgres:
-# image: postgres:9.4
-# container_name: postgres
-# environment:
-# - POSTGRES_USER:'postgres'
-# - POSTGRES_PASSWORD:'admin'
-# - POSTGRES_DB=basyx-directory
-# volumes:
-# - ./WebContent/WEB-INF/config/postgres/init.sql:/docker-entrypoint-initdb.d/init.sql
-# ports:
-# - 5433:5432
-# expose:
-# - 5432
-
-
-
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/pom.xml b/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/pom.xml
deleted file mode 100644
index b8ef81c..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/pom.xml
+++ /dev/null
@@ -1,86 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <!--
- Simple Docker Component
-
- Serves as a template for simple docker components that do not depend on other docker containers.
- Do NOT use the included in-memory registry in a productive environment - the entries are not stored permanently
- -->
-
- <parent>
- <groupId>org.eclipse.basyx</groupId>
- <artifactId>basyx.components.docker</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- </parent>
-
- <artifactId>basyx.components.xmlAAS</artifactId>
- <name>BaSyx XML Docker Component</name>
-
- <properties>
- <!--
- basyx.components.executable is the executable class with the definition of the public void main(String[]).
- It is needed when building the jar in the maven-jar-plugin (see basyx.components.docker/pom.xml)
- -->
- <basyx.components.executable>org.eclipse.basyx.components.executable.XMLExecutable</basyx.components.executable>
- </properties>
-
- <packaging>jar</packaging>
-
- <!-- Define additional plugins that are not included by default -->
- <!-- Plugin configuration is done in parent project(s) -->
- <build>
- <plugins>
- <!-- Attach sources to jar file -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-
- <profiles>
- <profile>
- <!--
- "Docker" profile - do not build & install docker images by default
- Run "mvn install -Pdocker" in order to include docker
- -->
- <id>docker</id>
- <build>
- <plugins>
- <!-- Read maven properties from file -->
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>properties-maven-plugin</artifactId>
- </plugin>
-
- <!-- Copy the dependencies necessary to run the jar -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-dependency-plugin</artifactId>
- </plugin>
-
- <!-- Build the docker image -->
- <plugin>
- <groupId>com.spotify</groupId>
- <artifactId>dockerfile-maven-plugin</artifactId>
- </plugin>
-
- <!-- Create integration test environment -->
- <plugin>
- <groupId>com.dkanejs.maven.plugins</groupId>
- <artifactId>docker-compose-maven-plugin</artifactId>
- </plugin>
-
- <!-- Run integration tests -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-failsafe-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
- </profile>
- </profiles>
-</project>
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/java/org/eclipse/basyx/components/XMLAASComponent.java b/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/java/org/eclipse/basyx/components/XMLAASComponent.java
deleted file mode 100644
index fd4006f..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/java/org/eclipse/basyx/components/XMLAASComponent.java
+++ /dev/null
@@ -1,123 +0,0 @@
-package org.eclipse.basyx.components;
-
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
-import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
-import org.eclipse.basyx.components.configuration.BaSyxConfiguration;
-import org.eclipse.basyx.components.servlet.aas.AASBundleServlet;
-import org.eclipse.basyx.components.xml.XMLAASBundleFactory;
-import org.eclipse.basyx.support.bundle.AASBundle;
-import org.eclipse.basyx.support.bundle.AASBundleDescriptorFactory;
-import org.eclipse.basyx.vab.protocol.http.server.AASHTTPServer;
-import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.xml.sax.SAXException;
-
-/**
- * A component that takes an xml file (according to the AAS XML-Schema) and provides the AAS via an HTTP server
- *
- * @author schnicke, espen
- *
- */
-public class XMLAASComponent {
- private static Logger logger = LoggerFactory.getLogger(XMLAASComponent.class);
-
- // The server with the servlet that will be created
- protected AASHTTPServer server;
-
- protected Collection<AASBundle> aasBundles;
-
- protected String hostName;
- protected int port;
- protected String path;
- protected String docBasePath;
- protected String registryUrl;
-
- protected XMLAASComponent(String hostName, int port, String path, String docBasePath) {
- // Sets the server context (still needs to load the bundle)
- this.hostName = hostName;
- this.port = port;
- this.path = path;
- this.docBasePath = docBasePath;
- }
-
- public XMLAASComponent(String hostName, int port, String path, String docBasePath, String xmlPath,
- String registryUrl) throws ParserConfigurationException, SAXException, IOException {
- this(hostName, port, path, docBasePath);
- String xmlContent = BaSyxConfiguration.getResourceString(xmlPath);
- setAASBundle(new XMLAASBundleFactory(xmlContent).create());
- setRegistryUrl(registryUrl);
- }
-
- protected void setAASBundle(Collection<AASBundle> aasBundles) {
- this.aasBundles = aasBundles;
- }
-
- protected void setRegistryUrl(String registryUrl) {
- this.registryUrl = registryUrl;
- }
-
-
- /**
- * Returns the set of AAS descriptors for the AAS contained in the AASX
- *
- * @param hostBasePath
- * the path to the server; helper method for e.g. virtualization
- * environments
- * @return
- */
- public Set<AASDescriptor> retrieveDescriptors(String hostBasePath) {
- return aasBundles.stream().map(b -> AASBundleDescriptorFactory.createAASDescriptor(b, hostBasePath))
- .collect(Collectors.toSet());
- }
-
- /**
- * Returns the set of AAS descriptors for the AAS contained in the AASX
- *
- * @return
- */
- public Set<AASDescriptor> retrieveDescriptors() {
- String hostBasePath = "http://" + hostName + ":" + port + "/" + path;
- return retrieveDescriptors(hostBasePath);
- }
-
- /**
- * Starts the AASX component at http://${hostName}:${port}/${path}
- *
- * @param hostName
- * @param port
- * @param path
- * @param docBasePath
- * @throws IOException
- * @throws SAXException
- * @throws ParserConfigurationException
- */
- public void startComponent() {
- logger.info("Create the server...");
- // Init HTTP context and add an XMLAAServlet according to the configuration
- BaSyxContext context = new BaSyxContext(path, docBasePath, hostName, port);
- // Create the Servlet for aas
- context.addServletMapping("/*", new AASBundleServlet(aasBundles));
- server = new AASHTTPServer(context);
-
-
- logger.info("Start the server...");
- server.start();
-
- if (registryUrl != null && !registryUrl.isEmpty()) {
- logger.info("Registering AAS at registry \"" + registryUrl + "\"...");
- AASRegistryProxy registryProxy = new AASRegistryProxy(registryUrl);
- Set<AASDescriptor> descriptors = retrieveDescriptors();
- descriptors.stream().forEach(registryProxy::register);
- } else {
- logger.info("No registry specified, skipped registration");
- }
- }
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/java/org/eclipse/basyx/components/executable/XMLExecutable.java b/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/java/org/eclipse/basyx/components/executable/XMLExecutable.java
deleted file mode 100644
index b912e66..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/java/org/eclipse/basyx/components/executable/XMLExecutable.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.eclipse.basyx.components.executable;
-
-import java.io.IOException;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.eclipse.basyx.components.XMLAASComponent;
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.xml.sax.SAXException;
-
-/**
- * Starts an HTTP server providing multiple AAS and submodels as described in
- * the XML file specified in the properties file <br />
- * They are made available at <i>localhost:4000/xmlAAS/$aasId/aas</i><br />
- * <br />
- * <b>Please note:</b> Neither the AASs nor the Submodels are added to the
- * registry. Additionally, the Submodel descriptors inside the AAS are missing.
- * <br />
- * There reason for this is, that the executable does not know about the outside
- * context (e.g. docker, ...)!
- *
- * @author haque, schnicke
- */
-public class XMLExecutable {
- // Creates a Logger based on the current class
- private static Logger logger = LoggerFactory.getLogger(XMLExecutable.class);
-
- public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
- logger.info("Starting BaSyx XML component");
-
- // Load configuration
- BaSyxContextConfiguration config = new BaSyxContextConfiguration();
- if (args.length > 0 && args[0] instanceof String) {
- // file path available? => load configs from file
- config.loadFromFile(args[0]);
- } else {
- // fallback: load default configs (in resources)
- config.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
- }
-
- XMLAASComponent component = new XMLAASComponent(config.getHostname(), config.getPort(), config.getContextPath(),
- config.getDocBasePath(), config.getProperty("xmlPath"), config.getProperty("registry"));
- component.startComponent();
- }
-}
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/java/org/eclipse/basyx/components/servlets/XMLAASServlet.java b/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/java/org/eclipse/basyx/components/servlets/XMLAASServlet.java
deleted file mode 100644
index e44ac91..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/java/org/eclipse/basyx/components/servlets/XMLAASServlet.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.eclipse.basyx.components.servlets;
-
-import java.io.IOException;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.eclipse.basyx.components.servlet.aas.AASBundleServlet;
-import org.eclipse.basyx.components.xml.XMLAASBundleFactory;
-import org.xml.sax.SAXException;
-
-/**
- * It imports AAS from given XML location provided in the context.properties and
- * maps the AAS to servlet. It also adds the submodels, assets and concept
- * descriptors to the AAS.
- *
- *
- * @author haque, schnicke
- */
-public class XMLAASServlet extends AASBundleServlet {
- private static final long serialVersionUID = -3487515646027982620L;
-
- public XMLAASServlet(String xmlContent) throws ParserConfigurationException, SAXException, IOException {
- super(new XMLAASBundleFactory(xmlContent).create());
- }
-}
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/resources/context.properties b/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/resources/context.properties
deleted file mode 100644
index f093e52..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/resources/context.properties
+++ /dev/null
@@ -1,4 +0,0 @@
-contextPath=/xmlAAS
-contextHostname=localhost
-contextPort=4000
-xmlPath=xml/aas.xml
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/resources/logback.xml b/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/resources/logback.xml
deleted file mode 100644
index 86341d6..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/resources/logback.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<configuration>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
-
- <!-- Example for a filter, which removes all entries not containing "[TEST]" in the message. -->
-
- <!--<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
- <evaluator>
- <expression>return message.contains("[TEST]");</expression>
- </evaluator>
- <OnMismatch>DENY</OnMismatch>
- <OnMatch>NEUTRAL</OnMatch>
- </filter>-->
-
- <encoder>
- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="INFO">
- <appender-ref ref="STDOUT" />
- </root>
-
-</configuration>
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/resources/xml/aas.xml b/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/resources/xml/aas.xml
deleted file mode 100644
index 04a32c8..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/resources/xml/aas.xml
+++ /dev/null
@@ -1,585 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<aas:aasenv xmlns:aas="http://www.admin-shell.io/aas/2/0"
- xmlns:IEC61360="http://www.admin-shell.io/IEC61360/2/0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.admin-shell.io/aas/2/0 AAS.xsd
- http://www.admin-shell.io/IEC61360/2/0 IEC61360.xsd">
- <aas:assetAdministrationShells>
- <!-- This AAS is populated with all possible fields -->
- <aas:assetAdministrationShell>
- <aas:idShort>aas1</aas:idShort>
- <aas:category>test_category</aas:category>
- <aas:description>
- <aas:langString lang="EN">aas_Description</aas:langString>
- <aas:langString lang="DE">Beschreibung Verwaltungsschale</aas:langString>
- </aas:description>
- <aas:parent>
- <!-- Parent is currently a String in the Schema. But it should be a Reference. -->
- <aas:keys>
- <aas:key idType="IRI" local="false" type="AssetAdministrationShell">aas_parent_id</aas:key>
- </aas:keys>
- </aas:parent>
- <aas:identification idType="IRI">www.admin-shell.io/aas-sample/2/0</aas:identification>
- <aas:administration>
- <aas:version>1</aas:version>
- <aas:revision>0</aas:revision>
- </aas:administration>
- <aas:embeddedDataSpecification>
- <aas:dataSpecificationContent>
- <aas:dataSpecificationIEC61360>
- <IEC61360:preferredName>
- <IEC61360:langString lang="DE">Drehzahl</IEC61360:langString>
- <IEC61360:langString lang="EN">Rotation Speed</IEC61360:langString>
- </IEC61360:preferredName>
- <IEC61360:shortName>
- <IEC61360:langString lang="DE">N</IEC61360:langString>
- </IEC61360:shortName>
- <IEC61360:unit>1/min</IEC61360:unit>
- <IEC61360:unitId>
- <IEC61360:keys>
- <IEC61360:key idType="IRDI" local="false" type="GlobalReference">
- 0173-1#05-AAA650#002
- </IEC61360:key>
- </IEC61360:keys>
- </IEC61360:unitId>
- <IEC61360:valueFormat>NR1..5</IEC61360:valueFormat>
- </aas:dataSpecificationIEC61360>
- </aas:dataSpecificationContent>
- <aas:dataSpecification>
- <aas:keys>
- <aas:key idType="IRI" local="false" type="GlobalReference">www.admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360</aas:key>
- </aas:keys>
- </aas:dataSpecification>
- </aas:embeddedDataSpecification>
- <aas:derivedFrom>
- <aas:keys>
- <aas:key type="ReferenceElement" local="false" idType="IRI">http://pk.festo.com/3s7plfdrs35</aas:key>
- </aas:keys>
- </aas:derivedFrom>
- <aas:assetRef>
- <aas:keys>
- <aas:key type="Asset" local="false" idType="IRI">http://pk.festo.com/3s7plfdrs35</aas:key>
- </aas:keys>
- </aas:assetRef>
- <aas:submodelRefs>
- <aas:submodelRef>
- <aas:keys>
- <aas:key type="Submodel" local="true" idType="IRI">http://www.zvei.de/demo/submodel/12345679</aas:key>
- </aas:keys>
- </aas:submodelRef>
- </aas:submodelRefs>
- <aas:views>
- <!-- This View is populated with all possible fields -->
- <aas:view>
- <aas:idShort>SampleView</aas:idShort>
- <aas:category>test_categogy</aas:category>
- <aas:description>
- <aas:langString lang="EN">View_Description</aas:langString>
- </aas:description>
- <aas:parent>
- <!-- Parent is currently a String in the Schema. But it should be a Reference. -->
- <aas:keys>
- <aas:key idType="IRI" local="false" type="Submodel">view_parent_id</aas:key>
- </aas:keys>
- </aas:parent>
- <aas:semanticId>
- <aas:keys>
- <aas:key idType="IRI" local="false" type="Submodel">view_semantic_id</aas:key>
- </aas:keys>
- </aas:semanticId>
- <aas:embeddedDataSpecification>
- <aas:dataSpecificationContent>
- <aas:dataSpecificationIEC61360>
- <IEC61360:preferredName>
- <IEC61360:langString lang="DE">Drehzahl</IEC61360:langString>
- <IEC61360:langString lang="EN">Rotation Speed</IEC61360:langString>
- </IEC61360:preferredName>
- <IEC61360:shortName>
- <IEC61360:langString lang="DE">N</IEC61360:langString>
- </IEC61360:shortName>
- <IEC61360:unit>1/min</IEC61360:unit>
- <IEC61360:unitId>
- <IEC61360:keys>
- <IEC61360:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</IEC61360:key>
- </IEC61360:keys>
- </IEC61360:unitId>
- <IEC61360:valueFormat>NR1..5</IEC61360:valueFormat>
- </aas:dataSpecificationIEC61360>
- </aas:dataSpecificationContent>
- <aas:dataSpecification>
- <aas:keys>
- <aas:key idType="IRI" local="false" type="GlobalReference">www.admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360</aas:key>
- </aas:keys>
- </aas:dataSpecification>
- </aas:embeddedDataSpecification>
- <aas:containedElements>
- <aas:containedElementRef>
- <aas:keys>
- <aas:key type="Submodel" local="true" idType="IRI">"http://www.zvei.de/demo/submodel/12345679"</aas:key>
- <aas:key type="Property" local="true" idType="IdShort">rotationSpeed</aas:key>
- </aas:keys>
- </aas:containedElementRef>
- </aas:containedElements>
- </aas:view>
- <!-- This is a View with only the minimal required information in it. To test for Nullpointers and such. -->
- <aas:view>
- <aas:idShort>EmptyView</aas:idShort>
- <aas:containedElements></aas:containedElements>
- </aas:view>
- </aas:views>
- <aas:conceptDictionaries>
- <aas:conceptDictionary>
- <aas:idShort>SampleDic</aas:idShort>
- <aas:conceptDescriptionRefs>
- <aas:conceptDescriptionRef>
- <aas:keys>
- <aas:key type="ConceptDescription" local="true" idType="IRI">www.festo.com/dic/08111234</aas:key>
- </aas:keys>
- </aas:conceptDescriptionRef>
- </aas:conceptDescriptionRefs>
- </aas:conceptDictionary>
- </aas:conceptDictionaries>
- </aas:assetAdministrationShell>
- <!-- This is an AAS with only the minimal required information in it. To test for Nullpointers and such. -->
- <aas:assetAdministrationShell>
- <aas:idShort>asset_admin_shell</aas:idShort>
- <aas:identification idType="IRI">www.admin-shell.io/aas-sample/1/1</aas:identification>
- <aas:assetRef>
- <aas:keys>
- <aas:key type="Asset" local="false" idType="IRI">http://pk.festo.com/3s7plfdrs35</aas:key>
- </aas:keys>
- </aas:assetRef>
- </aas:assetAdministrationShell>
- </aas:assetAdministrationShells>
- <aas:assets>
- <!-- This Asset is populated with all possible fields -->
- <aas:asset>
- <aas:idShort>3s7plfdrs35_asset1</aas:idShort>
- <aas:category>asset1_categogy</aas:category>
- <aas:description>
- <aas:langString lang="EN">asset1_Description</aas:langString>
- </aas:description>
- <aas:parent>
- <!-- Parent is currently a String in the Schema. But it should be a Reference. -->
- <aas:keys>
- <aas:key idType="IRI" local="false" type="Asset">asset_parent_id</aas:key>
- </aas:keys>
- </aas:parent>
- <aas:identification idType="IRI">http://pk.festo.com/3s7plfdrs35</aas:identification>
- <aas:administration>
- <aas:version>1</aas:version>
- <aas:revision>0</aas:revision>
- </aas:administration>
- <aas:embeddedDataSpecification>
- <aas:dataSpecificationContent>
- <aas:dataSpecificationIEC61360>
- <IEC61360:preferredName>
- <IEC61360:langString lang="DE">Drehzahl</IEC61360:langString>
- <IEC61360:langString lang="EN">Rotation Speed</IEC61360:langString>
- </IEC61360:preferredName>
- <IEC61360:shortName>
- <IEC61360:langString lang="DE">N</IEC61360:langString>
- </IEC61360:shortName>
- <IEC61360:unit>1/min</IEC61360:unit>
- <IEC61360:unitId>
- <IEC61360:keys>
- <IEC61360:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</IEC61360:key>
- </IEC61360:keys>
- </IEC61360:unitId>
- <IEC61360:valueFormat>NR1..5</IEC61360:valueFormat>
- </aas:dataSpecificationIEC61360>
- </aas:dataSpecificationContent>
- <aas:dataSpecification>
- <aas:keys>
- <aas:key idType="IRI" local="false" type="GlobalReference">www.admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360</aas:key>
- </aas:keys>
- </aas:dataSpecification>
- </aas:embeddedDataSpecification>
- <aas:assetIdentificationModelRef>
- <aas:keys>
- <aas:key type="ConceptDescription" local="true" idType="IRI">www.festo.com/dic/08111234</aas:key>
- </aas:keys>
- </aas:assetIdentificationModelRef>
- <aas:kind>Instance</aas:kind>
- </aas:asset>
- <aas:asset>
- <aas:idShort>emptyAsset</aas:idShort>
- <aas:identification idType="IRI">http://pk.festo.com/q30j38dlajx</aas:identification>
- </aas:asset>
- </aas:assets>
- <aas:submodels>
- <!-- This Submodel is populated with all possible fields -->
- <aas:submodel>
- <aas:idShort>submodel1</aas:idShort>
- <aas:category>submodel1_categogy</aas:category>
- <aas:description>
- <aas:langString lang="EN">submode1_decription</aas:langString>
- </aas:description>
- <aas:parent>
- <!-- Parent is currently a String in the Schema. But it should be a Reference. -->
- <aas:keys>
- <aas:key idType="IRI" local="false" type="Submodel">submodel_parent_id</aas:key>
- </aas:keys>
- </aas:parent>
- <aas:identification idType="IRI">http://www.zvei.de/demo/submodel/12345679</aas:identification>
- <aas:administration>
- <aas:version>1</aas:version>
- <aas:revision>0</aas:revision>
- </aas:administration>
- <aas:kind>Instance</aas:kind>
- <aas:semanticId>
- <aas:keys>
- <aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
- </aas:keys>
- </aas:semanticId>
- <aas:qualifier>
- <aas:qualifiers>
- <aas:formula>
- <aas:dependsOnRefs>
- <aas:reference>
- <aas:keys>
- <aas:key local="false" type="GlobalReference" idType="IRDI">qualifier_reference</aas:key>
- </aas:keys>
- </aas:reference>
- </aas:dependsOnRefs>
- </aas:formula>
- </aas:qualifiers>
- <aas:qualifiers>
- <aas:qualifier>
- <aas:valueId>
- <aas:keys>
- <aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
- </aas:keys>
- </aas:valueId>
- <aas:value>qualifierValue</aas:value>
- <aas:type>qualifierType</aas:type>
- <aas:valueType>valueType</aas:valueType>
- <aas:semanticId>
- <aas:keys>
- <aas:key idType="IRI" local="false" type="GlobalReference">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
- </aas:keys>
- </aas:semanticId>
- </aas:qualifier>
- </aas:qualifiers>
- </aas:qualifier>
- <aas:embeddedDataSpecification>
- <aas:dataSpecificationContent>
- <aas:dataSpecificationIEC61360>
- <IEC61360:preferredName>
- <IEC61360:langString lang="DE">Drehzahl</IEC61360:langString>
- <IEC61360:langString lang="EN">Rotation Speed</IEC61360:langString>
- </IEC61360:preferredName>
- <IEC61360:shortName>
- <IEC61360:langString lang="DE">N</IEC61360:langString>
- </IEC61360:shortName>
- <IEC61360:unit>1/min</IEC61360:unit>
- <IEC61360:unitId>
- <IEC61360:keys>
- <IEC61360:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</IEC61360:key>
- </IEC61360:keys>
- </IEC61360:unitId>
- <IEC61360:valueFormat>NR1..5</IEC61360:valueFormat>
- </aas:dataSpecificationIEC61360>
- </aas:dataSpecificationContent>
- <aas:dataSpecification>
- <aas:keys>
- <aas:key idType="IRI" local="false" type="GlobalReference">www.admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360</aas:key>
- </aas:keys>
- </aas:dataSpecification>
- </aas:embeddedDataSpecification>
- <aas:submodelElements>
- <aas:submodelElement>
- <aas:property>
- <aas:idShort>rotationSpeed</aas:idShort>
- <aas:category>VARIABLE</aas:category>
- <aas:semanticId>
- <aas:keys>
- <aas:key idType="IRI" type="ConceptDescription" local="true">www.festo.com/dic/08111234</aas:key>
- </aas:keys>
- </aas:semanticId>
- <aas:qualifier>
- <aas:qualifiers>
- <aas:qualifier>
- <aas:valueId>
- <aas:keys>
- <aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
- </aas:keys>
- </aas:valueId>
- <aas:value>qualifierValue</aas:value>
- <aas:type>qualifierType</aas:type>
- <aas:valueType>valueType</aas:valueType>
- <aas:semanticId>
- <aas:keys>
- <aas:key idType="IRI" local="false" type="GlobalReference">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
- </aas:keys>
- </aas:semanticId>
- </aas:qualifier>
- </aas:qualifiers>
- </aas:qualifier>
- <aas:embeddedDataSpecification>
- <aas:dataSpecificationContent>
- <aas:dataSpecificationIEC61360>
- <IEC61360:preferredName>
- <IEC61360:langString lang="DE">Drehzahl</IEC61360:langString>
- <IEC61360:langString lang="EN">Rotation Speed</IEC61360:langString>
- </IEC61360:preferredName>
- <IEC61360:shortName>
- <IEC61360:langString lang="DE">N</IEC61360:langString>
- </IEC61360:shortName>
- <IEC61360:unit>1/min</IEC61360:unit>
- <IEC61360:unitId>
- <IEC61360:keys>
- <IEC61360:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</IEC61360:key>
- </IEC61360:keys>
- </IEC61360:unitId>
- <IEC61360:valueFormat>NR1..5</IEC61360:valueFormat>
- </aas:dataSpecificationIEC61360>
- </aas:dataSpecificationContent>
- <aas:dataSpecification>
- <aas:keys>
- <aas:key idType="IRI" local="false" type="GlobalReference">www.admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360</aas:key>
- </aas:keys>
- </aas:dataSpecification>
- </aas:embeddedDataSpecification>
- <aas:value>2000</aas:value>
- <aas:valueType>double</aas:valueType>
- </aas:property>
- </aas:submodelElement>
- <aas:submodelElement>
- <aas:property>
- <aas:idShort>emptyDouble</aas:idShort>
- <aas:valueType>double</aas:valueType>
- </aas:property>
- </aas:submodelElement>
- <aas:submodelElement>
- <aas:basicEvent>
- <aas:idShort>basic_event_id</aas:idShort>
- <aas:observed>
- <aas:keys>
- <aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
- </aas:keys>
- </aas:observed>
- </aas:basicEvent>
- </aas:submodelElement>
- <aas:submodelElement>
- <aas:entity>
- <aas:idShort>entity_id</aas:idShort>
- <aas:assetRef>
- <aas:keys>
- <aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
- </aas:keys>
- </aas:assetRef>
- <aas:entityType>CoManagedEntity</aas:entityType>
- <aas:statements>
- <!-- XML Schema currently supports only one statement, but multiple should be supported -->
- <aas:submodelElement>
- <aas:file>
- <aas:idShort>file_ID</aas:idShort>
- <aas:mimeType>file_mimetype</aas:mimeType>
- <aas:value>file_value</aas:value>
- </aas:file>
- </aas:submodelElement>
- <aas:submodelElement>
- <aas:range>
- <aas:idShort>range_id</aas:idShort>
- <aas:min>10</aas:min>
- <aas:valueType>int</aas:valueType>
- </aas:range>
- </aas:submodelElement>
- </aas:statements>
- </aas:entity>
- </aas:submodelElement>
- <aas:submodelElement>
- <aas:multiLanguageProperty>
- <aas:idShort>multi_language_property_id</aas:idShort>
- <aas:valueId>
- <aas:keys>
- <aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</aas:key>
- </aas:keys>
- </aas:valueId>
- <aas:value>
- <aas:langString lang="DE">Eine Beschreibung auf deutsch</aas:langString>
- <aas:langString lang="EN">A description in english</aas:langString>
- </aas:value>
- </aas:multiLanguageProperty>
- </aas:submodelElement>
- <aas:submodelElement>
- <aas:range>
- <aas:idShort>range_id</aas:idShort>
- <aas:max>10</aas:max>
- <aas:min>1</aas:min>
- <aas:valueType>int</aas:valueType>
- </aas:range>
- </aas:submodelElement>
- <aas:submodelElement>
- <aas:file>
- <aas:idShort>file_id</aas:idShort>
- <aas:mimeType>file_mimetype</aas:mimeType>
- <aas:value>file_value</aas:value>
- </aas:file>
- </aas:submodelElement>
- <aas:submodelElement>
- <aas:blob>
- <aas:idShort>blob_id</aas:idShort>
- <aas:value>YmxvYit2YWx1ZQ==</aas:value>
- <aas:mimeType>blob_mimetype</aas:mimeType>
- </aas:blob>
- </aas:submodelElement>
- <aas:submodelElement>
- <aas:referenceElement>
- <aas:idShort>reference_ELE_ID</aas:idShort>
- <aas:value>
- <aas:keys>
- <aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</aas:key>
- </aas:keys>
- </aas:value>
- </aas:referenceElement>
- </aas:submodelElement>
- <aas:submodelElement>
- <aas:submodelElementCollection>
- <aas:idShort>submodelElementCollection_ID</aas:idShort>
- <aas:allowDuplicates>true</aas:allowDuplicates>
- <aas:ordered>false</aas:ordered>
- <aas:value>
- <aas:submodelElement>
- <aas:file>
- <aas:idShort>file_ID</aas:idShort>
- <aas:mimeType>file_mimetype</aas:mimeType>
- <aas:value>file_value</aas:value>
- </aas:file>
- </aas:submodelElement>
- <aas:submodelElement>
- <aas:blob>
- <aas:idShort>blob_id</aas:idShort>
- <aas:value>YmxvYit2YWx1ZQ==</aas:value>
- <aas:mimeType>blob_mimetype</aas:mimeType>
- </aas:blob>
- </aas:submodelElement>
- </aas:value>
- </aas:submodelElementCollection>
- </aas:submodelElement>
- <aas:submodelElement>
- <aas:relationshipElement>
- <aas:idShort>relationshipElement_ID</aas:idShort>
- <aas:first>
- <aas:keys>
- <aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#001</aas:key>
- </aas:keys>
- </aas:first>
- <aas:second>
- <aas:keys>
- <aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</aas:key>
- </aas:keys>
- </aas:second>
- </aas:relationshipElement>
- </aas:submodelElement>
- <aas:submodelElement>
- <aas:operation>
- <aas:idShort>operation_ID</aas:idShort>
- <aas:inoutputVariable>
- <aas:operationVariable>
- <aas:value>
- <aas:referenceElement>
- <aas:idShort>reference_ELE_ID2</aas:idShort>
- <aas:value>
- <aas:keys>
- <aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#003</aas:key>
- </aas:keys>
- </aas:value>
- </aas:referenceElement>
- </aas:value>
- </aas:operationVariable>
- </aas:inoutputVariable>
- <aas:inputVariable>
- <!-- The schema only allows one opVar in inputVariable, one in outputVariable and one in inoutputVariable. The Metamodel allows 0..* in each -->
- <!-- To be able to have multiple Vars they are surrounded by <aas:operationVariable>. This is also violating the Schema. -->
- <aas:operationVariable>
- <aas:value>
- <aas:file>
- <aas:idShort>file_ID</aas:idShort>
- <aas:mimeType>file_mimetype</aas:mimeType>
- <aas:value>file_value</aas:value>
- </aas:file>
- </aas:value>
- </aas:operationVariable>
- <aas:operationVariable>
- <aas:value>
- <aas:blob>
- <aas:idShort>blob_ID</aas:idShort>
- <aas:value>YmxvYit2YWx1ZQ==</aas:value>
- <aas:mimeType>blob_mimetype</aas:mimeType>
- </aas:blob>
- </aas:value>
- </aas:operationVariable>
- </aas:inputVariable>
- <aas:outputVariable>
- <aas:operationVariable>
- <aas:value>
- <aas:referenceElement>
- <aas:idShort>reference_ELE_ID</aas:idShort>
- <aas:value>
- <aas:keys>
- <aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</aas:key>
- </aas:keys>
- </aas:value>
- </aas:referenceElement>
- </aas:value>
- </aas:operationVariable>
- </aas:outputVariable>
- </aas:operation>
- </aas:submodelElement>
- </aas:submodelElements>
- </aas:submodel>
- </aas:submodels>
- <aas:conceptDescriptions>
- <!-- This ConceptDescription is populated with all possible fields -->
- <aas:conceptDescription>
- <aas:idShort>conceptDescription1</aas:idShort>
- <aas:category>cs_category</aas:category>
- <aas:description>
- <aas:langString lang="EN">conceptDescription_Description</aas:langString>
- </aas:description>
- <aas:parent>
- <!-- Parent is currently a String in the Schema. But it should be a Reference. -->
- <aas:keys>
- <aas:key idType="IRI" local="false" type="ConceptDescription">cs_parent_id</aas:key>
- </aas:keys>
- </aas:parent>
- <aas:identification idType="IRI">www.festo.com/dic/08111234</aas:identification>
- <aas:administration>
- <aas:version>1</aas:version>
- <aas:revision>0</aas:revision>
- </aas:administration>
- <aas:embeddedDataSpecification>
- <aas:dataSpecificationContent>
- <aas:dataSpecificationIEC61360>
- <IEC61360:preferredName>
- <IEC61360:langString lang="DE">Drehzahl</IEC61360:langString>
- <IEC61360:langString lang="EN">Rotation Speed</IEC61360:langString>
- </IEC61360:preferredName>
- <IEC61360:shortName>
- <IEC61360:langString lang="DE">N</IEC61360:langString>
- </IEC61360:shortName>
- <IEC61360:unit>1/min</IEC61360:unit>
- <IEC61360:unitId>
- <IEC61360:keys>
- <IEC61360:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</IEC61360:key>
- </IEC61360:keys>
- </IEC61360:unitId>
- <IEC61360:valueFormat>NR1..5</IEC61360:valueFormat>
- </aas:dataSpecificationIEC61360>
- </aas:dataSpecificationContent>
- <aas:dataSpecification>
- <aas:keys>
- <aas:key idType="IRI" local="false" type="GlobalReference">www.admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360</aas:key>
- </aas:keys>
- </aas:dataSpecification>
- </aas:embeddedDataSpecification>
- <aas:isCaseOf>
- <aas:keys>
- <aas:key idType="IRI" type="ConceptDescription" local="true">www.festo.com/dic/08111234</aas:key>
- <aas:key idType="IRI" type="ConceptDescription" local="true">www.festo.com/dic/08111234_2</aas:key>
- </aas:keys>
- </aas:isCaseOf>
- </aas:conceptDescription>
- </aas:conceptDescriptions>
-</aas:aasenv>
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/test/java/org/eclipse/basyx/regression/xmlAAS/ITInXMLAAS.java b/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/test/java/org/eclipse/basyx/regression/xmlAAS/ITInXMLAAS.java
deleted file mode 100644
index 3e15324..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/test/java/org/eclipse/basyx/regression/xmlAAS/ITInXMLAAS.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package org.eclipse.basyx.regression.xmlAAS;
-
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.eclipse.basyx.components.configuration.BaSyxDockerConfiguration;
-import org.junit.BeforeClass;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ITInXMLAAS extends XMLAASSuite {
- private static Logger logger = LoggerFactory.getLogger(ITInXMLAAS.class);
-
- @BeforeClass
- public static void setUpClass() {
- logger.info("Running integration test...");
-
- logger.info("Loading servlet configuration");
- // Load the servlet configuration inside of the docker configuration from properties file
- BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
- contextConfig.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
-
- // Load the docker environment configuration from properties file
- logger.info("Loading docker configuration");
- BaSyxDockerConfiguration dockerConfig = new BaSyxDockerConfiguration();
- dockerConfig.loadFromResource(BaSyxDockerConfiguration.DEFAULT_CONFIG_PATH);
-
- aasEndpoint = "http://localhost:" + dockerConfig.getHostPort() + contextConfig.getContextPath() + "/" + aasShortId + "/aas";
- smEndpoint = "http://localhost:" + dockerConfig.getHostPort() + contextConfig.getContextPath() + "/" + aasShortId + "/aas/submodels/" + smShortId + "/submodel";
-
- logger.info("AAS URL for integration test: " + aasEndpoint);
- }
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/test/java/org/eclipse/basyx/regression/xmlAAS/TestXMLAAS.java b/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/test/java/org/eclipse/basyx/regression/xmlAAS/TestXMLAAS.java
deleted file mode 100644
index 7fd042d..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/test/java/org/eclipse/basyx/regression/xmlAAS/TestXMLAAS.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package org.eclipse.basyx.regression.xmlAAS;
-
-import java.io.IOException;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.eclipse.basyx.components.executable.XMLExecutable;
-import org.junit.BeforeClass;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.xml.sax.SAXException;
-
-public class TestXMLAAS extends XMLAASSuite {
- private static Logger logger = LoggerFactory.getLogger(TestXMLAAS.class);
-
- @BeforeClass
- public static void setUpClass() throws ParserConfigurationException, SAXException, IOException {
- XMLExecutable.main(new String[] {});
-
- BaSyxContextConfiguration config = new BaSyxContextConfiguration();
- config.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
-
- aasEndpoint = "http://" + config.getHostname() + ":" + config.getPort() + "/" + config.getContextPath() + "/" + aasShortId + "/aas";
- smEndpoint = "http://" + config.getHostname() + ":" + config.getPort() + "/" + config.getContextPath() + "/" + aasShortId + "/aas/submodels/" + smShortId + "/submodel";
- logger.info("AAS URL for servlet test: " + aasEndpoint);
- }
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/test/java/org/eclipse/basyx/regression/xmlAAS/XMLAASSuite.java b/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/test/java/org/eclipse/basyx/regression/xmlAAS/XMLAASSuite.java
deleted file mode 100644
index 19105ff..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/test/java/org/eclipse/basyx/regression/xmlAAS/XMLAASSuite.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package org.eclipse.basyx.regression.xmlAAS;
-
-import static org.junit.Assert.assertEquals;
-
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.metamodel.connected.ConnectedAssetAdministrationShell;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
-import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.vab.protocol.api.IConnectorProvider;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Suite for testing that the XMLAAS servlet is set up correctly. The tests here
- * can be used by the servlet test itself and the integration test
- *
- * @author schnicke
- *
- */
-public class XMLAASSuite {
-
- protected IAASRegistryService registry;
-
- protected static final String aasShortId = "aas1";
- protected static final IIdentifier aasId = new ModelUrn("www.admin-shell.io/aas-sample/2/0");
- protected static final IIdentifier smId = new ModelUrn("http://www.zvei.de/demo/submodel/12345679");
- protected static final String smShortId = "submodel1";
-
- // Has to be individualized by each test inheriting from this suite
- protected static String aasEndpoint;
- protected static String smEndpoint;
-
- private ConnectedAssetAdministrationShellManager manager;
-
- /**
- * Before each test, a dummy registry is created and an AAS is added in the
- * registry
- */
- @Before
- public void setUp() {
- // Create a dummy registry to test integration of XML AAS
- registry = new InMemoryRegistry();
- AASDescriptor descriptor = new AASDescriptor(aasShortId, aasId, aasEndpoint);
- descriptor.addSubmodelDescriptor(new SubmodelDescriptor(smShortId, smId, smEndpoint));
- registry.register(descriptor);
-
- // Create a ConnectedAssetAdministrationShell using a
- // ConnectedAssetAdministrationShellManager
- IConnectorProvider connectorProvider = new HTTPConnectorProvider();
- manager = new ConnectedAssetAdministrationShellManager(registry, connectorProvider);
- }
-
- @Test
- public void testGetSingleAAS() throws Exception {
- ConnectedAssetAdministrationShell connectedAssetAdministrationShell = getConnectedAssetAdministrationShell();
- assertEquals(aasShortId, connectedAssetAdministrationShell.getIdShort());
- }
-
- @Test
- public void testGetSingleSubmodel() throws Exception {
- ISubModel subModel = getConnectedSubmodel();
- assertEquals(smShortId, subModel.getIdShort());
- }
-
- /**
- * Gets the connected Asset Administration Shell
- *
- * @return connected AAS
- * @throws Exception
- */
- private ConnectedAssetAdministrationShell getConnectedAssetAdministrationShell() throws Exception {
- return manager.retrieveAAS(aasId);
- }
-
- /**
- * Gets the connected Submodel
- *
- * @return connected SM
- * @throws Exception
- */
- private ISubModel getConnectedSubmodel() {
- return manager.retrieveSubModel(aasId, smId);
- }
-
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/test/resources/.env b/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/test/resources/.env
deleted file mode 100644
index 226a4c9..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/test/resources/.env
+++ /dev/null
@@ -1,5 +0,0 @@
-BASYX_HOST_PORT=8083
-BASYX_CONTAINER_PORT=4000
-BASYX_IMAGE_NAME=basys/aas-xml
-BASYX_CONTAINER_NAME=aas-xml
-BASYX_IMAGE_TAG=0.0.1-SNAPSHOT
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/pom.xml b/components/basys.components/basyx.components.docker/pom.xml
index 332d4c8..6afe083 100644
--- a/components/basys.components/basyx.components.docker/pom.xml
+++ b/components/basys.components/basyx.components.docker/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.eclipse.basyx</groupId>
<artifactId>basyx.components</artifactId>
- <version>0.0.1-SNAPSHOT</version>
+ <version>1.0.0</version>
</parent>
<artifactId>basyx.components.docker</artifactId>
@@ -15,10 +15,7 @@
<!-- Includes all components in this project as separated modules -->
<modules>
- <module>basyx.components.simple</module>
- <module>basyx.components.sqlregistry</module>
- <module>basyx.components.xmlAAS</module>
- <module>basyx.components.AASX</module>
+ <module>basyx.components.registry</module>
<module>basyx.components.AASServer</module>
</modules>
@@ -106,10 +103,17 @@
</executions>
<configuration>
<repository>${BASYX_IMAGE_NAME}</repository>
- <tag>${project.version}</tag>
+ <tag>${BASYX_IMAGE_TAG}</tag>
<buildArgs>
<JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
<PORT>${BASYX_CONTAINER_PORT}</PORT>
+ <!-- The system property/env keys for basyx configuration files -->
+ <CONTEXT_CONFIG_KEY>BASYX_CONTEXT</CONTEXT_CONFIG_KEY>
+ <REGISTRY_CONFIG_KEY>BASYX_REGISTRY</REGISTRY_CONFIG_KEY>
+ <AAS_CONFIG_KEY>BASYX_AAS</AAS_CONFIG_KEY>
+ <MONGODB_CONFIG_KEY>BASYX_MONGODB</MONGODB_CONFIG_KEY>
+ <DOCKER_CONFIG_KEY>BASYX_DOCKER</DOCKER_CONFIG_KEY>
+ <SQL_CONFIG_KEY>BASYX_SQL</SQL_CONFIG_KEY>
</buildArgs>
</configuration>
</plugin>
@@ -174,7 +178,7 @@
<dependency>
<groupId>org.eclipse.basyx</groupId>
<artifactId>basyx.components.lib</artifactId>
- <version>${project.version}</version>
+ <version>1.0.0</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.lib/pom.xml b/components/basys.components/basyx.components.lib/pom.xml
index f34dbff..1cf5fe2 100644
--- a/components/basys.components/basyx.components.lib/pom.xml
+++ b/components/basys.components/basyx.components.lib/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.eclipse.basyx</groupId>
<artifactId>basyx.components</artifactId>
- <version>0.0.1-SNAPSHOT</version>
+ <version>1.0.0</version>
</parent>
<artifactId>basyx.components.lib</artifactId>
@@ -13,18 +13,6 @@
<packaging>jar</packaging>
- <repositories>
- <repository>
- <id>mule</id>
- <name>Mule Repository</name>
- <url>https://repository.mulesoft.org/nexus/content/groups/public/</url>
- <layout>default</layout>
- <snapshots>
- <enabled>false</enabled>
- </snapshots>
- </repository>
- </repositories>
-
<!-- Define additional plugins that are not included by default -->
<build>
<plugins>
@@ -43,107 +31,8 @@
<artifactId>postgresql</artifactId>
<version>42.2.2</version>
</dependency>
-
- <dependency>
- <groupId>javax.enterprise</groupId>
- <artifactId>cdi-api</artifactId>
- <version>2.0</version>
- <scope>provided</scope>
- </dependency>
<dependency>
- <groupId>javax.el</groupId>
- <artifactId>el-api</artifactId>
- <version>2.2</version>
- </dependency>
-
- <dependency>
- <groupId>javax.inject</groupId>
- <artifactId>javax.inject</artifactId>
- <version>1</version>
- </dependency>
-
- <dependency>
- <groupId>javax.json</groupId>
- <artifactId>javax.json-api</artifactId>
- <version>1.0</version>
- </dependency>
-
- <dependency>
- <groupId>javax.xml.bind</groupId>
- <artifactId>jaxb-api</artifactId>
- <version>2.3.0</version>
- </dependency>
-
- <dependency>
- <groupId>javax.annotation</groupId>
- <artifactId>javax.annotation-api</artifactId>
- <version>1.3.2</version>
- </dependency>
-
- <dependency>
- <groupId>javax.persistence</groupId>
- <artifactId>persistence-api</artifactId>
- <version>1.0.2</version>
- </dependency>
-
- <dependency>
- <groupId>javax.validation</groupId>
- <artifactId>validation-api</artifactId>
- <version>2.0.1.Final</version>
- </dependency>
-
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>javax.servlet-api</artifactId>
- <version>3.1.0</version>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>javassist</groupId>
- <artifactId>javassist</artifactId>
- <version>3.12.1.GA</version>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.spec.javax.interceptor</groupId>
- <artifactId>jboss-interceptors-api_1.1_spec</artifactId>
- <version>1.0.1.Final</version>
- </dependency>
-
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- <version>4.2.0</version>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.glassfish.hk2</groupId>
- <artifactId>hk2-api</artifactId>
- <version>2.5.0</version>
- </dependency>
-
- <dependency>
- <groupId>org.glassfish.hk2</groupId>
- <artifactId>osgi-resource-locator</artifactId>
- <version>1.0.1</version>
- </dependency>
-
- <dependency>
- <groupId>org.glassfish.hk2.external</groupId>
- <artifactId>aopalliance-repackaged</artifactId>
- <version>2.5.0-b42</version>
- </dependency>
-
- <dependency>
- <groupId>org.eclipse</groupId>
- <artifactId>yasson</artifactId>
- <version>1.0.2</version>
- </dependency>
-
- <dependency>
<groupId>org.camunda.bpm</groupId>
<artifactId>camunda-engine</artifactId>
<version>7.12.0</version>
@@ -167,33 +56,6 @@
<version>1.4.197</version>
</dependency>
- <!-- Add from local repository because jar cannot be found on maven central -->
- <dependency>
- <groupId>javax.xml.xquery</groupId>
- <artifactId>xqj-api</artifactId>
- <version>1.0</version>
- </dependency>
-
-
- <!-- Add from external repository because jar cannot be found on maven central -->
- <dependency>
- <groupId>net.sf.saxon</groupId>
- <artifactId>saxon-xqj</artifactId>
- <version>8.9.0.4</version>
- </dependency>
-
- <dependency>
- <groupId>net.sf.saxon</groupId>
- <artifactId>Saxon-HE</artifactId>
- <version>9.5.1-5</version>
- </dependency>
-
- <dependency>
- <groupId>com.google.code.gson</groupId>
- <artifactId>gson</artifactId>
- <version>2.8.5</version>
- </dependency>
-
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/IComponent.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/IComponent.java
new file mode 100644
index 0000000..82f6a08
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/IComponent.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components;
+
+/**
+ * Common interfaces for all components allowing starting/stopping the component
+ *
+ * @author schnicke
+ *
+ */
+public interface IComponent {
+
+ /**
+ * Starts the component
+ */
+ public void startComponent();
+
+ /**
+ * Shuts down the component
+ */
+ public void stopComponent();
+}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/cfgprovider/CFGSubModelProvider.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/cfgprovider/CFGSubModelProvider.java
deleted file mode 100644
index fceb07d..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/cfgprovider/CFGSubModelProvider.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package org.eclipse.basyx.components.cfgprovider;
-
-import java.util.Map;
-
-import org.eclipse.basyx.components.provider.BaseConfiguredProvider;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-
-/**
- * Asset administration shell sub model provider that exports a properties file
- *
- * @author kuhn
- *
- */
-public class CFGSubModelProvider extends BaseConfiguredProvider {
-
- /**
- * Initiates a logger using the current class
- */
- private static final Logger logger = LoggerFactory.getLogger(CFGSubModelProvider.class);
-
- /**
- * Constructor
- */
- public CFGSubModelProvider(Map<Object, Object> cfgValues) {
- // Call base constructor
- super(cfgValues);
-
- // Add properties
- for (String key: getConfiguredProperties(cfgValues)) {
- // Create properties
- SubmodelElement elem = createSubmodelElement(key, cfgValues.get(key), cfgValues);
- createValue("submodel/" + SubmodelElementProvider.ELEMENTS, elem);
-
- // Debug output
- logger.debug("Adding configured property: "+key.toString()+" = "+cfgValues.get(key));
- }
- }
-}
-
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/cfgprovider/RawCFGSubModelProvider.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/cfgprovider/RawCFGSubModelProvider.java
deleted file mode 100644
index 405f33e..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/cfgprovider/RawCFGSubModelProvider.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package org.eclipse.basyx.components.cfgprovider;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.basyx.components.provider.BaseConfiguredProvider;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Asset administration shell sub model provider that exports a properties file
- *
- * @author kuhn
- *
- */
-public class RawCFGSubModelProvider extends BaseConfiguredProvider {
-
- /**
- * Initiates a logger using the current class
- */
- private static final Logger logger = LoggerFactory.getLogger(RawCFGSubModelProvider.class);
-
- private static final String FTYPE = "$ftype";
-
- /**
- * Constructor
- */
- @SuppressWarnings("unchecked")
- public RawCFGSubModelProvider(Map<Object, Object> cfgValues) {
- // Call base constructor -> creates base submodelData from cfgValues
- super(cfgValues);
-
- // Load properties
- for (Object key : cfgValues.keySet()) {
- // Do not put meta data keys into map
- if (((String) key).endsWith(FTYPE))
- continue;
-
- // Get path to element
- String[] path = splitPath((String) key);
-
- // Create path
- Map<String, Object> scope = new HashMap<>();
- scope = submodelData;
- for (int i = 0; i < path.length - 1; i++) {
- if (!scope.containsKey(path[i]))
- scope.put(path[i], new HashMap<String, Object>());
- scope = (Map<String, Object>) scope.get(path[i]);
- }
-
- // Get and optionally convert value
- Object value = cfgValues.get(key);
- // - Cast value if requested by user
- if (cfgValues.get(key + FTYPE) != null)
- switch ((String) cfgValues.get(key + FTYPE)) {
- case "int":
- value = Integer.parseInt((String) value);
- break;
- case "boolean":
- value = Boolean.parseBoolean((String) value);
- break;
- case "float":
- value = Float.parseFloat((String) value);
- break;
-
- default:
- logger.error("Unknown type:" + cfgValues.get(key + FTYPE));
- }
-
- logger.debug("Putting:" + key + " = " + cfgValues.get(key) + " as " + value.getClass().getName());
-
- scope.put(path[path.length - 1], value);
- }
-
- // Push data to provider
- setSubmodel(submodelData);
-
- // Print configuration values
- logger.debug("CFG exported");
- }
-}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxConfiguration.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxConfiguration.java
index 6ad9aba..08ae715 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxConfiguration.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxConfiguration.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.configuration;
import java.io.FileInputStream;
@@ -5,8 +14,10 @@
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
+import java.util.List;
import java.util.Map;
import java.util.Properties;
+import java.util.stream.Collectors;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
@@ -53,6 +64,29 @@
}
/**
+ * Load the configuration from a path relative to the current folder
+ *
+ * @param filePath Path to the resource in the application folder
+ */
+ public void loadFileOrDefaultResource(String fileKey, String defaultResource) {
+ // Try to load property that points to the configuration file (e.g. java -DfileKey=yx.properties [...])
+ String configFilePath = System.getProperty(fileKey);
+ if ( configFilePath == null || configFilePath.isEmpty() ) {
+ // Try to load environment variable that points to the configuration file
+ configFilePath = System.getenv(fileKey);
+ }
+
+ // Load context configuration
+ if (configFilePath != null && !configFilePath.isEmpty()) {
+ // file path available? => load configs from file
+ loadFromFile(configFilePath);
+ } else {
+ // fallback: load default configs (by resource)
+ loadFromResource(defaultResource);
+ }
+ }
+
+ /**
* Load the configuration from an input stream
*
* @param input the input stream containing the properties
@@ -105,6 +139,26 @@
}
/**
+ * Method for subclasses to read specific environment variables
+ *
+ * @param prefix The prefix of each of the environment variables
+ * @param properties The name of the properties in the config and environment (with prefix)
+ */
+ protected void loadFromEnvironmentVariables(String prefix, String... properties) {
+ try {
+ for (String propName : properties) {
+ String result = System.getenv(prefix + propName);
+ if (result != null) {
+ logger.info("Environment - " + propName + ": " + result);
+ setProperty(propName, result);
+ }
+ }
+ } catch (SecurityException e) {
+ logger.info("Reading configs from environment is not permitted");
+ }
+ }
+
+ /**
* Sets a property, if it is contained in this configuration
*
* @param name The name of the property
@@ -115,6 +169,16 @@
}
/**
+ * Returns all contained properties that begin with a specific prefix
+ *
+ * @param prefix The filtered prefix (e.g. "aas.")
+ * @return The list of all contained properties that begin with the prefix
+ */
+ public List<String> getProperties(String prefix) {
+ return values.keySet().stream().filter(key -> key.startsWith(prefix)).collect(Collectors.toList());
+ }
+
+ /**
* Queries a property
*/
public String getProperty(String name) {
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxContextConfiguration.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxContextConfiguration.java
index e9381a7..129667d 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxContextConfiguration.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxContextConfiguration.java
@@ -1,10 +1,19 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.configuration;
import java.util.HashMap;
import java.util.Map;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
/**
* Represents a BaSyx http servlet configuration for a BaSyxContext,
@@ -14,58 +23,134 @@
*
*/
public class BaSyxContextConfiguration extends BaSyxConfiguration {
-
- /**
- * Initiates a logger using the current class
- */
- private static final Logger logger = LoggerFactory.getLogger(BaSyxContextConfiguration.class);
-
+ // Prefix for environment variables
+ public static final String ENV_PREFIX = "BaSyxContext_";
+
// Default BaSyx Context configuration
- public static final String DEFAULT_CONTEXTPATH = "/basys.sdk";
+ public static final String DEFAULT_CONTEXTPATH = "basys.sdk";
public static final String DEFAULT_DOCBASE = System.getProperty("java.io.tmpdir");
public static final String DEFAULT_HOSTNAME = "localhost";
public static final int DEFAULT_PORT = 4000;
- private static final String CONTEXTPATH = "contextPath";
- private static final String DOCBASE = "contextDocPath";
- private static final String HOSTNAME = "contextHostname";
- private static final String PORT = "contextPort";
+ public static final String CONTEXTPATH = "contextPath";
+ public static final String DOCBASE = "contextDocPath";
+ public static final String HOSTNAME = "contextHostname";
+ public static final String PORT = "contextPort";
// The default path for the context properties file
public static final String DEFAULT_CONFIG_PATH = "context.properties";
+ // The default key for variables pointing to the configuration file
+ public static final String DEFAULT_FILE_KEY = "BASYX_CONTEXT";
+
public static Map<String, String> getDefaultProperties() {
Map<String, String> defaultProps = new HashMap<>();
defaultProps.put(CONTEXTPATH, DEFAULT_CONTEXTPATH);
- logger.debug("DEFAULT " + DOCBASE + " - " + DEFAULT_DOCBASE);
defaultProps.put(DOCBASE, DEFAULT_DOCBASE);
defaultProps.put(HOSTNAME, DEFAULT_HOSTNAME);
defaultProps.put(PORT, Integer.toString(DEFAULT_PORT));
return defaultProps;
}
+ /**
+ * Empty Constructor - use default values
+ */
public BaSyxContextConfiguration() {
super(getDefaultProperties());
}
+ /**
+ * Constructor with predefined value map
+ */
public BaSyxContextConfiguration(Map<String, String> values) {
super(values);
}
+ /**
+ * Constructor with initial configuration - docBasePath and hostname are default values
+ *
+ * @param port The port that will be occupied
+ * @param contextPath The subpath for this context
+ */
+ public BaSyxContextConfiguration(int port, String contextPath) {
+ this();
+ setPort(port);
+ setContextPath(contextPath);
+ }
+
+ /**
+ * Constructor with initial configuration - docBasePath and hostname are default values
+ *
+ * @param contextPath The subpath for this context
+ * @param docBasePath The local base path for the documents
+ * @param hostname The hostname
+ * @param port The port that will be occupied
+ */
+ public BaSyxContextConfiguration(String contextPath, String docBasePath, String hostname, int port) {
+ this();
+ setContextPath(contextPath);
+ setDocBasePath(docBasePath);
+ setHostname(hostname);
+ setPort(port);
+ }
+
+ public void loadFromEnvironmentVariables() {
+ String[] properties = { CONTEXTPATH, DOCBASE, HOSTNAME, PORT };
+ loadFromEnvironmentVariables(ENV_PREFIX, properties);
+ }
+
+ public void loadFromDefaultSource() {
+ loadFileOrDefaultResource(DEFAULT_FILE_KEY, DEFAULT_CONFIG_PATH);
+ loadFromEnvironmentVariables();
+ }
+
+ public BaSyxContext createBaSyxContext() {
+ String reqContextPath = getContextPath();
+ String reqDocBasePath = getDocBasePath();
+ String hostName = getHostname();
+ int reqPort = getPort();
+ return new BaSyxContext(reqContextPath, reqDocBasePath, hostName, reqPort);
+ }
+
public String getContextPath() {
return getProperty(CONTEXTPATH);
}
+ public void setContextPath(String contextPath) {
+ setProperty(CONTEXTPATH, VABPathTools.stripSlashes(contextPath));
+ }
+
public String getDocBasePath() {
- logger.debug("DEFAULT " + DOCBASE + " -- " + getProperty(DOCBASE));
return getProperty(DOCBASE);
}
+ public void setDocBasePath(String docBasePath) {
+ setProperty(DOCBASE, docBasePath);
+ }
+
public String getHostname() {
return getProperty(HOSTNAME);
}
+ public void setHostname(String hostname) {
+ setProperty(HOSTNAME, hostname);
+ }
+
public int getPort() {
return Integer.parseInt(getProperty(PORT));
}
+
+ public void setPort(int port) {
+ setProperty(PORT, Integer.toString(port));
+ }
+
+ public String getUrl() {
+ String contextPath = getContextPath();
+ String base = "http://" + getHostname() + ":" + getPort();
+ if (contextPath.isEmpty()) {
+ return base;
+ } else {
+ return VABPathTools.concatenatePaths(base, contextPath);
+ }
+ }
}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxDockerConfiguration.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxDockerConfiguration.java
index 72c4cca..8370580 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxDockerConfiguration.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxDockerConfiguration.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.configuration;
import java.util.HashMap;
@@ -10,20 +19,26 @@
*
*/
public class BaSyxDockerConfiguration extends BaSyxConfiguration {
- // Default BaSyx Context configuration
- private static final int DEFAULT_HOSTPORT = 8082;
- private static final int DEFAULT_CONTAINERPORT = 4000;
- private static final String DEFAULT_IMAGENAME = "basys/component";
- private static final String DEFAULT_CONTAINERNAME = "component";
+ // Prefix for environment variables
+ public static final String ENV_PREFIX = "BaSyxDocker_";
- private static final String HOSTPORT = "BASYX_HOST_PORT";
- private static final String CONTAINERPORT = "BASYX_CONTAINER_PORT";
- private static final String IMAGENAME = "BASYX_IMAGE_NAME";
- private static final String CONTAINERNAME = "BASYX_CONTAINER_NAME";
+ // Default BaSyx Context configuration
+ public static final int DEFAULT_HOSTPORT = 8082;
+ public static final int DEFAULT_CONTAINERPORT = 4000;
+ public static final String DEFAULT_IMAGENAME = "basys/component";
+ public static final String DEFAULT_CONTAINERNAME = "component";
+
+ public static final String HOSTPORT = "BASYX_HOST_PORT";
+ public static final String CONTAINERPORT = "BASYX_CONTAINER_PORT";
+ public static final String IMAGENAME = "BASYX_IMAGE_NAME";
+ public static final String CONTAINERNAME = "BASYX_CONTAINER_NAME";
// The default path for the context properties file
public static final String DEFAULT_CONFIG_PATH = ".env";
+ // The default key for variables pointing to the configuration file
+ public static final String DEFAULT_FILE_KEY = "BASYX_DOCKER";
+
public static Map<String, String> getDefaultProperties() {
Map<String, String> defaultProps = new HashMap<>();
defaultProps.put(HOSTPORT, Integer.toString(DEFAULT_HOSTPORT));
@@ -34,27 +49,75 @@
return defaultProps;
}
+ /**
+ * Empty Constructor - use default values
+ */
public BaSyxDockerConfiguration() {
super(getDefaultProperties());
}
+ /**
+ * Constructor with predefined value map
+ */
public BaSyxDockerConfiguration(Map<String, String> values) {
super(values);
}
+ /**
+ * Constructor with initial configuration
+ *
+ * @param hostPort The port for the HOST
+ * @param containerPort The port for the CONTAINER
+ * @param imageName The name of the image
+ * @param containerName The name of the container
+ */
+ public BaSyxDockerConfiguration(int hostPort, int containerPort, String imageName, String containerName) {
+ this();
+ setHostPort(hostPort);
+ setContainerPort(containerPort);
+ setImageName(imageName);
+ setContainerName(containerName);
+ }
+
+ public void loadFromEnvironmentVariables() {
+ String[] properties = { HOSTPORT, CONTAINERPORT, IMAGENAME, CONTAINERNAME };
+ loadFromEnvironmentVariables(ENV_PREFIX, properties);
+ }
+
+ public void loadFromDefaultSource() {
+ loadFileOrDefaultResource(DEFAULT_FILE_KEY, DEFAULT_CONFIG_PATH);
+ loadFromEnvironmentVariables();
+ }
+
public int getHostPort() {
return Integer.parseInt(getProperty(HOSTPORT));
}
+ public void setHostPort(int hostPort) {
+ setProperty(HOSTPORT, Integer.toString(hostPort));
+ }
+
public int getContainerPort() {
return Integer.parseInt(getProperty(CONTAINERPORT));
}
+ public void setContainerPort(int containerPort) {
+ setProperty(CONTAINERPORT, Integer.toString(containerPort));
+ }
+
public String getImageName() {
return getProperty(IMAGENAME);
}
+ public void setImageName(String imageName) {
+ setProperty(IMAGENAME, imageName);
+ }
+
public String getContainerName() {
return getProperty(CONTAINERNAME);
}
+
+ public void setContainerName(String containerName) {
+ setProperty(CONTAINERNAME, containerName);
+ }
}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxMongoDBConfiguration.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxMongoDBConfiguration.java
new file mode 100644
index 0000000..a0e0136
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxMongoDBConfiguration.java
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.configuration;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Represents a BaSyx configuration for a MongoDB connection.
+ *
+ * @author espen
+ *
+ */
+public class BaSyxMongoDBConfiguration extends BaSyxConfiguration {
+ // Prefix for environment variables
+ public static final String ENV_PREFIX = "BaSyxMongoDB_";
+
+ // Default BaSyx SQL configuration
+ public static final String DEFAULT_CONNECTIONURL = "mongodb://127.0.0.1:27017/";
+ public static final String DEFAULT_DATABASE = "admin";
+ public static final String DEFAULT_REGISTRY_COLLECTION = "basyxregistry";
+ public static final String DEFAULT_AAS_COLLECTION = "basyxaas";
+ public static final String DEFAULT_SUBMODEL_COLLECTION = "basyxsubmodel";
+
+ public static final String DATABASE = "dbname";
+ public static final String CONNECTIONURL = "dbconnectionstring";
+ public static final String REGISTRY_COLLECTION = "dbcollectionRegistry";
+ public static final String AAS_COLLECTION = "dbcollectionAAS";
+ public static final String SUBMODEL_COLLECTION = "dbcollectionSubmodels";
+
+ // The default path for the context properties file
+ public static final String DEFAULT_CONFIG_PATH = "mongodb.properties";
+
+ // The default key for variables pointing to the configuration file
+ public static final String DEFAULT_FILE_KEY = "BASYX_MONGODB";
+
+ public static Map<String, String> getDefaultProperties() {
+ Map<String, String> defaultProps = new HashMap<>();
+ defaultProps.put(CONNECTIONURL, DEFAULT_CONNECTIONURL);
+ defaultProps.put(DATABASE, DEFAULT_DATABASE);
+ defaultProps.put(REGISTRY_COLLECTION, DEFAULT_REGISTRY_COLLECTION);
+ defaultProps.put(AAS_COLLECTION, DEFAULT_AAS_COLLECTION);
+ defaultProps.put(SUBMODEL_COLLECTION, DEFAULT_SUBMODEL_COLLECTION);
+
+ return defaultProps;
+ }
+
+ /**
+ * Constructor with predefined value map
+ */
+ public BaSyxMongoDBConfiguration(Map<String, String> values) {
+ super(values);
+ }
+
+ /**
+ * Empty Constructor - use default values
+ */
+ public BaSyxMongoDBConfiguration() {
+ super(getDefaultProperties());
+ }
+
+ /**
+ * Constructor with initial configuration
+ *
+ * @param connectionUrl Connection-URL for the mongodb
+ * @param database The database that shall be used
+ * @param registryCollection Collection name for the registry data
+ * @param aasCollection Collection name for the AAS data
+ * @param submodelCollection Collection name for the submodel data
+ */
+ public BaSyxMongoDBConfiguration(String connectionUrl, String database, String registryCollection,
+ String aasCollection, String submodelCollection) {
+ this();
+ setConnectionUrl(connectionUrl);
+ setDatabase(database);
+ setRegistryCollection(registryCollection);
+ setAASCollection(aasCollection);
+ setSubmodelCollection(submodelCollection);
+ }
+
+ /**
+ * Constructor with initial configuration (without registry collection)
+ *
+ * @param connectionUrl Connection-URL for the mongodb
+ * @param database The database that shall be used
+ * @param aasCollection Collection name for the AAS data
+ * @param submodelCollection Collection name for the submodel data
+ */
+ public BaSyxMongoDBConfiguration(String connectionUrl, String database, String aasCollection,
+ String submodelCollection) {
+ this();
+ setConnectionUrl(connectionUrl);
+ setDatabase(database);
+ setAASCollection(aasCollection);
+ setSubmodelCollection(submodelCollection);
+ }
+
+ /**
+ * Constructor with initial configuration (without aas collection)
+ *
+ * @param connectionUrl Connection-URL for the mongodb
+ * @param database The database that shall be used
+ * @param aasCollection Collection name for the AAS data
+ * @param submodelCollection Collection name for the submodel data
+ */
+ public BaSyxMongoDBConfiguration(String connectionUrl, String database, String registryCollection) {
+ this();
+ setConnectionUrl(connectionUrl);
+ setDatabase(database);
+ setRegistryCollection(registryCollection);
+ }
+
+ public void loadFromEnvironmentVariables() {
+ String[] properties = { DATABASE, CONNECTIONURL, REGISTRY_COLLECTION, AAS_COLLECTION, SUBMODEL_COLLECTION };
+ loadFromEnvironmentVariables(ENV_PREFIX, properties);
+ }
+
+ public void loadFromDefaultSource() {
+ loadFileOrDefaultResource(DEFAULT_FILE_KEY, DEFAULT_CONFIG_PATH);
+ loadFromEnvironmentVariables();
+ }
+
+ public String getDatabase() {
+ return getProperty(DATABASE);
+ }
+
+ public void setDatabase(String database) {
+ setProperty(DATABASE, database);
+ }
+
+ public String getConnectionUrl() {
+ return getProperty(CONNECTIONURL);
+ }
+
+ public void setConnectionUrl(String connectionUrl) {
+ setProperty(CONNECTIONURL, connectionUrl);
+ }
+
+ public String getRegistryCollection() {
+ return getProperty(REGISTRY_COLLECTION);
+ }
+
+ public void setRegistryCollection(String registryCollection) {
+ setProperty(REGISTRY_COLLECTION, registryCollection);
+ }
+
+ public String getAASCollection() {
+ return getProperty(AAS_COLLECTION);
+ }
+
+ public void setAASCollection(String aasCollection) {
+ setProperty(AAS_COLLECTION, aasCollection);
+ }
+
+ public String getSubmodelCollection() {
+ return getProperty(SUBMODEL_COLLECTION);
+ }
+
+ public void setSubmodelCollection(String submodelCollection) {
+ setProperty(SUBMODEL_COLLECTION, submodelCollection);
+ }
+}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxMqttConfiguration.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxMqttConfiguration.java
new file mode 100644
index 0000000..08b7277
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxMqttConfiguration.java
@@ -0,0 +1,168 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.configuration;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+
+/**
+ * Represents a BaSyx mqtt configuration for an mqtt connection.
+ *
+ * @author espen
+ *
+ */
+public class BaSyxMqttConfiguration extends BaSyxConfiguration {
+ // Prefix for environment variables
+ public static final String ENV_PREFIX = "BaSyxMQTT_";
+
+ // Default BaSyx MQTT configuration
+ public static final String DEFAULT_USER = "";
+ public static final String DEFAULT_PASS = "";
+ public static final String DEFAULT_SERVER = "http://localhost:1883/";
+ public static final String DEFAULT_QOS = "1";
+
+ public static final String USER = "user";
+ public static final String PASS = "pass";
+ public static final String SERVER = "server";
+ public static final String QOS = "qos";
+ public static final String WHITELIST_PREFIX = "whitelist.";
+ public static final String WHITELIST_ELEMENT_PREFIX = "whitelist.element.";
+
+ // The default path for the context properties file
+ public static final String DEFAULT_CONFIG_PATH = "mqtt.properties";
+
+ // The default key for variables pointing to the configuration file
+ public static final String DEFAULT_FILE_KEY = "BASYX_MQTT";
+
+ public static Map<String, String> getDefaultProperties() {
+ Map<String, String> defaultProps = new HashMap<>();
+ defaultProps.put(USER, DEFAULT_USER);
+ defaultProps.put(PASS, DEFAULT_PASS);
+ defaultProps.put(SERVER, DEFAULT_SERVER);
+ defaultProps.put(QOS, DEFAULT_QOS);
+
+ return defaultProps;
+ }
+
+ /**
+ * Constructor with predefined value map
+ */
+ public BaSyxMqttConfiguration(Map<String, String> values) {
+ super(values);
+ }
+
+ /**
+ * Empty Constructor - use default values
+ */
+ public BaSyxMqttConfiguration() {
+ super(getDefaultProperties());
+ }
+
+ /**
+ * Constructor with initial configuration
+ *
+ * @param user Username for MQTT connection
+ * @param pass Password for MQTT connection
+ * @param server MQTT broker address
+ * @param qos MQTT quality of service level
+ */
+ public BaSyxMqttConfiguration(String user, String pass, String server, int qos) {
+ this();
+ setUser(user);
+ setPass(pass);
+ setServer(server);
+ setQoS(qos);
+ }
+
+ /**
+ * Load all settings except of the whitelist config part
+ */
+ public void loadFromEnvironmentVariables() {
+ String[] properties = { USER, PASS, SERVER, QOS };
+ loadFromEnvironmentVariables(ENV_PREFIX, properties);
+ }
+
+ public void loadFromDefaultSource() {
+ loadFileOrDefaultResource(DEFAULT_FILE_KEY, DEFAULT_CONFIG_PATH);
+ loadFromEnvironmentVariables();
+ }
+
+ public String getUser() {
+ return getProperty(USER);
+ }
+
+ public void setUser(String user) {
+ setProperty(USER, user);
+ }
+
+ public String getPass() {
+ return getProperty(PASS);
+ }
+
+ public void setPass(String pass) {
+ setProperty(PASS, pass);
+ }
+
+ public String getServer() {
+ return getProperty(SERVER);
+ }
+
+ public void setServer(String server) {
+ setProperty(SERVER, server);
+ }
+
+ public int getQoS() {
+ return Integer.parseInt(getProperty(QOS));
+ }
+
+ public void setQoS(int qos) {
+ setProperty(QOS, Integer.toString(qos));
+ }
+
+ public boolean isWhitelistEnabled(String submodelId) {
+ return "true".equals(getProperty(WHITELIST_PREFIX + submodelId));
+ }
+
+ public void setWhitelistEnabled(String submodelId, boolean enabled) {
+ String propertyName = WHITELIST_PREFIX + submodelId;
+ if (enabled) {
+ setProperty(propertyName, "true");
+ } else {
+ setProperty(propertyName, "false");
+ }
+ }
+
+ public Set<String> getWhitelist(String submodelId) {
+ Set<String> whitelist = new HashSet<>();
+ String fullPrefix = WHITELIST_ELEMENT_PREFIX + submodelId;
+ List<String> properties = getProperties(fullPrefix);
+
+ for ( String prop : properties ) {
+ if ( getProperty(prop).equals("true") ) {
+ // Removes submodel prefix (+ one separator) => whitelist.elements.smid.
+ String elementId = prop.substring(fullPrefix.length() + 1);
+ whitelist.add(elementId);
+ }
+ }
+ return whitelist;
+ }
+
+ public void setWhitelist(String submodelId, List<String> elementIds) {
+ String smPrefix = WHITELIST_ELEMENT_PREFIX + submodelId;
+ for (String elemId : elementIds) {
+ String propName = smPrefix + "." + elemId;
+ setProperty(propName, "true");
+ }
+ }
+}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxSQLConfiguration.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxSQLConfiguration.java
index 1b31a36..9702570 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxSQLConfiguration.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxSQLConfiguration.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.configuration;
import java.util.HashMap;
@@ -10,58 +19,118 @@
*
*/
public class BaSyxSQLConfiguration extends BaSyxConfiguration {
- // Default BaSyx SQL configuration
- private static final String DEFAULT_USER = "postgres";
- private static final String DEFAULT_PASS = "admin";
- private static final String DEFAULT_PATH = "//localhost/basyx-directory?";
- private static final String DEFAULT_DRV = "org.postgresql.Driver";
- private static final String DEFAULT_PREFIX = "jdbc:postgresql:";
+ // Prefix for environment variables
+ public static final String ENV_PREFIX = "BaSyxSQL_";
- private static final String USER = "dbuser";
- private static final String PASS = "dbpass";
- private static final String PATH = "dburl";
- private static final String DRV = "sqlDriver";
- private static final String PREFIX = "sqlPrefix";
+ // Default BaSyx SQL configuration
+ public static final String DEFAULT_USER = "postgres";
+ public static final String DEFAULT_PASS = "admin";
+ public static final String DEFAULT_PATH = "//localhost/basyx-directory?";
+ public static final String DEFAULT_DRV = "org.postgresql.Driver";
+ public static final String DEFAULT_PREFIX = "jdbc:postgresql:";
+
+ public static final String USER = "dbuser";
+ public static final String PASS = "dbpass";
+ public static final String PATH = "dburl";
+ public static final String DRIVER = "sqlDriver";
+ public static final String PREFIX = "sqlPrefix";
// The default path for the context properties file
public static final String DEFAULT_CONFIG_PATH = "sql.properties";
+ // The default key for variables pointing to the configuration file
+ public static final String DEFAULT_FILE_KEY = "BASYX_SQL";
+
public static Map<String, String> getDefaultProperties() {
Map<String, String> defaultProps = new HashMap<>();
defaultProps.put(USER, DEFAULT_USER);
defaultProps.put(PASS, DEFAULT_PASS);
defaultProps.put(PATH, DEFAULT_PATH);
- defaultProps.put(DRV, DEFAULT_DRV);
+ defaultProps.put(DRIVER, DEFAULT_DRV);
defaultProps.put(PREFIX, DEFAULT_PREFIX);
return defaultProps;
}
+ /**
+ * Constructor with predefined value map
+ */
public BaSyxSQLConfiguration(Map<String, String> values) {
super(values);
}
+ /**
+ * Empty Constructor - use default values
+ */
public BaSyxSQLConfiguration() {
super(getDefaultProperties());
}
+ /**
+ * Constructor with initial configuration
+ *
+ * @param user Username for SQL database
+ * @param pass Password for SQL database
+ * @param path SQL connection path
+ * @param driver SQL driver
+ * @param prefix SQL driver prefix
+ */
+ public BaSyxSQLConfiguration(String user, String pass, String path, String driver, String prefix) {
+ this();
+ setUser(user);
+ setPass(pass);
+ setPath(path);
+ setDriver(driver);
+ setPrefix(prefix);
+ }
+
+ public void loadFromEnvironmentVariables() {
+ String[] properties = { USER, PASS, PATH, DRIVER, PREFIX };
+ loadFromEnvironmentVariables(ENV_PREFIX, properties);
+ }
+
+ public void loadFromDefaultSource() {
+ loadFileOrDefaultResource(DEFAULT_FILE_KEY, DEFAULT_CONFIG_PATH);
+ loadFromEnvironmentVariables();
+ }
+
public String getUser() {
return getProperty(USER);
}
+ public void setUser(String user) {
+ setProperty(USER, user);
+ }
+
public String getPass() {
return getProperty(PASS);
}
+ public void setPass(String pass) {
+ setProperty(PASS, pass);
+ }
+
public String getPath() {
return getProperty(PATH);
}
- public String getDrv() {
- return getProperty(DRV);
+ public void setPath(String path) {
+ setProperty(PATH, path);
+ }
+
+ public String getDriver() {
+ return getProperty(DRIVER);
+ }
+
+ public void setDriver(String driver) {
+ setProperty(DRIVER, driver);
}
public String getPrefix() {
return getProperty(PREFIX);
}
+
+ public void setPrefix(String prefix) {
+ setProperty(PREFIX, prefix);
+ }
}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/CFGBaSyxConnection.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/CFGBaSyxConnection.java
index 1cb7301..1c46007 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/CFGBaSyxConnection.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/CFGBaSyxConnection.java
@@ -1,7 +1,16 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.configuration;
-import org.eclipse.basyx.vab.directory.api.IVABDirectoryService;
-import org.eclipse.basyx.vab.protocol.api.IConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
+import org.eclipse.basyx.vab.registry.api.IVABRegistryService;
@@ -69,7 +78,7 @@
/**
* Create protocol provider
*/
- public IConnectorProvider createConnectorProvider() {
+ public IConnectorFactory createConnectorProvider() {
// Create connector provider instance
return protocol.createInstance();
}
@@ -78,14 +87,14 @@
/**
* Instantiate the directory class
*/
- public IVABDirectoryService createDirectoryInstance() {
+ public IVABRegistryService createDirectoryInstance() {
// Try to create instance
try {
// Get Java class by name
Class<?> clazz = Class.forName(directoryProviderName);
// Instantiate class
- IVABDirectoryService directoryService = (IVABDirectoryService) clazz.newInstance();
+ IVABRegistryService directoryService = (IVABRegistryService) clazz.newInstance();
// Return directory service instance
return directoryService;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/CFGBaSyxProtocolType.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/CFGBaSyxProtocolType.java
index c3b5fda..6e6b414 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/CFGBaSyxProtocolType.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/CFGBaSyxProtocolType.java
@@ -1,8 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.configuration;
-import org.eclipse.basyx.vab.protocol.api.IConnectorProvider;
-import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnectorProvider;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
+import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnectorFactory;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
@@ -44,10 +53,10 @@
/**
* Create protocol instance
*/
- public IConnectorProvider createInstance() {
+ public IConnectorFactory createInstance() {
// Create protocol instance
- if (this.equals(HTTP)) return new HTTPConnectorProvider();
- if (this.equals(BASYX)) return new BaSyxConnectorProvider();
+ if (this.equals(HTTP)) return new HTTPConnectorFactory();
+ if (this.equals(BASYX)) return new BaSyxConnectorFactory();
// Unknown protocol
return null;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/ConfigurableComponent.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/ConfigurableComponent.java
index 856404d..4afde6f 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/ConfigurableComponent.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/ConfigurableComponent.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.configuration;
import org.eclipse.basyx.components.configuration.builder.BaSyxConfigurationBuilder;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/ConfigurableProperty.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/ConfigurableProperty.java
index d21d8e3..17979f8 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/ConfigurableProperty.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/ConfigurableProperty.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.configuration;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/builder/BaSyxConfigurationBuilder.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/builder/BaSyxConfigurationBuilder.java
index 3438b88..60e35fa 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/builder/BaSyxConfigurationBuilder.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/builder/BaSyxConfigurationBuilder.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.configuration.builder;
import org.eclipse.basyx.components.configuration.ConfigurableComponent;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/builder/BaSyxDeviceManagerConfigurationBuilder.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/builder/BaSyxDeviceManagerConfigurationBuilder.java
index 0f878ab..7e643f4 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/builder/BaSyxDeviceManagerConfigurationBuilder.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/builder/BaSyxDeviceManagerConfigurationBuilder.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.configuration.builder;
import org.eclipse.basyx.components.configuration.ConfigurableComponent;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/builder/BaSyxServiceConfigurationBuilder.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/builder/BaSyxServiceConfigurationBuilder.java
index aad6f59..96e438f 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/builder/BaSyxServiceConfigurationBuilder.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/builder/BaSyxServiceConfigurationBuilder.java
@@ -1,13 +1,22 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.configuration.builder;
import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
import org.eclipse.basyx.components.configuration.CFGBaSyxProtocolType;
import org.eclipse.basyx.components.configuration.ConfigurableComponent;
-import org.eclipse.basyx.vab.directory.api.IVABDirectoryService;
import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
+import org.eclipse.basyx.vab.registry.api.IVABRegistryService;
/**
* Configuration builder for BaSyx services
@@ -29,7 +38,7 @@
*/
protected CFGBaSyxProtocolType protocoltype = null;
- protected IVABDirectoryService vabDirectory = null;
+ protected IVABRegistryService vabDirectory = null;
/**
@@ -58,7 +67,7 @@
/**
* Create registry instance based on configuration
*/
- public IAASRegistryService getRegistry() {
+ public IAASRegistry getRegistry() {
// Create and return registry
return new AASRegistryProxy(registryURL);
}
@@ -81,7 +90,7 @@
* Set VAB Directory
*/
@SuppressWarnings("unchecked")
- public T directoryService(IVABDirectoryService vabDirectory) {
+ public T directoryService(IVABRegistryService vabDirectory) {
// Store VAB directory
this.vabDirectory = vabDirectory;
@@ -94,7 +103,7 @@
*/
public VABConnectionManager getConnectionManager() {
// Create and return VABConnectionManager
- return new VABConnectionManager(vabDirectory, new HTTPConnectorProvider());
+ return new VABConnectionManager(vabDirectory, new HTTPConnectorFactory());
}
/**
@@ -102,7 +111,7 @@
*/
public ConnectedAssetAdministrationShellManager getConnetedAASManager() {
// Create and return connected AAS-manager
- return new ConnectedAssetAdministrationShellManager(getRegistry(), new HTTPConnectorProvider());
+ return new ConnectedAssetAdministrationShellManager(getRegistry(), new HTTPConnectorFactory());
}
}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/exception/InsufficientConfigurationDataException.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/exception/InsufficientConfigurationDataException.java
index 49dbaec..22e73e4 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/exception/InsufficientConfigurationDataException.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/exception/InsufficientConfigurationDataException.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.configuration.exception;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseDevice.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseDevice.java
index a975fa6..9927759 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseDevice.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseDevice.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.device;
import org.eclipse.basyx.components.service.BaseBaSyxService;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseSmartDevice.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseSmartDevice.java
index 475e0b1..aa06d5f 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseSmartDevice.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseSmartDevice.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.device;
import org.eclipse.basyx.models.controlcomponent.ControlComponent;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseTCPControllableDeviceAdapter.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseTCPControllableDeviceAdapter.java
index 37fee53..4ab2335 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseTCPControllableDeviceAdapter.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseTCPControllableDeviceAdapter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.device;
import org.eclipse.basyx.components.netcomm.NetworkReceiver;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseTCPDeviceAdapter.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseTCPDeviceAdapter.java
index 354f885..3055c75 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseTCPDeviceAdapter.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseTCPDeviceAdapter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.device;
import org.eclipse.basyx.components.netcomm.TCPClient;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/IBaSysNativeDeviceStatus.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/IBaSysNativeDeviceStatus.java
index a5a8f1b..3734c51 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/IBaSysNativeDeviceStatus.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/IBaSysNativeDeviceStatus.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.device;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/devicemanager/DeviceManagerComponent.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/devicemanager/DeviceManagerComponent.java
index 4695058..040e0b1 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/devicemanager/DeviceManagerComponent.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/devicemanager/DeviceManagerComponent.java
@@ -1,5 +1,15 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.devicemanager;
+import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
@@ -77,7 +87,7 @@
* Returns the actual endpoint of the AAS managed by this component
*/
protected String getAASEndpoint(ModelUrn aasURN) {
- return VABPathTools.concatenatePaths(getAASServerURL(), "/aas", aasURN.getEncodedURN());
+ return VABPathTools.concatenatePaths(getAASServerURL(), AASAggregatorProvider.PREFIX, aasURN.getEncodedURN(), "/aas");
}
/**
@@ -88,9 +98,9 @@
*
* @return Sub model descriptor endpoint points to default AAS server location and contains default prefix path
*/
- protected SubmodelDescriptor addSubModelDescriptorURI(AASDescriptor aasDescriptor, ModelUrn subModelURN, String subModelId) {
+ protected SubmodelDescriptor addSubmodelDescriptorURI(AASDescriptor aasDescriptor, ModelUrn subModelURN, String subModelId) {
// Create sub model descriptor
- String submodelEndpoint = VABPathTools.concatenatePaths(getAASServerURL(), "/aas/submodels", subModelId);
+ String submodelEndpoint = VABPathTools.concatenatePaths(getAASServerURL(), AASAggregatorProvider.PREFIX, VABPathTools.encodePathElement(aasDescriptor.getIdentifier().getId()), "/aas/submodels", subModelId);
SubmodelDescriptor submodelDescriptor = new SubmodelDescriptor(subModelId, subModelURN, submodelEndpoint);
// Add sub model descriptor to AAS descriptor
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/devicemanager/TCPControllableDeviceManagerComponent.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/devicemanager/TCPControllableDeviceManagerComponent.java
index 9fc63d5..aa2cc3c 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/devicemanager/TCPControllableDeviceManagerComponent.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/devicemanager/TCPControllableDeviceManagerComponent.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.devicemanager;
import org.eclipse.basyx.components.netcomm.NetworkReceiver;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/devicemanager/TCPDeviceManagerComponent.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/devicemanager/TCPDeviceManagerComponent.java
index 8aa6fd8..3faa021 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/devicemanager/TCPDeviceManagerComponent.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/devicemanager/TCPDeviceManagerComponent.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.devicemanager;
import org.eclipse.basyx.components.netcomm.NetworkReceiver;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/AASDirectoryEntry.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/AASDirectoryEntry.java
deleted file mode 100644
index 84589ef..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/AASDirectoryEntry.java
+++ /dev/null
@@ -1,375 +0,0 @@
-package org.eclipse.basyx.components.directory;
-
-import java.util.Collection;
-import java.util.HashSet;
-
-import org.eclipse.basyx.components.directory.exception.AASDirectoryFormatException;
-
-
-
-/**
- * Asset Administration Shell or sub model directory entry
- *
- * IDs usually are formed as URIs: urn:<legalBody>:<SubUnit>:<Submodel>:<version>:<revision>:<elementID>#<instance>
- *
- * @author kuhn
- *
- */
-public class AASDirectoryEntry {
-
-
- /**
- * Indicate undefined AAS content type
- */
- public static final int AAS_CONTENTTYPE_UNDEFINED = -1;
-
-
- /**
- * Indicate local AAS content type. The serialized AAS is stored in the content property of this class.
- */
- public static final int AAS_CONTENTTYPE_LOCAL = 1;
-
-
- /**
- * Indicate remote AAS content type. The content property of this class contains a URL that points to the directory service.
- */
- public static final int AAS_CONTENTTYPE_REMOTE = 2;
-
-
- /**
- * Indicate proxy AAS content type. The content property of this class contains an ID (specified as URI) that points to the
- * AAS entry that all requests should be forwarded to.
- */
- public static final int AAS_CONTENTTYPE_PROXY = 3;
-
-
-
-
-
- /**
- * Store the AAS ID
- */
- protected String id = null;
-
-
- /**
- * Store the AAS content
- */
- protected String content = null;
-
-
- /**
- * Store the AAS content type (local, remote, or proxy)
- *
- * Local AAS content means that the AAS is serialized in the content property. Remote indicates
- * that the content property contains a URL that points to the AAS. Proxy indicates that the
- * content contains another AAS ID, to which requests will be forwarded.
- */
- protected int contentType = -1;
-
-
- /**
- * Store the tags for this AAS
- */
- protected HashSet<String> tags = new HashSet<>();
-
-
-
-
-
- /**
- * Constructor
- */
- public AASDirectoryEntry(String aasId, String aasContent, String aasContentType, String aasTags) {
- // Store AAS parameter
- id = aasId;
- content = aasContent;
-
-
- // Try to process AAS content type
- try {
- // Store AAS content type
- switch(aasContentType.toLowerCase()) {
- case "local": contentType = AAS_CONTENTTYPE_LOCAL; break;
- case "remote": contentType = AAS_CONTENTTYPE_REMOTE; break;
- case "proxy": contentType = AAS_CONTENTTYPE_PROXY; break;
-
- default: throw new AASDirectoryFormatException("Unknown content type: "+aasContentType);
- }
- } catch (NullPointerException e) {
- // Assume local AAS for undefined AAS types
- contentType = AAS_CONTENTTYPE_LOCAL;
- }
-
-
- // Try to Store AAS tags
- try {
- String[] splitTags = aasTags.split(",");
- // - Only add non-empty tags
- for (String tag: splitTags) if (tag.trim().length() > 0) tags.add(tag.trim());
- } catch (NullPointerException e) {
- // Accept AAS without tags
- }
- }
-
-
- /**
- * Check if ID is a valid URI. A valid URI starts with "urn:" prefix and defines at least a legal body.
- */
- public boolean isValidID() {
- return (id.startsWith("urn"));
- }
-
-
- /**
- * Check if ID contains a legal entity
- */
- public boolean hasLegalEntity() {
- // Split ID by ':' token
- String[] idParts = id.split(":");
-
- // Check if subunit is defined
- if (idParts.length < 2) return false;
-
- // Check if any information is contained in subunit field
- return (idParts[1].trim().length() > 0);
- }
-
-
- /**
- * Return the legal entity of this AAS
- */
- public String getLegalEntity() {
- // Split ID by ':' token
- String[] idParts = id.split(":");
-
- // Return legal Entity part
- return idParts[1];
- }
-
-
- /**
- * Check if AAS legal entity is of type (ends with given suffix, e.g. ".fraunhofer.de")
- */
- public boolean isLegalEntityOf(String suffix) {
- return getLegalEntity().endsWith(suffix);
- }
-
-
- /**
- * Check if ID contains a subunit
- */
- public boolean hasSubUnit() {
- // Split ID by ':' token
- String[] idParts = id.split(":");
-
- // Check if subunit is defined
- if (idParts.length < 3) return false;
-
- // Check if any information is contained in subunit field
- return (idParts[2].trim().length() > 0);
- }
-
-
- /**
- * Get the subunit of the ID field
- */
- public String getSubUnit() {
- // Split ID by ':' token
- String[] idParts = id.split(":");
-
- // Check if subunit is defined
- if (idParts.length < 3) return null;
-
- // Check if any information is contained in subunit field
- return idParts[2].trim();
- }
-
-
- /**
- * Check if ID contains a sub model
- */
- public boolean hasSubModel() {
- // Split ID by ':' token
- String[] idParts = id.split(":");
-
- // Check if subunit is defined
- if (idParts.length < 4) return false;
-
- // Check if any information is contained in subunit field
- return (idParts[3].trim().length() > 0);
- }
-
-
- /**
- * Get the sub model of the ID field
- */
- public String getSubModel() {
- // Split ID by ':' token
- String[] idParts = id.split(":");
-
- // Check if subunit is defined
- if (idParts.length < 4) return null;
-
- // Check if any information is contained in subunit field
- return idParts[3].trim();
- }
-
-
- /**
- * Check if ID contains a version
- */
- public boolean hasVersion() {
- // Split ID by ':' token
- String[] idParts = id.split(":");
-
- // Check if subunit is defined
- if (idParts.length < 5) return false;
-
- // Check if any information is contained in subunit field
- return (idParts[4].trim().length() > 0);
- }
-
-
- /**
- * Get AAS version
- */
- public String getVersion() {
- // Split ID by ':' token
- String[] idParts = id.split(":");
-
- // Check if subunit is defined
- if (idParts.length < 5) return null;
-
- // Check if any information is contained in subunit field
- return idParts[4].trim();
- }
-
-
- /**
- * Check if ID contains a revision
- */
- public boolean hasRevision() {
- // Split ID by ':' token
- String[] idParts = id.split(":");
-
- // Check if subunit is defined
- if (idParts.length < 6) return false;
-
- // Check if any information is contained in subunit field
- return (idParts[5].trim().length() > 0);
- }
-
-
- /**
- * Get AAS revision
- */
- public String getRevision() {
- // Split ID by ':' token
- String[] idParts = id.split(":");
-
- // Check if subunit is defined
- if (idParts.length < 6) return null;
-
- // Check if any information is contained in subunit field
- return idParts[5].trim();
- }
-
-
- /**
- * Check if ID contains an element ID
- */
- public boolean hasElementID() {
- // Split ID by ':' token
- String[] idParts = id.split(":");
-
- // Check if subunit is defined
- if (idParts.length < 7) return false;
-
- // Remove element instance if an instance is defined
- if (idParts[6].indexOf('#') > -1) idParts[6]=idParts[6].substring(0, idParts[6].indexOf('#'));
- // Check if any information is contained in subunit field
- return (idParts[6].trim().length() > 0);
- }
-
-
- /**
- * Get element ID
- */
- public String getElementID() {
- // Split ID by ':' token
- String[] idParts = id.split(":");
-
- // Check if subunit is defined
- if (idParts.length < 7) return null;
-
- // Remove element instance if an instance is defined
- if (idParts[6].indexOf('#') > -1) idParts[6]=idParts[6].substring(0, idParts[6].indexOf('#'));
- // Check if any information is contained in subunit field
- return idParts[6].trim();
- }
-
-
- /**
- * Check if ID contains an instance
- */
- public boolean hasElementInstance() {
- // Split ID by ':' token
- String[] idParts = id.split(":");
-
- // Check if subunit is defined
- if (idParts.length < 7) return false;
-
- // Remove element instance if an instance is defined
- if (idParts[6].indexOf('#') > -1) idParts[6]=idParts[6].substring(idParts[6].indexOf('#'));
- // Check if any information is contained in subunit field
- return (idParts[6].trim().length() > 0);
- }
-
-
- /**
- * Get instance ID
- */
- public String getElementInstance() {
- // Catch all exceptions
- try {
- // Split ID by ':' token
- String[] idParts = id.split(":");
-
- // Check if subunit is defined
- if (idParts.length < 7) return null;
-
- // Remove element instance if an instance is defined
- if (idParts[6].indexOf('#') > -1) idParts[6]=idParts[6].substring(idParts[6].indexOf('#')+1);
-
- // Check if any information is contained in subunit field
- return idParts[6].trim();
- } catch (Exception e) {
- return null;
- }
- }
-
-
- /**
- * Get AAS content
- */
- public String getAASContent() {
- return content;
- }
-
-
- /**
- * Get AAS content type
- */
- public int getAASContentType() {
- return contentType;
- }
-
-
- /**
- * Get AAS tags
- */
- public Collection<String> getAASTags() {
- return tags;
- }
-}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/exception/AASDirectoryFormatException.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/exception/AASDirectoryFormatException.java
deleted file mode 100644
index 79aacf2..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/exception/AASDirectoryFormatException.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.eclipse.basyx.components.directory.exception;
-
-
-
-
-/**
- * Indicate a problem with the AAS directory format
- *
- * @author kuhn
- *
- */
-public class AASDirectoryFormatException extends RuntimeException {
-
-
- /**
- * Version number support for serialized instances
- */
- private static final long serialVersionUID = 1L;
-
-
- /**
- * Error message
- */
- protected String errorMessage = null;
-
-
-
-
- /**
- * Constructor
- */
- public AASDirectoryFormatException(String errorMsg) {
- errorMessage = errorMsg;
- }
-}
-
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/exception/AASDirectoryProviderException.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/exception/AASDirectoryProviderException.java
deleted file mode 100644
index 30edf58..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/exception/AASDirectoryProviderException.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.eclipse.basyx.components.directory.exception;
-
-
-
-
-/**
- * Indicate a problem with the AAS directory provider
- *
- * @author kuhn
- *
- */
-public class AASDirectoryProviderException extends RuntimeException {
-
-
- /**
- * Version number support for serialized instances
- */
- private static final long serialVersionUID = 1L;
-
-
- /**
- * Error message
- */
- protected String errorMessage = null;
-
-
-
-
- /**
- * Constructor
- */
- public AASDirectoryProviderException(String errorMsg) {
- errorMessage = errorMsg;
- }
-}
-
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/json/JSONAASBundleFactory.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/json/JSONAASBundleFactory.java
new file mode 100644
index 0000000..bd9ae1d
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/json/JSONAASBundleFactory.java
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.json;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+import org.eclipse.basyx.aas.factory.json.JSONToMetamodelConverter;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.IIdentifiable;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.support.bundle.AASBundle;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Creates multiple {@link AASBundle} from a JSON containing several AAS and
+ * Submodels <br />
+ * TODO: ConceptDescriptions
+ *
+ * @author espen
+ *
+ */
+public class JSONAASBundleFactory {
+ private static Logger logger = LoggerFactory.getLogger(JSONAASBundleFactory.class);
+
+ private String content;
+
+ /**
+ *
+ * @param jsonContent
+ * the content of the JSON
+ */
+ public JSONAASBundleFactory(String jsonContent) {
+ this.content = jsonContent;
+ }
+
+ public JSONAASBundleFactory(Path jsonFile) throws IOException {
+ content = new String(Files.readAllBytes(jsonFile));
+ }
+
+ /**
+ * Creates the set of {@link AASBundle} contained in the JSON string.
+ *
+ * @return
+ */
+ public Set<AASBundle> create() {
+ JSONToMetamodelConverter converter = new JSONToMetamodelConverter(content);
+
+ List<AssetAdministrationShell> shells = converter.parseAAS();
+ List<Submodel> submodels = converter.parseSubmodels();
+
+ List<Asset> assets = converter.parseAssets();
+
+ Set<AASBundle> bundles = new HashSet<>();
+
+ for (AssetAdministrationShell shell : shells) {
+ // Retrieve asset
+ try {
+ IReference assetRef = shell.getAssetReference();
+ Asset asset = getByReference(assetRef, assets);
+ shell.setAsset(asset);
+ } catch (ResourceNotFoundException e) {
+ logger.warn("Can't find asset with id " + shell.getAssetReference().getKeys().get(0).getValue() + " for AAS " + shell.getIdShort() + "; If the asset is not provided in another way, this is an error!");
+ }
+
+ // Retrieve submodels
+ Set<ISubmodel> currentSM = retrieveSubmodelsForAAS(submodels, shell);
+ bundles.add(new AASBundle(shell, currentSM));
+ }
+
+ return bundles;
+ }
+
+ /**
+ * Retrieves the Submodels belonging to an AAS
+ *
+ * @param submodels
+ * @param shell
+ * @return
+ */
+ private Set<ISubmodel> retrieveSubmodelsForAAS(List<Submodel> submodels, AssetAdministrationShell shell) {
+ Set<ISubmodel> currentSM = new HashSet<>();
+
+ for (IReference submodelRef : shell.getSubmodelReferences()) {
+ try {
+ ISubmodel sm = getByReference(submodelRef, submodels);
+ currentSM.add(sm);
+ logger.debug("Found Submodel " + sm.getIdShort() + " for AAS " + shell.getIdShort());
+ } catch (ResourceNotFoundException e) {
+ // If there's no match, the submodel is assumed to be provided by different
+ // means, e.g. it is already being hosted
+ logger.warn("Could not find Submodel " + submodelRef.getKeys().get(0).getValue() + " for AAS " + shell.getIdShort() + "; If it is not hosted elsewhere this is an error!");
+ }
+ }
+ return currentSM;
+ }
+
+ /**
+ * Retrieves an identifiable from a list of identifiable by its reference
+ *
+ * @param submodelRef
+ * @param identifiable
+ * @return
+ * @throws ResourceNotFoundException
+ */
+ private <T extends IIdentifiable> T getByReference(IReference ref, List<T> identifiable) throws ResourceNotFoundException {
+ IKey lastKey = null;
+ // It may be that only one key fits to the Submodel contained in the XML
+ for (IKey key : ref.getKeys()) {
+ lastKey = key;
+ // There will only be a single submodel matching the identification at max
+ Optional<T> match = identifiable.stream().filter(s -> s.getIdentification().getId().equals(key.getValue())).findFirst();
+ if (match.isPresent()) {
+ return match.get();
+ }
+ }
+ if (lastKey == null) {
+ throw new ResourceNotFoundException("Could not resolve reference without keys");
+ } else {
+ throw new ResourceNotFoundException(
+ "Could not resolve reference with last key '" + lastKey.getValue() + "'");
+ }
+
+ // If no identifiable is found, indicate it by throwing an exception
+
+ }
+}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/NetworkReceiver.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/NetworkReceiver.java
index aa2986f..59edcb7 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/NetworkReceiver.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/NetworkReceiver.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.netcomm;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/TCPClient.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/TCPClient.java
index 4611f1d..3848ae9 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/TCPClient.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/TCPClient.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.netcomm;
import java.io.IOException;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/TCPCommunicator.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/TCPCommunicator.java
index 59ce17c..b3780d0 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/TCPCommunicator.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/TCPCommunicator.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.netcomm;
import java.io.IOException;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/TCPServer.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/TCPServer.java
index 9170bd6..b89d82b 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/TCPServer.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/TCPServer.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.netcomm;
import java.io.IOException;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/processengine/connector/DeviceServiceDelegate.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/processengine/connector/DeviceServiceDelegate.java
index cb10cbb..d7ee47a 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/processengine/connector/DeviceServiceDelegate.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/processengine/connector/DeviceServiceDelegate.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.processengine.connector;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/processengine/connector/DeviceServiceExecutor.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/processengine/connector/DeviceServiceExecutor.java
index c5dbbea..a249694 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/processengine/connector/DeviceServiceExecutor.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/processengine/connector/DeviceServiceExecutor.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.processengine.connector;
import java.util.ArrayList;
@@ -5,7 +14,7 @@
import java.util.Map;
import org.eclipse.basyx.aas.manager.api.IAssetAdministrationShellManager;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
@@ -51,7 +60,7 @@
IIdentifier smId = new Identifier(IdentifierType.CUSTOM, submodelid);
// create the submodel of the corresponding aas
- ISubModel serviceSubmodel = manager.retrieveSubModel(aasId, smId);
+ ISubmodel serviceSubmodel = manager.retrieveSubmodel(aasId, smId);
// navigate to the expected service
Map<String, IOperation> operations = serviceSubmodel.getOperations();
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/processengine/connector/IDeviceServiceExecutor.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/processengine/connector/IDeviceServiceExecutor.java
index 20a5ee6..c2b0031 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/processengine/connector/IDeviceServiceExecutor.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/processengine/connector/IDeviceServiceExecutor.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.processengine.connector;
import java.util.List;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/provider/BaseConfiguredProvider.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/provider/BaseConfiguredProvider.java
index ca5da6d..f2a418d 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/provider/BaseConfiguredProvider.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/provider/BaseConfiguredProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.provider;
import java.util.Collection;
@@ -9,7 +18,7 @@
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.facade.SubmodelFacadeCustomSemantics;
import org.eclipse.basyx.submodel.metamodel.facade.SubmodelFacadeIRDISemantics;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.AdministrativeInformation;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
@@ -20,8 +29,8 @@
import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
import org.eclipse.basyx.submodel.restapi.vab.VABSubmodelAPI;
import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
import org.slf4j.Logger;
@@ -34,7 +43,7 @@
*
*/
-public class BaseConfiguredProvider extends SubModelProvider {
+public class BaseConfiguredProvider extends SubmodelProvider {
/**
* Initiates a logger using the current class
@@ -44,7 +53,7 @@
/**
* This is a sub model
*/
- protected SubModel submodelData = null;
+ protected Submodel submodelData = null;
public static final String SUBMODELSEMANTICS = "submodelSemantics";
public static final String TYPE = "type";
@@ -61,12 +70,12 @@
super();
// Create sub model
- submodelData = createSubModel(cfgValues);
+ submodelData = createSubmodel(cfgValues);
setSubmodel(submodelData);
}
- protected void setSubmodel(SubModel sm) {
+ protected void setSubmodel(Submodel sm) {
setAPI(new VABSubmodelAPI(new VABMapProvider(sm)));
}
@@ -96,7 +105,7 @@
*/
protected Collection<String> getConfiguredProperties(Map<Object, Object> cfgValues) {
// Split property string
- return splitString((String) cfgValues.get(SubmodelElementProvider.PROPERTIES));
+ return splitString((String) cfgValues.get(MultiSubmodelElementProvider.ELEMENTS));
}
/**
@@ -136,9 +145,9 @@
* @param cfgValues
* Provider configuration
*/
- protected SubModel createSubModel(Map<Object, Object> cfgValues) {
+ protected Submodel createSubmodel(Map<Object, Object> cfgValues) {
// Create sub model
- SubModel submodel = null;
+ Submodel submodel = null;
// Try to load and convert configuration values. Keep value null if any error occurs
String basyx_submodelSemantics = null;
@@ -225,7 +234,7 @@
// If no sub model was created, create an empty one
if (submodel == null)
- submodel = new SubModel();
+ submodel = new Submodel();
// Return sub model data
return submodel;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/service/BaseBaSyxService.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/service/BaseBaSyxService.java
index 7b7ea46..65e6bd5 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/service/BaseBaSyxService.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/service/BaseBaSyxService.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.service;
import java.util.HashMap;
@@ -5,7 +14,7 @@
import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
import org.eclipse.basyx.components.configuration.ConfigurableComponent;
import org.eclipse.basyx.components.configuration.builder.BaSyxServiceConfigurationBuilder;
import org.eclipse.basyx.vab.manager.VABConnectionManager;
@@ -55,7 +64,7 @@
/**
* Registry proxy reference that will be used for registering sub models
*/
- protected IAASRegistryService registryProxy = null;
+ protected IAASRegistry registryProxy = null;
@@ -243,7 +252,7 @@
/**
* Set AAS registry proxy
*/
- protected void setRegistry(IAASRegistryService regProxy) {
+ protected void setRegistry(IAASRegistry regProxy) {
registryProxy = regProxy;
}
@@ -251,7 +260,7 @@
/**
* Get AAS registry proxy reference
*/
- protected IAASRegistryService getRegistry() {
+ protected IAASRegistry getRegistry() {
return registryProxy;
}
}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/aas/AASBundleServlet.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/aas/AASBundleServlet.java
deleted file mode 100644
index 3d7d21a..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/aas/AASBundleServlet.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package org.eclipse.basyx.components.servlet.aas;
-
-import java.util.Collection;
-import java.util.Collections;
-
-import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.aas.restapi.AASModelProvider;
-import org.eclipse.basyx.aas.restapi.MultiAASProvider;
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
-import org.eclipse.basyx.support.bundle.AASBundle;
-import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
-
-/**
- * Servlet providing multiple AAS based on a passed {@link AASBundle}
- *
- * @author schnicke
- *
- */
-public class AASBundleServlet extends VABHTTPInterface<MultiAASProvider> {
- private static final long serialVersionUID = 4441135540490088430L;
-
- /**
- * Creates a servlet hosting the AAS and its submodels specified in the bundle
- *
- * @param bundle
- */
- public AASBundleServlet(AASBundle bundle) {
- this(Collections.singleton(bundle));
- }
-
- /**
- * Creates a servlet hosting multiple AAS and their submodels as specified in
- * the bundle list
- *
- * @param bundles
- */
- public AASBundleServlet(Collection<AASBundle> bundles) {
- super(new MultiAASProvider());
-
- MultiAASProvider multiAASProvider = getModelProvider();
-
- for (AASBundle bundle : bundles) {
- multiAASProvider.addMultiSubmodelProvider(bundle.getAAS().getIdShort(), createMultiSubmodelProvider(bundle));
- }
- }
-
- /**
- * Creates the MultiSubmodelProvider based on a single bundle
- *
- * @param bundle
- * @return
- */
- private VABMultiSubmodelProvider createMultiSubmodelProvider(AASBundle bundle) {
- VABMultiSubmodelProvider provider = new VABMultiSubmodelProvider();
- IAssetAdministrationShell shell = bundle.getAAS();
-
- // Check for correct type
- if (!(shell instanceof AssetAdministrationShell)) {
- throw new RuntimeException("Only instances of AssetAdministrationShell are allowed here");
- }
-
- provider.setAssetAdministrationShell(new AASModelProvider((AssetAdministrationShell) shell));
- for (ISubModel sm : bundle.getSubmodels()) {
-
- if (!(sm instanceof SubModel)) {
- throw new RuntimeException("Only instances of SubModel are allowed here");
- }
-
- provider.addSubmodel(sm.getIdShort(), new SubModelProvider((SubModel) sm));
- }
- return provider;
- }
-}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/aas/AASServlet.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/aas/AASServlet.java
index e8a2194..2758fc9 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/aas/AASServlet.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/aas/AASServlet.java
@@ -1,8 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.servlet.aas;
import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
import org.eclipse.basyx.aas.restapi.AASModelProvider;
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
+import org.eclipse.basyx.aas.restapi.MultiSubmodelProvider;
import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
/**
@@ -11,7 +20,7 @@
* @author kuhn
*
*/
-public class AASServlet extends VABHTTPInterface<VABMultiSubmodelProvider> {
+public class AASServlet extends VABHTTPInterface<MultiSubmodelProvider> {
/**
* ID of serialized instances
@@ -22,7 +31,7 @@
* Default constructor - based on a VABMultiSubmodelProvider
*/
public AASServlet() {
- super(new VABMultiSubmodelProvider());
+ super(new MultiSubmodelProvider());
}
/**
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/registry/StaticCFGDirectoryServlet.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/registry/StaticCFGDirectoryServlet.java
deleted file mode 100644
index 57d0cbf..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/registry/StaticCFGDirectoryServlet.java
+++ /dev/null
@@ -1,454 +0,0 @@
-package org.eclipse.basyx.components.servlet.registry;
-
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URLDecoder;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.eclipse.basyx.components.directory.AASDirectoryEntry;
-import org.eclipse.basyx.components.directory.exception.AASDirectoryProviderException;
-import org.eclipse.basyx.vab.protocol.http.server.BasysHTTPServlet;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-
-
-/**
- * Static configuration file based directory provider
- *
- * This directory provider provides a static directory. It therefore only supports get() operations.
- * Modification of the directory via PUT/POST/PATCH/DELETE operations is not supported.
- *
- * @author kuhn
- *
- */
-public class StaticCFGDirectoryServlet extends BasysHTTPServlet {
-
- /**
- * Initiates a logger using the current class
- */
- private static final Logger logger = LoggerFactory.getLogger(StaticCFGDirectoryServlet.class);
-
-
- /**
- * Version information to identify the version of serialized instances
- */
- private static final long serialVersionUID = 1L;
-
-
-
- /**
- * Configuration properties (raw input from file)
- */
- protected Properties properties = null;
-
-
- /**
- * Asset administration shells by ID
- */
- protected Map<String, AASDirectoryEntry> aasByID = new HashMap<>();
-
-
- /**
- * Asset administration shells by tag
- */
- protected Map<String, Collection<AASDirectoryEntry>> aasByTag = new HashMap<>();
-
-
- /**
- * Uplink server
- */
- protected String uplink = null;
-
-
- /**
- * Downlink servers
- */
- protected Map<String, String> downlinks = new HashMap<>();
-
-
-
-
-
- /**
- * Constructor
- */
- public StaticCFGDirectoryServlet() {
- // Invoke base constructor
- super();
- }
-
- /**
- * Adds init parameter to servlet
- */
- @Override
- public String getInitParameter(String name) {
-
- if (name.equals("config")) return "/WebContent/WEB-INF/config/directory/cfgdirectory/directory.properties";
-
- return null;
- }
-
- /**
- * Load a property
- */
- protected String extractProperty(Properties prop, String key) {
- // Check if properties contain value
- if (!prop.containsKey(key)) return null;
-
- // Extract and remove value
- String value = (String) prop.get(key);
- prop.remove(key);
-
- // Return value
- return value;
- }
-
-
-
- /**
- * Extract property keys with prefix and suffix. Prefix and suffix is removed from key.
- */
- protected Collection<String> getProperties(Properties prop, String prefix, String suffix) {
- // Store result
- HashSet<String> result = new HashSet<>();
-
- // Iterate keys
- for (String key: prop.stringPropertyNames()) {
- if (key.startsWith(prefix) && key.endsWith(suffix)) result.add(key.substring(prefix.length(), key.length()-suffix.length()));
- }
-
- // Return result
- return result;
- }
-
-
-
- /**
- * Extract downlink servers
- */
- protected Map<String, String> extractDownlinks(Properties prop) {
- // Return value
- Map<String, String> result = new HashMap<>();
-
- // Downlink server names
- Collection<String> downlinkServerNames = getProperties(prop, "cfg.downlink.", ".pattern");
-
- // Remove downlink pattern and server URL
- for (String name: downlinkServerNames) {
- // Get downlink pattern and server URL
- result.put(prop.getProperty("cfg.downlink."+name+".pattern"), prop.getProperty("cfg.downlink."+name+".directory"));
- // Remove pattern and directory properties
- prop.remove("cfg.downlink."+name+".pattern");
- prop.remove("cfg.downlink."+name+".directory");
- }
-
- // Return downlink server mappings
- return result;
- }
-
-
-
- /**
- * Extract Asset Administration Shell definitions
- */
- protected Map<String, AASDirectoryEntry> extractAAS(Properties prop) {
- // Return value
- Map<String, AASDirectoryEntry> result = new HashMap<>();
-
- // Get AAS IDs
- Collection<String> aasIDs = getProperties(prop, "", ".id");
-
- // Create AAS directory entries from properties
- for (String aasID : aasIDs) {
- // Create AAS directory entry
- AASDirectoryEntry entry = new AASDirectoryEntry(prop.getProperty(aasID+".id"), prop.getProperty(aasID+".aas"), prop.getProperty(aasID+".type"), prop.getProperty(aasID+".tags"));
-
- // Add AAS directory entry
- result.put(prop.getProperty(aasID+".id"), entry);
- }
-
- // Return ID to AAS mappings
- return result;
- }
-
-
-
- /**
- * Map AAS tags to AAS
- */
- protected Map<String, Collection<AASDirectoryEntry>> mapAASToTags(Map<String, AASDirectoryEntry> aasByID) {
- // Return value
- Map<String, Collection<AASDirectoryEntry>> result = new HashMap<>();
-
- // Iterate AAS directory entries
- for (AASDirectoryEntry dirEntry: aasByID.values()) {
- // Process tags
- for (String tag: dirEntry.getAASTags()) {
- // Create tag if necessary
- if (!result.containsKey(tag)) {result.put(tag, new HashSet<AASDirectoryEntry>());}
-
- // Add AAS to tag
- result.get(tag).add(dirEntry);
- }
- }
-
- // Return HashTag to AAS mappings
- return result;
- }
-
-
-
- /**
- * Load properties from file
- */
- protected void loadProperties(String cfgFilePath) {
- // Read property file
- try {
- // Open property file
- InputStream input = getServletContext().getResourceAsStream(cfgFilePath);
-
- // Instantiate property structure
- properties = new Properties();
- properties.load(input);
-
- logger.debug("properties:"+properties);
- logger.debug("properties (keys):"+properties.keySet());
- logger.debug("properties (cfg.downlink.is.pattern):"+properties.get("cfg.downlink.is.pattern"));
-
- // Process properties
- // - Uplink server
- uplink = extractProperty(properties, "cfg.uplink");
- // - Downlink servers
- downlinks = extractDownlinks(properties);
- // - AAS by ID
- aasByID = extractAAS(properties);
- // - AAS by tag
- aasByTag = mapAASToTags(aasByID);
-
- logger.debug("Downlink:"+downlinks);
- logger.debug("properties:"+properties);
- logger.debug("aasbyID:"+aasByID);
-
- } catch (IOException e) {
- // Output exception
- e.printStackTrace();
- }
- }
-
-
-
- /**
- * Initialize servlet
- *
- * @throws ServletException
- */
- @Override
- public void init() throws ServletException {
- // Call base implementation
- super.init();
-
- // Read configuration values
- String configFilePath = getInitParameter("config");
- // - Read property file
- loadProperties(configFilePath);
- }
-
-
- /**
- * Get AAS content from AASDirectoryEntry
- */
- protected String getAASContent(AASDirectoryEntry directoryEntry) {
- // Process directory entry
- switch (directoryEntry.getAASContentType()) {
-
- // Local content type
- case AASDirectoryEntry.AAS_CONTENTTYPE_LOCAL:
- return directoryEntry.getAASContent();
-
- // Remote content type
- case AASDirectoryEntry.AAS_CONTENTTYPE_REMOTE:
- throw new AASDirectoryProviderException("Unsupported AAS content type");
-
- // Proxy content type - content is ID of AAS that contains the information
- case AASDirectoryEntry.AAS_CONTENTTYPE_PROXY:
- return getAASContentByID(directoryEntry.getAASContent());
-
- // Unknown content type
- default:
- throw new AASDirectoryProviderException("Unknown AAS content type");
- }
- }
-
-
-
- /**
- * Get requested tags as collection
- */
- protected Collection<String> getTagsAsCollection(String tags) {
- // Collection stores AAS tags
- Collection<String> alltags = new HashSet<>();
-
- // Catch null pointer exceptions
- try {
- // Get AAS tags
- String[] splitTags = tags.split(",");
-
- // Only add non-empty tags
- for (String tag: splitTags) if (tag.trim().length() > 0) alltags.add(tag.trim());
- } catch (NullPointerException e) {}
-
- // Return all tags
- return alltags;
- }
-
-
-
- /**
- * Get a specific AAS content with ID
- */
- protected String getAASContentByID(String aasID) {
- // Extract requested AAS ID
- AASDirectoryEntry aas = aasByID.get(aasID);
-
- // Null pointer check
- if (aas == null)
- return null;
-
- // Return result
- return getAASContent(aas);
- }
-
-
-
-
-
- /**
- * Implement "Get" operation
- *
- * Process HTTP get request - get sub model property value
- */
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- // Process request depending on the path and on parameter
- String uri = req.getRequestURI();
- String contextPath = req.getContextPath();
- String path = URLDecoder.decode(uri.substring(contextPath.length()+1).substring(req.getServletPath().length()), "UTF-8"); // plus 1 for "/"
-
- // Extract action parameter
- Collection<String> alltags = getTagsAsCollection(req.getParameter("tags"));
-
-
- // Setup HTML response header
- resp.setContentType("application/json");
- resp.setCharacterEncoding("UTF-8");
-
-
- // Process get request
- // - Get all (local) AAS
- if (path.equals("api/v1/registry")) {
- // Extract AAS directory entries
- Collection<AASDirectoryEntry> entries = null;
-
- // Check if tags are to be processed
- if (alltags.isEmpty()) {
- // Get all tags
- entries = aasByID.values();
- } else {
- // HashSet that holds all elements
- Set<AASDirectoryEntry> taggedEntries = new HashSet<>();
-
- // Get tagged elements that have all requested tags
- // - Get first requested tag
- taggedEntries.addAll(aasByTag.get(alltags.iterator().next()));
- // - Remove all directory entries that do not have all tags
- for (String tag: alltags) taggedEntries.retainAll(aasByTag.get(tag));
- // - Place remaining elements into entries collection
- entries = taggedEntries;
- }
-
- // Build response string
- StringBuilder response = new StringBuilder();
- for (AASDirectoryEntry entry: entries) response.append(getAASContent(entry));
-
- // Write result
- sendResponse(response.toString(), resp.getWriter());
- // End processing
- return;
- }
- // Get a specific AAS
- else if (path.startsWith("api/v1/registry/")) {
- logger.debug("Getting:"+path);
-
- // Get requested AAS with ID
- String aas = getAASContentByID(path.substring(new String("api/v1/registry/").length()));
-
- // Write result
- sendResponse(aas, resp.getWriter());
- // End processing
- return;
- } else {
- // Send null response for unknown path
- sendResponse(null, resp.getWriter());
- return;
- }
- }
-
-
-
- /**
- * Implement "Put" operation
- */
- @Override
- protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- // Indicate an unsupported operation
- resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, "Request not implemented for this service");
- }
-
-
-
- /**
- * <pre>
- * Handle HTTP POST operation. Creates a new Property, Operation, Event, Submodel or AAS or invokes an operation.
- */
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- // Indicate an unsupported operation
- resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, "Request not implemented for this service");
- }
-
-
-
- /**
- * Handle a HTTP PATCH operation. Updates a map or collection respective to action string.
- *
- */
- @Override
- protected void doPatch(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- // Indicate an unsupported operation
- resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, "Request not implemented for this service");
- }
-
-
-
- /**
- * Implement "Delete" operation. Deletes any resource under the given path.
- */
- @Override
- protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- // Indicate an unsupported operation
- resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, "Request not implemented for this service");
- }
-}
-
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/SQLSubModelProviderServlet.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/SQLSubModelProviderServlet.java
deleted file mode 100644
index 7de51c7..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/SQLSubModelProviderServlet.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package org.eclipse.basyx.components.servlet.submodel;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Properties;
-
-import javax.servlet.ServletException;
-
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
-import org.eclipse.basyx.components.provider.BaseConfiguredProvider;
-import org.eclipse.basyx.components.sqlprovider.SQLPreconfiguredSubModelProvider;
-import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
-
-/**
- * Servlet interface for SQL sub model provider
- *
- * @author kuhn
- *
- */
-public class SQLSubModelProviderServlet extends VABHTTPInterface<VABMultiSubmodelProvider> {
-
- /**
- * Version information to identify the version of serialized instances
- */
- private static final long serialVersionUID = 1L;
-
- /**
- * Sub model ID
- */
- protected String submodelID = null;
-
- /**
- * Configuration properties
- */
- protected Properties cfgProperties = null;
-
- /**
- * Constructor
- */
- public SQLSubModelProviderServlet() {
- // Invoke base constructor
- super(new VABMultiSubmodelProvider());
- }
-
- /**
- * Initialize servlet
- *
- * @throws ServletException
- */
- public void init() throws ServletException {
- // Call base implementation
- super.init();
-
- // Read configuration values
- String configFilePath = (String) getInitParameter("config");
-
- // Read property file
- try {
- // Open property file
- InputStream input = getServletContext().getResourceAsStream(configFilePath);
-
- // Instantiate property structure
- cfgProperties = new Properties();
- cfgProperties.load(input);
-
- // Extract sub model provider properties
- this.submodelID = cfgProperties.getProperty(BaseConfiguredProvider.buildBasyxCfgName(BaseConfiguredProvider.SUBMODELID));
-
- } catch (IOException e) {
- // Output exception
- e.printStackTrace();
- }
-
- // Instantiate and add sub model provider
- SQLPreconfiguredSubModelProvider sqlSMProvider = new SQLPreconfiguredSubModelProvider(cfgProperties);
- // - Add sub model provider
- this.getModelProvider().addSubmodel(submodelID, sqlSMProvider);
- }
-}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/SubmodelServlet.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/SubmodelServlet.java
index a728dd3..6d790ac 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/SubmodelServlet.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/SubmodelServlet.java
@@ -1,7 +1,16 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.servlet.submodel;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
/**
@@ -10,7 +19,7 @@
* @author kuhn
*
*/
-public class SubmodelServlet extends VABHTTPInterface<SubModelProvider> {
+public class SubmodelServlet extends VABHTTPInterface<SubmodelProvider> {
/**
* ID of serialized instances
@@ -22,14 +31,14 @@
*/
public SubmodelServlet() {
// Invoke base constructor
- super(new SubModelProvider());
+ super(new SubmodelProvider());
}
/**
* Constructor with a predefined submodel
*/
- public SubmodelServlet(SubModel exportedModel) {
+ public SubmodelServlet(Submodel exportedModel) {
// Invoke base constructor
- super(new SubModelProvider(exportedModel));
+ super(new SubmodelProvider(exportedModel));
}
}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/AbstractCFGSubModelProviderServlet.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/AbstractCFGSubModelProviderServlet.java
deleted file mode 100644
index c87d657..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/AbstractCFGSubModelProviderServlet.java
+++ /dev/null
@@ -1,113 +0,0 @@
-package org.eclipse.basyx.components.servlet.submodel.cfg;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Properties;
-
-import javax.servlet.ServletException;
-
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
-import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Abstract super class for all config file using submodel provider servlets
- *
- * @author schnicke
- *
- */
-public abstract class AbstractCFGSubModelProviderServlet extends VABHTTPInterface<VABMultiSubmodelProvider> {
-
- /**
- * Initiates a logger using the current class
- */
- private static final Logger logger = LoggerFactory.getLogger(AbstractCFGSubModelProviderServlet.class);
-
- /**
- * Version information to identify the version of serialized instances
- */
- private static final long serialVersionUID = 1L;
-
- /**
- * Store ID of the sub model provided by this provider
- */
- protected String submodelID = null;
-
- /**
- * Configuration properties
- */
- protected Properties properties = null;
-
-
- /**
- * Standard constructor creating a servlet containing a new
- * VABMultiSubmodelProvider()
- */
- public AbstractCFGSubModelProviderServlet() {
- super(new VABMultiSubmodelProvider());
- }
-
- /**
- * Load properties from file
- */
- protected void loadProperties(String cfgFilePath) {
- // Read property file
- try {
- // Open property file
- InputStream input = getServletContext().getResourceAsStream(cfgFilePath);
-
- // Instantiate property structure
- properties = new Properties();
- properties.load(input);
-
- // Extract AAS properties
- this.submodelID = properties.getProperty(getSubmodelId());
- } catch (IOException e) {
- // Output exception
- e.printStackTrace();
- }
- }
-
- /**
- * Initialize servlet
- *
- * @throws ServletException
- */
- @Override
- public void init() throws ServletException {
- // Call base implementation
- super.init();
-
- // Read configuration values
- String configFilePath = getInitParameter("config");
- // - Read property file
- loadProperties(configFilePath);
-
- logger.debug("1:" + submodelID);
-
- // Create sub model provider
- SubModelProvider submodelProvider = createProvider(properties);
- // - Add sub model provider
- this.getModelProvider().addSubmodel(submodelID, submodelProvider);
-
- logger.debug("CFG file loaded");
- }
-
- /**
- * Retrieves the submodel id
- *
- * @return
- */
- protected abstract String getSubmodelId();
-
- /**
- * Creates the appropriate provider based on the passed properties
- *
- * @param properties
- * @return
- */
- protected abstract SubModelProvider createProvider(Properties properties);
-
-}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/CFGSubModelProviderServlet.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/CFGSubModelProviderServlet.java
deleted file mode 100644
index 1391f89..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/CFGSubModelProviderServlet.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package org.eclipse.basyx.components.servlet.submodel.cfg;
-
-import java.util.Properties;
-
-import org.eclipse.basyx.components.cfgprovider.CFGSubModelProvider;
-import org.eclipse.basyx.components.provider.BaseConfiguredProvider;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
-
-/**
- * Servlet interface for configuration file sub model provider
- *
- * @author kuhn
- *
- */
-public class CFGSubModelProviderServlet extends AbstractCFGSubModelProviderServlet {
-
- /**
- * Version information to identify the version of serialized instances
- */
- private static final long serialVersionUID = -7525848804623194574L;
-
-
- @Override
- protected String getSubmodelId() {
- return BaseConfiguredProvider.buildBasyxCfgName(BaseConfiguredProvider.SUBMODELID);
- }
-
- @Override
- protected SubModelProvider createProvider(Properties properties) {
- return new CFGSubModelProvider(properties);
- }
-}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/RawCFGSubModelProviderServlet.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/RawCFGSubModelProviderServlet.java
deleted file mode 100644
index 9a87495..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/RawCFGSubModelProviderServlet.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.eclipse.basyx.components.servlet.submodel.cfg;
-
-import java.util.Properties;
-
-import org.eclipse.basyx.components.cfgprovider.RawCFGSubModelProvider;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
-
-/**
- * Servlet interface for configuration file sub model provider
- *
- * @author kuhn
- *
- */
-public class RawCFGSubModelProviderServlet extends AbstractCFGSubModelProviderServlet {
-
- /**
- * Version information to identify the version of serialized instances
- */
- private static final long serialVersionUID = -8132051635222485719L;
-
-
- @Override
- protected String getSubmodelId() {
- return Referable.IDSHORT;
- }
-
-
- @Override
- protected SubModelProvider createProvider(Properties properties) {
- return new RawCFGSubModelProvider(properties);
- }
-}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/vab/VABLambdaServlet.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/vab/VABLambdaServlet.java
index fbd7e5d..1113c40 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/vab/VABLambdaServlet.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/vab/VABLambdaServlet.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.servlet.vab;
import java.util.HashMap;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLPreconfiguredSubModelProvider.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLPreconfiguredSubModelProvider.java
deleted file mode 100644
index 43dc58e..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLPreconfiguredSubModelProvider.java
+++ /dev/null
@@ -1,517 +0,0 @@
-package org.eclipse.basyx.components.sqlprovider;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-
-import org.eclipse.basyx.components.provider.BaseConfiguredProvider;
-import org.eclipse.basyx.components.sqlprovider.driver.SQLDriver;
-import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLQuery;
-import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLRunner;
-import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLUpdate;
-import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-
-
-/**
- * Asset administration shell sub model provider that connects to SQL database
- *
- * @author kuhn
- *
- */
-public class SQLPreconfiguredSubModelProvider extends BaseConfiguredProvider {
-
- /**
- * Initiates a logger using the current class
- */
- private static final Logger logger = LoggerFactory.getLogger(SQLPreconfiguredSubModelProvider.class);
-
- /**
- * SQL database user name
- */
- protected String sqlUser = null;
-
- /**
- * SQL database password
- */
- protected String sqlPass = null;
-
- /**
- * SQL database path
- */
- protected String sqlURL = null;
-
-
-
- /**
- * SQL database driver
- */
- protected String sqlDriver = null;
-
- /**
- * SQL database query prefix
- */
- protected String sqlPrefix = null;
-
-
-
- /**
- * SQL property connections
- */
- protected Set<String> sqlPropertyConnections = new HashSet<>();
-
-
- /**
- * SQL operation connections
- */
- protected Set<String> sqlOperationConnections = new HashSet<>();
-
-
-
- /**
- * Run queries to access properties via 'get' operation
- */
- protected Map<String, DynamicSQLRunner> propertyGetQueries = new HashMap<>();
-
-
- /**
- * Run SQL update to access properties via 'set' operation
- */
- protected Map<String, DynamicSQLRunner> propertySetQueries = new HashMap<>();
-
-
- /**
- * Run SQL update to access properties via 'create' operation
- */
- protected Map<String, DynamicSQLRunner> propertyCreateQueries = new HashMap<>();
-
-
- /**
- * Run SQL update to access properties via 'delete' operation
- */
- protected Map<String, DynamicSQLRunner> propertyDeleteQueries = new HashMap<>();
-
-
-
- /**
- * SQL operations
- */
- protected Map<String, DynamicSQLRunner> operations = new HashMap<>();
-
-
- /**
- * SQL operations that run as update operations. Not contained operations are query operations.
- */
- protected Set<String> updateOperations = new HashSet<>();
-
- /**
- * An SQL driver instance to connect to the database
- */
- protected SQLDriver driver;
-
-
- public static final String DBUSER = "dbuser";
- public static final String DBPASS = "dbpass";
- public static final String DBURL = "dburl";
- public static final String DRIVER = "driver";
- public static final String PREFIX = "prefix";
- public static final String PROPERTIES = "properties";
- public static final String OPERATIONS = "operations";
-
-
- /**
- * Constructor
- */
- public SQLPreconfiguredSubModelProvider(Properties cfgValues) {
- // Call base constructor
- super(cfgValues);
-
- // Create sub model
- submodelData = createSubModel(cfgValues);
-
- // Load predefined elements from sub model
-
- try {
- setModelPropertyValue("", submodelData);
- } catch (Exception e) {
- e.printStackTrace();
- }
-
-
- // Extract SQL properties
- sqlUser = cfgValues.getProperty(buildSqlCfgName(DBUSER));
- sqlPass = cfgValues.getProperty(buildSqlCfgName(DBPASS));
- sqlURL = cfgValues.getProperty(buildSqlCfgName(DBURL));
-
- // Extract SQL driver properties
- sqlDriver = cfgValues.getProperty(buildSqlCfgName(DRIVER));
- sqlPrefix = cfgValues.getProperty(buildSqlCfgName(PREFIX));
-
- // Create a SQL driver instance
- driver = new SQLDriver(sqlURL, sqlUser, sqlPass, sqlPrefix, sqlDriver);
-
- // Load and parse SQL property and operation connections
- sqlPropertyConnections.addAll(splitString(cfgValues.getProperty(buildSqlCfgName(PROPERTIES))));
- sqlOperationConnections.addAll(splitString(cfgValues.getProperty(buildSqlCfgName(OPERATIONS))));
-
-
-
- // Add properties
- for (String propertyName: sqlPropertyConnections) createSQLProperty(propertyName, cfgValues);
-
- /*
- // Try to parse parameter
- propertyGetQueries.put(propertyName, createSQLOperation(propertyName+".get", cfgValues));
- propertySetQueries.put(propertyName, createSQLOperation(propertyName+".set", cfgValues));
- propertyCreateQueries.put(propertyName, createSQLOperation(propertyName+".create", cfgValues));
- propertyDeleteQueries.put(propertyName, createSQLOperation(propertyName+".delete", cfgValues));
-
-
- Map<String, Object> mapAccessors = VABLambdaProviderHelper.createMap((Supplier<?>) () -> {
- return propertyMap_val;
- }, (Consumer<Map<String, Object>>) (map) -> {
- propertyMap_val = map;
- }, (BiConsumer<String, Object>) (key, value) -> {
- propertyMap_val.put(key, value);
- }, (Consumer<Object>) (o) -> {
- propertyMap_val.remove(o);
- });
-
- }*/
-
-
- // Add operations
- //for (String operationName: sqlOperationConnections) createSQLOperation(operationName, cfgValues);
- /*{
- // Create operation
- operations.put(operationName, createSQLOperation(operationName, cfgValues));
- // Mark operation as update operation depending on operations/<operationName>_kind property value
- try {
- if (cfgValues.getProperty(operationName+"_kind").trim().equalsIgnoreCase("update")) {
- updateOperations.add(operationName);
- }
- } catch (Exception e) {}
- }*/
- }
-
-
-
- /**
- * Create an SQL property
- */
- protected void createSQLProperty(String name, Properties cfgValues) {
- // Create Map with lambdas that hold SQL operations
- Map<String, Object> value = new HashMap<>();
-
- // Get operation
- {
- // Get parameter
- String queryString = cfgValues.getProperty(name+".get");
- String resultFilterOp = cfgValues.getProperty(name+".get.result");
-
- // Trim query string and resultFilterOp (remove '"' at beginning and end)
- queryString = queryString.substring(1, queryString.length()-1);
- try {resultFilterOp = resultFilterOp.substring(1, resultFilterOp.length()-1);} catch (NullPointerException | StringIndexOutOfBoundsException e) {}
-
- // Create dynamic SQL query
- value.put(VABLambdaHandler.VALUE_GET_SUFFIX, new DynamicSQLQuery(driver, queryString, resultFilterOp));
- }
-
- // Set operation
- {
- // Get parameter
- String updateString = cfgValues.getProperty(name+".set");
-
- // Trim query string and resultFilterOp (remove '"' at beginning and end)
- updateString = updateString.substring(1, updateString.length()-1);
-
- // Create dynamic SQL query
- value.put(VABLambdaHandler.VALUE_SET_SUFFIX, new DynamicSQLUpdate(driver, updateString));
- }
-
- // Delete operation
- {
- // Get parameter
- String updateString = cfgValues.getProperty(name+".delete");
-
- // Trim query string and resultFilterOp (remove '"' at beginning and end)
- updateString = updateString.substring(1, updateString.length()-1);
-
- // Create dynamic SQL query
- value.put(VABLambdaHandler.VALUE_REMOVEKEY_SUFFIX, new DynamicSQLUpdate(driver, updateString));
- value.put(VABLambdaHandler.VALUE_REMOVEOBJ_SUFFIX, new DynamicSQLUpdate(driver, updateString));
- }
-
- // Create operation
- {
- // Get parameter
- String updateString = cfgValues.getProperty(name+".create");
-
- // Trim query string and resultFilterOp (remove '"' at beginning and end)
- updateString = updateString.substring(1, updateString.length()-1);
-
- // Create dynamic SQL query
- value.put(VABLambdaHandler.VALUE_INSERT_SUFFIX, new DynamicSQLUpdate(driver, updateString));
- }
-
-
- logger.debug("Putting SQL:"+name);
- // Add property as map of lambdas
- submodelData.getProperties().put(name, createSubmodelElement(name, value, cfgValues));
- }
-
-
- /**
- * Create a dynamic SQL operation
- */
- protected DynamicSQLRunner createSQLOperation(String propertyName, Properties cfgValues) {/*
- // Check parameter presence
- if (!cfgValues.containsKey(propertyName)) return null;
-
- // Get parameter count and parameter count
- int parameterCount = Integer.parseInt(cfgValues.getProperty(propertyName+".parameter"));
- String queryString = cfgValues.getProperty(propertyName);
- String resultFilterOp = cfgValues.getProperty(propertyName+".result");
-
- // Trim query string and resultFilterOp (remove '"' at beginning and end)
- queryString = queryString.substring(1, queryString.length()-1);
- try {resultFilterOp = resultFilterOp.substring(1, resultFilterOp.length()-1);} catch (NullPointerException | StringIndexOutOfBoundsException e) {}
-
- // Create dynamic SQL query
- DynamicSQLRunner sqlQuery = new DynamicSQLRunner(sqlURL, sqlUser, sqlPass, sqlPrefix, sqlDriver, parameterCount, queryString, resultFilterOp);
-
- // Return created query
- return sqlQuery;*/
-
- return null;
- }
-
-
- /**
- * Split a whitespace delimited string
- */
- protected Collection<String> splitString(String input) {
- // Return value
- HashSet<String> result = new HashSet<>();
-
- // Split string into segments
- for (String inputStr: input.split(" ")) result.add(inputStr.trim());
-
- // Return result
- return result;
- }
-
-
- /**
- * Create a key list for an SQL statement
- *//*
- protected String sqlCreateKeys(Collection<String> keys) {
- // Return value builder
- StringBuilder result = new StringBuilder();
-
- // Process keys
- // - Flag that handles the first key
- boolean isFirst = true;
- // - Process keys
- for (String key: keys) {if (!isFirst) result.append(","); else isFirst=false; result.append(key);}
-
- // Return string
- return result.toString();
- }*/
-
-
- /**
- * Extract a list of values from a map
- *//*
- protected String sqlCreateValues(Collection<Object> values) {
- // Return value builder
- StringBuilder result = new StringBuilder();
-
- // Process keys
- // - Flag that handles the first key
- boolean isFirst = true;
- // - Process keys
- for (Object key: values) {if (!isFirst) result.append(","); else isFirst=false; result.append("'"+key+"'");}
-
- // Return string
- return result.toString();
- }*/
-
-
-
- /**
- * Create (insert) a value into the SQL table
- *//*
- @Override @SuppressWarnings("unchecked")
- public void createValue(String propertyName, Object arg1) throws Exception {
- // Set query
- DynamicSQLRunner query = propertyCreateQueries.get(propertyName);
-
- // Null pointer check
- if (query == null) return;
-
- // Create parameter array
- Object[] parameter = new Object[2];
- parameter[0] = sqlCreateKeys(((Map<String, Object>) arg1).keySet());
- parameter[1] = sqlCreateValues(((Map<String, Object>) arg1).values());
-
- // Execute query and return result
- query.runUpdate(parameter);
- }*/
-
-
-
- /**
- * Delete a value from the SQL table
- *//*
- @Override
- public void deleteValue(String arg0) throws Exception {
- // This is not implemented
- }*/
-
-
-
- /**
- * Delete a value from the SQL table
- *//*
- @Override @SuppressWarnings("unchecked")
- public void deleteValue(String propertyName, Object arg1) throws Exception {
- // Set query
- DynamicSQLRunner query = propertyDeleteQueries.get(propertyName);
-
- // Null pointer check
- if (query == null) return;
-
- // Cast argument to collection
- Collection<Object> parameterList = (Collection<Object>) arg1;
-
- // Create parameter array
- Object[] parameter = new Object[parameterList.size()];
- // - Copy parameter
- int counter = 0; for (Object par: parameterList) parameter[counter++] = par;
-
- // Execute query and return result
- query.runUpdate(parameter);
- }*/
-
-
-/*
- @Override
- public Map<String, IElementReference> getContainedElements(String arg0) {
- // TODO Auto-generated method stub
- return null;
- }
-
-
- @Override
- public String getElementScope(String arg0) {
- logger.debug("GetScope:"+arg0);
- // TODO Auto-generated method stub
- return null;
- }
-*/
-
-
- /**
- * Query the SQL database
- *//*
- @Override
- public Object getModelPropertyValue(String propertyName) {
- // Get query
- DynamicSQLRunner query = propertyGetQueries.get(propertyName);
-
- // Null pointer check
- if (query == null) return null;
-
- // Execute query and return result
- return query.runQuery();
- }*/
-
-
-
- /**
- * Invoke operation with given parameter list
- *//*
- @Override
- public Object invokeOperation(String propertyName, Object[] parameter) throws Exception {
- // Set query
- DynamicSQLRunner query = operations.get(propertyName);
-
- // Null pointer check
- if (query == null) return null;
-
- // Execute query and return result
- if (updateOperations.contains(propertyName)) {
- query.runUpdate(parameter);
- return null;
- } else {
- return query.runQuery(parameter);
- }
- }*/
-
-
-
- /**
- * Invoke set operation with given parameter
- *//*
- @Override @SuppressWarnings("unchecked")
- public void setModelPropertyValue(String propertyName, Object arg1) throws Exception {
- // Set query
- DynamicSQLRunner query = propertySetQueries.get(propertyName);
-
- // Null pointer check
- if (query == null) return;
-
- logger.debug("LENC:"+arg1);
-
- // Create parameter array
- Object[] parameter = null;
- // - Process collections
- if (arg1 instanceof Collection) {
- // Cast to collection
- Collection<Object> parameterList = (Collection<Object>) arg1;
-
- // Create parameter array and copy parameter
- parameter = new Object[parameterList.size()];
- int counter = 0; for (Object par: parameterList) parameter[counter++] = par;
- } else {
- // Create parameter array and copy parameter
- parameter = new Object[1];
- parameter[0] = arg1;
- }
-
-
- // Execute query and return result
- query.runUpdate(parameter);
- }*/
-
-
-
- /**
- * Invoke set operation with given parameter list
- *//*
- @Override
- public void setModelPropertyValue(String propertyName, Object... parameter) throws Exception {
- // Set query
- DynamicSQLRunner query = propertySetQueries.get(propertyName);
-
- // Null pointer check
- if (query == null) return;
-
- logger.debug("LEN:"+parameter.length);
- logger.debug("LEN-0:"+parameter[0]);
-
- // Execute query and return result
- query.runUpdate(parameter);
- }*/
-
- public static String buildSqlCfgName(String valueName) {
- return BaseConfiguredProvider.buildCfgName("basyx.sql", valueName);
- }
-}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLProviderTestOLD.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLProviderTestOLD.java
deleted file mode 100644
index 772b1ee..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLProviderTestOLD.java
+++ /dev/null
@@ -1,186 +0,0 @@
-package org.eclipse.basyx.components.sqlprovider;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Collection;
-import java.util.LinkedList;
-
-import org.eclipse.basyx.components.sqlprovider.driver.ISQLDriver;
-import org.eclipse.basyx.components.sqlprovider.driver.SQLDriver;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class SQLProviderTestOLD {
-
- /**
- * Initiates a logger using the current class
- */
- private static final Logger logger = LoggerFactory.getLogger(SQLProviderTestOLD.class);
-
-
- /**
- * Define a parameter tuple (name/type)
- *
- * @author kuhn
- *
- */
- static class Parameter {
- String name;
- String type;
-
-
- /**
- * Constructor
- *
- * @param name Parameter name
- * @param type Parameter type
- */
- Parameter(String name, String type) {
- this.name = name;
- this.type = type;
- }
-
-
- /**
- * Return parameter name
- *
- * @return parameter name
- */
- public String getName() {
- return name;
- }
-
-
- /**
- * Return parameter type
- *
- * @return parameter type
- */
- public String getType() {
- return type;
- }
- }
-
-
-
-
- /**
- * Get operation name of operation definition
- *
- * @param opDef The operation definition string
- * @return Operation name
- */
- public static String getOperation(String opDef) {
- // Get operation name
- return opDef.substring(0, opDef.indexOf("("));
- }
-
-
-
- /**
- * Get parameter list of an operation definition
- *
- * A parameter list contains of a name and of a type for each parameter+
- *
- * @param opDef The operation definition string
- * @return Collection of Parameter definitions
- */
- public static Collection<Parameter> getParameter(String opDef) {
- // Return type
- LinkedList<Parameter> result = new LinkedList<>();
-
- // Extract parameter sequence
- String callParameterStr = opDef.substring(opDef.indexOf("(")+1, opDef.length()-1);
- String[] callParameterList = callParameterStr.split(",");
-
- // Iterate all parameter. If no parameter is given, the loop will execute once with an empty String (length = 0)
- for (String parameterDef: callParameterList) {
- // Only process strings with a length > 0
- if (parameterDef.length() == 0) continue;
-
- // Add parameter
- result.add(new Parameter(parameterDef.substring(0, parameterDef.indexOf(":")).trim(), parameterDef.substring(parameterDef.indexOf(":")+1).trim().toLowerCase()));
- }
-
- // Return result
- return result;
- }
-
-
-
- /**
- * Create a SQL string from an input SQL string with place holders in format $x with x being an integer number.
- *
- * @param baseString SQL string with place holders
- * @param parameter Parameter values that place holders are substituted for
- *
- * @return SQL string with parameter instead of place holders
- */
- public static String getSQLString(String baseString, Collection<String> parameter) {
- // Resulting SQL String
- String result = baseString;
-
- // Replace place holders with parameter
- // - Counter variable
- int counter = 1;
- // - Replace all place holders
- for (String par: parameter) {
- result = result.replace("$"+counter, par);
- counter++;
- }
-
- // Return SQL string with resolved parameter
- return result;
- }
-
-
-
- public static void main(String[] args) throws SQLException {
- logger.debug("Test");
-
- ISQLDriver sqlDriver = new SQLDriver("localhost:5432/basyx-sample-vibrations", "postgres", "admin", "jdbc:postgresql://", "org.postgresql.Driver");
-
-
-
- Collection<String> sqlQuery1Params = new LinkedList<>();
- sqlQuery1Params.add(Integer.valueOf(1).toString());
- String sqlQuery1String = getSQLString("SELECT * FROM vibrations.sensors WHERE vibrations.sensors.sensorid='$1'", sqlQuery1Params);
-
- ResultSet result1 = sqlDriver.sqlQuery(sqlQuery1String);
-
- logger.debug(""+result1);
- logger.debug(""+result1.next());
- logger.debug("ID : "+result1.getString("sensorid"));
- logger.debug("NAME : "+result1.getString("sensorname"));
- logger.debug(""+result1.next());
-
-
-
- Collection<String> sqlQuery2Params = new LinkedList<>();
- sqlQuery2Params.add("vibrations.sensors.sensorid");
- sqlQuery2Params.add(Integer.valueOf(1).toString());
- String sqlQuery2String = getSQLString("SELECT * FROM vibrations.sensors WHERE $1='$2'", sqlQuery2Params);
-
- ResultSet result2 = sqlDriver.sqlQuery(sqlQuery2String);
-
- logger.debug(""+result2);
- logger.debug(""+result2.next());
- logger.debug("ID : "+result2.getString("sensorid"));
- logger.debug("NAME : "+result2.getString("sensorname"));
- logger.debug(""+result2.next());
-
-
-
- String call1 = "MapString()";
-
- logger.debug("- "+getOperation(call1));
- logger.debug("- "+getParameter(call1));
-
-
- String call2 = "MapArray(sensorid:int, sensorname:String)";
-
- logger.debug("- "+getOperation(call2));
- logger.debug("- "+getParameter(call2));
-
- }
-}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLSubModelProvider.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLSubModelProvider.java
deleted file mode 100644
index 59697d6..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLSubModelProvider.java
+++ /dev/null
@@ -1,511 +0,0 @@
-package org.eclipse.basyx.components.sqlprovider;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-
-import org.eclipse.basyx.components.provider.BaseConfiguredProvider;
-import org.eclipse.basyx.components.sqlprovider.driver.SQLDriver;
-import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLQuery;
-import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLRunner;
-import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLUpdate;
-import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-
-
-/**
- * Asset administration shell sub model provider that connects to SQL database
- *
- * @author kuhn
- *
- */
-public class SQLSubModelProvider extends BaseConfiguredProvider {
-
- /**
- * Initiates a logger using the current class
- */
- private static final Logger logger = LoggerFactory.getLogger(SQLSubModelProvider.class);
-
- /**
- * SQL database user name
- */
- protected String sqlUser = null;
-
- /**
- * SQL database password
- */
- protected String sqlPass = null;
-
- /**
- * SQL database path
- */
- protected String sqlURL = null;
-
-
-
- /**
- * SQL database driver
- */
- protected String sqlDriver = null;
-
- /**
- * SQL database query prefix
- */
- protected String sqlPrefix = null;
-
- /**
- * An SQL driver instance to connect to the database
- */
- protected SQLDriver driver;
-
-
- /**
- * SQL property connections
- */
- protected Set<String> sqlPropertyConnections = new HashSet<>();
-
-
- /**
- * SQL operation connections
- */
- protected Set<String> sqlOperationConnections = new HashSet<>();
-
-
-
- /**
- * Run queries to access properties via 'get' operation
- */
- protected Map<String, DynamicSQLRunner> propertyGetQueries = new HashMap<>();
-
-
- /**
- * Run SQL update to access properties via 'set' operation
- */
- protected Map<String, DynamicSQLRunner> propertySetQueries = new HashMap<>();
-
-
- /**
- * Run SQL update to access properties via 'create' operation
- */
- protected Map<String, DynamicSQLRunner> propertyCreateQueries = new HashMap<>();
-
-
- /**
- * Run SQL update to access properties via 'delete' operation
- */
- protected Map<String, DynamicSQLRunner> propertyDeleteQueries = new HashMap<>();
-
-
-
- /**
- * SQL operations
- */
- protected Map<String, DynamicSQLRunner> operations = new HashMap<>();
-
-
- /**
- * SQL operations that run as update operations. Not contained operations are query operations.
- */
- protected Set<String> updateOperations = new HashSet<>();
-
-
-
-
- /**
- * Constructor
- */
- public SQLSubModelProvider(Properties cfgValues) {
- // Call base constructor
- super(cfgValues);
-
- // Create sub model
- submodelData = createSubModel(cfgValues);
-
- // Load predefined elements from sub model
- try {
- setModelPropertyValue("", submodelData);
- } catch (Exception e) {
- e.printStackTrace();
- }
-
-
- // Extract SQL properties
- sqlUser = cfgValues.getProperty(
- SQLPreconfiguredSubModelProvider.buildSqlCfgName(SQLPreconfiguredSubModelProvider.DBUSER));
- sqlPass = cfgValues.getProperty(
- SQLPreconfiguredSubModelProvider.buildSqlCfgName(SQLPreconfiguredSubModelProvider.DBPASS));
- sqlURL = cfgValues.getProperty(
- SQLPreconfiguredSubModelProvider.buildSqlCfgName(SQLPreconfiguredSubModelProvider.DBURL));
-
- // Extract SQL driver properties
- sqlDriver = cfgValues.getProperty(
- SQLPreconfiguredSubModelProvider.buildSqlCfgName(SQLPreconfiguredSubModelProvider.DRIVER));
- sqlPrefix = cfgValues.getProperty(
- SQLPreconfiguredSubModelProvider.buildSqlCfgName(SQLPreconfiguredSubModelProvider.PREFIX));
-
- // Create a SQL driver instance
- driver = new SQLDriver(sqlURL, sqlUser, sqlPass, sqlPrefix, sqlDriver);
-
- // Load and parse SQL property and operation connections
- sqlPropertyConnections.addAll(splitString(cfgValues.getProperty(
- SQLPreconfiguredSubModelProvider.buildSqlCfgName(SQLPreconfiguredSubModelProvider.PROPERTIES))));
- sqlOperationConnections.addAll(splitString(cfgValues.getProperty(
- SQLPreconfiguredSubModelProvider.buildSqlCfgName(SQLPreconfiguredSubModelProvider.OPERATIONS))));
-
-
-
- // Add properties
- for (String propertyName: sqlPropertyConnections) createSQLProperty(propertyName, cfgValues);
-
- /*
- // Try to parse parameter
- propertyGetQueries.put(propertyName, createSQLOperation(propertyName+".get", cfgValues));
- propertySetQueries.put(propertyName, createSQLOperation(propertyName+".set", cfgValues));
- propertyCreateQueries.put(propertyName, createSQLOperation(propertyName+".create", cfgValues));
- propertyDeleteQueries.put(propertyName, createSQLOperation(propertyName+".delete", cfgValues));
-
-
- Map<String, Object> mapAccessors = VABLambdaProviderHelper.createMap((Supplier<?>) () -> {
- return propertyMap_val;
- }, (Consumer<Map<String, Object>>) (map) -> {
- propertyMap_val = map;
- }, (BiConsumer<String, Object>) (key, value) -> {
- propertyMap_val.put(key, value);
- }, (Consumer<Object>) (o) -> {
- propertyMap_val.remove(o);
- });
-
- }*/
-
-
- // Add operations
- //for (String operationName: sqlOperationConnections) createSQLOperation(operationName, cfgValues);
- /*{
- // Create operation
- operations.put(operationName, createSQLOperation(operationName, cfgValues));
- // Mark operation as update operation depending on operations/<operationName>_kind property value
- try {
- if (cfgValues.getProperty(operationName+"_kind").trim().equalsIgnoreCase("update")) {
- updateOperations.add(operationName);
- }
- } catch (Exception e) {}
- }*/
- }
-
-
-
- /**
- * Create an SQL property
- */
- protected void createSQLProperty(String name, Properties cfgValues) {
- // Create Map with lambdas that hold SQL operations
- Map<String, Object> value = new HashMap<>();
-
- // Get operation
- {
- // Get parameter
- String queryString = cfgValues.getProperty(name+".get");
- String resultFilterOp = cfgValues.getProperty(name+".get.result");
-
- // Trim query string and resultFilterOp (remove '"' at beginning and end)
- queryString = queryString.substring(1, queryString.length()-1);
- try {resultFilterOp = resultFilterOp.substring(1, resultFilterOp.length()-1);} catch (NullPointerException | StringIndexOutOfBoundsException e) {}
-
- // Create dynamic SQL query
- value.put(VABLambdaHandler.VALUE_GET_SUFFIX, new DynamicSQLQuery(driver, queryString, resultFilterOp));
- }
-
- // Set operation
- {
- // Get parameter
- String updateString = cfgValues.getProperty(name+".set");
-
- // Trim query string and resultFilterOp (remove '"' at beginning and end)
- updateString = updateString.substring(1, updateString.length()-1);
-
- // Create dynamic SQL query
- value.put(VABLambdaHandler.VALUE_SET_SUFFIX, new DynamicSQLUpdate(driver, updateString));
- }
-
- // Delete operation
- {
- // Get parameter
- String updateString = cfgValues.getProperty(name+".delete");
-
- // Trim query string and resultFilterOp (remove '"' at beginning and end)
- updateString = updateString.substring(1, updateString.length()-1);
-
- // Create dynamic SQL query
- value.put(VABLambdaHandler.VALUE_REMOVEKEY_SUFFIX, new DynamicSQLUpdate(driver, updateString));
- value.put(VABLambdaHandler.VALUE_REMOVEOBJ_SUFFIX, new DynamicSQLUpdate(driver, updateString));
- }
-
- // Create operation
- {
- // Get parameter
- String updateString = cfgValues.getProperty(name+".create");
-
- // Trim query string and resultFilterOp (remove '"' at beginning and end)
- updateString = updateString.substring(1, updateString.length()-1);
-
- // Create dynamic SQL query
- value.put(VABLambdaHandler.VALUE_INSERT_SUFFIX, new DynamicSQLUpdate(driver, updateString));
- }
-
-
- logger.debug("Putting SQL:"+name);
- // Add property as map of lambdas
- submodelData.getProperties().put(name, createSubmodelElement(name, value, cfgValues));
- }
-
-
- /**
- * Create a dynamic SQL operation
- */
- protected DynamicSQLRunner createSQLOperation(String propertyName, Properties cfgValues) {/*
- // Check parameter presence
- if (!cfgValues.containsKey(propertyName)) return null;
-
- // Get parameter count and parameter count
- int parameterCount = Integer.parseInt(cfgValues.getProperty(propertyName+".parameter"));
- String queryString = cfgValues.getProperty(propertyName);
- String resultFilterOp = cfgValues.getProperty(propertyName+".result");
-
- // Trim query string and resultFilterOp (remove '"' at beginning and end)
- queryString = queryString.substring(1, queryString.length()-1);
- try {resultFilterOp = resultFilterOp.substring(1, resultFilterOp.length()-1);} catch (NullPointerException | StringIndexOutOfBoundsException e) {}
-
- // Create dynamic SQL query
- DynamicSQLRunner sqlQuery = new DynamicSQLRunner(sqlURL, sqlUser, sqlPass, sqlPrefix, sqlDriver, parameterCount, queryString, resultFilterOp);
-
- // Return created query
- return sqlQuery;*/
-
- return null;
- }
-
-
- /**
- * Split a whitespace delimited string
- */
- protected Collection<String> splitString(String input) {
- // Return value
- HashSet<String> result = new HashSet<>();
-
- // Split string into segments
- for (String inputStr: input.split(" ")) result.add(inputStr.trim());
-
- // Return result
- return result;
- }
-
-
- /**
- * Create a key list for an SQL statement
- *//*
- protected String sqlCreateKeys(Collection<String> keys) {
- // Return value builder
- StringBuilder result = new StringBuilder();
-
- // Process keys
- // - Flag that handles the first key
- boolean isFirst = true;
- // - Process keys
- for (String key: keys) {if (!isFirst) result.append(","); else isFirst=false; result.append(key);}
-
- // Return string
- return result.toString();
- }*/
-
-
- /**
- * Extract a list of values from a map
- *//*
- protected String sqlCreateValues(Collection<Object> values) {
- // Return value builder
- StringBuilder result = new StringBuilder();
-
- // Process keys
- // - Flag that handles the first key
- boolean isFirst = true;
- // - Process keys
- for (Object key: values) {if (!isFirst) result.append(","); else isFirst=false; result.append("'"+key+"'");}
-
- // Return string
- return result.toString();
- }*/
-
-
-
- /**
- * Create (insert) a value into the SQL table
- *//*
- @Override @SuppressWarnings("unchecked")
- public void createValue(String propertyName, Object arg1) throws Exception {
- // Set query
- DynamicSQLRunner query = propertyCreateQueries.get(propertyName);
-
- // Null pointer check
- if (query == null) return;
-
- // Create parameter array
- Object[] parameter = new Object[2];
- parameter[0] = sqlCreateKeys(((Map<String, Object>) arg1).keySet());
- parameter[1] = sqlCreateValues(((Map<String, Object>) arg1).values());
-
- // Execute query and return result
- query.runUpdate(parameter);
- }*/
-
-
-
- /**
- * Delete a value from the SQL table
- *//*
- @Override
- public void deleteValue(String arg0) throws Exception {
- // This is not implemented
- }*/
-
-
-
- /**
- * Delete a value from the SQL table
- *//*
- @Override @SuppressWarnings("unchecked")
- public void deleteValue(String propertyName, Object arg1) throws Exception {
- // Set query
- DynamicSQLRunner query = propertyDeleteQueries.get(propertyName);
-
- // Null pointer check
- if (query == null) return;
-
- // Cast argument to collection
- Collection<Object> parameterList = (Collection<Object>) arg1;
-
- // Create parameter array
- Object[] parameter = new Object[parameterList.size()];
- // - Copy parameter
- int counter = 0; for (Object par: parameterList) parameter[counter++] = par;
-
- // Execute query and return result
- query.runUpdate(parameter);
- }*/
-
-
-/*
- @Override
- public Map<String, IElementReference> getContainedElements(String arg0) {
- // TODO Auto-generated method stub
- return null;
- }
-
-
- @Override
- public String getElementScope(String arg0) {
- logger.debug("GetScope:"+arg0);
- // TODO Auto-generated method stub
- return null;
- }
-*/
-
-
- /**
- * Query the SQL database
- *//*
- @Override
- public Object getModelPropertyValue(String propertyName) {
- // Get query
- DynamicSQLRunner query = propertyGetQueries.get(propertyName);
-
- // Null pointer check
- if (query == null) return null;
-
- // Execute query and return result
- return query.runQuery();
- }*/
-
-
-
- /**
- * Invoke operation with given parameter list
- *//*
- @Override
- public Object invokeOperation(String propertyName, Object[] parameter) throws Exception {
- // Set query
- DynamicSQLRunner query = operations.get(propertyName);
-
- // Null pointer check
- if (query == null) return null;
-
- // Execute query and return result
- if (updateOperations.contains(propertyName)) {
- query.runUpdate(parameter);
- return null;
- } else {
- return query.runQuery(parameter);
- }
- }*/
-
-
-
- /**
- * Invoke set operation with given parameter
- *//*
- @Override @SuppressWarnings("unchecked")
- public void setModelPropertyValue(String propertyName, Object arg1) throws Exception {
- // Set query
- DynamicSQLRunner query = propertySetQueries.get(propertyName);
-
- // Null pointer check
- if (query == null) return;
-
- logger.debug("LENC:"+arg1);
-
- // Create parameter array
- Object[] parameter = null;
- // - Process collections
- if (arg1 instanceof Collection) {
- // Cast to collection
- Collection<Object> parameterList = (Collection<Object>) arg1;
-
- // Create parameter array and copy parameter
- parameter = new Object[parameterList.size()];
- int counter = 0; for (Object par: parameterList) parameter[counter++] = par;
- } else {
- // Create parameter array and copy parameter
- parameter = new Object[1];
- parameter[0] = arg1;
- }
-
-
- // Execute query and return result
- query.runUpdate(parameter);
- }*/
-
-
-
- /**
- * Invoke set operation with given parameter list
- *//*
- @Override
- public void setModelPropertyValue(String propertyName, Object... parameter) throws Exception {
- // Set query
- DynamicSQLRunner query = propertySetQueries.get(propertyName);
-
- // Null pointer check
- if (query == null) return;
-
- logger.debug("LEN:"+parameter.length);
- logger.debug("LEN-0:"+parameter[0]);
-
- // Execute query and return result
- query.runUpdate(parameter);
- }*/
-}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/driver/ISQLDriver.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/driver/ISQLDriver.java
deleted file mode 100644
index 37095d0..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/driver/ISQLDriver.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.eclipse.basyx.components.sqlprovider.driver;
-
-import java.sql.ResultSet;
-
-
-
-/**
- * Database access interface
- *
- * @author kuhn
- *
- */
-public interface ISQLDriver {
-
-
- /**
- * Execute a SQL query
- */
- public ResultSet sqlQuery(String queryString);
-
-
- /**
- * Execute a SQL update
- */
- public void sqlUpdate(String updateString);
-}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/driver/SQLDriver.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/driver/SQLDriver.java
deleted file mode 100644
index 94931ee..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/driver/SQLDriver.java
+++ /dev/null
@@ -1,221 +0,0 @@
-package org.eclipse.basyx.components.sqlprovider.driver;
-
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-
-import javax.sql.rowset.CachedRowSet;
-import javax.sql.rowset.RowSetFactory;
-import javax.sql.rowset.RowSetProvider;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.zaxxer.hikari.HikariDataSource;
-
-
-/**
- * Access SQL database
- *
- * @author kuhn
- *
- */
-public class SQLDriver implements ISQLDriver {
- private static Logger logger = LoggerFactory.getLogger(SQLDriver.class);
-
-
- /**
- * Store user name
- */
- protected String userName = null;
-
- /**
- * Store password
- */
- protected String password = null;
-
- /**
- * Store path to database server
- */
- protected String dbPath = null;
-
-
- /**
- * Store query prefix
- */
- protected String queryPrefix = null;
-
-
- /**
- * Store driver class (with package name)
- */
- protected String qualDriverClass = null;
-
-
- /**
- * JDBC connection
- */
- protected Connection connect = null;
-
- /**
- * Data source
- */
- protected HikariDataSource ds = null;
-
-
-
-
- /**
- * Create a SQL driver and a SQL connection
- */
- public SQLDriver(String path, String user, String pass, String qryPfx, String qDrvCls) {
- // Store parameter
- userName = user;
- password = pass;
- dbPath = path;
- queryPrefix = qryPfx;
- qualDriverClass = qDrvCls;
-
- // This will load the MySQL driver, each DB has its own driver
- try {
- Class.forName(qualDriverClass);
- } catch (ClassNotFoundException e) {
- logger.error("Could not init SQLDriver", e);
- }
- }
-
-
-
- /**
- * Execute a SQL query
- */
- public CachedRowSet sqlQuery(String queryString) {
- // Store SQL statement, flag that indicates whether the connection was created by this
- // operation (and needs to be closed), and result
- Statement statement = null;
- CachedRowSet rowSet = null;
-
-
- // Access database
- try {
- // Open a connection with data source
- openConnection();
-
- // Statements allow to issue SQL queries to the database
- statement = connect.createStatement();
-
- // ResultSet gets the result of the SQL query
- ResultSet resultSet = statement.executeQuery(queryString);
-
- // Convert DB data to memory cache
- rowSet = getCachedRowSet(resultSet);
-
- // Close connection with data source
- closeConnection();
- } catch (SQLException e) {
- logger.error("sqlQuery failed", e);
- }
-
- // Return result of query
- return rowSet;
- }
-
-
-
- /**
- * Execute a SQL update
- */
- public void sqlUpdate(String updateString) {
- // Store SQL statement
- Statement statement = null;
-
- // Access database
- try {
- // Open a connection with data source
- openConnection();
-
- // Statements allow to issue SQL queries to the database
- statement = connect.createStatement();
-
- // ResultSet gets the result of the SQL query
- statement.executeUpdate(updateString);
-
- // Close connection with data source
- closeConnection();
- } catch (SQLException e) {
- logger.error("sqlUpdate failed", e);
- }
- }
-
-
-
- /**
- * Open connection
- */
- public void openConnection() {
- // Access database
- try {
- // Open connection
- if (connect == null) {
- openDataSource();
- connect = ds.getConnection();
- }
- } catch (SQLException e) {
- logger.error("Failed to open sql driver connection", e);
- }
- }
-
-
- /**
- * Close connection
- */
- public void closeConnection() {
- // Access database
- try {
- // Close connection
- if (connect != null) {
- connect.close();
- connect = null;
- }
- } catch (SQLException e) {
- logger.error("Failed to close sql driver connection", e);
- }
- }
-
-
- /**
- * Get connection
- */
- public Connection getConnection() {
- return connect;
- }
-
-
- /**
- * Indicate if driver has open connection
- */
- public boolean hasOpenConnection() {
- return (connect == null);
- }
-
- /**
- * Open Data source
- */
- private void openDataSource() {
- if (ds == null) {
- ds = new HikariDataSource();
- ds.setJdbcUrl(queryPrefix+dbPath);
- ds.setUsername(userName);
- ds.setPassword(password);
- }
- }
-
- private CachedRowSet getCachedRowSet(ResultSet resultSet) throws SQLException {
- RowSetFactory factory = RowSetProvider.newFactory();
- CachedRowSet rowset = factory.createCachedRowSet();
- rowset.populate(resultSet);
- return rowset;
- }
-}
-
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLOperation.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLOperation.java
deleted file mode 100644
index 9b8449a..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLOperation.java
+++ /dev/null
@@ -1,111 +0,0 @@
-package org.eclipse.basyx.components.sqlprovider.query;
-
-import java.lang.reflect.InvocationTargetException;
-import java.sql.ResultSet;
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.function.Function;
-
-import org.eclipse.basyx.components.sqlprovider.driver.ISQLDriver;
-import org.eclipse.basyx.components.tools.propertyfile.opdef.OperationDefinition;
-import org.eclipse.basyx.components.tools.propertyfile.opdef.Parameter;
-import org.eclipse.basyx.components.tools.propertyfile.opdef.ResultFilter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-
-/**
- * Implement a generic SQL query
- *
- * @author kuhn
- *
- */
-public class DynamicSQLOperation extends DynamicSQLRunner implements Function<Object[], Object> {
- private static Logger logger = LoggerFactory.getLogger(DynamicSQLOperation.class);
-
-
- /**
- * Store SQL query string with place holders ($x)
- */
- protected String sqlQueryString = null;
-
-
- /**
- * Store SQL result filter
- */
- protected String resultFilterString = null;
-
-
-
-
-
- /**
- * Constructor
- */
- public DynamicSQLOperation(ISQLDriver driver, String query, String sqlResultFilter) {
- // Invoke base constructor
- super(driver);
-
- // Store parameter count and SQL query string
- sqlQueryString = query;
- resultFilterString = sqlResultFilter;
- }
-
-
- /**
- * Constructor
- */
- public DynamicSQLOperation(String path, String user, String pass, String qryPfx, String qDrvCls, String query, String sqlResultFilter) {
- // Invoke base constructor
- super(path, user, pass, qryPfx, qDrvCls);
-
- // Store parameter count and SQL query string
- sqlQueryString = query;
- resultFilterString = sqlResultFilter;
- }
-
-
- /**
- * Execute query with given parameter
- */
- @Override
- public Object apply(Object[] parameter) {
- // Create list of query parameter
- Collection<String> sqlQueryParameter = new LinkedList<>();
- // - Add parameter
- for (Object par: parameter) sqlQueryParameter.add(par.toString());
-
- // Apply parameter and create SQL query string
- String sqlQuery = OperationDefinition.getSQLString(sqlQueryString, sqlQueryParameter);
-
- logger.debug("Running SQL query:" + sqlQuery);
-
- // Execute SQL query
- ResultSet sqlResult = sqlDriver.sqlQuery(sqlQuery);
-
- // Extract input parameter definition
- Collection<Parameter> resultParameter = OperationDefinition.getParameter(resultFilterString);
-
- // Process result
- try {
- // Create inner parameter array for call
- Object[] callParameterInner = new Object[resultParameter.size()];
- int i=0; for (String column: getColumnNames(resultParameter)) callParameterInner[i++]=column;
-
- // Create parameter array for call
- Object[] callParameter = new Object[2];
- callParameter[0] = sqlResult;
- callParameter[1] = callParameterInner;
-
- // Invoke result filter operation using static invocation
- return ResultFilter.class.getMethod(OperationDefinition.getOperation(resultFilterString), getMethodParameter(resultParameter)).invoke(null, callParameter);
- } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
- logger.error("Could not invoke dynamic sql operation", e);
- }
-
- // No result
- return null;
- }
-}
-
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLQuery.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLQuery.java
deleted file mode 100644
index 6a5befe..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLQuery.java
+++ /dev/null
@@ -1,153 +0,0 @@
-package org.eclipse.basyx.components.sqlprovider.query;
-
-import java.lang.reflect.InvocationTargetException;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Collection;
-import java.util.Map;
-import java.util.function.Supplier;
-
-import org.eclipse.basyx.components.sqlprovider.driver.ISQLDriver;
-import org.eclipse.basyx.components.tools.propertyfile.opdef.OperationDefinition;
-import org.eclipse.basyx.components.tools.propertyfile.opdef.Parameter;
-import org.eclipse.basyx.components.tools.propertyfile.opdef.ResultFilter;
-
-
-
-/**
- * Implement a generic SQL query
- *
- * @author kuhn
- *
- */
-public class DynamicSQLQuery extends DynamicSQLRunner implements Supplier<Object> {
-
-
- /**
- * Store SQL query string with place holders ($x)
- */
- protected String sqlQueryString = null;
-
-
- /**
- * Store SQL result filter
- */
- protected String resultFilterString = null;
-
-
-
-
-
- /**
- * Constructor that accepts a driver
- */
- public DynamicSQLQuery(ISQLDriver driver, String query, String sqlResultFilter) {
- // Invoke base constructor
- super(driver);
-
- // Store SQL query string and result filter
- sqlQueryString = query;
- resultFilterString = sqlResultFilter;
- }
-
-
- /**
- * Constructor
- */
- public DynamicSQLQuery(String path, String user, String pass, String qryPfx, String qDrvCls, String query, String sqlResultFilter) {
- // Invoke base constructor
- super(path, user, pass, qryPfx, qDrvCls);
-
- // Store SQL query string and result filter
- sqlQueryString = query;
- resultFilterString = sqlResultFilter;
- }
-
-
- /**
- * Execute query without parameter
- */
- @Override
- public Object get() {
- // Execute SQL query
- ResultSet sqlResult = sqlDriver.sqlQuery(sqlQueryString);
-
- // Process result
- return processResult(sqlResult);
- }
-
-
- /**
- * Execute query without parameter, do not post process result
- */
- public ResultSet getRaw() {
- // Execute SQL query
- return sqlDriver.sqlQuery(sqlQueryString);
- }
-
-
- /**
- * Execute query without parameter
- */
- public Object get(Map<String,Object> param) {
- // Apply parameter and create SQL query string
- String sqlQuery = OperationDefinition.getSQLString(sqlQueryString, param);
-
- // Execute SQL query
- ResultSet sqlResult = sqlDriver.sqlQuery(sqlQuery);
-
- // Process result
- return processResult(sqlResult);
- }
-
-
- /**
- * Execute query without parameter, do not post process result
- */
- public ResultSet getRaw(Map<String,Object> param) {
- // Apply parameter and create SQL query string
- String sqlQuery = OperationDefinition.getSQLString(sqlQueryString, param);
-
- // Execute SQL query
- return sqlDriver.sqlQuery(sqlQuery);
- }
-
-
-
- /**
- * Process result parameter
- */
- protected Object processResult(ResultSet sqlResult) {
- // Extract input parameter definition
- Collection<Parameter> parameter = OperationDefinition.getParameter(resultFilterString);
-
- // Process result
- try {
- // Create inner parameter array for call
- Object[] callParameterInner = new Object[parameter.size()];
- int i=0; for (String column: getColumnNames(parameter)) callParameterInner[i++]=column;
-
- // Create parameter array for call
- Object[] callParameter = new Object[2];
- callParameter[0] = sqlResult;
- callParameter[1] = callParameterInner;
-
- // Invoke result filter operation using static invocation
- Object result = ResultFilter.class.getMethod(OperationDefinition.getOperation(resultFilterString), getMethodParameter(parameter)).invoke(null, callParameter);
-
- // Close result set
- sqlResult.close();
-
- // Return result
- return result;
-
- } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | SQLException e) {
- // Print exception to console
- e.printStackTrace();
- }
-
- // No result
- return null;
- }
-}
-
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLRunner.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLRunner.java
deleted file mode 100644
index d3a3a88..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLRunner.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package org.eclipse.basyx.components.sqlprovider.query;
-
-import java.sql.ResultSet;
-import java.util.Collection;
-import java.util.LinkedList;
-import org.eclipse.basyx.components.sqlprovider.driver.ISQLDriver;
-import org.eclipse.basyx.components.sqlprovider.driver.SQLDriver;
-import org.eclipse.basyx.components.tools.propertyfile.opdef.Parameter;
-
-
-
-
-/**
- * SQL query operation
- *
- * @author kuhn
- *
- */
-public class DynamicSQLRunner {
-
-
- /**
- * Store SQL driver instance
- */
- protected ISQLDriver sqlDriver = null;
-
-
-
-
-
- /**
- * Constructor that accepts a driver
- */
- public DynamicSQLRunner(ISQLDriver driver) {
- // Store SQL driver instance
- sqlDriver = driver;
- }
-
-
- /**
- * Constructor
- */
- public DynamicSQLRunner(String path, String user, String pass, String qryPfx, String qDrvCls) {
- // Create SQL driver instance
- sqlDriver = new SQLDriver(path, user, pass, qryPfx, qDrvCls);
- }
-
-
-
- /**
- * Get method parameter definition
- */
- protected Class<?>[] getMethodParameter(Collection<Parameter> parameter) {
- // Store operation signature
- Class<?>[] result = new Class<?>[2];
-
- // Operation signature is ResultSet and a list of string parameter that define column names
- result[0] = ResultSet.class;
- result[1] = Object[].class;
-
- // Return signature
- return result;
- }
-
-
- /**
- * Get column names
- */
- protected Collection<String> getColumnNames(Collection<Parameter> parameter) {
- // Return value
- Collection<String> result = new LinkedList<>();
-
- for (Parameter par: parameter) result.add(par.getName());
-
- return result;
- }
-}
-
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLUpdate.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLUpdate.java
deleted file mode 100644
index 773824b..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLUpdate.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package org.eclipse.basyx.components.sqlprovider.query;
-
-import java.util.Map;
-import java.util.function.Consumer;
-
-import org.eclipse.basyx.components.sqlprovider.driver.ISQLDriver;
-import org.eclipse.basyx.components.tools.propertyfile.opdef.OperationDefinition;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-
-/**
- * Implement a generic SQL query
- *
- * @author kuhn
- *
- */
-public class DynamicSQLUpdate extends DynamicSQLRunner implements Consumer<Map<String,Object>> {
- private static Logger logger = LoggerFactory.getLogger(DynamicSQLUpdate.class);
-
- /**
- * Store SQL query string with place holders ($x)
- */
- protected String sqlQueryString = null;
-
-
-
-
- /**
- * Constructor
- */
- public DynamicSQLUpdate(ISQLDriver driver, String query) {
- // Invoke base constructor
- super(driver);
-
- // Store parameter count and SQL query string
- sqlQueryString = query;
- }
-
-
- /**
- * Constructor
- */
- public DynamicSQLUpdate(String path, String user, String pass, String qryPfx, String qDrvCls, String query) {
- // Invoke base constructor
- super(path, user, pass, qryPfx, qDrvCls);
-
- // Store parameter count and SQL query string
- sqlQueryString = query;
- }
-
-
-
- /**
- * Execute update with given parameter
- */
- @Override
- public void accept(Map<String,Object> parameter) {
- logger.debug("(Parameters) Running SQL update: " + parameter);
-
- // Apply parameter and create SQL query string
- String sqlQuery = OperationDefinition.getSQLString(sqlQueryString, parameter);
-
- logger.debug("(Query) Running SQL update:" + sqlQuery);
-
- // Execute SQL query
- sqlDriver.sqlUpdate(sqlQuery);
- }
-}
-
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/tools/propertyfile/opdef/OperationDefinition.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/tools/propertyfile/opdef/OperationDefinition.java
index 659be20..4db6996 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/tools/propertyfile/opdef/OperationDefinition.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/tools/propertyfile/opdef/OperationDefinition.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.tools.propertyfile.opdef;
import java.util.Collection;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/tools/propertyfile/opdef/Parameter.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/tools/propertyfile/opdef/Parameter.java
index 197aba9..5b18e59 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/tools/propertyfile/opdef/Parameter.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/tools/propertyfile/opdef/Parameter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.tools.propertyfile.opdef;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/tools/propertyfile/opdef/ResultFilter.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/tools/propertyfile/opdef/ResultFilter.java
index f7313ff..38d1851 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/tools/propertyfile/opdef/ResultFilter.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/tools/propertyfile/opdef/ResultFilter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.tools.propertyfile.opdef;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/xml/XMLAASBundleFactory.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/xml/XMLAASBundleFactory.java
index 3aac43f..751dea4 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/xml/XMLAASBundleFactory.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/xml/XMLAASBundleFactory.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.components.xml;
import java.io.IOException;
@@ -15,11 +24,12 @@
import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
import org.eclipse.basyx.submodel.metamodel.api.qualifier.IIdentifiable;
import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
import org.eclipse.basyx.support.bundle.AASBundle;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;
@@ -38,16 +48,6 @@
private String content;
/**
- * Internal exception used to indicate that the resource was not found
- *
- * @author schnicke
- *
- */
- private class ResourceNotFoundException extends Exception {
- private static final long serialVersionUID = -1247012719907370743L;
- }
-
- /**
*
* @param xmlContent
* the content of the XML
@@ -72,7 +72,7 @@
XMLToMetamodelConverter converter = new XMLToMetamodelConverter(content);
List<IAssetAdministrationShell> shells = converter.parseAAS();
- List<ISubModel> submodels = converter.parseSubmodels();
+ List<ISubmodel> submodels = converter.parseSubmodels();
List<IAsset> assets = converter.parseAssets();
@@ -89,7 +89,7 @@
}
// Retrieve submodels
- Set<ISubModel> currentSM = retrieveSubmodelsForAAS(submodels, shell);
+ Set<ISubmodel> currentSM = retrieveSubmodelsForAAS(submodels, shell);
bundles.add(new AASBundle(shell, currentSM));
}
@@ -103,12 +103,12 @@
* @param shell
* @return
*/
- private Set<ISubModel> retrieveSubmodelsForAAS(List<ISubModel> submodels, IAssetAdministrationShell shell) {
- Set<ISubModel> currentSM = new HashSet<>();
+ private Set<ISubmodel> retrieveSubmodelsForAAS(List<ISubmodel> submodels, IAssetAdministrationShell shell) {
+ Set<ISubmodel> currentSM = new HashSet<>();
for (IReference submodelRef : shell.getSubmodelReferences()) {
try {
- ISubModel sm = getByReference(submodelRef, submodels);
+ ISubmodel sm = getByReference(submodelRef, submodels);
currentSM.add(sm);
logger.debug("Found Submodel " + sm.getIdShort() + " for AAS " + shell.getIdShort());
} catch (ResourceNotFoundException e) {
@@ -129,16 +129,23 @@
* @throws ResourceNotFoundException
*/
private <T extends IIdentifiable> T getByReference(IReference ref, List<T> submodels) throws ResourceNotFoundException {
+ IKey lastKey = null;
// It may be that only one key fits to the Submodel contained in the XML
for (IKey key : ref.getKeys()) {
+ lastKey = key;
// There will only be a single submodel matching the identification at max
Optional<T> match = submodels.stream().filter(s -> s.getIdentification().getId().equals(key.getValue())).findFirst();
if (match.isPresent()) {
return match.get();
}
}
+ if (lastKey == null) {
+ throw new ResourceNotFoundException("Could not resolve reference without keys");
+ } else {
+ throw new ResourceNotFoundException("Could not resolve reference with last key " + lastKey.getValue());
+ }
// If no identifiable is found, indicate it by throwing an exception
- throw new ResourceNotFoundException();
+
}
}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ControlComponent.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ControlComponent.java
index c005711..4458a3c 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ControlComponent.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ControlComponent.java
@@ -1,10 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.models.controlcomponent;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
-import java.util.List;
import java.util.Map;
import java.util.function.Function;
@@ -19,48 +27,32 @@
public abstract class ControlComponent extends HashMap<String, Object> {
// Miscellaneous String constants
- private static final String STATUS = "status";
- private static final String ORDER_LIST = "orderList";
- private static final String OCCUPIERID_LOCAL = "LOCAL";
- private static final String OPERATIONS = "operations";
- private static final String SERVICE = "service";
+ public static final String STATUS = "STATUS";
+ public static final String OPERATIONS = "OPERATIONS";
// String constants for operations
- public static final String OPERATION_CLEAR = "clear";
- public static final String OPERATION_STOP = "stop";
- public static final String OPERATION_ABORT = "abort";
- public static final String OPERATION_UNSUSPEND = "unsuspend";
- public static final String OPERATION_SUSPEND = "suspend";
- public static final String OPERATION_UNHOLD = "unhold";
- public static final String OPERATION_HOLD = "hold";
- public static final String OPERATION_RESET = "reset";
- public static final String OPERATION_START = "start";
- public static final String OPERATION_SIMULATION = "simulation";
- public static final String OPERATION_MANUAL = "manual";
- public static final String OPERATION_AUTO = "auto";
- public static final String OPERATION_SEMIAUTO = "semiauto";
- public static final String OPERATION_PRIORITY = "priority";
- public static final String OPERATION_OCCUPY = "occupy";
- public static final String OPERATION_FREE = "free";
- public static final String OPERATION_BSTATE = "bstate";
+ public static final String OPERATION_CLEAR = "CLEAR";
+ public static final String OPERATION_STOP = "STOP";
+ public static final String OPERATION_ABORT = "ABORT";
+ public static final String OPERATION_RESET = "RESET";
+ public static final String OPERATION_START = "START";
+ public static final String OPERATION_MANUAL = "MANUAL";
+ public static final String OPERATION_AUTO = "AUTO";
+ public static final String OPERATION_PRIORITY = "PRIO";
+ public static final String OPERATION_OCCUPY = "OCCUPY";
+ public static final String OPERATION_FREE = "FREE";
// String constants for setting execution state
public static final String CMD = "cmd";
- // String constants for overwrite
- private static final String LOCAL_OVERWRITE_FREE = "localOverwriteFree";
- private static final String LOCAL_OVERWRITE = "localOverwrite";
-
// String constants for status
- private static final String PREV_ERROR = "prevError";
- private static final String ERROR_STATE = "errorState";
- private static final String WORK_STATE = "workState";
- private static final String OP_MODE = "opMode";
- private static final String EX_STATE = "exState";
- private static final String EX_MODE = "exMode";
- private static final String LAST_OCCUPIER = "lastOccupier";
- private static final String OCCUPIER = "occupier";
- private static final String OCCUPATION_STATE = "occupationState";
+ public static final String ERROR_STATE = "ER";
+ public static final String WORK_STATE = "WORKST";
+ public static final String OP_MODE = "OPMODE";
+ public static final String EX_STATE = "EXST";
+ public static final String EX_MODE = "EXMODE";
+ public static final String OCCUPIER = "OCCUPIER";
+ public static final String OCCUPATION_STATE = "OCCST";
/**
* The status map implements the service/ substructure of the control component structure. It also
@@ -84,13 +76,11 @@
// Populate control component "status" sub structure
put(OCCUPATION_STATE, OccupationState.FREE.getValue()); // Occupation state: FREE
put(OCCUPIER, ""); // Occupier: none
- put(LAST_OCCUPIER, ""); // Last occupier: none
put(EX_MODE, ExecutionMode.AUTO.getValue()); // Execution mode: AUTO
put(EX_STATE, ExecutionState.IDLE.getValue()); // Execution state: IDLE
put(OP_MODE, ""); // Component specific operation mode (e.g. active service)
put(WORK_STATE, ""); // Component specific work state
put(ERROR_STATE, ""); // Component error state
- put(PREV_ERROR, ""); // Component previous error
}
@@ -119,13 +109,11 @@
switch(key) {
case OCCUPATION_STATE: for (ControlComponentChangeListener listener: listeners) listener.onNewOccupationState(OccupationState.byValue((int) value)); break;
case OCCUPIER: for (ControlComponentChangeListener listener: listeners) listener.onNewOccupier(value.toString()); break;
- case LAST_OCCUPIER: for (ControlComponentChangeListener listener: listeners) listener.onLastOccupier(value.toString()); break;
case EX_MODE: for (ControlComponentChangeListener listener: listeners) listener.onChangedExecutionMode(ExecutionMode.byValue((int) value)); break;
case EX_STATE: for (ControlComponentChangeListener listener: listeners) listener.onChangedExecutionState(ExecutionState.byValue(value.toString())); break;
case OP_MODE: for (ControlComponentChangeListener listener: listeners) listener.onChangedOperationMode(value.toString()); break;
case WORK_STATE: for (ControlComponentChangeListener listener: listeners) listener.onChangedWorkState(value.toString()); break;
case ERROR_STATE: for (ControlComponentChangeListener listener: listeners) listener.onChangedErrorState(value.toString()); break;
- case PREV_ERROR: for (ControlComponentChangeListener listener: listeners) listener.onChangedPrevError(value.toString()); break;
}
// Return result
@@ -145,7 +133,7 @@
/**
* Operations map
*/
- protected Map<String, Object> operations = new HashMap<String, Object>();
+ protected Map<String, Function<?, ?>> operations = new HashMap<>();
/**
@@ -173,8 +161,6 @@
*/
public ControlComponent() {
// Add control component output signals to map
- // - Order list
- put(ORDER_LIST, new LinkedList<String>());
// - "status" sub structure
status = new StatusMap();
put(STATUS, status);
@@ -182,85 +168,51 @@
// Input signals
// - Command / stores last command
put(CMD, ""); // No command
- put(LOCAL_OVERWRITE, ""); // Local override signal
- put(LOCAL_OVERWRITE_FREE, ""); // Local override release signal
// Operations
// - Add "operations" sub structure
put(OPERATIONS, operations);
- // - Service operations
- Map<String, Function<?, ?>> serviceOperations = new HashMap<>();
// - Populate service operations
- serviceOperations.put(OPERATION_FREE, (Function<Object[], Void> & Serializable) (v) -> {
+ operations.put(OPERATION_FREE, (Function<Object[], Void> & Serializable) (v) -> {
freeControlComponent((String) v[0]);
return null;
});
- serviceOperations.put(OPERATION_OCCUPY, (Function<Object[], Void> & Serializable) (v) -> {
+ operations.put(OPERATION_OCCUPY, (Function<Object[], Void> & Serializable) (v) -> {
occupyControlComponent((String) v[0]);
return null;
});
- serviceOperations.put(OPERATION_PRIORITY, (Function<Object[], Void> & Serializable) (v) -> {
+ operations.put(OPERATION_PRIORITY, (Function<Object[], Void> & Serializable) (v) -> {
priorityOccupation((String) v[0]);
return null;
});
- serviceOperations.put(OPERATION_AUTO, (Function<Object, Void> & Serializable) (v) -> {
+ operations.put(OPERATION_AUTO, (Function<Object, Void> & Serializable) (v) -> {
this.setExecutionMode(ExecutionMode.AUTO);
return null;
});
- serviceOperations.put(OPERATION_SEMIAUTO, (Function<Object, Void> & Serializable) (v) -> {
- this.setExecutionMode(ExecutionMode.SEMIAUTO);
- return null;
- });
- serviceOperations.put(OPERATION_MANUAL, (Function<Object, Void> & Serializable) (v) -> {
+ operations.put(OPERATION_MANUAL, (Function<Object, Void> & Serializable) (v) -> {
this.setExecutionMode(ExecutionMode.MANUAL);
return null;
});
- serviceOperations.put(OPERATION_SIMULATION, (Function<Object, Void> & Serializable) (v) -> {
- this.setExecutionMode(ExecutionMode.SIMULATION);
- return null;
- });
- serviceOperations.put(OPERATION_START, (Function<Object, Void> & Serializable) (v) -> {
+ operations.put(OPERATION_START, (Function<Object, Void> & Serializable) (v) -> {
this.changeExecutionState(ExecutionOrder.START.getValue());
return null;
});
- serviceOperations.put(OPERATION_RESET, (Function<Object, Void> & Serializable) (v) -> {
+ operations.put(OPERATION_RESET, (Function<Object, Void> & Serializable) (v) -> {
this.changeExecutionState(ExecutionOrder.RESET.getValue());
return null;
});
- serviceOperations.put(OPERATION_HOLD, (Function<Object, Void> & Serializable) (v) -> {
- this.changeExecutionState(ExecutionOrder.HOLD.getValue());
- return null;
- });
- serviceOperations.put(OPERATION_UNHOLD, (Function<Object, Void> & Serializable) (v) -> {
- this.changeExecutionState(ExecutionOrder.UNHOLD.getValue());
- return null;
- });
- serviceOperations.put(OPERATION_SUSPEND, (Function<Object, Void> & Serializable) (v) -> {
- this.changeExecutionState(ExecutionOrder.SUSPEND.getValue());
- return null;
- });
- serviceOperations.put(OPERATION_UNSUSPEND, (Function<Object, Void> & Serializable) (v) -> {
- this.changeExecutionState(ExecutionOrder.UNSUSPEND.getValue());
- return null;
- });
- serviceOperations.put(OPERATION_ABORT, (Function<Object, Void> & Serializable) (v) -> {
+ operations.put(OPERATION_ABORT, (Function<Object, Void> & Serializable) (v) -> {
this.changeExecutionState(ExecutionOrder.ABORT.getValue());
return null;
});
- serviceOperations.put(OPERATION_STOP, (Function<Object, Void> & Serializable) (v) -> {
+ operations.put(OPERATION_STOP, (Function<Object, Void> & Serializable) (v) -> {
this.changeExecutionState(ExecutionOrder.STOP.getValue());
return null;
});
- serviceOperations.put(OPERATION_CLEAR, (Function<Object, Void> & Serializable) (v) -> {
+ operations.put(OPERATION_CLEAR, (Function<Object, Void> & Serializable) (v) -> {
this.changeExecutionState(ExecutionOrder.CLEAR.getValue());
return null;
});
- serviceOperations.put(OPERATION_BSTATE, (Function<Object, Void> & Serializable) (v) -> {
- this.setOperationMode("BSTATE");
- return null;
- });
- // - Add service operations to sub structure
- operations.put(SERVICE, serviceOperations);
}
@@ -297,17 +249,7 @@
public void removeControlComponentChangeListener(ControlComponentChangeListener listener) {
listeners.remove(listener);
}
-
- /**
- * Get "operations" map
- */
- @SuppressWarnings("unchecked")
- protected Map<String, Function<?, ?>> getServiceOperationMap() {
- return (Map<String, Function<?, ?>>) operations.get(SERVICE);
- }
-
-
/**
* Update an value
@@ -325,8 +267,6 @@
// Process variable changes
switch(key) {
case CMD: changeExecutionState(value.toString()); break;
- case LOCAL_OVERWRITE: invokeLocalOverwrite(); break;
- case LOCAL_OVERWRITE_FREE: clearLocalOverwrite(); break;
}
// Return result
@@ -341,8 +281,6 @@
// Update occupier if sender is occupier
if (senderId.equals(this.getOccupierID())) {
// Get occupier from last occupier and reset last occupier
- this.setOccupierID(this.getLastOccupierID());
- this.setLastOccupierID("");
// Component is free if last occupier is empty, occupied otherwise
if (this.getOccupierID().isEmpty()) this.setOccupationState(OccupationState.FREE); else this.setOccupationState(OccupationState.OCCUPIED);
}
@@ -364,40 +302,11 @@
private void priorityOccupation(String occupier) {
// Occupy component if component is FREE or OCCUPIED
if ((this.getOccupationState().equals(OccupationState.FREE)) || (this.getOccupationState().equals(OccupationState.OCCUPIED))) {
- this.setLastOccupierID(this.getOccupierID());
this.setOccupierID(occupier);
this.setOccupationState(OccupationState.PRIORITY);
}
}
-
-
- /**
- * Helper method - local overwrite of OCCUPIED or PRIORITY occupation
- */
- private void invokeLocalOverwrite() {
- // Store current occupier because we need to restore it later
- savedOccupierID = this.getOccupierID();
- // Enter local overwrite state
- this.setOccupationState(OccupationState.LOCAL);
- this.setOccupierID(OCCUPIERID_LOCAL);
- }
-
-
- /**
- * Helper method - clear local occupier overwrite status
- */
- private void clearLocalOverwrite() {
- // Restore current occupier ID
- this.setOccupierID(savedOccupierID);
-
- // Restore occupier state based on variables
- if (this.getOccupierID().isEmpty()) this.setOccupationState(OccupationState.FREE); else
- if (this.getLastOccupierID().isEmpty()) this.setOccupationState(OccupationState.OCCUPIED); else
- this.setOccupationState(OccupationState.PRIORITY);
- }
-
-
/**
* Change execution state based on execution order
*/
@@ -546,37 +455,6 @@
throw new RuntimeException("Unexpected state complete order in state "+getExecutionState());
}
}
-
-
- /**
- * Get order list
- */
- @SuppressWarnings("unchecked")
- public List<String> getOrderList() {
- // Get map entry
- return (List<String>) get(ORDER_LIST);
- }
-
-
- /**
- * Add order to order list
- */
- @SuppressWarnings("unchecked")
- public void addOrder(String newOrder) {
- // Get map entry
- ((List<String>) get(ORDER_LIST)).add(newOrder);
- }
-
-
- /**
- * Clear order list
- */
- @SuppressWarnings("unchecked")
- public void clearOrder() {
- // Get map entry
- ((List<String>) get(ORDER_LIST)).clear();
- }
-
/**
* Get occupation state
@@ -616,28 +494,6 @@
status.put(OCCUPIER, occId);
}
-
- /**
- * Get last occupier ID
- */
- public String getLastOccupierID() {
- // If member is not set, a null pointer Exception will be thrown when invoking toString(). Return an empty string in this case (=no occupier)
- try {
- return status.get(LAST_OCCUPIER).toString();
- } catch (NullPointerException e) {
- return "";
- }
- }
-
-
- /**
- * Set last occupier ID
- */
- public void setLastOccupierID(String occId) {
- status.put(LAST_OCCUPIER, occId);
- }
-
-
/**
* Get execution mode
*/
@@ -743,26 +599,7 @@
// Change error state
status.put(ERROR_STATE, errorState);
}
-
-
- /**
- * Get last error state
- */
- public String getLastErrorState() {
- // If member is not set, a null pointer Exception will be thrown when invoking toString(). Return an empty string in this case (=no occupier)
- try {return status.get(PREV_ERROR).toString();} catch (NullPointerException e) {return "";}
- }
-
-
- /**
- * Set last error state
- */
- public void setLastErrorState(String lastErrorState) {
- // Change last error state
- status.put(PREV_ERROR, lastErrorState);
- }
-
-
+
/**
* Get last command
@@ -780,42 +617,6 @@
// Change last command
put(CMD, cmd);
}
-
-
- /**
- * Get local overwrite variable
- */
- public String getLocalOverwrite() {
- // If member is not set, a null pointer Exception will be thrown when invoking toString(). Return an empty string in this case (=no occupier)
- try {return get(LOCAL_OVERWRITE).toString();} catch (NullPointerException e) {return "";}
- }
-
-
- /**
- * Set local overwrite variable
- */
- public void setLocalOverwrite(String cmd) {
- // Change local overwrite command
- put(LOCAL_OVERWRITE, cmd);
- }
-
-
- /**
- * Get local overwrite free variable
- */
- public String getLocalOverwriteFree() {
- // If member is not set, a null pointer Exception will be thrown when invoking toString(). Return an empty string in this case (=no occupier)
- try {return get(LOCAL_OVERWRITE_FREE).toString();} catch (NullPointerException e) {return "";}
- }
-
-
- /**
- * Set local overwrite free variable
- */
- public void setLocalOverwriteFree(String cmd) {
- // Change local overwrite free command
- put(LOCAL_OVERWRITE_FREE, cmd);
- }
}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ControlComponentChangeListener.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ControlComponentChangeListener.java
index 682f404..e842153 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ControlComponentChangeListener.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ControlComponentChangeListener.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.models.controlcomponent;
@@ -27,14 +36,6 @@
* Indicate new occupation state
*/
public void onNewOccupationState(OccupationState state);
-
-
- /**
- * Indicate a change of last occupier. This is probably not relevant for many sub classes, therefore this class
- * provides a default implementation.
- */
- default void onLastOccupier(String lastOccupierId) { /* Do nothing */ }
-
/**
* Indicate an execution mode change
@@ -64,12 +65,5 @@
* Indicate an error state change
*/
public void onChangedErrorState(String newWorkState);
-
-
- /**
- * Indicate an previous error state change. This is probably not relevant for many sub classes, therefore this class
- * provides a default implementation.
- */
- default void onChangedPrevError(String newWorkState) { /* Do nothing */ }
}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ExecutionMode.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ExecutionMode.java
index 6575810..31ecadc 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ExecutionMode.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ExecutionMode.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.models.controlcomponent;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ExecutionOrder.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ExecutionOrder.java
index 363a7c6..461958a 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ExecutionOrder.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ExecutionOrder.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.models.controlcomponent;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ExecutionState.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ExecutionState.java
index 32301de..fbe371a 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ExecutionState.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ExecutionState.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.models.controlcomponent;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/OccupationState.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/OccupationState.java
index 24dd288..09c199c 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/OccupationState.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/OccupationState.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.models.controlcomponent;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/SimpleControlComponent.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/SimpleControlComponent.java
index ebdc938..b7caeb9 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/SimpleControlComponent.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/SimpleControlComponent.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.models.controlcomponent;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/SimpleProxyControlComponent.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/SimpleProxyControlComponent.java
index 4d2d100..a8e2973 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/SimpleProxyControlComponent.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/SimpleProxyControlComponent.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.models.controlcomponent;
import org.eclipse.basyx.components.netcomm.NetworkReceiver;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/support/bundle/AASBundle.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/support/bundle/AASBundle.java
index db6a3fe..78448a2 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/support/bundle/AASBundle.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/support/bundle/AASBundle.java
@@ -1,9 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.support.bundle;
import java.util.Set;
import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
/**
* Helper class to bundle an AAS with its corresponding submodels, e.g. for
@@ -14,9 +23,9 @@
*/
public class AASBundle {
private IAssetAdministrationShell aas;
- private Set<ISubModel> submodels;
+ private Set<ISubmodel> submodels;
- public AASBundle(IAssetAdministrationShell aas, Set<ISubModel> submodels) {
+ public AASBundle(IAssetAdministrationShell aas, Set<ISubmodel> submodels) {
super();
this.aas = aas;
this.submodels = submodels;
@@ -26,7 +35,7 @@
return aas;
}
- public Set<ISubModel> getSubmodels() {
+ public Set<ISubmodel> getSubmodels() {
return submodels;
}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/support/bundle/AASBundleDescriptorFactory.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/support/bundle/AASBundleDescriptorFactory.java
index 2291fa4..f598baf 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/support/bundle/AASBundleDescriptorFactory.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/support/bundle/AASBundleDescriptorFactory.java
@@ -1,13 +1,20 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.support.bundle;
import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
-import org.eclipse.basyx.components.servlet.aas.AASBundleServlet;
import org.eclipse.basyx.vab.modelprovider.VABPathTools;
/**
- * Helper class that supports AASDescriptor utilization for an AASBundle under
- * the assumption, that is is hosted using {@link AASBundleServlet}
+ * Helper class that supports AASDescriptor utilization for an AASBundle
*
* @author schnicke
*
@@ -15,8 +22,9 @@
public class AASBundleDescriptorFactory {
/**
* Creates the AASDescriptor for the given bundle and hostPath
+ *
* @param bundle
- * @param hostBasePath the hostBasePath the {@link AASBundleServlet} will be hosted on
+ * @param hostBasePath
* @return
*/
public static AASDescriptor createAASDescriptor(AASBundle bundle, String hostBasePath) {
@@ -24,7 +32,9 @@
String nHostBasePath = VABPathTools.stripSlashes(hostBasePath);
// Create AASDescriptor
- String aasBase = VABPathTools.concatenatePaths(nHostBasePath, bundle.getAAS().getIdShort(), "aas");
+ String endpointId = bundle.getAAS().getIdentification().getId();
+ endpointId = VABPathTools.encodePathElement(endpointId);
+ String aasBase = VABPathTools.concatenatePaths(nHostBasePath, endpointId, "aas");
AASDescriptor desc = new AASDescriptor(bundle.getAAS(), aasBase);
bundle.getSubmodels().stream().forEach(s -> {
SubmodelDescriptor smDesc = new SubmodelDescriptor(s, VABPathTools.concatenatePaths(aasBase, "submodels", s.getIdShort(), "submodel"));
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/support/bundle/AASBundleHelper.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/support/bundle/AASBundleHelper.java
new file mode 100644
index 0000000..f7a48fa
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/support/bundle/AASBundleHelper.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.support.bundle;
+
+import java.util.Collection;
+
+import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * This class can be used to check if all required resources are present on a server<br>
+ * (e.g. after a restart) and upload them if necessary.
+ *
+ * @author conradi
+ *
+ */
+public class AASBundleHelper {
+
+ private static Logger logger = LoggerFactory.getLogger(AASBundleHelper.class);
+
+ /**
+ * Checks (by ID) if all AASs/SMs contained<br>
+ * in the given AASBundles exist in the AASAggregator.<br>
+ * Adds missing ones to the Aggregator.<br>
+ * If a given object already exists in the Aggregator it will NOT be replaced.
+ *
+ * @param aggregator the Aggregator to be populated
+ * @param bundles the AASBundles
+ * @return true if an AAS/SM was uploaded; false otherwise
+ */
+ public static boolean integrate(IAASAggregator aggregator, Collection<AASBundle> bundles) {
+
+ if(aggregator == null || bundles == null) {
+ throw new RuntimeException("'aggregator' and 'bundles' must not be null.");
+ }
+
+ boolean objectUploaded = false;
+
+ for(AASBundle bundle: bundles) {
+ IAssetAdministrationShell aas = bundle.getAAS();
+
+ try {
+ aggregator.getAAS(aas.getIdentification());
+ // If no ResourceNotFoundException occurs, AAS exists on server
+ // -> no further action required
+ } catch(ResourceNotFoundException e) {
+ // AAS does not exist and needs to be pushed to the server
+ // Cast Interface to concrete class
+ if(aas instanceof AssetAdministrationShell) {
+ aggregator.createAAS((AssetAdministrationShell) aas);
+ objectUploaded = true;
+ } else {
+ throw new RuntimeException("aas Objects in bundles need to be instance of 'AssetAdministrationShell'");
+ }
+ }
+
+ IModelProvider provider = aggregator.getAASProvider(aas.getIdentification());
+ for (ISubmodel sm : bundle.getSubmodels()) {
+ try {
+ provider.getValue("/aas/submodels/" + sm.getIdShort());
+ // If no ResourceNotFoundException occurs, SM exists on server
+ // -> no further action required
+ } catch (ResourceNotFoundException e) {
+ // AAS does not exist and needs to be pushed to the server
+ // Check if ISubmodel is a concrete Submodel
+ if (sm instanceof Submodel) {
+ provider.setValue("/aas/submodels/" + sm.getIdShort(), sm);
+ objectUploaded = true;
+ } else {
+ throw new RuntimeException("sm Objects in bundles need to be instance of 'Submodel'");
+ }
+ }
+ }
+ }
+ return objectUploaded;
+ }
+
+ /**
+ * Registers a given set of bundles with the registry
+ *
+ * @param registry
+ * the registry to register with
+ * @param bundles
+ * the bundles to register
+ * @param aasAggregatorPath
+ * the aggregator path, e.g. <i>http://localhost:4000/shells</i>
+ */
+ public static void register(IAASRegistry registry, Collection<AASBundle> bundles, String aasAggregatorPath) {
+ bundles.stream().map(b -> AASBundleDescriptorFactory.createAASDescriptor(b, aasAggregatorPath)).forEach(registry::register);
+ }
+
+ /**
+ * Deregisters a given set of bundles from a given registry
+ *
+ * @param registry the registry to deregister from
+ * @param bundles the AASBundles to be deregistred
+ */
+ public static void deregister(IAASRegistry registry, Collection<AASBundle> bundles) {
+ if(registry != null && bundles != null) {
+ for(AASBundle bundle: bundles) {
+ IAssetAdministrationShell aas = bundle.getAAS();
+
+ try {
+ registry.delete(aas.getIdentification());
+ } catch (ProviderException e) {
+ logger.info("The AAS '" + aas.getIdShort() + "' can't be deregistered. It was not found in registry.");
+ // Just continue if deregistration failed
+ }
+
+ for(ISubmodel sm: bundle.getSubmodels()) {
+ try {
+ registry.delete(sm.getIdentification());
+ } catch (ProviderException e) {
+ logger.info("The SM '" + sm.getIdShort() + "' can't be deregistered. It was not found in registry.");
+ // Just continue if deregistration failed
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/ActiveModel.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/ActiveModel.java
index b072acf..de44bf5 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/ActiveModel.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/ActiveModel.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.tools.aas.active;
import java.util.HashSet;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/HTTPGetter.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/HTTPGetter.java
index 7e2293b..232461a 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/HTTPGetter.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/HTTPGetter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.tools.aas.active;
import java.io.Serializable;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/HTTPSupplier.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/HTTPSupplier.java
index 4a28099..7fd75e7 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/HTTPSupplier.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/HTTPSupplier.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.tools.aas.active;
import java.io.Serializable;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/VABModelTask.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/VABModelTask.java
index b629185..c1cac68 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/VABModelTask.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/VABModelTask.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.tools.aas.active;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/VABModelTaskGroup.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/VABModelTaskGroup.java
index 5f5ed0a..88dbad6 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/VABModelTaskGroup.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/VABModelTaskGroup.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.tools.aas.active;
import java.util.LinkedList;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/driver/ISQLDriver.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/driver/ISQLDriver.java
new file mode 100644
index 0000000..d9f8e60
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/driver/ISQLDriver.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.tools.sql.driver;
+
+import java.sql.ResultSet;
+
+
+
+/**
+ * Database access interface
+ *
+ * @author kuhn
+ *
+ */
+public interface ISQLDriver {
+
+
+ /**
+ * Execute a SQL query
+ */
+ public ResultSet sqlQuery(String queryString);
+
+
+ /**
+ * Execute a SQL update
+ */
+ public void sqlUpdate(String updateString);
+}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/driver/SQLDriver.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/driver/SQLDriver.java
new file mode 100644
index 0000000..36fc400
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/driver/SQLDriver.java
@@ -0,0 +1,233 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.tools.sql.driver;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import javax.sql.rowset.CachedRowSet;
+import javax.sql.rowset.RowSetFactory;
+import javax.sql.rowset.RowSetProvider;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.zaxxer.hikari.HikariDataSource;
+
+
+/**
+ * Access SQL database
+ *
+ * @author kuhn
+ *
+ */
+public class SQLDriver implements ISQLDriver {
+ private static Logger logger = LoggerFactory.getLogger(SQLDriver.class);
+
+
+ /**
+ * Store user name
+ */
+ protected String userName = null;
+
+ /**
+ * Store password
+ */
+ protected String password = null;
+
+ /**
+ * Store path to database server
+ */
+ protected String dbPath = null;
+
+
+ /**
+ * Store query prefix
+ */
+ protected String queryPrefix = null;
+
+
+ /**
+ * Store driver class (with package name)
+ */
+ protected String qualDriverClass = null;
+
+
+ /**
+ * JDBC connection
+ */
+ protected Connection connect = null;
+
+ /**
+ * Data source
+ */
+ protected HikariDataSource ds = null;
+
+
+
+
+ /**
+ * Create a SQL driver and a SQL connection
+ */
+ public SQLDriver(String path, String user, String pass, String qryPfx, String qDrvCls) {
+ // Store parameter
+ userName = user;
+ password = pass;
+ dbPath = path;
+ queryPrefix = qryPfx;
+ qualDriverClass = qDrvCls;
+
+ // This will load the MySQL driver, each DB has its own driver
+ try {
+ Class.forName(qualDriverClass);
+ } catch (ClassNotFoundException e) {
+ logger.error("Could not init SQLDriver", e);
+ }
+ }
+
+
+
+ /**
+ * Execute a SQL query
+ */
+ @Override
+ public CachedRowSet sqlQuery(String queryString) {
+ // Store SQL statement, flag that indicates whether the connection was created by this
+ // operation (and needs to be closed), and result
+ Statement statement = null;
+ CachedRowSet rowSet = null;
+
+
+ // Access database
+ try {
+ // Open a connection with data source
+ openConnection();
+
+ // Statements allow to issue SQL queries to the database
+ statement = connect.createStatement();
+
+ // ResultSet gets the result of the SQL query
+ ResultSet resultSet = statement.executeQuery(queryString);
+
+ // Convert DB data to memory cache
+ rowSet = getCachedRowSet(resultSet);
+
+ // Close connection with data source
+ closeConnection();
+ } catch (SQLException e) {
+ logger.error("sqlQuery failed", e);
+ }
+
+ // Return result of query
+ return rowSet;
+ }
+
+
+
+ /**
+ * Execute a SQL update
+ */
+ @Override
+ public void sqlUpdate(String updateString) {
+ // Store SQL statement
+ Statement statement = null;
+
+ // Access database
+ try {
+ // Open a connection with data source
+ openConnection();
+
+ // Statements allow to issue SQL queries to the database
+ statement = connect.createStatement();
+
+ // ResultSet gets the result of the SQL query
+ statement.executeUpdate(updateString);
+
+ // Close connection with data source
+ closeConnection();
+ } catch (SQLException e) {
+ logger.error("sqlUpdate failed", e);
+ }
+ }
+
+
+
+ /**
+ * Open connection
+ */
+ public void openConnection() {
+ // Access database
+ try {
+ // Open connection
+ if (connect == null) {
+ openDataSource();
+ connect = ds.getConnection();
+ }
+ } catch (SQLException e) {
+ logger.error("Failed to open sql driver connection", e);
+ }
+ }
+
+
+ /**
+ * Close connection
+ */
+ public void closeConnection() {
+ // Access database
+ try {
+ // Close connection
+ if (connect != null) {
+ connect.close();
+ connect = null;
+ }
+ } catch (SQLException e) {
+ logger.error("Failed to close sql driver connection", e);
+ }
+ }
+
+
+ /**
+ * Get connection
+ */
+ public Connection getConnection() {
+ return connect;
+ }
+
+
+ /**
+ * Indicate if driver has open connection
+ */
+ public boolean hasOpenConnection() {
+ return (connect == null);
+ }
+
+ /**
+ * Open Data source
+ */
+ private void openDataSource() {
+ if (ds == null) {
+ ds = new HikariDataSource();
+ ds.setJdbcUrl(queryPrefix+dbPath);
+ ds.setUsername(userName);
+ ds.setPassword(password);
+ ds.setMaximumPoolSize(5);
+ }
+ }
+
+ private CachedRowSet getCachedRowSet(ResultSet resultSet) throws SQLException {
+ RowSetFactory factory = RowSetProvider.newFactory();
+ CachedRowSet rowset = factory.createCachedRowSet();
+ rowset.populate(resultSet);
+ return rowset;
+ }
+}
+
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLOperation.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLOperation.java
new file mode 100644
index 0000000..1706406
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLOperation.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.tools.sql.query;
+
+import java.lang.reflect.InvocationTargetException;
+import java.sql.ResultSet;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.function.Function;
+
+import org.eclipse.basyx.components.tools.propertyfile.opdef.OperationDefinition;
+import org.eclipse.basyx.components.tools.propertyfile.opdef.Parameter;
+import org.eclipse.basyx.components.tools.propertyfile.opdef.ResultFilter;
+import org.eclipse.basyx.tools.sql.driver.ISQLDriver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+/**
+ * Implement a generic SQL query
+ *
+ * @author kuhn
+ *
+ */
+public class DynamicSQLOperation extends DynamicSQLRunner implements Function<Object[], Object> {
+ private static Logger logger = LoggerFactory.getLogger(DynamicSQLOperation.class);
+
+
+ /**
+ * Store SQL query string with place holders ($x)
+ */
+ protected String sqlQueryString = null;
+
+
+ /**
+ * Store SQL result filter
+ */
+ protected String resultFilterString = null;
+
+
+
+
+
+ /**
+ * Constructor
+ */
+ public DynamicSQLOperation(ISQLDriver driver, String query, String sqlResultFilter) {
+ // Invoke base constructor
+ super(driver);
+
+ // Store parameter count and SQL query string
+ sqlQueryString = query;
+ resultFilterString = sqlResultFilter;
+ }
+
+
+ /**
+ * Constructor
+ */
+ public DynamicSQLOperation(String path, String user, String pass, String qryPfx, String qDrvCls, String query, String sqlResultFilter) {
+ // Invoke base constructor
+ super(path, user, pass, qryPfx, qDrvCls);
+
+ // Store parameter count and SQL query string
+ sqlQueryString = query;
+ resultFilterString = sqlResultFilter;
+ }
+
+
+ /**
+ * Execute query with given parameter
+ */
+ @Override
+ public Object apply(Object[] parameter) {
+ // Create list of query parameter
+ Collection<String> sqlQueryParameter = new LinkedList<>();
+ // - Add parameter
+ for (Object par: parameter) sqlQueryParameter.add(par.toString());
+
+ // Apply parameter and create SQL query string
+ String sqlQuery = OperationDefinition.getSQLString(sqlQueryString, sqlQueryParameter);
+
+ logger.debug("Running SQL query:" + sqlQuery);
+
+ // Execute SQL query
+ ResultSet sqlResult = sqlDriver.sqlQuery(sqlQuery);
+
+ // Extract input parameter definition
+ Collection<Parameter> resultParameter = OperationDefinition.getParameter(resultFilterString);
+
+ // Process result
+ try {
+ // Create inner parameter array for call
+ Object[] callParameterInner = new Object[resultParameter.size()];
+ int i=0; for (String column: getColumnNames(resultParameter)) callParameterInner[i++]=column;
+
+ // Create parameter array for call
+ Object[] callParameter = new Object[2];
+ callParameter[0] = sqlResult;
+ callParameter[1] = callParameterInner;
+
+ // Invoke result filter operation using static invocation
+ return ResultFilter.class.getMethod(OperationDefinition.getOperation(resultFilterString), getMethodParameter(resultParameter)).invoke(null, callParameter);
+ } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+ logger.error("Could not invoke dynamic sql operation", e);
+ }
+
+ // No result
+ return null;
+ }
+}
+
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLQuery.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLQuery.java
new file mode 100644
index 0000000..039c9f3
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLQuery.java
@@ -0,0 +1,162 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.tools.sql.query;
+
+import java.lang.reflect.InvocationTargetException;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.eclipse.basyx.components.tools.propertyfile.opdef.OperationDefinition;
+import org.eclipse.basyx.components.tools.propertyfile.opdef.Parameter;
+import org.eclipse.basyx.components.tools.propertyfile.opdef.ResultFilter;
+import org.eclipse.basyx.tools.sql.driver.ISQLDriver;
+
+
+
+/**
+ * Implement a generic SQL query
+ *
+ * @author kuhn
+ *
+ */
+public class DynamicSQLQuery extends DynamicSQLRunner implements Supplier<Object> {
+
+
+ /**
+ * Store SQL query string with place holders ($x)
+ */
+ protected String sqlQueryString = null;
+
+
+ /**
+ * Store SQL result filter
+ */
+ protected String resultFilterString = null;
+
+
+
+
+
+ /**
+ * Constructor that accepts a driver
+ */
+ public DynamicSQLQuery(ISQLDriver driver, String query, String sqlResultFilter) {
+ // Invoke base constructor
+ super(driver);
+
+ // Store SQL query string and result filter
+ sqlQueryString = query;
+ resultFilterString = sqlResultFilter;
+ }
+
+
+ /**
+ * Constructor
+ */
+ public DynamicSQLQuery(String path, String user, String pass, String qryPfx, String qDrvCls, String query, String sqlResultFilter) {
+ // Invoke base constructor
+ super(path, user, pass, qryPfx, qDrvCls);
+
+ // Store SQL query string and result filter
+ sqlQueryString = query;
+ resultFilterString = sqlResultFilter;
+ }
+
+
+ /**
+ * Execute query without parameter
+ */
+ @Override
+ public Object get() {
+ // Execute SQL query
+ ResultSet sqlResult = sqlDriver.sqlQuery(sqlQueryString);
+
+ // Process result
+ return processResult(sqlResult);
+ }
+
+
+ /**
+ * Execute query without parameter, do not post process result
+ */
+ public ResultSet getRaw() {
+ // Execute SQL query
+ return sqlDriver.sqlQuery(sqlQueryString);
+ }
+
+
+ /**
+ * Execute query without parameter
+ */
+ public Object get(Map<String,Object> param) {
+ // Apply parameter and create SQL query string
+ String sqlQuery = OperationDefinition.getSQLString(sqlQueryString, param);
+
+ // Execute SQL query
+ ResultSet sqlResult = sqlDriver.sqlQuery(sqlQuery);
+
+ // Process result
+ return processResult(sqlResult);
+ }
+
+
+ /**
+ * Execute query without parameter, do not post process result
+ */
+ public ResultSet getRaw(Map<String,Object> param) {
+ // Apply parameter and create SQL query string
+ String sqlQuery = OperationDefinition.getSQLString(sqlQueryString, param);
+
+ // Execute SQL query
+ return sqlDriver.sqlQuery(sqlQuery);
+ }
+
+
+
+ /**
+ * Process result parameter
+ */
+ protected Object processResult(ResultSet sqlResult) {
+ // Extract input parameter definition
+ Collection<Parameter> parameter = OperationDefinition.getParameter(resultFilterString);
+
+ // Process result
+ try {
+ // Create inner parameter array for call
+ Object[] callParameterInner = new Object[parameter.size()];
+ int i=0; for (String column: getColumnNames(parameter)) callParameterInner[i++]=column;
+
+ // Create parameter array for call
+ Object[] callParameter = new Object[2];
+ callParameter[0] = sqlResult;
+ callParameter[1] = callParameterInner;
+
+ // Invoke result filter operation using static invocation
+ Object result = ResultFilter.class.getMethod(OperationDefinition.getOperation(resultFilterString), getMethodParameter(parameter)).invoke(null, callParameter);
+
+ // Close result set
+ sqlResult.close();
+
+ // Return result
+ return result;
+
+ } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | SQLException e) {
+ // Print exception to console
+ e.printStackTrace();
+ }
+
+ // No result
+ return null;
+ }
+}
+
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLRunner.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLRunner.java
new file mode 100644
index 0000000..476bc6e
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLRunner.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.tools.sql.query;
+
+import java.sql.ResultSet;
+import java.util.Collection;
+import java.util.LinkedList;
+
+import org.eclipse.basyx.components.tools.propertyfile.opdef.Parameter;
+import org.eclipse.basyx.tools.sql.driver.ISQLDriver;
+import org.eclipse.basyx.tools.sql.driver.SQLDriver;
+
+
+
+
+/**
+ * SQL query operation
+ *
+ * @author kuhn
+ *
+ */
+public class DynamicSQLRunner {
+
+
+ /**
+ * Store SQL driver instance
+ */
+ protected ISQLDriver sqlDriver = null;
+
+
+
+
+
+ /**
+ * Constructor that accepts a driver
+ */
+ public DynamicSQLRunner(ISQLDriver driver) {
+ // Store SQL driver instance
+ sqlDriver = driver;
+ }
+
+
+ /**
+ * Constructor
+ */
+ public DynamicSQLRunner(String path, String user, String pass, String qryPfx, String qDrvCls) {
+ // Create SQL driver instance
+ sqlDriver = new SQLDriver(path, user, pass, qryPfx, qDrvCls);
+ }
+
+
+
+ /**
+ * Get method parameter definition
+ */
+ protected Class<?>[] getMethodParameter(Collection<Parameter> parameter) {
+ // Store operation signature
+ Class<?>[] result = new Class<?>[2];
+
+ // Operation signature is ResultSet and a list of string parameter that define column names
+ result[0] = ResultSet.class;
+ result[1] = Object[].class;
+
+ // Return signature
+ return result;
+ }
+
+
+ /**
+ * Get column names
+ */
+ protected Collection<String> getColumnNames(Collection<Parameter> parameter) {
+ // Return value
+ Collection<String> result = new LinkedList<>();
+
+ for (Parameter par: parameter) result.add(par.getName());
+
+ return result;
+ }
+}
+
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLUpdate.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLUpdate.java
new file mode 100644
index 0000000..0160392
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLUpdate.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.tools.sql.query;
+
+import java.util.Map;
+import java.util.function.Consumer;
+
+import org.eclipse.basyx.components.tools.propertyfile.opdef.OperationDefinition;
+import org.eclipse.basyx.tools.sql.driver.ISQLDriver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+/**
+ * Implement a generic SQL query
+ *
+ * @author kuhn
+ *
+ */
+public class DynamicSQLUpdate extends DynamicSQLRunner implements Consumer<Map<String,Object>> {
+ private static Logger logger = LoggerFactory.getLogger(DynamicSQLUpdate.class);
+
+ /**
+ * Store SQL query string with place holders ($x)
+ */
+ protected String sqlQueryString = null;
+
+
+
+
+ /**
+ * Constructor
+ */
+ public DynamicSQLUpdate(ISQLDriver driver, String query) {
+ // Invoke base constructor
+ super(driver);
+
+ // Store parameter count and SQL query string
+ sqlQueryString = query;
+ }
+
+
+ /**
+ * Constructor
+ */
+ public DynamicSQLUpdate(String path, String user, String pass, String qryPfx, String qDrvCls, String query) {
+ // Invoke base constructor
+ super(path, user, pass, qryPfx, qDrvCls);
+
+ // Store parameter count and SQL query string
+ sqlQueryString = query;
+ }
+
+
+
+ /**
+ * Execute update with given parameter
+ */
+ @Override
+ public void accept(Map<String,Object> parameter) {
+ logger.debug("(Parameters) Running SQL update: " + parameter);
+
+ // Apply parameter and create SQL query string
+ String sqlQuery = OperationDefinition.getSQLString(sqlQueryString, parameter);
+
+ logger.debug("(Query) Running SQL update:" + sqlQuery);
+
+ // Execute SQL query
+ sqlDriver.sqlUpdate(sqlQuery);
+ }
+}
+
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLCollection.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLCollection.java
index 0a1f9b2..be67a61 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLCollection.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLCollection.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.tools.sqlproxy;
import java.lang.reflect.Array;
@@ -9,9 +18,9 @@
import java.util.List;
import java.util.Map;
-import org.eclipse.basyx.components.sqlprovider.driver.ISQLDriver;
-import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLQuery;
-import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLUpdate;
+import org.eclipse.basyx.tools.sql.driver.ISQLDriver;
+import org.eclipse.basyx.tools.sql.query.DynamicSQLQuery;
+import org.eclipse.basyx.tools.sql.query.DynamicSQLUpdate;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLConnector.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLConnector.java
index d4a113a..bb4f086 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLConnector.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLConnector.java
@@ -1,7 +1,16 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.tools.sqlproxy;
-import org.eclipse.basyx.components.sqlprovider.driver.ISQLDriver;
-import org.eclipse.basyx.components.sqlprovider.driver.SQLDriver;
+import org.eclipse.basyx.tools.sql.driver.ISQLDriver;
+import org.eclipse.basyx.tools.sql.driver.SQLDriver;
/**
* Base class for classes that connect to SQL databases
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLMap.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLMap.java
index 846282b..ca2f8ed 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLMap.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLMap.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.tools.sqlproxy;
import java.sql.ResultSet;
@@ -10,9 +19,9 @@
import java.util.Map;
import java.util.Set;
-import org.eclipse.basyx.components.sqlprovider.driver.ISQLDriver;
-import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLQuery;
-import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLUpdate;
+import org.eclipse.basyx.tools.sql.driver.ISQLDriver;
+import org.eclipse.basyx.tools.sql.query.DynamicSQLQuery;
+import org.eclipse.basyx.tools.sql.query.DynamicSQLUpdate;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLProxy.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLProxy.java
index 3ad7f8b..f517e36 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLProxy.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLProxy.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.tools.sqlproxy;
import java.sql.ResultSet;
@@ -7,9 +16,9 @@
import java.util.Map;
import java.util.Set;
-import org.eclipse.basyx.components.sqlprovider.driver.ISQLDriver;
-import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLQuery;
-import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLUpdate;
+import org.eclipse.basyx.tools.sql.driver.ISQLDriver;
+import org.eclipse.basyx.tools.sql.query.DynamicSQLQuery;
+import org.eclipse.basyx.tools.sql.query.DynamicSQLUpdate;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLRootElement.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLRootElement.java
index c0e0024..fb04c06 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLRootElement.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLRootElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.tools.sqlproxy;
import java.util.Collection;
@@ -6,8 +15,8 @@
import java.util.Set;
import java.util.stream.Collectors;
-import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLQuery;
-import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLUpdate;
+import org.eclipse.basyx.tools.sql.query.DynamicSQLQuery;
+import org.eclipse.basyx.tools.sql.query.DynamicSQLUpdate;
@@ -38,7 +47,7 @@
/**
* Creates the root table if it does not exist (including a possibly missing schema)
*/
- public void create() {
+ public void createRootTableIfNotExists() {
createSchema();
createRootTable();
}
@@ -54,38 +63,41 @@
/**
* Get next free identifier for another element
*/
- @SuppressWarnings("unchecked")
public int getNextIdentifier() {
- // Element ID
- int elementID = -1;
+ Map<String, Object> sqlResult = readCurrentElementPointer();
+ // Store element ID
+ int elementId = Integer.parseInt((String) sqlResult.get("NextElementID"));
+
+ // SQL update statement
+ String updateString = "UPDATE elements." + getSqlTableID() + " SET NextElementID='" + (elementId + 1)
+ + "', ElementPrefix='" + sqlResult.get("ElementPrefix") + "'";
+ DynamicSQLUpdate dynUpdate = new DynamicSQLUpdate(getDriver(), updateString);
+
+ // Empty parameter set
+ Map<String, Object> parameter = new HashMap<>();
+
+ // Execute SQL statement
+ dynUpdate.accept(parameter);
+
+ // Return element ID
+ return elementId;
+ }
+
+ @SuppressWarnings("unchecked")
+ private Map<String, Object> readCurrentElementPointer() {
// SQL query string
- String queryString = "SELECT * FROM elements."+getSqlTableID();
- DynamicSQLQuery dynQuery = new DynamicSQLQuery(getDriver(), queryString, "mapArray(NextElementID:Integer,ElementPrefix:String)");
+ String queryString = "SELECT * FROM elements." + getSqlTableID();
+ DynamicSQLQuery dynQuery = new DynamicSQLQuery(getDriver(), queryString,
+ "mapArray(NextElementID:Integer,ElementPrefix:String)");
// Empty parameter set
Map<String, Object> parameter = new HashMap<>();
- // - Execute query, return the column as
- Map<String, Object> sqlResult = (Map<String, Object>) dynQuery.get(parameter);
-
- // Store element ID
- elementID = Integer.parseInt((String) sqlResult.get("NextElementID"));
-
-
- // SQL update statement
- String updateString = "UPDATE elements."+getSqlTableID()+" SET NextElementID='"+(elementID+1)+"', ElementPrefix='"+sqlResult.get("ElementPrefix")+"'";
- DynamicSQLUpdate dynUpdate = new DynamicSQLUpdate(getDriver(), updateString);
-
- // Empty parameter set
- parameter.clear();
-
- // Execute SQL statement
- dynUpdate.accept(parameter);
-
- // Return element ID
- return elementID;
+ // - Execute query, return the column as
+ return (Map<String, Object>) dynQuery.get(parameter);
}
+
/**
* Creates a schema for the root element
*/
@@ -131,16 +143,20 @@
// Execute SQL statement
dynCmd.accept(parameter);
+ Map<String, Object> currentPointer = readCurrentElementPointer();
- // Initially fill table
- String sqlInsertString = "INSERT INTO elements."+ getSqlTableID() +" (NextElementID, ElementPrefix) VALUES ('1', '"+getSqlTableID()+":')";
- DynamicSQLUpdate dynUpdate = new DynamicSQLUpdate(getDriver(), sqlInsertString);
+ if (!currentPointer.containsKey("NextElementID")) {
+ // Initially fill table if it is empty
+ String sqlInsertString = "INSERT INTO elements." + getSqlTableID()
+ + " (NextElementID, ElementPrefix) VALUES ('1', '" + getSqlTableID() + ":')";
+ DynamicSQLUpdate dynUpdate = new DynamicSQLUpdate(getDriver(), sqlInsertString);
- // Clear parameter
- parameter.clear();
-
- // Run SQL operation
- dynUpdate.accept(parameter);
+ // Clear parameter
+ parameter.clear();
+
+ // Run SQL operation
+ dynUpdate.accept(parameter);
+ }
}
@@ -231,5 +247,23 @@
// Execute SQL statement
dynCmd.accept(parameter);
}
+
+ /**
+ * Creates a new root map, if it does not exist. Otherwise, returns
+ * the first map within this root element.
+ *
+ * @return
+ */
+ public SQLMap retrieveRootMap() {
+ Map<String, Object> currentPointer = readCurrentElementPointer();
+ int elementId = Integer.parseInt((String) currentPointer.get("NextElementID"));
+ if (elementId == 1) {
+ // No element has been created, yet => create new root map
+ return createMap(getNextIdentifier());
+ } else {
+ // Root map already exists => return first
+ return new SQLMap(this, 1);
+ }
+ }
}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLTableRow.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLTableRow.java
index c722968..5dc64d9 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLTableRow.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLTableRow.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.tools.sqlproxy;
import java.io.ByteArrayInputStream;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/exception/UnknownElementTypeException.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/exception/UnknownElementTypeException.java
index c127ad5..ae59d25 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/exception/UnknownElementTypeException.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/exception/UnknownElementTypeException.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.tools.sqlproxy.exception;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/webserviceclient/WebServiceJSONClient.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/webserviceclient/WebServiceJSONClient.java
index 6e1e528..dd1aa4f 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/webserviceclient/WebServiceJSONClient.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/webserviceclient/WebServiceJSONClient.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.tools.webserviceclient;
import java.util.ArrayList;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/webserviceclient/WebServiceRawClient.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/webserviceclient/WebServiceRawClient.java
index 2a8f760..d1cb6b3 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/webserviceclient/WebServiceRawClient.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/webserviceclient/WebServiceRawClient.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.tools.webserviceclient;
import java.io.Serializable;
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProvider.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProvider.java
deleted file mode 100644
index 655af40..0000000
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProvider.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package org.eclipse.basyx.regression.cfgprovider;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Map;
-
-import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
-import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-/**
- * Test queries to CFG file provider
- *
- * @author kuhn
- *
- */
-public class TestCFGProvider {
-
-
- /**
- * VAB connection manager backend
- */
- protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(), new HTTPConnectorProvider());
-
-
- /**
- * Makes sure Tomcat Server is started with basyx.components regression test case
- */
- @ClassRule
- public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
-
-
- /**
- * Test basic queries
- */
- @SuppressWarnings("unchecked")
- @Test
- public void test() throws Exception {
- // Connect to sub model "CfgFileTestAAS"
- VABElementProxy connSubModel = this.connManager.connectToVABElement("CfgFileTestAAS");
-
-
- // Get property value
- Map<String, Object> value1 = (Map<String, Object>) connSubModel
- .getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty1/value");
-
- assertEquals("exampleStringValue", value1.get(Property.VALUE));
-
-
- // Get property value
- Map<String, Object> value2 = (Map<String, Object>) connSubModel
- .getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty2/value");
- assertEquals("12", value2.get(Property.VALUE));
-
- // Get property value
- Map<String, Object> value3 = (Map<String, Object>) connSubModel
- .getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty3/value");
- assertEquals("45.8", value3.get(Property.VALUE));
- }
-}
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProviderPropertyMetaData.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProviderPropertyMetaData.java
deleted file mode 100644
index 4af91ac..0000000
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProviderPropertyMetaData.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package org.eclipse.basyx.regression.cfgprovider;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Collection;
-import java.util.Map;
-
-import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
-import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-/**
- * Test queries to CFG file provider
- *
- * @author kuhn
- *
- */
-public class TestCFGProviderPropertyMetaData {
-
- /**
- * VAB connection manager backend
- */
- protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(),
- new HTTPConnectorProvider());
-
- /**
- * Makes sure Tomcat Server is started
- */
- @ClassRule
- public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
-
- /**
- * Test basic queries
- */
- @SuppressWarnings("unchecked")
- @Test
- public void test() throws Exception {
-
- // Connect to sub model "CfgFileTestAAS"
- VABElementProxy connSubModel = this.connManager.connectToVABElement("CfgFileTestAAS");
-
- // Get property value
- Map<String, Object> value1 = (Map<String, Object>) connSubModel
- .getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty1");
- assertEquals("exampleStringValue", value1.get(Property.VALUE));
- // - Check property meta data (description)
- Map<String, Object> value1a = (Map<String, Object>) connSubModel
- .getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty1");
- LangStrings description = LangStrings.createAsFacade((Collection<Map<String, Object>>) value1a.get("description"));
- assertEquals("Configuration property description", description.get(""));
-
- // Get property value
- Map<String, Object> value2 = (Map<String, Object>) connSubModel
- .getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty2");
- assertEquals("12", value2.get(Property.VALUE));
- // - Check property meta data (description)
- Map<String, Object> value2a = (Map<String, Object>) connSubModel
- .getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty2");
- description = LangStrings.createAsFacade((Collection<Map<String, Object>>) value2a.get("description"));
- assertEquals("Configuration property description on multiple lines", description.get(""));
-
- // Get property value
- Map<String, Object> value3 = (Map<String, Object>) connSubModel
- .getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty3");
- assertEquals("45.8", value3.get(Property.VALUE));
- }
-}
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProviderSubmodelMetaData.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProviderSubmodelMetaData.java
deleted file mode 100644
index d38a7de..0000000
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProviderSubmodelMetaData.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package org.eclipse.basyx.regression.cfgprovider;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Collection;
-import java.util.Map;
-
-import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
-import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.AdministrativeInformation;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
-import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-
-/**
- * Test queries to CFG file provider
- *
- * @author kuhn
- *
- */
-public class TestCFGProviderSubmodelMetaData {
-
-
- /**
- * VAB connection manager backend
- */
- protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(), new HTTPConnectorProvider());
-
- /**
- * Makes sure Tomcat Server is started
- */
- @ClassRule
- public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
-
- /**
- * Test basic queries
- */
- @SuppressWarnings("unchecked")
- @Test
- public void test() throws Exception {
-
- // Connect to sub model "CfgFileTestAAS"
- VABElementProxy connSubModel = this.connManager.connectToVABElement("CfgFileTestAAS");
-
-
- // Get property value
- Map<String, Object> sampleCFG = (Map<String, Object>) connSubModel
- .getModelPropertyValue("/aas/submodels/sampleCFG");
-
- LangStrings description = LangStrings.createAsFacade((Collection<Map<String, Object>>) sampleCFG.get("description"));
- assertEquals("BaSys regression test file for CFG file provider", description.get(""));
-
- // Get property value
- assertEquals("1.0",
- AdministrativeInformation.createAsFacade((Map<String, Object>) sampleCFG.get(Identifiable.ADMINISTRATION))
- .getVersion());
-
- // Get complete sub model
- Object value3 = connSubModel.getModelPropertyValue("/aas/submodels/sampleCFG");
- }
-}
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestAASDirectoryEntry.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestAASDirectoryEntry.java
deleted file mode 100644
index 662b48f..0000000
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestAASDirectoryEntry.java
+++ /dev/null
@@ -1,217 +0,0 @@
-package org.eclipse.basyx.regression.directory.file;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import org.eclipse.basyx.components.directory.AASDirectoryEntry;
-import org.junit.Test;
-
-
-
-/**
- * Test the AAS Directory entry class
- *
- * @author kuhn
- *
- */
-public class TestAASDirectoryEntry {
-
-
-
- /**
- * Execute test case that tests parsing of id constructor parameter
- */
- @Test
- public void testConstuctorParameterID() {
- // Test object with minimal ID
- AASDirectoryEntry aasEntry1 = new AASDirectoryEntry("urn:FHG", "<serializedAAS>", "local", "");
- // - Validate object
- assertTrue(aasEntry1.isValidID());
- assertTrue(aasEntry1.getLegalEntity().equals("FHG"));
- assertTrue(aasEntry1.isLegalEntityOf("FHG"));
- assertFalse(aasEntry1.hasSubUnit());
- assertFalse(aasEntry1.hasSubModel());
- assertFalse(aasEntry1.hasVersion());
- assertFalse(aasEntry1.hasRevision());
-
-
- // Test object with empty ID, SubUnit and sub model
- AASDirectoryEntry aasEntry2 = new AASDirectoryEntry("urn:::::", "<serializedAAS>", "local", "");
- // - Validate object
- assertTrue(aasEntry2.isValidID());
- assertFalse(aasEntry2.hasLegalEntity());
- assertFalse(aasEntry2.hasSubUnit());
- assertFalse(aasEntry2.hasSubModel());
- assertFalse(aasEntry2.hasVersion());
- assertFalse(aasEntry2.hasRevision());
-
-
- // Test object with almost empty ID and SubUnit
- AASDirectoryEntry aasEntry3 = new AASDirectoryEntry("urn: : : : : ", "<serializedAAS>", "local", "");
- // - Validate object
- assertTrue(aasEntry3.isValidID());
- assertFalse(aasEntry3.hasLegalEntity());
- assertFalse(aasEntry3.hasSubUnit());
- assertFalse(aasEntry3.hasSubModel());
- assertFalse(aasEntry3.hasVersion());
- assertFalse(aasEntry3.hasRevision());
-
-
- // Test object with ID, SubUnit, version and revision
- AASDirectoryEntry aasEntry4 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1", "<serializedAAS>", "local", "");
- // - Validate object
- assertTrue(aasEntry4.isValidID());
- assertTrue(aasEntry4.getLegalEntity().equals("FHG"));
- assertTrue(aasEntry4.isLegalEntityOf("FHG"));
- assertTrue(aasEntry4.hasSubUnit());
- assertTrue(aasEntry4.getSubUnit().equals("iese"));
- assertTrue(aasEntry4.hasSubModel());
- assertTrue(aasEntry4.getSubModel().equals("aas"));
- assertTrue(aasEntry4.hasVersion());
- assertTrue(aasEntry4.getVersion().equals("0.97"));
- assertTrue(aasEntry4.hasRevision());
- assertTrue(aasEntry4.getRevision().equals("1"));
- assertFalse(aasEntry4.hasElementID());
-
-
- // Test object with ID, SubUnit, version and revision
- AASDirectoryEntry aasEntry5 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:entity", "<serializedAAS>", "local", "");
- // - Validate object
- assertTrue(aasEntry5.isValidID());
- assertTrue(aasEntry5.getLegalEntity().equals("FHG"));
- assertTrue(aasEntry5.isLegalEntityOf("FHG"));
- assertTrue(aasEntry5.hasSubUnit());
- assertTrue(aasEntry5.getSubUnit().equals("iese"));
- assertTrue(aasEntry5.hasSubModel());
- assertTrue(aasEntry5.getSubModel().equals("aas"));
- assertTrue(aasEntry5.hasVersion());
- assertTrue(aasEntry5.getVersion().equals("0.97"));
- assertTrue(aasEntry5.hasRevision());
- assertTrue(aasEntry5.getRevision().equals("1"));
- assertTrue(aasEntry5.hasElementID());
- assertTrue(aasEntry5.getElementID().equals("entity"));
-
-
- // Test object with ID, SubUnit, version and revision
- AASDirectoryEntry aasEntry6 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:entity#001", "<serializedAAS>", "local", "");
- // - Validate object
- assertTrue(aasEntry6.isValidID());
- assertTrue(aasEntry6.getLegalEntity().equals("FHG"));
- assertTrue(aasEntry6.isLegalEntityOf("FHG"));
- assertTrue(aasEntry6.hasSubUnit());
- assertTrue(aasEntry6.getSubUnit().equals("iese"));
- assertTrue(aasEntry6.hasSubModel());
- assertTrue(aasEntry6.getSubModel().equals("aas"));
- assertTrue(aasEntry6.hasVersion());
- assertTrue(aasEntry6.getVersion().equals("0.97"));
- assertTrue(aasEntry6.hasRevision());
- assertTrue(aasEntry6.getRevision().equals("1"));
- assertTrue(aasEntry6.hasElementID());
- assertTrue(aasEntry6.getElementID().equals("entity"));
- assertTrue(aasEntry6.hasElementInstance());
- assertTrue(aasEntry6.getElementInstance().equals("001"));
-
-
- // Test object with ID, SubUnit, version and revision
- AASDirectoryEntry aasEntry7 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "local", "");
- // - Validate object
- assertTrue(aasEntry7.isValidID());
- assertTrue(aasEntry7.getLegalEntity().equals("FHG"));
- assertTrue(aasEntry7.isLegalEntityOf("FHG"));
- assertTrue(aasEntry7.hasSubUnit());
- assertTrue(aasEntry7.getSubUnit().equals("iese"));
- assertTrue(aasEntry7.hasSubModel());
- assertTrue(aasEntry7.getSubModel().equals("aas"));
- assertTrue(aasEntry7.hasVersion());
- assertTrue(aasEntry7.getVersion().equals("0.97"));
- assertTrue(aasEntry7.hasRevision());
- assertTrue(aasEntry7.getRevision().equals("1"));
- assertFalse(aasEntry7.hasElementID());
- assertTrue(aasEntry7.hasElementInstance());
- assertTrue(aasEntry7.getElementInstance().equals("001"));
- }
-
-
-
- /**
- * Execute test case that tests parsing of content and content type constructor parameter
- */
- @Test
- public void testConstuctorParameterContentAndContentType() {
- // Test object with local content and without tags
- AASDirectoryEntry aasEntry1 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "local", "");
- // - Validate object
- assertTrue(aasEntry1.getAASContent().equals("<serializedAAS>"));
- assertTrue(aasEntry1.getAASContentType() == AASDirectoryEntry.AAS_CONTENTTYPE_LOCAL);
- assertTrue(aasEntry1.getAASTags().isEmpty());
-
-
- // Test object with remote content and without tags
- AASDirectoryEntry aasEntry2 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "remote", "");
- // - Validate object
- assertTrue(aasEntry2.getAASContent().equals("<serializedAAS>"));
- assertTrue(aasEntry2.getAASContentType() == AASDirectoryEntry.AAS_CONTENTTYPE_REMOTE);
- assertTrue(aasEntry2.getAASTags().isEmpty());
-
-
- // Test object with remote content and without tags
- AASDirectoryEntry aasEntry3 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "ReMote", "");
- // - Validate object
- assertTrue(aasEntry3.getAASContent().equals("<serializedAAS>"));
- assertTrue(aasEntry3.getAASContentType() == AASDirectoryEntry.AAS_CONTENTTYPE_REMOTE);
- assertTrue(aasEntry3.getAASTags().isEmpty());
-
-
- // Test object with proxy content and without tags
- AASDirectoryEntry aasEntry4 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "PROXY", "");
- // - Validate object
- assertTrue(aasEntry4.getAASContent().equals("<serializedAAS>"));
- assertTrue(aasEntry4.getAASContentType() == AASDirectoryEntry.AAS_CONTENTTYPE_PROXY);
- assertTrue(aasEntry4.getAASTags().isEmpty());
- }
-
-
-
- /**
- * Execute test case that tests parsing of tags constructor parameter
- */
- @Test
- public void testConstuctorParameterTags() {
- // Test object without tags
- AASDirectoryEntry aasEntry1 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "local", "");
- // - Validate object
- assertTrue(aasEntry1.getAASTags().isEmpty());
-
-
- // Test object with one tag
- AASDirectoryEntry aasEntry2 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "local", "tag1");
- // - Validate object
- assertTrue(aasEntry2.getAASTags().size() == 1);
- assertTrue(aasEntry2.getAASTags().toArray(new String[1])[0].equals("tag1"));
-
-
- // Test object with one tag
- AASDirectoryEntry aasEntry3 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "local", "tag1,tag2");
- // - Validate object
- assertTrue(aasEntry3.getAASTags().size() == 2);
- assertTrue(aasEntry3.getAASTags().toArray(new String[2])[0].equals("tag1"));
- assertTrue(aasEntry3.getAASTags().toArray(new String[2])[1].equals("tag2"));
- }
-
-
-
- /**
- * Execute test case that tests invalid directory entries
- */
- @Test
- public void testInvalidConstuctorParameter() {
- // Test object with minimal ID
- AASDirectoryEntry aasEntry1 = new AASDirectoryEntry("FHG", "<serializedAAS>", "local", "");
- // - Validate object
- assertFalse(aasEntry1.isValidID());
- assertFalse(aasEntry1.hasLegalEntity());
- assertFalse(aasEntry1.hasSubUnit());
- assertFalse(aasEntry1.hasSubModel());
- }
-}
-
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestStaticDirectoryFileProvider.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestStaticDirectoryFileProvider.java
deleted file mode 100644
index 9449904..0000000
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestStaticDirectoryFileProvider.java
+++ /dev/null
@@ -1,142 +0,0 @@
-package org.eclipse.basyx.regression.directory.file;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-
-import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
-import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
-import org.eclipse.basyx.tools.webserviceclient.WebServiceRawClient;
-import org.eclipse.basyx.vab.coder.json.metaprotocol.MetaprotocolHandler;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-
-
-/**
- * Test queries to CFG file directory provider
- *
- * @author kuhn
- *
- */
-public class TestStaticDirectoryFileProvider {
-
- /**
- * Makes sure Tomcat Server is started
- */
- @ClassRule
- public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
- private MetaprotocolHandler handler = new MetaprotocolHandler();
-
- /**
- * Execute test case that test working calls
- */
- @Test
- public void testWorkingCalls() {
- // Invoke BaSyx service calls via web services
- WebServiceRawClient client = new WebServiceRawClient();
-
- // Directory web service URL
- String wsURL = "http://localhost:8080/basys.components/Testsuite/Directory/CFGFile";
-
-
- // First test - get all locally registered AAS
- {
- // Get all locally registered AAS
- String result = getResult(client.get(wsURL + "/api/v1/registry"));
-
- // Check if all AAS are contained in result
- assertTrue(result.contains("{content.aas1}"));
- assertTrue(result.contains("{content.aas2}"));
- assertTrue(result.contains("{content.aas3}"));
- assertTrue(result.contains("{content.aas4}"));
- }
-
-
- // Get a specific AAS (1)
- try {
- // Get a known AAS by its ID
- String result = getResult(client.get(wsURL + "/api/v1/registry/urn:de.FHG:es.iese:aas:0.98:5:lab/" + URLEncoder.encode("microscope#A-19", "UTF-8")));
-
- // Check if all AAS are contained in result
- assertTrue(result.equals("{content.aas1}"));
- } catch (Exception e) {
- fail("Get specific AAS test case did throw exception:"+e);
- }
-
-
- // Get a specific AAS (2)
- try {
- // Get a known AAS by its ID
- String result = getResult(client.get(wsURL + "/api/v1/registry/urn:de.FHG:es.iese:aas:0.98:5:lab/" + URLEncoder.encode("microscope#A-18", "UTF-8")));
-
- // Check if all AAS are contained in result
- assertTrue(result.equals("{content.aas2}"));
- } catch (Exception e) {
- fail("Get specific AAS test case did throw exception:"+e);
- }
-
-
- // Get a specific AAS (3)
- try {
- // Get a known AAS by its ID
- String result = getResult(client.get(wsURL + "/api/v1/registry/urn:de.FHG:es.iese:aas:0.98:5:lab/" + URLEncoder.encode("microscope#A-17", "UTF-8")));
-
- // Check if all AAS are contained in result
- assertTrue(result.equals("{content.aas3}"));
- } catch (Exception e) {
- fail("Get specific AAS test case did throw exception:"+e);
- }
-
-
- // Get a specific AAS (4)
- try {
- // Get a known AAS by its ID
- String result = getResult(client.get(wsURL + "/api/v1/registry/urn:de.FHG:es.iese:aas:0.98:5:lab/" + URLEncoder.encode("microscope#A-16", "UTF-8")));
-
- // Check if all AAS are contained in result
- assertTrue(result.equals("{content.aas4}"));
- } catch (Exception e) {
- fail("Get specific AAS test case did throw exception:"+e);
- }
- }
-
-
-
- /**
- * Execute test case that test non-working calls
- *
- * @throws UnsupportedEncodingException
- */
- @Test
- public void testNonWorkingCalls() throws UnsupportedEncodingException {
- // Invoke service call via web services
- WebServiceRawClient client = new WebServiceRawClient();
-
- // Directory web service URL
- String wsURL = "http://localhost:8080/basys.components/Testsuite/Directory/CFGFile";
-
-
- // Get unknown AAS ID
- // Get a known AAS by its ID
- String result = getResult(client.get(
- wsURL + "/api/v1/registry/urn:de.FHG:es.iese:aas:0.98:5:lab/" + URLEncoder.encode("unknown", "UTF-8")));
-
- // Check if the getting a non existing URL returns a null
- assertEquals(null, result);
- }
-
- private String getResult(String res) {
- try {
- return (String) handler.deserialize(res);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-}
-
-
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestStaticDirectoryFileProviderExceptions.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestStaticDirectoryFileProviderExceptions.java
deleted file mode 100644
index 54e4749..0000000
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestStaticDirectoryFileProviderExceptions.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package org.eclipse.basyx.regression.directory.file;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-
-import javax.ws.rs.ServerErrorException;
-
-import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
-import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
-import org.eclipse.basyx.tools.webserviceclient.WebServiceJSONClient;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-
-/**
- * Test queries to CFG file provider
- *
- * @author kuhn
- *
- */
-public class TestStaticDirectoryFileProviderExceptions {
-
- /**
- * Makes sure Tomcat Server is started
- */
- @ClassRule
- public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
-
- /**
- * Execute test case that tests not implemented calls
- *
- * @throws UnsupportedEncodingException
- */
- @Test
- public void testUnsupportedCalls() throws UnsupportedEncodingException {
- // Invoke BaSyx service calls via web services
- WebServiceJSONClient client = new WebServiceJSONClient();
-
- // Directory web service URL
- String wsURL = "http://localhost:8080/basys.components/Testsuite/Directory/CFGFile";
-
-
-
- // Register a new AAS (using POST)
- try {
- // Get a known AAS by its ID
- client.post(wsURL + "/api/v1/registry", "Some content");
-
- // Exception was not thrown
- fail("Expected exception indicating that feature is not implemented was not thrown");
- } catch (ServerErrorException e) {
- // Check return code for expected return value (501)
- assertEquals(501, e.getResponse().getStatus());
-
- }
-
-
-
- // Renew a specific AAS registration (using PUT)
- try {
- // Get a known AAS by its ID
- client.put(wsURL + "/api/v1/registry/urn:de.FHG:es.iese:aas:0.98:5:lab/" + URLEncoder.encode("microscope#A-19", "UTF-8"), "Some updated content");
-
- // Exception was not thrown
- fail("Expected exception indicating that feature is not implemented was not thrown");
- } catch (ServerErrorException e) {
- // Check return code for expected return value (501)
- assertEquals(501, e.getResponse().getStatus());
- }
-
-
- // Delete a specific AAS registration (using PUT)
- try {
- // Get a known AAS by its ID
- client.delete(wsURL+"/api/v1/registry/urn:de.FHG:es.iese:aas:0.98:5:lab/"+URLEncoder.encode("microscope#A-19","UTF-8"));
-
- // Exception was not thrown
- fail("Expected exception indicating that feature is not implemented was not thrown");
- } catch (ServerErrorException e) {
- // Check return code for expected return value (501)
- assertEquals(501, e.getResponse().getStatus());
- }
-
- }
-}
-
-
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/models/controlcomponent/TestSimpleControlComponent.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/models/controlcomponent/TestSimpleControlComponent.java
index 0841263..230cf02 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/models/controlcomponent/TestSimpleControlComponent.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/models/controlcomponent/TestSimpleControlComponent.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.regression.models.controlcomponent;
import static org.junit.Assert.assertTrue;
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/DynamicActivitiProcessTest.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/DynamicActivitiProcessTest.java
index 5f5f0b9..eb26743 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/DynamicActivitiProcessTest.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/DynamicActivitiProcessTest.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.regression.processengineconnector;
@@ -180,4 +189,4 @@
output.close();
}
-}
\ No newline at end of file
+}
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/TestAASServicecall.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/TestAASServicecall.java
index 56a028c..2a3fdc6 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/TestAASServicecall.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/TestAASServicecall.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.regression.processengineconnector;
import static org.junit.Assert.assertEquals;
@@ -10,19 +19,19 @@
import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
import org.eclipse.basyx.aas.restapi.AASModelProvider;
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
+import org.eclipse.basyx.aas.restapi.MultiSubmodelProvider;
import org.eclipse.basyx.components.processengine.connector.DeviceServiceExecutor;
import org.eclipse.basyx.regression.support.processengine.aas.DeviceAdministrationShellFactory;
import org.eclipse.basyx.regression.support.processengine.stubs.CoilcarStub;
import org.eclipse.basyx.regression.support.processengine.submodel.DeviceSubmodelFactory;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
import org.eclipse.basyx.testsuite.regression.vab.gateway.ConnectorProviderStub;
import org.junit.Before;
import org.junit.Test;
@@ -76,19 +85,19 @@
coilcar = new CoilcarStub();
// Create the submodel of services provided by the coilcar with id "submodel1"
- SubModel sm = new DeviceSubmodelFactory().create(SUBMODEL_ID, coilcar);
+ Submodel sm = new DeviceSubmodelFactory().create(SUBMODEL_ID, coilcar);
// Create VAB multi-submodel provider for holding the sub-models
- VABMultiSubmodelProvider provider = new VABMultiSubmodelProvider();
+ MultiSubmodelProvider provider = new MultiSubmodelProvider();
// Add sub-model to the provider
- provider.addSubmodel(SUBMODEL_ID, new SubModelProvider(sm));
+ provider.addSubmodel(new SubmodelProvider(sm));
// Add aas to the provider
provider.setAssetAdministrationShell(new AASModelProvider(aas));
// Create registry for aas
- IAASRegistryService registry = new InMemoryRegistry();
+ IAASRegistry registry = new InMemoryRegistry();
// Create aas descriptor
IIdentifier id = new Identifier(IdentifierType.CUSTOM, AAS_ID);
@@ -96,7 +105,7 @@
// create submodel descriptor
IIdentifier smId = new Identifier(IdentifierType.CUSTOM, SUBMODEL_ID);
- SubmodelDescriptor smDescriptor = new SubmodelDescriptor("submodel1Name", smId, "/aas/submodels/"+SUBMODEL_ID);
+ SubmodelDescriptor smDescriptor = new SubmodelDescriptor("submodel1Name", smId, "/aas/submodels/" + SUBMODEL_ID + "/submodel");
// Add submodel descriptor to aas descriptor
aasDescriptor.addSubmodelDescriptor(smDescriptor);
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/TestJavaDelegate.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/TestJavaDelegate.java
index 9eeeecf..14fcefe 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/TestJavaDelegate.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/TestJavaDelegate.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.regression.processengineconnector;
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/TestTransportProcess_ConfigureEngineProgrammatically.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/TestTransportProcess_ConfigureEngineProgrammatically.java
index 4e616a9..0905775 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/TestTransportProcess_ConfigureEngineProgrammatically.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/TestTransportProcess_ConfigureEngineProgrammatically.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.regression.processengineconnector;
import java.io.File;
@@ -22,7 +31,7 @@
import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
@@ -92,7 +101,7 @@
// register the aas
registry.register(ccDescriptor);
- manager = new ConnectedAssetAdministrationShellManager(registry, new HTTPConnectorProvider());
+ manager = new ConnectedAssetAdministrationShellManager(registry, new HTTPConnectorFactory());
}
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderAAS.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderAAS.java
deleted file mode 100644
index 1ef899b..0000000
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderAAS.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package org.eclipse.basyx.regression.rawcfgprovider;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Map;
-
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
-import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-
-/**
- * Test queries to CFG file provider
- *
- * @author kuhn
- *
- */
-public class TestRawCFGProviderAAS {
-
-
- /**
- * VAB connection manager backend
- */
- protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(), new HTTPConnectorProvider());
-
- /**
- * Makes sure Tomcat Server is started
- */
- @ClassRule
- public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
-
- /**
- * Test basic queries
- */
- @SuppressWarnings({ "unchecked" })
- @Test
- public void test() throws Exception {
-
- // Connect to sub model "CfgFileTestAAS"
- VABElementProxy connSubModel = this.connManager.connectToVABElement("AASProvider");
-
-
- // Create map with complex type
- AssetAdministrationShell aas = new AssetAdministrationShell();
- aas.setIdShort("testAAS");
-
- // Create AAS structure on server
- connSubModel.createValue("/aas", aas);
-
-
- // Read complex property completely
- Map<String, Object> aasReadBack = (Map<String, Object>) connSubModel.getModelPropertyValue("/aas");
-
- assertEquals(aas.getIdShort(), AssetAdministrationShell.createAsFacade(aasReadBack).getIdShort());
-
- // Read AAS SubModel
- Map<String, Object> smReadBack = (Map<String, Object>) connSubModel
- .getModelPropertyValue("/aas/submodels/rawSampleCFG");
-
- assertEquals("rawSampleCFG", SubModel.createAsFacade(smReadBack).getIdShort());
-
- }
-}
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderAASNewModel.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderAASNewModel.java
deleted file mode 100644
index 8f9efc0..0000000
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderAASNewModel.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package org.eclipse.basyx.regression.rawcfgprovider;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Map;
-
-import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
-import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-
-/**
- * Test queries to CFG file provider
- *
- * @author kuhn
- *
- */
-public class TestRawCFGProviderAASNewModel {
-
-
- /**
- * VAB connection manager backend
- */
- protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(), new HTTPConnectorProvider());
-
- /**
- * Makes sure Tomcat Server is started
- */
- @ClassRule
- public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
-
- /**
- * Test basic queries
- */
- @SuppressWarnings({ "unchecked", "unused" })
- @Test
- public void test() throws Exception {
-
- // Connect to sub model "CfgFileTestAAS"
- VABElementProxy connSubModel = this.connManager.connectToVABElement("RawCfgFileTestAAS");
-
-
- // Create map with complex type
- Property prop = new Property ();
- prop.setIdShort("prop");
- // Create AAS structure on server
- connSubModel.createValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES, prop);
-
-
- // Read complex property completely
- Map<String, Object> aasReadBack = (Map<String, Object>) connSubModel.getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/prop");
- assertEquals(prop.getIdShort(), Property.createAsFacade(prop).getIdShort());
- }
-}
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderSimpleValues.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderSimpleValues.java
deleted file mode 100644
index ef95857..0000000
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderSimpleValues.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package org.eclipse.basyx.regression.rawcfgprovider;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Map;
-
-import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
-import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.AdministrativeInformation;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-/**
- * Test queries to CFG file provider
- *
- * @author kuhn
- *
- */
-public class TestRawCFGProviderSimpleValues {
-
- /**
- * VAB connection manager backend
- */
- protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(),
- new HTTPConnectorProvider());
-
- /**
- * Makes sure Tomcat Server is started
- */
- @ClassRule
- public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
-
- /**
- * Test basic queries
- */
- @SuppressWarnings("unchecked")
- @Test
- public void test() throws Exception {
-
- // Connect to sub model "CfgFileTestAAS"
- VABElementProxy connSubModel = this.connManager.connectToVABElement("RawCfgFileTestAAS");
-
- // Check sub model meta data
- Map<String, Object> submodel = (Map<String, Object>) connSubModel
- .getModelPropertyValue("/aas/submodels/rawSampleCFG");
- assertEquals("1.0",
- AdministrativeInformation.createAsFacade((Map<String, Object>) submodel.get(Identifiable.ADMINISTRATION))
- .getVersion());
-
- // Get property value
- Map<String, Object> value1 = (Map<String, Object>) connSubModel
- .getModelPropertyValue("/aas/submodels/rawSampleCFG/submodelElements/cfgProperty1/value");
- assertEquals("exampleStringValueRaw", value1.get(Property.VALUE));
- Map<String, Object> cfgProperty1 = (Map<String, Object>) connSubModel
- .getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty1");
- assertEquals("Configuration property description", cfgProperty1.get("description"));
-
- // Get property value
- Map<String, Object> value2 = (Map<String, Object>) connSubModel
- .getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty2/value");
- assertEquals(12, value2.get(Property.VALUE));
- // - Check property meta data (description)
- Map<String, Object> cfgProperty2 = (Map<String, Object>) connSubModel
- .getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty2");
- assertEquals("Configuration property description on multiple lines", cfgProperty2.get("description"));
-
- // Get property value
- Map<String, Object> value3 = (Map<String, Object>) connSubModel
- .getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty3/value");
- assertEquals("45.8", value3.get(Property.VALUE));
-
- // Get property value
- Map<String, Object> value4 = (Map<String, Object>) connSubModel
- .getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty4/value");
- assertEquals("44.8", value4.get(Property.VALUE));
- Map<String, Object> cfgProperty4 = (Map<String, Object>) connSubModel
- .getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty4");
- assertEquals("Another configuration property description", cfgProperty4.get("description"));
- assertEquals("8", cfgProperty4.get("newMetaData"));
- }
-}
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sql/SQLInvocationsTest.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sql/SQLInvocationsTest.java
new file mode 100644
index 0000000..4c03525
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sql/SQLInvocationsTest.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.sql;
+
+import java.util.Collection;
+import java.util.LinkedList;
+
+import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
+import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
+import org.junit.ClassRule;
+import org.junit.Ignore;
+import org.junit.Test;
+
+
+
+/**
+ * Test SQL invocations
+ *
+ * @author kuhn
+ *
+ */
+public class SQLInvocationsTest {
+
+
+ /**
+ * Store HTTP asset administration shell manager backend
+ */
+ protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(), new HTTPConnectorFactory());
+
+ /**
+ * Makes sure Tomcat Server is started
+ */
+ @ClassRule
+ public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
+
+ /**
+ * Test basic queries
+ */
+ @SuppressWarnings("unused")
+ @Test
+ @Ignore //FIXME the SQLTestSubmodel does not contain any operations
+ public void test() throws Exception {
+
+ // Connect to sub model "CfgFileTestAAS"
+ VABElementProxy connSubmodel = this.connManager.connectToVABElement("SQLTestSubmodel");
+
+
+ // Get property value (1)
+ Object value1 = connSubmodel.invokeOperation("/aas/submodels/SQLTestSubmodel/operations/sensorIDForName", "VS_0001");
+
+ // Get property value (2)
+ Object value2 = connSubmodel.invokeOperation("/aas/submodels/SQLTestSubmodel/operations/sensorIDForName", "VS_0002");
+
+
+ // Call operation that inserts a value into the database
+ // - Insert line into table
+ connSubmodel.invokeOperation("/aas/submodels/SQLTestSubmodel/operations/addSensorID", "sensorname, sensorid", "'VS_0005', '321'");
+
+ // Get property value (3)
+ Object value3 = connSubmodel.invokeOperation("/aas/submodels/SQLTestSubmodel/operations/sensorIDForName", "VS_0005");
+
+
+ // Delete property 'VS_0005'
+ // - Collection that contains call values
+ Collection<String> callValues4 = new LinkedList<>();
+ callValues4.add("VS_0005");
+ // - Delete sensor from table
+ connSubmodel.deleteValue("/aas/submodels/SQLTestSubmodel/properties/sensorNames", callValues4);
+
+ // Get property value (4)
+ Object value4 = connSubmodel.invokeOperation("/aas/submodels/SQLTestSubmodel/operations/sensorIDForName", "VS_0005");
+ }
+}
+
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sql/SQLQueriesTest.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sql/SQLQueriesTest.java
new file mode 100644
index 0000000..f2f9983
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sql/SQLQueriesTest.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.sql;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
+import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
+import org.junit.ClassRule;
+import org.junit.Ignore;
+import org.junit.Test;
+
+
+
+/**
+ * Test SQL queries
+ *
+ * @author kuhn
+ *
+ */
+public class SQLQueriesTest {
+
+
+ /**
+ * Store HTTP asset administration shell manager backend
+ */
+ protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(), new HTTPConnectorFactory());
+
+ /**
+ * Makes sure Tomcat Server is started
+ */
+ @ClassRule
+ public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
+
+
+ /**
+ * Test basic queries
+ */
+ @Test
+ @Ignore
+ public void test() throws Exception {
+
+ // Connect to sub model "CfgFileTestAAS"
+ VABElementProxy connSubmodel = this.connManager.connectToVABElement("SQLTestSubmodel");
+
+
+ // Get sub model
+ Object value0A = connSubmodel.getValue("/aas/submodels/SQLTestSubmodel");
+
+
+ // Get properties
+ Object value0B = connSubmodel.getValue("/aas/submodels/SQLTestSubmodel/dataElements");
+
+
+ // Get property value
+ Object value1 = connSubmodel
+ .getValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames/value");
+
+ // Get property value with meta data
+ Object value1a = connSubmodel.getValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames");
+
+
+ // Create a new property
+ // - HashMap that contains new table line
+ Map<String, Object> newTableLine = new HashMap<>();
+ newTableLine.put("sensorname", "VS_0003");
+ newTableLine.put("sensorid", "033542");
+ Property p = new Property(newTableLine);
+ p.setIdShort("sensorNames");
+ // - Insert line into table
+ connSubmodel.createValue("/aas/submodels/SQLTestSubmodel/dataElements", p);
+
+ // Get property value again
+ Object value2 = connSubmodel
+ .getValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames/value");
+
+ Object value2a = connSubmodel.getValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames");
+
+
+ // Update property value
+ // - Here this adds a new value into the table
+ // - Collection that contains call values
+ Map<String, Object> updatedTableLine = new HashMap<>();
+ updatedTableLine.put("sensorname", "VS_0004");
+ updatedTableLine.put("sensorid", "033542");
+ // - Update table line
+ connSubmodel.setValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames/value",
+ updatedTableLine);
+
+ // Get property value again
+ Object value3 = connSubmodel
+ .getValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames/value");
+
+
+ // Delete property with ID 033542
+ // - Map that contains call values
+ Map<String, Object> removedTableLine = new HashMap<>();
+ removedTableLine.put("sensorid", "033542");
+ // - Delete sensor from table
+ connSubmodel.deleteValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames/value", removedTableLine);
+
+ // Get property value again
+ Object value4 = connSubmodel
+ .getValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames/value");
+
+
+
+ // Get property meta data value
+ Object value5 = connSubmodel
+ .getValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames/category");
+ }
+}
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlprovider/SQLInvocationsTest.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlprovider/SQLInvocationsTest.java
deleted file mode 100644
index f8beb36..0000000
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlprovider/SQLInvocationsTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package org.eclipse.basyx.regression.sqlprovider;
-
-import java.util.Collection;
-import java.util.LinkedList;
-
-import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
-import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
-import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Ignore;
-import org.junit.Test;
-
-
-
-/**
- * Test SQL invocations
- *
- * @author kuhn
- *
- */
-public class SQLInvocationsTest {
-
-
- /**
- * Store HTTP asset administration shell manager backend
- */
- protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(), new HTTPConnectorProvider());
-
- /**
- * Makes sure Tomcat Server is started
- */
- @ClassRule
- public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
-
- /**
- * Test basic queries
- */
- @SuppressWarnings("unused")
- @Test
- @Ignore //FIXME the SQLTestSubmodel does not contain any operations
- public void test() throws Exception {
-
- // Connect to sub model "CfgFileTestAAS"
- VABElementProxy connSubModel = this.connManager.connectToVABElement("SQLTestSubmodel");
-
-
- // Get property value (1)
- Object value1 = connSubModel.invokeOperation("/aas/submodels/SQLTestSubmodel/operations/sensorIDForName", "VS_0001");
-
- // Get property value (2)
- Object value2 = connSubModel.invokeOperation("/aas/submodels/SQLTestSubmodel/operations/sensorIDForName", "VS_0002");
-
-
- // Call operation that inserts a value into the database
- // - Insert line into table
- connSubModel.invokeOperation("/aas/submodels/SQLTestSubmodel/operations/addSensorID", "sensorname, sensorid", "'VS_0005', '321'");
-
- // Get property value (3)
- Object value3 = connSubModel.invokeOperation("/aas/submodels/SQLTestSubmodel/operations/sensorIDForName", "VS_0005");
-
-
- // Delete property 'VS_0005'
- // - Collection that contains call values
- Collection<String> callValues4 = new LinkedList<>();
- callValues4.add("VS_0005");
- // - Delete sensor from table
- connSubModel.deleteValue("/aas/submodels/SQLTestSubmodel/properties/sensorNames", callValues4);
-
- // Get property value (4)
- Object value4 = connSubModel.invokeOperation("/aas/submodels/SQLTestSubmodel/operations/sensorIDForName", "VS_0005");
- }
-}
-
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlprovider/SQLQueriesTest.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlprovider/SQLQueriesTest.java
deleted file mode 100644
index a06b966..0000000
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlprovider/SQLQueriesTest.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package org.eclipse.basyx.regression.sqlprovider;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
-import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Ignore;
-import org.junit.Test;
-
-
-
-/**
- * Test SQL queries
- *
- * @author kuhn
- *
- */
-public class SQLQueriesTest {
-
-
- /**
- * Store HTTP asset administration shell manager backend
- */
- protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(), new HTTPConnectorProvider());
-
- /**
- * Makes sure Tomcat Server is started
- */
- @ClassRule
- public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
-
-
- /**
- * Test basic queries
- */
- @Test
- @Ignore
- public void test() throws Exception {
-
- // Connect to sub model "CfgFileTestAAS"
- VABElementProxy connSubModel = this.connManager.connectToVABElement("SQLTestSubmodel");
-
-
- // Get sub model
- Object value0A = connSubModel.getModelPropertyValue("/aas/submodels/SQLTestSubmodel");
-
-
- // Get properties
- Object value0B = connSubModel.getModelPropertyValue("/aas/submodels/SQLTestSubmodel/dataElements");
-
-
- // Get property value
- Object value1 = connSubModel
- .getModelPropertyValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames/value");
-
- // Get property value with meta data
- Object value1a = connSubModel.getModelPropertyValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames");
-
-
- // Create a new property
- // - HashMap that contains new table line
- Map<String, Object> newTableLine = new HashMap<>();
- newTableLine.put("sensorname", "VS_0003");
- newTableLine.put("sensorid", "033542");
- Property p = new Property(newTableLine);
- p.setIdShort("sensorNames");
- // - Insert line into table
- connSubModel.createValue("/aas/submodels/SQLTestSubmodel/dataElements", p);
-
- // Get property value again
- Object value2 = connSubModel
- .getModelPropertyValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames/value");
-
- Object value2a = connSubModel.getModelPropertyValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames");
-
-
- // Update property value
- // - Here this adds a new value into the table
- // - Collection that contains call values
- Map<String, Object> updatedTableLine = new HashMap<>();
- updatedTableLine.put("sensorname", "VS_0004");
- updatedTableLine.put("sensorid", "033542");
- // - Update table line
- connSubModel.setModelPropertyValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames/value",
- updatedTableLine);
-
- // Get property value again
- Object value3 = connSubModel
- .getModelPropertyValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames/value");
-
-
- // Delete property with ID 033542
- // - Map that contains call values
- Map<String, Object> removedTableLine = new HashMap<>();
- removedTableLine.put("sensorid", "033542");
- // - Delete sensor from table
- connSubModel.deleteValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames/value", removedTableLine);
-
- // Get property value again
- Object value4 = connSubModel
- .getModelPropertyValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames/value");
-
-
-
- // Get property meta data value
- Object value5 = connSubModel
- .getModelPropertyValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames/category");
- }
-}
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLConfig.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLConfig.java
index a1a592f..a483a90 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLConfig.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLConfig.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.regression.sqlproxy;
/**
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestCollectionSetOperations.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestCollectionSetOperations.java
index 0e18044..e54d7fa 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestCollectionSetOperations.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestCollectionSetOperations.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.regression.sqlproxy;
import static org.junit.Assert.assertTrue;
@@ -40,7 +49,7 @@
sqlRootElement.drop();
// Create new table in database for root element
- sqlRootElement.create();
+ sqlRootElement.createRootTableIfNotExists();
// Create collection
Collection<Object> sqlColl = sqlRootElement.createCollection(1);
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestCollectionSimple.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestCollectionSimple.java
index 0b4f6c6..e13d8fe 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestCollectionSimple.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestCollectionSimple.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.regression.sqlproxy;
import static org.junit.Assert.assertTrue;
@@ -41,7 +50,7 @@
sqlRootElement.drop();
// Create new table in database for root element
- sqlRootElement.create();
+ sqlRootElement.createRootTableIfNotExists();
// Create collection
Collection<Object> sqlColl = sqlRootElement.createCollection(1);
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestCollectionTypes.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestCollectionTypes.java
index 606cf87..ed03ba1 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestCollectionTypes.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestCollectionTypes.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.regression.sqlproxy;
import static org.junit.Assert.assertTrue;
@@ -41,7 +50,7 @@
sqlRootElement.drop();
// Create new table in database for root element
- sqlRootElement.create();
+ sqlRootElement.createRootTableIfNotExists();
// Create collection
Collection<Object> sqlColl = sqlRootElement.createCollection(1);
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapArrayTypes.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapArrayTypes.java
index 024dde1..d84053c 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapArrayTypes.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapArrayTypes.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.regression.sqlproxy;
import static org.junit.Assert.assertTrue;
@@ -40,7 +49,7 @@
sqlRootElement.drop();
// Create new table in database for root element
- sqlRootElement.create();
+ sqlRootElement.createRootTableIfNotExists();
// Create new SQL map
Map<String, Object> sqlMap = sqlRootElement.createMap(1);
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapSetOperations.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapSetOperations.java
index 12a4c6c..fec4a59 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapSetOperations.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapSetOperations.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.regression.sqlproxy;
import static org.junit.Assert.assertTrue;
@@ -46,7 +55,7 @@
sqlRootElement.drop();
// Create new table in database for root element
- sqlRootElement.create();
+ sqlRootElement.createRootTableIfNotExists();
// Create new SQL map
Map<String, Object> sqlMap = sqlRootElement.createMap(1);
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapSimple.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapSimple.java
index b198ccf..62e7a5b 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapSimple.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapSimple.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.regression.sqlproxy;
import static org.junit.Assert.assertTrue;
@@ -41,7 +50,7 @@
sqlRootElement.drop();
// Create new table in database for root element
- sqlRootElement.create();
+ sqlRootElement.createRootTableIfNotExists();
// Create new SQL map
Map<String, Object> sqlMap = sqlRootElement.createMap(1);
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapSimpleTypes.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapSimpleTypes.java
index ff26f0a..2df7ea5 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapSimpleTypes.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapSimpleTypes.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.regression.sqlproxy;
import static org.junit.Assert.assertTrue;
@@ -39,7 +48,7 @@
sqlRootElement.drop();
// Create new table in database for root element
- sqlRootElement.create();
+ sqlRootElement.createRootTableIfNotExists();
// Create new SQL map
Map<String, Object> sqlMap = sqlRootElement.createMap(1);
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestRootElement.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestRootElement.java
index fdb94ea..8ffeac1 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestRootElement.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestRootElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.regression.sqlproxy;
import static org.junit.Assert.assertTrue;
@@ -32,7 +41,7 @@
// Create SQL root element
sqlRootElement = new SQLRootElement(SQLConfig.SQLUSER, SQLConfig.SQLPW, "//localhost/basyx-map?", "org.postgresql.Driver", "jdbc:postgresql:", "root_el_01");
// - Create new table in database for root element
- sqlRootElement.create();
+ sqlRootElement.createRootTableIfNotExists();
// Get element IDs
assertTrue(sqlRootElement.getNextIdentifier() == 1);
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestRootElementSQLElements.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestRootElementSQLElements.java
index 4839945..90aff02 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestRootElementSQLElements.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestRootElementSQLElements.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.regression.sqlproxy;
import static org.junit.Assert.assertTrue;
@@ -37,7 +46,7 @@
sqlRootElement = new SQLRootElement(SQLConfig.SQLUSER, SQLConfig.SQLPW, "//localhost/basyx-map?", "org.postgresql.Driver", "jdbc:postgresql:", "root_el_01");
// - Create new table in database for root element
sqlRootElement.drop();
- sqlRootElement.create();
+ sqlRootElement.createRootTableIfNotExists();
// Create map
Map<String, Object> rootMap = sqlRootElement.createMap(0);
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/bundle/TestAASBundleDescriptorFactory.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/bundle/TestAASBundleDescriptorFactory.java
index 42d5003..95e63c2 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/bundle/TestAASBundleDescriptorFactory.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/bundle/TestAASBundleDescriptorFactory.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.regression.support.bundle;
import static org.junit.Assert.assertEquals;
@@ -7,7 +16,8 @@
import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
import org.eclipse.basyx.support.bundle.AASBundle;
import org.eclipse.basyx.support.bundle.AASBundleDescriptorFactory;
import org.eclipse.basyx.vab.modelprovider.VABPathTools;
@@ -24,10 +34,10 @@
public void testDescriptorCreation() {
String aasId = "aasId";
AssetAdministrationShell shell = new AssetAdministrationShell();
- shell.setIdShort(aasId);
+ shell.setIdentification(new Identifier(IdentifierType.CUSTOM, aasId));
String smId = "smId";
- SubModel sm = new SubModel();
+ Submodel sm = new Submodel();
sm.setIdShort(smId);
sm.setIdentification(IdentifierType.IRI, "aasIdIRI");
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/bundle/TestAASBundleHelper.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/bundle/TestAASBundleHelper.java
new file mode 100644
index 0000000..8c28852
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/bundle/TestAASBundleHelper.java
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.support.bundle;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.basyx.aas.aggregator.AASAggregator;
+import org.eclipse.basyx.aas.aggregator.proxy.AASAggregatorProxy;
+import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.support.bundle.AASBundle;
+import org.eclipse.basyx.support.bundle.AASBundleHelper;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test for the AASBundelIntegrator
+ *
+ * @author conradi
+ *
+ */
+public class TestAASBundleHelper {
+
+ private static final String AAS_ID = "TestAAS";
+ private static final String SM_ID = "TestSM";
+
+
+ private AASAggregatorProxy aggregator;
+ private List<AASBundle> bundles;
+ private AASAggregatorProvider provider;
+
+
+
+ @Before
+ public void init() {
+ provider = new AASAggregatorProvider(new AASAggregator());
+ aggregator = new AASAggregatorProxy(new VABElementProxy("/shells", provider));
+ bundles = new ArrayList<>();
+ }
+
+ /**
+ * This test loads an AAS and its two Submodels into the Aggregator,
+ * runs the integration with AAS and Submodels with the same IDs, but different content,
+ * checks if integration does NOT replace the models in the Aggregator.
+ */
+ @Test
+ public void testIntegrationOfExistingAASAndSM() {
+ AASBundle bundle = getTestBundle();
+ bundles.add(bundle);
+
+ // Load AAS and SM AASAggregator
+ AssetAdministrationShell aas = (AssetAdministrationShell) bundle.getAAS();
+ Set<ISubmodel> submodels = bundle.getSubmodels();
+ Submodel sm = (Submodel) submodels.iterator().next();
+ pushAAS(aas);
+ pushSubmodel(sm, aas.getIdentification());
+
+ assertFalse(AASBundleHelper.integrate(aggregator, bundles));
+ checkAggregatorContent();
+ }
+
+ /**
+ * This test loads an AAS into the Aggregator,
+ * runs the integration with the AAS and a SM,
+ * checks if both is present in Aggregator afterwards.
+ */
+ @Test
+ public void testIntegrationOfExistingAASAndNonexistingSM() {
+ AASBundle bundle = getTestBundle();
+ bundles.add(bundle);
+
+ // Load only AAS into AASAggregator
+ AssetAdministrationShell aas = (AssetAdministrationShell) bundle.getAAS();
+ pushAAS(aas);
+
+ assertTrue(AASBundleHelper.integrate(aggregator, bundles));
+ checkAggregatorContent();
+ }
+
+ /**
+ * This test loads nothing into the Aggregator,
+ * runs the integration with the AAS and a SM,
+ * checks if both is present in Aggregator afterwards.
+ */
+ @Test
+ public void testIntegrationOfNonexistingAASAndSM() {
+ AASBundle bundle = getTestBundle();
+ bundles.add(bundle);
+
+ assertTrue(AASBundleHelper.integrate(aggregator, bundles));
+ checkAggregatorContent();
+ }
+
+ /**
+ * This test loads nothing into the Aggregator,
+ * runs the integration with the AAS and a SM,
+ * checks if both is present in Aggregator afterwards. Furthermore,
+ * the AASAggregator has a registry for registering and resolving potential
+ * submodels.
+ */
+ @Test
+ public void testIntegrationOfNonexistingAASAndSMWithRegistry() {
+ IAASRegistry registry = new InMemoryRegistry();
+ provider = new AASAggregatorProvider(new AASAggregator(registry));
+ aggregator = new AASAggregatorProxy(new VABElementProxy("/shells", provider));
+
+ AASBundle bundle = getTestBundle();
+ bundles.add(bundle);
+
+ assertTrue(AASBundleHelper.integrate(aggregator, bundles));
+ checkAggregatorContent();
+ }
+
+ @SuppressWarnings("unchecked")
+ private void checkAggregatorContent() {
+ IAssetAdministrationShell aas = aggregator.getAAS(new Identifier(IdentifierType.CUSTOM, AAS_ID));
+ assertEquals(AAS_ID, aas.getIdShort());
+ IModelProvider provider = aggregator.getAASProvider(new Identifier(IdentifierType.CUSTOM, AAS_ID));
+
+ Submodel sm = SubmodelElementMapCollectionConverter.mapToSM(
+ (Map<String, Object>) provider.getValue("/aas/submodels/" + SM_ID));
+
+ assertEquals(SM_ID, sm.getIdentification().getId());
+ }
+
+ private void pushAAS(AssetAdministrationShell aas) {
+ aggregator.createAAS(aas);
+ }
+
+ private void pushSubmodel(Submodel sm, IIdentifier aasIdentifier) {
+ provider.setValue("/" + AASAggregatorProvider.PREFIX + "/" + aasIdentifier.getId() + "/aas/submodels/" + sm.getIdShort(), sm);
+ }
+
+ private AASBundle getTestBundle() {
+ Submodel sm = new Submodel();
+ sm.setIdShort(SM_ID);
+ sm.setIdentification(IdentifierType.CUSTOM, SM_ID);
+
+ AssetAdministrationShell aas = new AssetAdministrationShell();
+ aas.setIdentification(IdentifierType.CUSTOM, AAS_ID);
+ aas.setIdShort(AAS_ID);
+ aas.addSubmodel(sm);
+
+ return new AASBundle(aas, new HashSet<>(Arrays.asList(sm)));
+ }
+}
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/directory/ComponentsTestsuiteDirectory.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/directory/ComponentsTestsuiteDirectory.java
index 523136d..32f3923 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/directory/ComponentsTestsuiteDirectory.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/directory/ComponentsTestsuiteDirectory.java
@@ -1,6 +1,15 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.regression.support.directory;
-import org.eclipse.basyx.vab.directory.memory.InMemoryDirectory;
+import org.eclipse.basyx.vab.registry.memory.VABInMemoryRegistry;
@@ -11,7 +20,7 @@
* @author kuhn
*
*/
-public class ComponentsTestsuiteDirectory extends InMemoryDirectory {
+public class ComponentsTestsuiteDirectory extends VABInMemoryRegistry {
/**
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/aas/DeviceAdministrationShellFactory.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/aas/DeviceAdministrationShellFactory.java
index 4d5831d..ae86a08 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/aas/DeviceAdministrationShellFactory.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/aas/DeviceAdministrationShellFactory.java
@@ -1,9 +1,20 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.regression.support.processengine.aas;
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
public class DeviceAdministrationShellFactory {
@@ -11,11 +22,11 @@
public AssetAdministrationShell create(String aasid, String submodelid) {
// create the aas, add submodel to aas using VABMultiSubmodelProvider
IIdentifier id = new Identifier(IdentifierType.CUSTOM, submodelid);
- SubModel sm = new SubModel();
+ Submodel sm = new Submodel();
sm.setIdentification(id.getIdType(), id.getId());
- AssetAdministrationShell aas = new AssetAdministrationShell();
- aas.addSubModel(sm);
- aas.put("idshort", aasid);
+ sm.setIdShort("smIdShort");
+ AssetAdministrationShell aas = new AssetAdministrationShell(aasid, new Identifier(IdentifierType.CUSTOM, aasid + "Id"), new Asset("assetId", new Identifier(IdentifierType.CUSTOM, aasid + "assetId"), AssetKind.INSTANCE));
+ aas.addSubmodel(sm);
return aas;
}
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/servlet/CoilcarAASServlet.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/servlet/CoilcarAASServlet.java
index 427ffff..dfc1709 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/servlet/CoilcarAASServlet.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/servlet/CoilcarAASServlet.java
@@ -1,13 +1,22 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.regression.support.processengine.servlet;
import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
import org.eclipse.basyx.aas.restapi.AASModelProvider;
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
+import org.eclipse.basyx.aas.restapi.MultiSubmodelProvider;
import org.eclipse.basyx.regression.support.processengine.aas.DeviceAdministrationShellFactory;
import org.eclipse.basyx.regression.support.processengine.stubs.Coilcar;
import org.eclipse.basyx.regression.support.processengine.submodel.DeviceSubmodelFactory;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
/**
@@ -16,13 +25,13 @@
* @author zhangzai
*
*/
-public class CoilcarAASServlet extends VABHTTPInterface<VABMultiSubmodelProvider> {
+public class CoilcarAASServlet extends VABHTTPInterface<MultiSubmodelProvider> {
private static final long serialVersionUID = 1L;
private String aasid = "coilcar";
private String submodelid = "submodel1";
public CoilcarAASServlet() {
- super(new VABMultiSubmodelProvider());
+ super(new MultiSubmodelProvider());
// Create the aas
AssetAdministrationShell coilcarAAS = new DeviceAdministrationShellFactory().create(aasid, submodelid);
@@ -31,10 +40,10 @@
coilcarAAS.setIdShort(aasid);
// Create the sub-model
- SubModel coilcarSubmodel = new DeviceSubmodelFactory().create(submodelid, new Coilcar());
+ Submodel coilcarSubmodel = new DeviceSubmodelFactory().create(submodelid, new Coilcar());
getModelProvider().setAssetAdministrationShell(new AASModelProvider(coilcarAAS));
- getModelProvider().addSubmodel(submodelid, new SubModelProvider(coilcarSubmodel));
+ getModelProvider().addSubmodel(new SubmodelProvider(coilcarSubmodel));
}
-}
\ No newline at end of file
+}
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/BPMNEngineStub.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/BPMNEngineStub.java
index ebd37b7..0b2302d 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/BPMNEngineStub.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/BPMNEngineStub.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.regression.support.processengine.stubs;
import java.lang.reflect.Field;
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/BPMNModelFactory.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/BPMNModelFactory.java
index 35e515e..d63b000 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/BPMNModelFactory.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/BPMNModelFactory.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.regression.support.processengine.stubs;
import static org.camunda.bpm.model.bpmn.impl.BpmnModelConstants.CAMUNDA_NS;
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/Coilcar.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/Coilcar.java
index c9db39d..77deec6 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/Coilcar.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/Coilcar.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.regression.support.processengine.stubs;
import org.slf4j.Logger;
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/CoilcarStub.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/CoilcarStub.java
index 10ee907..b00d284 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/CoilcarStub.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/CoilcarStub.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.regression.support.processengine.stubs;
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/DeviceServiceExecutorStub.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/DeviceServiceExecutorStub.java
index bce54c5..3edb2af 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/DeviceServiceExecutorStub.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/DeviceServiceExecutorStub.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.regression.support.processengine.stubs;
import java.util.List;
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/ICoilcar.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/ICoilcar.java
index 76d0e8b..7e7b387 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/ICoilcar.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/ICoilcar.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.regression.support.processengine.stubs;
public interface ICoilcar {
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/ProcessInstanceStub.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/ProcessInstanceStub.java
index 732691e..8b25108 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/ProcessInstanceStub.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/ProcessInstanceStub.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.regression.support.processengine.stubs;
import org.camunda.bpm.engine.impl.pvm.runtime.ExecutionImpl;
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/submodel/DeviceSubmodelFactory.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/submodel/DeviceSubmodelFactory.java
index 1e1f82d..69a358a 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/submodel/DeviceSubmodelFactory.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/submodel/DeviceSubmodelFactory.java
@@ -1,17 +1,30 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.regression.support.processengine.submodel;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import org.eclipse.basyx.regression.support.processengine.stubs.ICoilcar;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
public class DeviceSubmodelFactory {
- public SubModel create(String id, ICoilcar coilcar) {
+ public Submodel create(String id, ICoilcar coilcar) {
// create a single value property
Property property1 = new Property(0);
property1.setIdShort("currentPosition");
@@ -26,12 +39,16 @@
Operation op1 = new Operation((Function<Object[], Object>) obj -> {
return coilcar.liftTo((int)obj[0]);
});
+ op1.setInputVariables(Collections.singletonList(new OperationVariable(new Property("position", 0))));
+ op1.setOutputVariables(Collections.singletonList(new OperationVariable(new Property("result", 0))));
op1.setIdShort("liftTo");
Operation op2 = new Operation((Function<Object[], Object>) obj -> {
coilcar.moveTo((int)obj[0]);
return true;
});
+ op2.setInputVariables(Collections.singletonList(new OperationVariable(new Property("position", 0))));
+ op2.setOutputVariables(Collections.singletonList(new OperationVariable(new Property("result", 0))));
op2.setIdShort("moveTo");
// create a list for defined operations
@@ -44,9 +61,9 @@
propList.add(property2);
propList.add(property3);
// create the sub-model and add the property and operations to the sub-model
- SubModel sm = new SubModel(propList, opList);
-
- sm.setIdShort(id);
+ Submodel sm = new Submodel(id, new Identifier(IdentifierType.CUSTOM, id + "Custom"));
+ propList.forEach(sm::addSubmodelElement);
+ opList.forEach(sm::addSubmodelElement);
return sm;
}
}
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/server/context/ComponentsRegressionContext.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/server/context/ComponentsRegressionContext.java
index aebfe25..ab98927 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/server/context/ComponentsRegressionContext.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/server/context/ComponentsRegressionContext.java
@@ -1,9 +1,14 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.regression.support.server.context;
-import org.eclipse.basyx.components.servlet.registry.StaticCFGDirectoryServlet;
-import org.eclipse.basyx.components.servlet.submodel.SQLSubModelProviderServlet;
-import org.eclipse.basyx.components.servlet.submodel.cfg.CFGSubModelProviderServlet;
-import org.eclipse.basyx.components.servlet.submodel.cfg.RawCFGSubModelProviderServlet;
import org.eclipse.basyx.regression.support.processengine.servlet.CoilcarAASServlet;
import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
@@ -33,10 +38,6 @@
super("/basys.components", "");
// Define Servlet infrastructure
- addServletMapping("/Testsuite/components/BaSys/1.0/provider/sqlsm/*", new SQLSubModelProviderServlet().withParameter("config", "/WebContent/WEB-INF/config/sqlprovider/sampledb.properties"));
- addServletMapping("/Testsuite/components/BaSys/1.0/provider/cfgsm/*", new CFGSubModelProviderServlet().withParameter("config", "/WebContent/WEB-INF/config/cfgprovider/samplecfg.properties"));
- addServletMapping("/Testsuite/components/BaSys/1.0/provider/rawcfgsm/*", new RawCFGSubModelProviderServlet().withParameter("config", "/WebContent/WEB-INF/config/rawcfgprovider/samplecfg.properties"));
- addServletMapping("/Testsuite/Directory/CFGFile/*", new StaticCFGDirectoryServlet().withParameter("config", "/WebContent/WEB-INF/config/directory/cfgdirectory/directory.properties"));
addServletMapping("/Testsuite/Processengine/coilcar/*", new CoilcarAASServlet());
}
}
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/xml/TestXMLAASBundleFactory.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/xml/TestXMLAASBundleFactory.java
index 3817d18..9e3836c 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/xml/TestXMLAASBundleFactory.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/xml/TestXMLAASBundleFactory.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.regression.xml;
import static org.junit.Assert.assertTrue;
@@ -10,7 +19,7 @@
import org.eclipse.basyx.components.configuration.BaSyxConfiguration;
import org.eclipse.basyx.components.xml.XMLAASBundleFactory;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
import org.eclipse.basyx.support.bundle.AASBundle;
import org.junit.Test;
import org.xml.sax.SAXException;
@@ -51,11 +60,11 @@
AASBundle minimalAASBundle = minimalBundleOptional.get();
// Check full AAS
- Set<ISubModel> fullAASSM = fullAASBundle.getSubmodels();
+ Set<ISubmodel> fullAASSM = fullAASBundle.getSubmodels();
assertTrue(fullAASSM.stream().anyMatch(s -> s.getIdentification().getId().equals("http://www.zvei.de/demo/submodel/12345679")));
// Check minimal AAS
- Set<ISubModel> minimalAASSM = minimalAASBundle.getSubmodels();
+ Set<ISubmodel> minimalAASSM = minimalAASBundle.getSubmodels();
assertTrue(minimalAASSM.isEmpty());
}
}
diff --git a/components/basys.components/docker-compose.yml b/components/basys.components/docker-compose.yml
new file mode 100644
index 0000000..749de1f
--- /dev/null
+++ b/components/basys.components/docker-compose.yml
@@ -0,0 +1,17 @@
+version: '2.1'
+services:
+ postgres:
+ image: postgres:12.1
+ container_name: postgres
+ environment:
+ - POSTGRES_USER:'postgres'
+ - POSTGRES_PASSWORD:'admin'
+ - POSTGRES_DB=basyx-directory
+ ports:
+ - 127.0.0.1:5432:5432
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U postgres"]
+ interval: 3s
+ timeout: 3s
+ retries: 5
+
diff --git a/components/basys.components/mvnw b/components/basys.components/mvnw
new file mode 100755
index 0000000..a16b543
--- /dev/null
+++ b/components/basys.components/mvnw
@@ -0,0 +1,310 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+# JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+# M2_HOME - location of maven2's installed home dir
+# MAVEN_OPTS - parameters passed to the Java VM when running Maven
+# e.g. to debug Maven itself, use
+# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ] ; then
+
+ if [ -f /etc/mavenrc ] ; then
+ . /etc/mavenrc
+ fi
+
+ if [ -f "$HOME/.mavenrc" ] ; then
+ . "$HOME/.mavenrc"
+ fi
+
+fi
+
+# OS specific support. $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "`uname`" in
+ CYGWIN*) cygwin=true ;;
+ MINGW*) mingw=true;;
+ Darwin*) darwin=true
+ # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
+ # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
+ if [ -z "$JAVA_HOME" ]; then
+ if [ -x "/usr/libexec/java_home" ]; then
+ export JAVA_HOME="`/usr/libexec/java_home`"
+ else
+ export JAVA_HOME="/Library/Java/Home"
+ fi
+ fi
+ ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+ if [ -r /etc/gentoo-release ] ; then
+ JAVA_HOME=`java-config --jre-home`
+ fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+ ## resolve links - $0 may be a link to maven's home
+ PRG="$0"
+
+ # need this for relative symlinks
+ while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG="`dirname "$PRG"`/$link"
+ fi
+ done
+
+ saveddir=`pwd`
+
+ M2_HOME=`dirname "$PRG"`/..
+
+ # make it fully qualified
+ M2_HOME=`cd "$M2_HOME" && pwd`
+
+ cd "$saveddir"
+ # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --unix "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+fi
+
+# For Mingw, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME="`(cd "$M2_HOME"; pwd)`"
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+ javaExecutable="`which javac`"
+ if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
+ # readlink(1) is not available as standard on Solaris 10.
+ readLink=`which readlink`
+ if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
+ if $darwin ; then
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
+ else
+ javaExecutable="`readlink -f \"$javaExecutable\"`"
+ fi
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+ JAVA_HOME="$javaHome"
+ export JAVA_HOME
+ fi
+ fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+ if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ else
+ JAVACMD="`which java`"
+ fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+ echo "Error: JAVA_HOME is not defined correctly." >&2
+ echo " We cannot execute $JAVACMD" >&2
+ exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+ echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+
+ if [ -z "$1" ]
+ then
+ echo "Path not specified to find_maven_basedir"
+ return 1
+ fi
+
+ basedir="$1"
+ wdir="$1"
+ while [ "$wdir" != '/' ] ; do
+ if [ -d "$wdir"/.mvn ] ; then
+ basedir=$wdir
+ break
+ fi
+ # workaround for JBEAP-8937 (on Solaris 10/Sparc)
+ if [ -d "${wdir}" ]; then
+ wdir=`cd "$wdir/.."; pwd`
+ fi
+ # end of workaround
+ done
+ echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+ if [ -f "$1" ]; then
+ echo "$(tr -s '\n' ' ' < "$1")"
+ fi
+}
+
+BASE_DIR=`find_maven_basedir "$(pwd)"`
+if [ -z "$BASE_DIR" ]; then
+ exit 1;
+fi
+
+##########################################################################################
+# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+# This allows using the maven wrapper in projects that prohibit checking in binary data.
+##########################################################################################
+if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found .mvn/wrapper/maven-wrapper.jar"
+ fi
+else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
+ fi
+ if [ -n "$MVNW_REPOURL" ]; then
+ jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+ else
+ jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+ fi
+ while IFS="=" read key value; do
+ case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
+ esac
+ done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Downloading from: $jarUrl"
+ fi
+ wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
+ if $cygwin; then
+ wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
+ fi
+
+ if command -v wget > /dev/null; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found wget ... using wget"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ wget "$jarUrl" -O "$wrapperJarPath"
+ else
+ wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
+ fi
+ elif command -v curl > /dev/null; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found curl ... using curl"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ curl -o "$wrapperJarPath" "$jarUrl" -f
+ else
+ curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+ fi
+
+ else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Falling back to using Java to download"
+ fi
+ javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+ # For Cygwin, switch paths to Windows format before running javac
+ if $cygwin; then
+ javaClass=`cygpath --path --windows "$javaClass"`
+ fi
+ if [ -e "$javaClass" ]; then
+ if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Compiling MavenWrapperDownloader.java ..."
+ fi
+ # Compiling the Java class
+ ("$JAVA_HOME/bin/javac" "$javaClass")
+ fi
+ if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+ # Running the downloader
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Running MavenWrapperDownloader.java ..."
+ fi
+ ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
+ fi
+ fi
+ fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
+if [ "$MVNW_VERBOSE" = true ]; then
+ echo $MAVEN_PROJECTBASEDIR
+fi
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --path --windows "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+ [ -n "$MAVEN_PROJECTBASEDIR" ] &&
+ MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
+fi
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+exec "$JAVACMD" \
+ $MAVEN_OPTS \
+ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+ "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+ ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/components/basys.components/mvnw.cmd b/components/basys.components/mvnw.cmd
new file mode 100644
index 0000000..c8d4337
--- /dev/null
+++ b/components/basys.components/mvnw.cmd
@@ -0,0 +1,182 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM https://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Maven Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM set title of command window
+title %0
+@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
+if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+
+FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+ IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
+)
+
+@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
+if exist %WRAPPER_JAR% (
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Found %WRAPPER_JAR%
+ )
+) else (
+ if not "%MVNW_REPOURL%" == "" (
+ SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+ )
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Couldn't find %WRAPPER_JAR%, downloading it ...
+ echo Downloading from: %DOWNLOAD_URL%
+ )
+
+ powershell -Command "&{"^
+ "$webclient = new-object System.Net.WebClient;"^
+ "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
+ "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
+ "}"^
+ "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
+ "}"
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Finished downloading %WRAPPER_JAR%
+ )
+)
+@REM End of extension
+
+@REM Provide a "standardized" way to retrieve the CLI args that will
+@REM work with both Windows and non-Windows executions.
+set MAVEN_CMD_LINE_ARGS=%*
+
+%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
+if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%" == "on" pause
+
+if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
+
+exit /B %ERROR_CODE%
diff --git a/components/basys.components/pom.xml b/components/basys.components/pom.xml
index 79515eb..6bc6bf7 100644
--- a/components/basys.components/pom.xml
+++ b/components/basys.components/pom.xml
@@ -5,7 +5,7 @@
<groupId>org.eclipse.basyx</groupId>
<artifactId>basyx.components</artifactId>
- <version>0.0.1-SNAPSHOT</version>
+ <version>1.0.0</version>
<name>BaSyx Components</name>
<packaging>pom</packaging>
@@ -79,6 +79,8 @@
<excludes>
<exclude>**/*HTTP*</exclude>
<exclude>**/*TCP*</exclude>
+ <!-- Exclude explicit MongoDB tests for CI -->
+ <exclude>**/*MongoDB*</exclude>
</excludes>
</configuration>
</plugin>
@@ -119,14 +121,14 @@
<dependency>
<groupId>org.eclipse.basyx</groupId>
<artifactId>basyx.sdk</artifactId>
- <version>0.0.1-SNAPSHOT</version>
+ <version>1.0.0</version>
</dependency>
<!-- BaSyx SDK tests -->
<dependency>
<groupId>org.eclipse.basyx</groupId>
<artifactId>basyx.sdk</artifactId>
- <version>0.0.1-SNAPSHOT</version>
+ <version>1.0.0</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
diff --git a/components/basyx.tck/.gitignore b/components/basyx.tck/.gitignore
new file mode 100644
index 0000000..e0e5af1
--- /dev/null
+++ b/components/basyx.tck/.gitignore
@@ -0,0 +1,72 @@
+regressiontest/
+
+.classpath
+.project
+
+test.txt
+
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+.mvn/wrapper/maven-wrapper.jar
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.settings/
+.loadpath
+.recommenders
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# PyDev specific (Python IDE for Eclipse)
+*.pydevproject
+
+# CDT-specific (C/C++ Development Tooling)
+.cproject
+
+# CDT- autotools
+.autotools
+
+# Java annotation processor (APT)
+.factorypath
+
+# PDT-specific (PHP Development Tools)
+.buildpath
+
+# sbteclipse plugin
+.target
+
+# Tern plugin
+.tern-project
+
+# TeXlipse plugin
+.texlipse
+
+# STS (Spring Tool Suite)
+.springBeans
+
+# Code Recommenders
+.recommenders/
+
+# Annotation Processing
+.apt_generated/
+
+# Scala IDE specific (Scala & Java development for Eclipse)
+.cache-main
+.scala_dependencies
+.worksheet
\ No newline at end of file
diff --git a/components/basyx.tck/basyx.tck.AASServer/pom.xml b/components/basyx.tck/basyx.tck.AASServer/pom.xml
new file mode 100644
index 0000000..f4b0326
--- /dev/null
+++ b/components/basyx.tck/basyx.tck.AASServer/pom.xml
@@ -0,0 +1,58 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.eclipse.basyx</groupId>
+ <artifactId>basyx.tck</artifactId>
+ <version>1.0.0</version>
+ </parent>
+
+ <artifactId>basyx.tck.AASServer</artifactId>
+ <name>TCK for AAS API</name>
+ <packaging>jar</packaging>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+ </properties>
+
+ <build>
+ <sourceDirectory>src/main/java</sourceDirectory>
+ <testSourceDirectory>src/test/java</testSourceDirectory>
+
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <descriptor>src/main/assembly/assembly.xml</descriptor>
+ <archive>
+ <manifest>
+ <mainClass>org.eclipse.basyx.testsuite.regression.aas.metamodel.AASServerTestApplication</mainClass>
+ </manifest>
+ </archive>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+
+ <dependencies>
+ <!-- This component is based on the xmlAAS component -->
+ <dependency>
+ <groupId>org.eclipse.basyx</groupId>
+ <artifactId>basyx.components.AASServer</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <!-- BaSyx SDK -->
+ <dependency>
+ <groupId>org.eclipse.basyx</groupId>
+ <artifactId>basyx.sdk</artifactId>
+ </dependency>
+ <!-- BaSyx SDK tests -->
+ <dependency>
+ <groupId>org.eclipse.basyx</groupId>
+ <artifactId>basyx.sdk</artifactId>
+ <classifier>tests</classifier>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
diff --git a/components/basyx.tck/basyx.tck.AASServer/src/main/assembly/assembly.xml b/components/basyx.tck/basyx.tck.AASServer/src/main/assembly/assembly.xml
new file mode 100644
index 0000000..2a283bf
--- /dev/null
+++ b/components/basyx.tck/basyx.tck.AASServer/src/main/assembly/assembly.xml
@@ -0,0 +1,28 @@
+<assembly
+ xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
+ <id>fat-tests</id>
+ <formats>
+ <format>jar</format>
+ </formats>
+ <includeBaseDirectory>false</includeBaseDirectory>
+ <dependencySets>
+ <dependencySet>
+ <outputDirectory>/</outputDirectory>
+ <useProjectArtifact>true</useProjectArtifact>
+ <unpack>true</unpack>
+ <scope>test</scope>
+ </dependencySet>
+ </dependencySets>
+ <fileSets>
+ <fileSet>
+ <directory>${project.build.directory}/test-classes</directory>
+ <outputDirectory>/</outputDirectory>
+ <includes>
+ <include>**/*.class</include>
+ </includes>
+ <useDefaultExcludes>true</useDefaultExcludes>
+ </fileSet>
+ </fileSets>
+</assembly>
\ No newline at end of file
diff --git a/components/basyx.tck/basyx.tck.AASServer/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/AASAggregatorSuiteWithDefinedURL.java b/components/basyx.tck/basyx.tck.AASServer/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/AASAggregatorSuiteWithDefinedURL.java
new file mode 100644
index 0000000..7ce61cb
--- /dev/null
+++ b/components/basyx.tck/basyx.tck.AASServer/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/AASAggregatorSuiteWithDefinedURL.java
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.aas.metamodel;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
+import org.eclipse.basyx.aas.aggregator.proxy.AASAggregatorProxy;
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.connected.ConnectedAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
+import org.eclipse.basyx.components.aas.aasx.AASXPackageManager;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.connected.ConnectedSubmodel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.support.bundle.AASBundle;
+import org.eclipse.basyx.testsuite.regression.aas.aggregator.AASAggregatorSuite;
+import org.junit.Test;
+
+/**
+ * Instantiate a concrete test suite for AASAggregator from the abstract test
+ * suite.
+ *
+ * @author zhangzai
+ *
+ */
+public class AASAggregatorSuiteWithDefinedURL extends AASAggregatorSuite {
+
+ public static String url;
+ private static final String aas1Id = "smart.festo.com/demo/aas/1/1/454576463545648365874";
+ private static final String aas2Id = "www.admin-shell.io/aas-sample/1/1";
+
+ /**
+ * A bundle of AAS extracted from the AASX package
+ */
+ private Map<String, IAssetAdministrationShell> aasMap = new HashMap<>();
+ private Set<AASBundle> aasBundles;
+
+ @Override
+ protected IAASAggregator getAggregator() {
+ return new AASAggregatorProxy(url);
+ }
+
+ /**
+ * Fetch AAS from AASX package and create them on the server
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testMetaModel() throws Exception {
+ // First argument is the server URL
+ String serverHost = url;
+
+ // Create a in-memory registry
+ InMemoryRegistry registry = new InMemoryRegistry();
+
+ ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(registry);
+
+ // Get the AAS Bundle
+ // Instantiate the aasx package manager
+ String aasxPath = "aasx/01_Festo.aasx";
+ AASXPackageManager packageManager = new AASXPackageManager(aasxPath);
+
+ // Unpack the files referenced by the aas
+ packageManager.unzipRelatedFiles();
+
+ // Retrieve the aas from the package
+ aasBundles = packageManager.retrieveAASBundles();
+
+ // Create the AAS on the server
+ aasBundles.forEach((x) -> {
+ // Get the ID of the AAS
+ AssetAdministrationShell aas = (AssetAdministrationShell) x.getAAS();
+ IIdentifier aasid = aas.getIdentification();
+
+ // Create the AAS on the server
+ manager.createAAS(aas, serverHost);
+ aasMap.put(aasid.getId(), aas);
+
+ // create the Submodels
+ x.getSubmodels().forEach(y -> {
+ manager.createSubmodel(aasid, (Submodel) y);
+ });
+
+ });
+
+ // Check the created AAS from the aasx package
+ checkAAS(aas1Id, manager);
+ checkAAS(aas2Id, manager);
+ }
+
+ /**
+ * Check whether the aas is created correctly
+ *
+ * @param manager
+ * @throws Exception
+ */
+ private void checkAAS(String aasid, ConnectedAssetAdministrationShellManager manager) throws Exception {
+ IIdentifier aasIdentifier = new Identifier(IdentifierType.IRI, aasid);
+
+ // Get the created AAS from the server
+ IAASAggregator aasAggregator = getAggregator();
+ ConnectedAssetAdministrationShell remoteAas = manager.retrieveAAS(aasIdentifier);
+
+ // Get the expected aas from aas bundle
+ IAssetAdministrationShell expected = aasMap.get(aasid);
+
+ // compare the both aas
+ AssetAdministrationShell localCopy = remoteAas.getLocalCopy();
+
+ assertEquals(expected.getIdentification(), localCopy.getIdentification());
+ assertEquals(expected.getAsset(), localCopy.getAsset());
+ assertEquals(expected.getIdShort(), localCopy.getIdShort());
+ assertEquals(expected.getIdentification(), localCopy.getIdentification());
+ assertEquals(expected.getDescription(), localCopy.getDescription());
+
+ // References can be built in different ways, therefore a direct comparison is not possible
+ assertEquals(expected.getSubmodelReferences().size(), localCopy.getSubmodelReferences().size());
+
+ // Get submodels from bundle
+ AASBundle aasBundle = aasBundles.stream().filter(b -> b.getAAS().getIdentification().getId().equals(aasIdentifier.getId())).findFirst().get();
+ aasBundle.getSubmodels().forEach(expectedSm -> {
+ Map<String, ISubmodel> sms = manager.retrieveSubmodels(aasIdentifier);
+ // get submodel from remote
+ ConnectedSubmodel remote = (ConnectedSubmodel) sms.get(expectedSm.getIdShort());
+ // compare the both submodels
+ checkSM(expectedSm, remote.getLocalCopy());
+ });
+
+
+ // Delete the AAS
+ aasAggregator.deleteAAS(aasIdentifier);
+
+ }
+
+ /**
+ * Checks whether two Submodels are equal
+ *
+ * @param expected
+ * @param actual
+ */
+ private void checkSM(ISubmodel expected, ISubmodel actual) {
+ assertEquals(expected.getIdShort(), actual.getIdShort());
+ assertEquals(expected.getIdentification(), actual.getIdentification());
+ assertEquals(expected.getDescription(), actual.getDescription());
+ assertEquals(expected.getReference(), actual.getReference());
+ assertEquals(expected.getQualifiers(), actual.getQualifiers());
+ assertEquals(expected.getSubmodelElements().size(), actual.getSubmodelElements().size());
+
+ for(String id: expected.getSubmodelElements().keySet()) {
+ assertTrue(actual.getSubmodelElements().containsKey(id));
+ }
+ }
+
+
+}
diff --git a/components/basyx.tck/basyx.tck.AASServer/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/AASServerTestApplication.java b/components/basyx.tck/basyx.tck.AASServer/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/AASServerTestApplication.java
new file mode 100644
index 0000000..37ad199
--- /dev/null
+++ b/components/basyx.tck/basyx.tck.AASServer/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/AASServerTestApplication.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.aas.metamodel;
+
+import org.junit.internal.TextListener;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+
+/**
+ * Application for testing an AAS server The first argument is the server host +
+ * context-path The application creates an internal registry, then extract the
+ * AASs from an existing AASX package. After that, it create the AASs and their
+ * sub-models on the server.
+ *
+ * @author zhangzai
+ *
+ */
+public class AASServerTestApplication {
+
+
+ public static void main(String[] args) throws Exception {
+
+ // First argument is the inserted url
+ String url = args[0];
+ AASAggregatorSuiteWithDefinedURL.url = url;
+
+
+
+ // Run junit test in a java application
+ JUnitCore junit = new JUnitCore();
+ junit.addListener(new TextListener(System.out));
+
+
+ Result result = junit.run(AASAggregatorSuiteWithDefinedURL.class);
+
+ System.out.println("Finished. Result: Failures: " +
+ result.getFailureCount() + ". Ignored: " +
+ result.getIgnoreCount() + ". Tests run: " +
+ result.getRunCount() + ". Time: " +
+ result.getRunTime() + "ms.");
+
+ }
+
+}
diff --git a/components/basyx.tck/basyx.tck.registry/pom.xml b/components/basyx.tck/basyx.tck.registry/pom.xml
new file mode 100644
index 0000000..b609541
--- /dev/null
+++ b/components/basyx.tck/basyx.tck.registry/pom.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.eclipse.basyx</groupId>
+ <artifactId>basyx.tck</artifactId>
+ <version>1.0.0</version>
+ </parent>
+
+ <artifactId>basyx.tck.registry</artifactId>
+
+ <name>TCK for AASRegistry</name>
+ <url>http://maven.apache.org</url>
+ <packaging>jar</packaging>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+ </properties>
+
+ <build>
+ <sourceDirectory>src/main/java</sourceDirectory>
+ <testSourceDirectory>src/test/java</testSourceDirectory>
+
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <descriptor>src/main/assembly/assembly.xml</descriptor>
+ <archive>
+ <manifest>
+ <mainClass>org.eclipse.basyx.testsuite.regression.aas.registration.RegistryProviderTestApplication</mainClass>
+ </manifest>
+ </archive>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <!-- BaSyx SDK -->
+ <dependency>
+ <groupId>org.eclipse.basyx</groupId>
+ <artifactId>basyx.sdk</artifactId>
+ </dependency>
+ <!-- BaSyx SDK tests -->
+ <dependency>
+ <groupId>org.eclipse.basyx</groupId>
+ <artifactId>basyx.sdk</artifactId>
+ <classifier>tests</classifier>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/components/basyx.tck/basyx.tck.registry/src/main/assembly/assembly.xml b/components/basyx.tck/basyx.tck.registry/src/main/assembly/assembly.xml
new file mode 100644
index 0000000..2a283bf
--- /dev/null
+++ b/components/basyx.tck/basyx.tck.registry/src/main/assembly/assembly.xml
@@ -0,0 +1,28 @@
+<assembly
+ xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
+ <id>fat-tests</id>
+ <formats>
+ <format>jar</format>
+ </formats>
+ <includeBaseDirectory>false</includeBaseDirectory>
+ <dependencySets>
+ <dependencySet>
+ <outputDirectory>/</outputDirectory>
+ <useProjectArtifact>true</useProjectArtifact>
+ <unpack>true</unpack>
+ <scope>test</scope>
+ </dependencySet>
+ </dependencySets>
+ <fileSets>
+ <fileSet>
+ <directory>${project.build.directory}/test-classes</directory>
+ <outputDirectory>/</outputDirectory>
+ <includes>
+ <include>**/*.class</include>
+ </includes>
+ <useDefaultExcludes>true</useDefaultExcludes>
+ </fileSet>
+ </fileSets>
+</assembly>
\ No newline at end of file
diff --git a/components/basyx.tck/basyx.tck.registry/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/RegistryProviderSuiteWithDefinedURL.java b/components/basyx.tck/basyx.tck.registry/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/RegistryProviderSuiteWithDefinedURL.java
new file mode 100644
index 0000000..0d4b242
--- /dev/null
+++ b/components/basyx.tck/basyx.tck.registry/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/RegistryProviderSuiteWithDefinedURL.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.aas.registration;
+
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+
+/**
+ * Instantiate a concrete test class for the abstract test suite
+ *
+ * @author zhangzai
+ *
+ */
+public class RegistryProviderSuiteWithDefinedURL extends TestRegistryProviderSuite {
+
+ public static String url;// for example: "http://localhost:4999/";
+
+ @Override
+ protected IAASRegistry getRegistryService() {
+ return new AASRegistryProxy(url);
+ }
+
+ @Override
+ public void testDeleteByAssetIdCall() {
+ // Not within official specification
+ }
+
+ @Override
+ public void testDeleteWithAssetExtension() {
+ // Not within official specification
+ }
+
+}
diff --git a/components/basyx.tck/basyx.tck.registry/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/RegistryProviderTestApplication.java b/components/basyx.tck/basyx.tck.registry/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/RegistryProviderTestApplication.java
new file mode 100644
index 0000000..5cb66e8
--- /dev/null
+++ b/components/basyx.tck/basyx.tck.registry/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/RegistryProviderTestApplication.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.aas.registration;
+
+import org.junit.internal.TextListener;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+
+/**
+ * The main class that executes the concrete test suite of the registry provider
+ *
+ * @author zhangzai
+ *
+ */
+public class RegistryProviderTestApplication {
+
+
+ /**
+ * Run the test suite of the registry provider with inserted url
+ *
+ * @param args - URL inserted by the user
+ */
+ public static void main(String[] args) {
+ // First argument is the inserted url
+ String url = args[0];
+
+ // Run the junit tests
+ JUnitCore junit = new JUnitCore();
+ junit.addListener(new TextListener(System.out));
+
+ RegistryProviderSuiteWithDefinedURL.url = url;
+ Result result = junit.run(RegistryProviderSuiteWithDefinedURL.class);
+
+ System.out.println("Finished. Result: Failures: " +
+ result.getFailureCount() + ". Ignored: " +
+ result.getIgnoreCount() + ". Tests run: " +
+ result.getRunCount() + ". Time: " +
+ result.getRunTime() + "ms.");
+ }
+}
diff --git a/components/basyx.tck/pom.xml b/components/basyx.tck/pom.xml
new file mode 100644
index 0000000..9abf62a
--- /dev/null
+++ b/components/basyx.tck/pom.xml
@@ -0,0 +1,126 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.eclipse.basyx</groupId>
+ <artifactId>basyx.tck</artifactId>
+ <version>1.0.0</version>
+
+
+ <packaging>pom</packaging>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+ </properties>
+
+ <!-- Includes all components in this project as separated modules -->
+ <modules>
+ <module>basyx.tck.AASServer</module>
+ <module>basyx.tck.registry</module>
+ </modules>
+
+
+ <build>
+ <!-- Specifies plugin settings that are common for all submodules -->
+ <pluginManagement>
+ <plugins>
+ <!-- Compile Java sources using Java 8 -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.8.1</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+
+ <!-- Attach sources to jar file -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>3.2.1</version>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <goals>
+ <goal>jar-no-fork</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <!-- Generate separate jar for tests and exclude logback.xml from generated jars -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>3.1.1</version>
+ <configuration>
+ <excludes>
+ <exclude>**/logback.xml</exclude>
+ </excludes>
+ </configuration>
+ <executions>
+ <execution>
+ <goals>
+ <goal>test-jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <!-- Run unit tests -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>3.0.0-M3</version>
+ </plugin>
+
+ <!-- Run integration tests -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <version>3.0.0-M3</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>integration-test</goal>
+ <goal>verify</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+
+ <!-- Every submodule depends on these dependencies -->
+ <dependencies>
+ <!-- JUnit 4 for running JUnit tests -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.12</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <!-- Specifies dependency settings for all submodules using these dependencies -->
+ <dependencyManagement>
+ <dependencies>
+ <!-- BaSyx SDK -->
+ <dependency>
+ <groupId>org.eclipse.basyx</groupId>
+ <artifactId>basyx.sdk</artifactId>
+ <version>1.0.0</version>
+ </dependency>
+ <!-- BaSyx SDK tests -->
+ <dependency>
+ <groupId>org.eclipse.basyx</groupId>
+ <artifactId>basyx.sdk</artifactId>
+ <version>1.0.0</version>
+ <classifier>tests</classifier>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+</project>
\ No newline at end of file
diff --git a/examples/.mvn/wrapper/MavenWrapperDownloader.java b/examples/.mvn/wrapper/MavenWrapperDownloader.java
new file mode 100644
index 0000000..e76d1f3
--- /dev/null
+++ b/examples/.mvn/wrapper/MavenWrapperDownloader.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2007-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import java.net.*;
+import java.io.*;
+import java.nio.channels.*;
+import java.util.Properties;
+
+public class MavenWrapperDownloader {
+
+ private static final String WRAPPER_VERSION = "0.5.6";
+ /**
+ * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
+ */
+ private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
+ + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
+
+ /**
+ * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
+ * use instead of the default one.
+ */
+ private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
+ ".mvn/wrapper/maven-wrapper.properties";
+
+ /**
+ * Path where the maven-wrapper.jar will be saved to.
+ */
+ private static final String MAVEN_WRAPPER_JAR_PATH =
+ ".mvn/wrapper/maven-wrapper.jar";
+
+ /**
+ * Name of the property which should be used to override the default download url for the wrapper.
+ */
+ private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
+
+ public static void main(String args[]) {
+ System.out.println("- Downloader started");
+ File baseDirectory = new File(args[0]);
+ System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
+
+ // If the maven-wrapper.properties exists, read it and check if it contains a custom
+ // wrapperUrl parameter.
+ File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
+ String url = DEFAULT_DOWNLOAD_URL;
+ if(mavenWrapperPropertyFile.exists()) {
+ FileInputStream mavenWrapperPropertyFileInputStream = null;
+ try {
+ mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
+ Properties mavenWrapperProperties = new Properties();
+ mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
+ url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
+ } catch (IOException e) {
+ System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
+ } finally {
+ try {
+ if(mavenWrapperPropertyFileInputStream != null) {
+ mavenWrapperPropertyFileInputStream.close();
+ }
+ } catch (IOException e) {
+ // Ignore ...
+ }
+ }
+ }
+ System.out.println("- Downloading from: " + url);
+
+ File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
+ if(!outputFile.getParentFile().exists()) {
+ if(!outputFile.getParentFile().mkdirs()) {
+ System.out.println(
+ "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
+ }
+ }
+ System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
+ try {
+ downloadFileFromURL(url, outputFile);
+ System.out.println("Done");
+ System.exit(0);
+ } catch (Throwable e) {
+ System.out.println("- Error downloading");
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ private static void downloadFileFromURL(String urlString, File destination) throws Exception {
+ if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
+ String username = System.getenv("MVNW_USERNAME");
+ char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
+ Authenticator.setDefault(new Authenticator() {
+ @Override
+ protected PasswordAuthentication getPasswordAuthentication() {
+ return new PasswordAuthentication(username, password);
+ }
+ });
+ }
+ URL website = new URL(urlString);
+ ReadableByteChannel rbc;
+ rbc = Channels.newChannel(website.openStream());
+ FileOutputStream fos = new FileOutputStream(destination);
+ fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
+ fos.close();
+ rbc.close();
+ }
+
+}
diff --git a/examples/.mvn/wrapper/maven-wrapper.jar b/examples/.mvn/wrapper/maven-wrapper.jar
new file mode 100644
index 0000000..2cc7d4a
--- /dev/null
+++ b/examples/.mvn/wrapper/maven-wrapper.jar
Binary files differ
diff --git a/examples/.mvn/wrapper/maven-wrapper.properties b/examples/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 0000000..642d572
--- /dev/null
+++ b/examples/.mvn/wrapper/maven-wrapper.properties
@@ -0,0 +1,2 @@
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
diff --git a/examples/basys.examples/examples/org/eclipse/basyx/examples/snippets/undoc/aas/embedhttp/EmbeddedHTTP.java b/examples/basys.examples/examples/org/eclipse/basyx/examples/snippets/undoc/aas/embedhttp/EmbeddedHTTP.java
index e32c767..ba6bb8d 100644
--- a/examples/basys.examples/examples/org/eclipse/basyx/examples/snippets/undoc/aas/embedhttp/EmbeddedHTTP.java
+++ b/examples/basys.examples/examples/org/eclipse/basyx/examples/snippets/undoc/aas/embedhttp/EmbeddedHTTP.java
@@ -1,14 +1,23 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.snippets.undoc.aas.embedhttp;
import static org.junit.Assert.assertTrue;
import org.eclipse.basyx.aas.api.resources.ISingleProperty;
-import org.eclipse.basyx.aas.api.resources.ISubModel;
+import org.eclipse.basyx.aas.api.resources.ISubmodel;
import org.eclipse.basyx.aas.backend.connected.ConnectedAssetAdministrationShellManager;
import org.eclipse.basyx.aas.backend.connector.http.HTTPConnectorProvider;
import org.eclipse.basyx.aas.metamodel.factory.MetaModelElementFactory;
-import org.eclipse.basyx.aas.metamodel.hashmap.aas.SubModel;
+import org.eclipse.basyx.aas.metamodel.hashmap.aas.Submodel;
import org.eclipse.basyx.aas.metamodel.hashmap.aas.submodelelement.property.Property;
import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
import org.eclipse.basyx.vab.core.VABConnectionManager;
@@ -52,7 +61,7 @@
/**
* Example sub model. This example sub model is created with the BaSyx SDK factory and defines the AAS meta model properties
*/
- static class SampleSubModel extends SubModel {
+ static class SampleSubmodel extends Submodel {
/**
* Version number of serialized instance
@@ -64,7 +73,7 @@
*
* This sub model contains static properties, i.e. properties that have a static value assigned.
*/
- public SampleSubModel() {
+ public SampleSubmodel() {
// Create factory that helps with property creation
// - This factory creates sub model properties and ensures presence of all meta data
MetaModelElementFactory fac = new MetaModelElementFactory();
@@ -83,20 +92,20 @@
/**
* Create sub model
*/
- public void createSubModel() {
+ public void createSubmodel() {
// Server connections
// - Connect to sub model. Connecting to a sub model by its ID is discouraged, because a sub
// model ID is not necessarily unique outside the scope of its AAS. If users want to connect
// directly to sub models, the registry needs to support this, and unique identifies (as here)
// must be used. For portability, users should connect to sub models instead via an AAS ID and
// sub model ID tuple, as illustrated in the registry examples.
- VABElementProxy connSubModel1 = this.connManager.connectToVABElement(STATUS_SM);
+ VABElementProxy connSubmodel1 = this.connManager.connectToVABElement(STATUS_SM);
// Instantiate sub model
- SubModel submodel = new SampleSubModel();
+ Submodel submodel = new SampleSubmodel();
// Transfer sub model to server
- connSubModel1.createElement("aas/submodels/" + STATUS_SM, submodel);
+ connSubmodel1.createElement("aas/submodels/" + STATUS_SM, submodel);
}
@@ -109,7 +118,7 @@
// Create and connect SDK connector
ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(connManager);
// - Retrieve sub model
- ISubModel subModel = manager.retrieveSM(STATUS_SM);
+ ISubmodel subModel = manager.retrieveSM(STATUS_SM);
// Read sub model properties
String smId = subModel.getId();
@@ -140,12 +149,12 @@
@Test
public void runTest() throws Exception {
// Create and start embedded HTTP server
- EmbeddedHTTPServer server = new EmbeddedHTTPSubModelServer("/BaSys/1.0/embedHTTP", new VABLambdaProvider(new SampleSubModel()));
+ EmbeddedHTTPServer server = new EmbeddedHTTPSubmodelServer("/BaSys/1.0/embedHTTP", new VABLambdaProvider(new SampleSubmodel()));
// - Start server
server.start();
// Connect to server, create sub model, and test access to sub model
- createSubModel();
+ createSubmodel();
testCRUDAAS();
// Stop HTTP server
diff --git a/examples/basys.examples/examples/org/eclipse/basyx/examples/snippets/undoc/aas/embedhttp/EmbeddedHTTPServer.java b/examples/basys.examples/examples/org/eclipse/basyx/examples/snippets/undoc/aas/embedhttp/EmbeddedHTTPServer.java
index bb690df..505018d 100644
--- a/examples/basys.examples/examples/org/eclipse/basyx/examples/snippets/undoc/aas/embedhttp/EmbeddedHTTPServer.java
+++ b/examples/basys.examples/examples/org/eclipse/basyx/examples/snippets/undoc/aas/embedhttp/EmbeddedHTTPServer.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.snippets.undoc.aas.embedhttp;
import java.io.IOException;
diff --git a/examples/basys.examples/examples/org/eclipse/basyx/examples/snippets/undoc/aas/embedhttp/EmbeddedHTTPSubModelServer.java b/examples/basys.examples/examples/org/eclipse/basyx/examples/snippets/undoc/aas/embedhttp/EmbeddedHTTPSubModelServer.java
index af110b2..5a8ca5b 100644
--- a/examples/basys.examples/examples/org/eclipse/basyx/examples/snippets/undoc/aas/embedhttp/EmbeddedHTTPSubModelServer.java
+++ b/examples/basys.examples/examples/org/eclipse/basyx/examples/snippets/undoc/aas/embedhttp/EmbeddedHTTPSubModelServer.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.snippets.undoc.aas.embedhttp;
import java.util.HashMap;
@@ -14,13 +23,13 @@
* @author kuhn
*
*/
-public class EmbeddedHTTPSubModelServer extends EmbeddedHTTPServer {
+public class EmbeddedHTTPSubmodelServer extends EmbeddedHTTPServer {
/**
* Constructor
*/
- public EmbeddedHTTPSubModelServer(String context, IModelProvider provider) {
+ public EmbeddedHTTPSubmodelServer(String context, IModelProvider provider) {
// Invoke base constructor
super(context, provider);
diff --git a/examples/basys.examples/pom.xml b/examples/basys.examples/pom.xml
index 9091809..e47a66e 100644
--- a/examples/basys.examples/pom.xml
+++ b/examples/basys.examples/pom.xml
@@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.eclipse.basyx</groupId>
<artifactId>basyx.examples</artifactId>
- <version>0.0.1-SNAPSHOT</version>
+ <version>1.0.0</version>
<packaging>jar</packaging>
<name>BaSyx Examples</name>
@@ -11,18 +11,6 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
- <repositories>
- <repository>
- <id>mule</id>
- <name>Mule Repository</name>
- <url>https://repository.mulesoft.org/nexus/content/groups/public/</url>
- <layout>default</layout>
- <snapshots>
- <enabled>false</enabled>
- </snapshots>
- </repository>
- </repositories>
-
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<testSourceDirectory>src/test/java</testSourceDirectory>
@@ -111,189 +99,33 @@
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
-
- <!-- https://mvnrepository.com/artifact/javax.ws.rs/javax.ws.rs-api -->
- <!-- https://mvnrepository.com/artifact/org.glassfish.jersey.core/jersey-client -->
- <!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api -->
- <!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-catalina
- (Tomcat 8, not 9) -->
- <dependency>
- <groupId>org.json</groupId>
- <artifactId>json</artifactId>
- <version>20180813</version>
- <!-- <scope>provided</scope> -->
- </dependency>
- <!-- Dependencies removed from Classpath -->
- <!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
- <dependency>
- <groupId>org.postgresql</groupId>
- <artifactId>postgresql</artifactId>
- <version>42.2.2</version>
- </dependency>
- <!-- https://mvnrepository.com/artifact/org.glassfish.hk2.external/aopalliance-repackaged -->
- <dependency>
- <groupId>org.glassfish.hk2.external</groupId>
- <artifactId>aopalliance-repackaged</artifactId>
- <version>2.5.0-b42</version>
- </dependency>
- <!-- https://mvnrepository.com/artifact/javax.enterprise/cdi-api -->
- <dependency>
- <groupId>javax.enterprise</groupId>
- <artifactId>cdi-api</artifactId>
- <version>2.0</version>
- <scope>provided</scope>
- </dependency>
- <!-- https://mvnrepository.com/artifact/javax.el/el-api -->
- <dependency>
- <groupId>javax.el</groupId>
- <artifactId>el-api</artifactId>
- <version>2.2</version>
- </dependency>
- <!-- https://mvnrepository.com/artifact/org.glassfish.hk2/hk2-api -->
- <dependency>
- <groupId>org.glassfish.hk2</groupId>
- <artifactId>hk2-api</artifactId>
- <version>2.5.0</version>
- </dependency>
- <!-- https://mvnrepository.com/artifact/javassist/javassist -->
- <dependency>
- <groupId>javassist</groupId>
- <artifactId>javassist</artifactId>
- <version>3.12.1.GA</version>
- </dependency>
- <!-- https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api -->
- <!-- https://mvnrepository.com/artifact/javax.inject/javax.inject -->
- <dependency>
- <groupId>javax.inject</groupId>
- <artifactId>javax.inject</artifactId>
- <version>1</version>
- </dependency>
- <!-- https://mvnrepository.com/artifact/javax.json/javax.json-api -->
- <dependency>
- <groupId>javax.json</groupId>
- <artifactId>javax.json-api</artifactId>
- <version>1.0</version>
- </dependency>
- <!-- https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api -->
- <dependency>
- <groupId>javax.xml.bind</groupId>
- <artifactId>jaxb-api</artifactId>
- <version>2.3.0</version>
- </dependency>
- <!-- https://mvnrepository.com/artifact/org.jboss.spec.javax.interceptor/jboss-interceptors-api_1.1_spec -->
- <dependency>
- <groupId>org.jboss.spec.javax.interceptor</groupId>
- <artifactId>jboss-interceptors-api_1.1_spec</artifactId>
- <version>1.0.1.Final</version>
- </dependency>
- <!-- https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api -->
- <dependency>
- <groupId>javax.annotation</groupId>
- <artifactId>javax.annotation-api</artifactId>
- <version>1.3.2</version>
- </dependency>
- <!-- https://mvnrepository.com/artifact/org.osgi/org.osgi.core -->
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- <version>4.2.0</version>
- <scope>provided</scope>
- </dependency>
- <!-- https://mvnrepository.com/artifact/org.glassfish.hk2/osgi-resource-locator -->
- <dependency>
- <groupId>org.glassfish.hk2</groupId>
- <artifactId>osgi-resource-locator</artifactId>
- <version>1.0.1</version>
- </dependency>
- <!-- https://mvnrepository.com/artifact/javax.persistence/persistence-api -->
- <dependency>
- <groupId>javax.persistence</groupId>
- <artifactId>persistence-api</artifactId>
- <version>1.0.2</version>
- </dependency>
- <!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
- <dependency>
- <groupId>javax.validation</groupId>
- <artifactId>validation-api</artifactId>
- <version>2.0.1.Final</version>
- </dependency>
- <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>javax.servlet-api</artifactId>
- <version>3.1.0</version>
- <scope>provided</scope>
- </dependency>
-
- <!-- https://mvnrepository.com/artifact/org.eclipse/yasson -->
- <dependency>
- <groupId>org.eclipse</groupId>
- <artifactId>yasson</artifactId>
- <version>1.0.2</version>
- </dependency>
-
- <!-- https://mvnrepository.com/artifact/javax.xml.xquery/xqj-api (Add from
- local repository because jar cannot be found on maven central -->
- <dependency>
- <groupId>javax.xml.xquery</groupId>
- <artifactId>xqj-api</artifactId>
- <version>1.0</version>
- </dependency>
-
- <!-- https://mvnrepository.com/artifact/net.sf.saxon/saxon-xqj -->
- <!-- <dependency> <groupId>net.sf.saxon</groupId> <artifactId>saxon-xqj</artifactId>
- <version>9.x</version> </dependency> -->
-
- <!-- https://mvnrepository.com/artifact/net.sf.saxon/saxon-xqj -->
- <dependency>
- <groupId>net.sf.saxon</groupId>
- <artifactId>saxon-xqj</artifactId>
- <version>8.9.0.4</version>
- </dependency>
-
-
- <!-- https://mvnrepository.com/artifact/net.sf.saxon/Saxon-HE -->
- <dependency>
- <groupId>net.sf.saxon</groupId>
- <artifactId>Saxon-HE</artifactId>
- <version>9.5.1-5</version>
- </dependency>
-
-
- <dependency>
- <groupId>com.google.code.gson</groupId>
- <artifactId>gson</artifactId>
- <version>2.8.5</version>
- </dependency>
-
<!-- Add BaSys components from local repository. Maven build of SDK must generate a jar and place it into the repository to update -->
<dependency>
<groupId>org.eclipse.basyx</groupId>
<artifactId>basyx.components.lib</artifactId>
- <version>0.0.1-SNAPSHOT</version>
+ <version>1.0.0</version>
</dependency>
<!-- Add explicit SQLRegistry dependency -->
<dependency>
<groupId>org.eclipse.basyx</groupId>
- <artifactId>basyx.components.sqlregistry</artifactId>
- <version>0.0.1-SNAPSHOT</version>
+ <artifactId>basyx.components.registry</artifactId>
+ <version>1.0.2</version>
</dependency>
-
<!-- Add explicit AAS Server component dependency -->
<dependency>
<groupId>org.eclipse.basyx</groupId>
<artifactId>basyx.components.AASServer</artifactId>
- <version>0.0.1-SNAPSHOT</version>
+ <version>1.0.0</version>
</dependency>
<!-- Adds additional classes of the BaSys SDK for tests -->
<dependency>
<groupId>org.eclipse.basyx</groupId>
<artifactId>basyx.sdk</artifactId>
- <version>0.0.1-SNAPSHOT</version>
+ <version>1.0.0</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/deployment/BaSyxDeployment.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/deployment/BaSyxDeployment.java
deleted file mode 100644
index df42bca..0000000
--- a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/deployment/BaSyxDeployment.java
+++ /dev/null
@@ -1,140 +0,0 @@
-package org.eclipse.basyx.examples.deployment;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.basyx.vab.protocol.http.server.AASHTTPServer;
-import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
-import org.eclipse.basyx.vab.service.api.BaSyxService;
-import org.junit.rules.ExternalResource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-
-
-/**
- * This class represents a BaSyx deployment with servers / servlets and assets for running BaSyx examples
- *
- * @author kuhn
- *
- */
-public class BaSyxDeployment extends ExternalResource {
-
- /**
- * Initiates a logger using the current class
- */
- private static final Logger logger = LoggerFactory.getLogger(BaSyxDeployment.class);
-
-
- /**
- * Store context objects
- */
- protected Object[] contextComponents = null;
-
- /**
- * Map runnable names to runnables
- */
- protected Map<String, BaSyxService> contectRunnablesByName = new HashMap<>();
-
- /**
- * Deployment on HTTP server
- */
- private AASHTTPServer server;
-
-
-
- /**
- * Constructor - accept parameter of type BaSyxContext or Runnable
- */
- public BaSyxDeployment(Object... components) {
- // Store context objects
- contextComponents = components;
-
- // Store runnable objects by name
- for (Object obj: contextComponents) {
- // Check component type
- if (!(obj instanceof BaSyxService)) continue;
-
- // Add BaSyxContextRunnable to context
- // - Cast object
- BaSyxService contextRunnable = (BaSyxService) obj;
- // - Add context runnable to map if it is named
- if (contextRunnable.getName() == null) continue;
- // - Add context runnable to map
- contectRunnablesByName.put(contextRunnable.getName(), contextRunnable);
- }
- }
-
-
-
- /**
- * Execute before a test case starts
- */
- @Override
- protected void before() {
- // Iterate context components
- for (Object contextComponent: contextComponents) {
- // Process BaSyx context objects that run in a tomcat server
- if (contextComponent instanceof BaSyxContext) {
- // Get HTTP server resource
- server = new AASHTTPServer((BaSyxContext) contextComponent);
- // - Start the server
- server.start();
- // - Continue loop
- continue;
- }
-
- // Process runnables
- if (contextComponent instanceof BaSyxService) {
- // Execute runnable
- ((BaSyxService) contextComponent).start();
- // - Continue loop
- continue;
- }
-
- logger.error("Error:"+contextComponent);
-
- // Unknown deployment context
- throw new UnknownContextComponentTypeException();
- }
- }
-
-
- /**
- * Execute after test case ends
- */
- @Override
- protected void after() {
- // Iterate context components
- for (Object contextComponent: contextComponents) {
- // Process BaSyx context objects that run in a tomcat server
- if (contextComponent instanceof BaSyxContext) {
- // - Shutdown the server
- server.shutdown();
- // - Continue loop
- continue;
- }
-
- // Process runnables
- if (contextComponent instanceof BaSyxService) {
- // Execute runnable
- ((BaSyxService) contextComponent).stop();
- // - Continue loop
- continue;
- }
-
- // Unknown deployment context
- throw new UnknownContextComponentTypeException();
- }
- }
-
-
- /**
- * Get context runnable by name
- */
- public BaSyxService getRunnable(String name) {
- return contectRunnablesByName.get(name);
- }
-}
-
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/deployment/UnknownContextComponentTypeException.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/deployment/UnknownContextComponentTypeException.java
deleted file mode 100644
index d2da851..0000000
--- a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/deployment/UnknownContextComponentTypeException.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.eclipse.basyx.examples.deployment;
-
-
-/**
- * This exception indicates the presence of an unknown component type in a BaSyx context
- *
- * @author kuhn
- *
- */
-public class UnknownContextComponentTypeException extends RuntimeException {
-
-
- /**
- * Version information for serialized instances
- */
- private static final long serialVersionUID = 1L;
-}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/examplescenario/BaSyxExampleScenario.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/examplescenario/BaSyxExampleScenario.java
deleted file mode 100644
index d9542bc..0000000
--- a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/examplescenario/BaSyxExampleScenario.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.eclipse.basyx.examples.examplescenario;
-
-import java.util.function.Supplier;
-
-
-
-/**
- * Base class for all BaSyx examples
- *
- * @author kuhn
- */
-public class BaSyxExampleScenario {
-
-
-
- /**
- * Wait for a condition
- */
- protected void waitfor(Supplier<Boolean> function) {
- while (!function.get()) Thread.yield();
- }
-}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/cloudedgedeployment/CloudEdgeDeploymentScenario.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/cloudedgedeployment/CloudEdgeDeploymentScenario.java
index fc6ba2e..0134160 100644
--- a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/cloudedgedeployment/CloudEdgeDeploymentScenario.java
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/cloudedgedeployment/CloudEdgeDeploymentScenario.java
@@ -1,13 +1,33 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.scenarios.cloudedgedeployment;
-import org.basyx.components.AASServer.AASServerComponent;
+
+import java.util.ArrayList;
+import java.util.List;
+
import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
-import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.components.IComponent;
+import org.eclipse.basyx.components.aas.AASServerComponent;
+import org.eclipse.basyx.components.aas.configuration.AASServerBackend;
+import org.eclipse.basyx.components.aas.configuration.BaSyxAASServerConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.components.registry.RegistryComponent;
+import org.eclipse.basyx.components.registry.configuration.BaSyxRegistryConfiguration;
+import org.eclipse.basyx.components.registry.configuration.RegistryBackend;
import org.eclipse.basyx.components.servlet.submodel.SubmodelServlet;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.vab.protocol.http.server.AASHTTPServer;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxHTTPServer;
import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
@@ -20,7 +40,7 @@
* Server B is created as a server hosted near a machine.
* It provides a Submodel containing sensor value.
*
- * @author conradi
+ * @author conradi, schnicke
*
*/
public class CloudEdgeDeploymentScenario {
@@ -28,7 +48,8 @@
/**
* The registry used in the manager
*/
- public IAASRegistryService registry;
+ private IAASRegistry registry;
+ public static String registryPath = "http://localhost:8080/registry";
/**
* AASManager used to handle registration and server communication
@@ -38,19 +59,23 @@
/**
* Identifier of the AAS hosted in the cloud.
*/
- public IIdentifier aasIdentifier = ComponentBuilder.getAAS().getIdentification();
+ public static IIdentifier aasIdentifier = ComponentBuilder.getAAS().getIdentification();
/**
* Identifier of the SM hosted in the cloud.
* It contains never changing properties of the machine.
*/
- public IIdentifier docuSmIdentifier = ComponentBuilder.getDocuSMDescriptor().getIdentifier();
+ public static IIdentifier docuSmIdentifier = ComponentBuilder.getDocuSMDescriptor().getIdentifier();
/**
* Identifier of the SM hosted near the machine.
* It contains constantly changing sensor data.
*/
- public IIdentifier edgeSmIdentifier = ComponentBuilder.getEdgeSubmodelDescriptor().getIdentifier();
+ public static IIdentifier edgeSmIdentifier = ComponentBuilder.getEdgeSubmodelDescriptor().getIdentifier();
+
+ // Used for shutting down the scenario
+ private List<IComponent> startedComponents = new ArrayList<>();
+ private BaSyxHTTPServer edgeServer;
/**
* Main method to start the scenario
@@ -66,28 +91,29 @@
*/
public CloudEdgeDeploymentScenario() {
- startupEdgeServer();
- startupCloudServer();
-
+ startupRegistryServer();
// Create a InMemoryRegistry to be used by the manager
- registry = new InMemoryRegistry();
+ registry = new AASRegistryProxy(registryPath);
+ startupEdgeServer();
+ startupCloudServer();
+
// Create a ConnectedAASManager with the registry created above
aasManager = new ConnectedAssetAdministrationShellManager(registry);
// Push the AAS to the cloud server
// The manager automatically registers it in the registry
- aasManager.createAAS(ComponentBuilder.getAAS(), aasIdentifier, "http://localhost:8081/cloud");
+ aasManager.createAAS(ComponentBuilder.getAAS(), "http://localhost:8081/cloud");
// Get the docuSubmodel from the ComponentBuilder
- SubModel docuSubmodel = ComponentBuilder.getDocuSM();
+ Submodel docuSubmodel = ComponentBuilder.getDocuSM();
// Push the docuSubmodel to the cloud
// The manager automatically registers it in the registry
- aasManager.createSubModel(aasIdentifier, docuSubmodel);
+ aasManager.createSubmodel(aasIdentifier, docuSubmodel);
// Add the already existing edgeSM to the descriptor of the aas
@@ -95,7 +121,20 @@
}
/**
- * Startup a server responsible for hosting the "current_temp" edgeSubModel
+ * Startup an empty registry at "http://localhost:8080/registry"
+ *
+ */
+ private void startupRegistryServer() {
+ // Start an InMemory registry server with a direct configuration
+ BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration(8080, "registry");
+ BaSyxRegistryConfiguration registryConfig = new BaSyxRegistryConfiguration(RegistryBackend.INMEMORY);
+ IComponent component = new RegistryComponent(contextConfig, registryConfig);
+ component.startComponent();
+ startedComponents.add(component);
+ }
+
+ /**
+ * Startup a server responsible for hosting the "current_temp" edgeSubmodel
* at the endpoint "http://localhost:8082/oven/current_temp"
*
* In this example this server is hosted close to the machine
@@ -104,21 +143,22 @@
*/
private void startupEdgeServer() {
- // Create a BaSyxConetxt for port 8082 with an empty endpoint and the tmpdir for storing its data
- BaSyxContext context = new BaSyxContext("", System.getProperty("java.io.tmpdir"), "localhost", 8082);
+ // Create a BaSyxConetxt for port 8082 with an empty endpoint
+ BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration(8082, "");
+ BaSyxContext context = contextConfig.createBaSyxContext();
// Get the edgeSubmodel from the ComponentBuilder
- SubModel edgeSubmodel = ComponentBuilder.createEdgeSubModel();
+ Submodel edgeSubmodel = ComponentBuilder.createEdgeSubmodel();
// Create a new SubmodelServlet containing the edgeSubmodel
SubmodelServlet smServlet = new SubmodelServlet(edgeSubmodel);
- // Add the SubmodelServlet mapping to the context at the path "/oven/current_temp"
- context.addServletMapping("/oven/current_temp/*", smServlet);
+ // Add the SubmodelServlet mapping to the context at the path "/oven/curr_temp"
+ context.addServletMapping("/oven/" + ComponentBuilder.EDGESM_ID_SHORT + "/*", smServlet);
// Create and start a HTTP server with the context created above
- AASHTTPServer edgeServer = new AASHTTPServer(context);
+ edgeServer = new BaSyxHTTPServer(context);
edgeServer.start();
}
@@ -130,12 +170,24 @@
*
*/
private void startupCloudServer() {
-
- // Create a server at port 8081 with the endpoint "/cloud"
- AASServerComponent cloudServer = new AASServerComponent("localhost", 8081, "/cloud", "/");
+ // Load the server context from a .properties file resource
+ BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
+ contextConfig.loadFromResource("CloudEdgeDeploymentScenarioAASContext.properties");
+
+ // Create the AAS - Can alternatively also be loaded from a .property file
+ BaSyxAASServerConfiguration aasServerConfig = new BaSyxAASServerConfiguration(AASServerBackend.INMEMORY, "", registryPath);
+
+ // Create a server according to this configuration
+ AASServerComponent cloudServer = new AASServerComponent(contextConfig, aasServerConfig);
// Start the created server
cloudServer.startComponent();
+ startedComponents.add(cloudServer);
}
-}
\ No newline at end of file
+ public void stop() {
+ startedComponents.stream().forEach(IComponent::stopComponent);
+ edgeServer.shutdown();
+ }
+
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/cloudedgedeployment/ComponentBuilder.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/cloudedgedeployment/ComponentBuilder.java
index ffa8803..853ef18 100644
--- a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/cloudedgedeployment/ComponentBuilder.java
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/cloudedgedeployment/ComponentBuilder.java
@@ -1,9 +1,21 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.scenarios.cloudedgedeployment;
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.CustomId;
import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
@@ -14,21 +26,17 @@
*
*/
public class ComponentBuilder {
+ public static final String AAS_ID_SHORT = "oven";
+ public static final String AAS_ID = "basyx.examples.oven";
+ public static final String AAS_ENDPOINT = "http://localhost:8081/cloud/shells/" + AAS_ID + "/aas";
public static final String EDGESM_ID_SHORT = "curr_temp";
- public static final String EDGESM_ID = "current_oven_temperature";
- public static final String EDGESM_ENDPOINT = "http://localhost:8082/oven/current_temp";
+ public static final String EDGESM_ID = "basyx.examples.oven.current_oven_temperature";
+ public static final String EDGESM_ENDPOINT = "http://localhost:8082/oven/" + EDGESM_ID_SHORT + "/submodel";
public static final String DOCUSM_ID_SHORT = "oven_doc";
- public static final String DOCUSM_ID = "oven_documentation_sm";
- public static final String DOCUSM_ENDPOINT = "http://localhost:8081/cloud/aasList/aasId/aas/submodels/oven_doc";
-
- public static final String AAS_ID_SHORT = "aasIdShort";
- public static final String AAS_ID = "aasId";
- public static final String AAS_ENDPOINT = "http://localhost:8081/cloud/aasList/aasId/aas";
-
-
-
+ public static final String DOCUSM_ID = "basyx.examples.oven.oven_documentation_sm";
+ public static final String DOCUSM_ENDPOINT = "http://localhost:8081/cloud/shells/" + AAS_ID + "/aas/submodels/" + DOCUSM_ID_SHORT + "/submodel";
/**
* Creates the AAS, which gets pushed to the cloud server
@@ -36,10 +44,13 @@
* @return the created AAS
*/
public static AssetAdministrationShell getAAS() {
- AssetAdministrationShell aas = new AssetAdministrationShell();
- aas.setIdShort(AAS_ID_SHORT);
- aas.setIdentification(IdentifierType.CUSTOM, AAS_ID);
- return aas;
+ // Create the oven asset
+ Asset ovenAsset = new Asset("OvenAsset", new CustomId("basyx.examples.OvenAsset"), AssetKind.INSTANCE);
+
+ // Create the AAS representing the oven
+ AssetAdministrationShell ovenAAS = new AssetAdministrationShell(AAS_ID_SHORT, new CustomId(AAS_ID), ovenAsset);
+
+ return ovenAAS;
}
/**
@@ -48,16 +59,15 @@
*
* @return the created Submodel
*/
- public static SubModel getDocuSM() {
- SubModel sm = new SubModel();
- sm.setIdentification(IdentifierType.CUSTOM, DOCUSM_ID);
- sm.setIdShort(DOCUSM_ID_SHORT);
+ public static Submodel getDocuSM() {
+ // Create the documentation Submodel
+ Submodel docuSm = new Submodel(DOCUSM_ID_SHORT, new CustomId(DOCUSM_ID));
- Property property = new Property(1000);
- property.setIdShort("max_temp");
- sm.addSubModelElement(property);
+ // Create the maximum temperature property and include it in the submodel
+ Property maxTemp = new Property("max_temp", 1000);
+ docuSm.addSubmodelElement(maxTemp);
- return sm;
+ return docuSm;
}
/**
@@ -75,17 +85,15 @@
*
* @return the created Submodel
*/
- public static SubModel createEdgeSubModel() {
- SubModel sm = new SubModel();
- sm.setIdentification(IdentifierType.CUSTOM, EDGESM_ID);
- sm.setIdShort(EDGESM_ID_SHORT);
+ public static Submodel createEdgeSubmodel() {
+ // Create the edge submodel
+ Submodel edgeSm = new Submodel(EDGESM_ID_SHORT, new CustomId(EDGESM_ID));
// The property in this Submodel contains the currently measured temperature of the oven
// It is represented by a static value in this example
- Property property = new Property(31);
- property.setIdShort("temp");
- sm.addSubModelElement(property);
- return sm;
+ Property property = new Property("temp", 31);
+ edgeSm.addSubmodelElement(property);
+ return edgeSm;
}
/**
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/staticdynamic/ExampleDynamicSubmodel.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/staticdynamic/ExampleDynamicSubmodel.java
new file mode 100644
index 0000000..da55cbb
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/staticdynamic/ExampleDynamicSubmodel.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.scenarios.staticdynamic;
+
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+
+/**
+ * Minimal implementation of a dynamic information Submodel <br>
+ * Please note that it is just for showcasing, several mandatory attributes are
+ * missing.
+ *
+ * @author schnicke, conradi
+ *
+ */
+public class ExampleDynamicSubmodel extends Submodel {
+
+ public static final String SM_ID_SHORT = "maintenance";
+ public static final String SM_ID = "maintenanceInformationSubmodel";
+
+ public static final String PROPERTY_ID_SHORT = "interval";
+ public static final String PROPERTY_VALUE = "2 months";
+
+
+ public ExampleDynamicSubmodel() {
+ // Create Property
+ Property interval = new Property();
+ interval.setValue(PROPERTY_VALUE);
+ interval.setIdShort(PROPERTY_ID_SHORT);
+
+ // Add the property to the submodel
+ addSubmodelElement(interval);
+
+ // Set the idShort
+ setIdShort(SM_ID_SHORT);
+
+ // Set Identification
+ setIdentification(IdentifierType.CUSTOM, SM_ID);
+ }
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/staticdynamic/StaticDynamicScenario.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/staticdynamic/StaticDynamicScenario.java
new file mode 100644
index 0000000..86630e8
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/staticdynamic/StaticDynamicScenario.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.scenarios.staticdynamic;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.eclipse.basyx.aas.aggregator.proxy.AASAggregatorProxy;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.components.IComponent;
+import org.eclipse.basyx.components.aas.AASServerComponent;
+import org.eclipse.basyx.components.aas.aasx.AASXPackageManager;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.components.registry.RegistryComponent;
+import org.eclipse.basyx.components.registry.configuration.BaSyxRegistryConfiguration;
+import org.eclipse.basyx.components.registry.configuration.RegistryBackend;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.support.bundle.AASBundle;
+import org.eclipse.basyx.support.bundle.AASBundleHelper;
+import org.xml.sax.SAXException;
+
+/**
+ * Example scenario showcasing how to enrich AAS data provided as AASX with static data <br>
+ * For this, a previously defined AASX package is loaded and a static
+ * submodel is added to the already defined submodels <br>
+ * For a detailed description of the scenario, see:<br>
+ * https://wiki.eclipse.org/BaSyx_/_Scenarios_/_Static_Dynamic_Extension
+ *
+ * @author schnicke, conradi
+ *
+ */
+public class StaticDynamicScenario {
+
+ public static final String REGISTRY_URL = "http://localhost:4000/registry";
+ public static final String SERVER_URL = "http://localhost:4001/aasx/shells";
+
+ public static final String AAS_ID = "smart.festo.com/demo/aas/1/1/454576463545648365874";
+ public static final String AAS_ID_SHORT = "Festo_3S7PM0CP4BD";
+ public static final String AAS_ENDPOINT = SERVER_URL + "shells/smart.festo.com%2Fdemo%2Faas%2F1%2F1%2F454576463545648365874/aas";
+
+ private List<IComponent> startedComponents = new ArrayList<>();
+
+
+
+ public static void main(String[] args) throws InvalidFormatException, IOException, ParserConfigurationException, SAXException {
+ new StaticDynamicScenario();
+ }
+
+ public StaticDynamicScenario() throws InvalidFormatException, IOException, ParserConfigurationException, SAXException {
+
+ // Startup the registry server
+ startRegistry();
+
+ // Startup the server
+ startAASServer();
+
+ // Load Bundles from .aasx file
+ AASXPackageManager packageManager = new AASXPackageManager("aasx/01_Festo.aasx");
+ Set<AASBundle> bundles = packageManager.retrieveAASBundles();
+
+ // Create static Submodel
+ Submodel sm = new ExampleDynamicSubmodel();
+
+ // Get the correct Bundle from the Set
+ AASBundle bundle = findBundle(bundles, AAS_ID_SHORT);
+
+ // Add the new Submodel to the Bundle
+ bundle.getSubmodels().add(sm);
+
+ // Load the new Bundles to the Server
+ AASBundleHelper.integrate(new AASAggregatorProxy(SERVER_URL), bundles);
+
+ // Get a RegistryProxy and register all Objects contained in the Bundles
+ AASRegistryProxy proxy = new AASRegistryProxy(REGISTRY_URL);
+ AASBundleHelper.register(proxy, bundles, SERVER_URL);
+
+ }
+
+ /**
+ * Starts an empty registry at "http://localhost:4000"
+ */
+ private void startRegistry() {
+ // Load a registry context configuration using a .properties file
+ BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
+ contextConfig.loadFromResource("RegistryContext.properties");
+ BaSyxRegistryConfiguration registryConfig = new BaSyxRegistryConfiguration(RegistryBackend.INMEMORY);
+ RegistryComponent registry = new RegistryComponent(contextConfig, registryConfig);
+ registry.startComponent();
+ startedComponents.add(registry);
+ }
+
+ /**
+ * Startup an empty server at "http://localhost:4001/aasx/"
+ */
+ private void startAASServer() {
+ // Create a server at port 4001 with the endpoint "/aasx"
+ BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration(4001, "/aasx");
+ AASServerComponent aasServer = new AASServerComponent(contextConfig);
+
+ // Start the created server
+ aasServer.startComponent();
+ startedComponents.add(aasServer);
+ }
+
+
+ /**
+ * Finds the Bundle containing the AAS with the specified IdShort
+ *
+ * @param bundles the Set of Bundles
+ * @param aasID the Id of the AAS of the wanted Bundle
+ * @return the Bundle containing the AAS with the specified Id or null if it does not exist
+ */
+ private AASBundle findBundle(Set<AASBundle> bundles, String aasIdShort) {
+ for (AASBundle aasBundle : bundles) {
+ if(aasBundle.getAAS().getIdShort().equals(aasIdShort))
+ return aasBundle;
+ }
+ return null;
+ }
+
+ /**
+ * Shuts down all started IComponent servers
+ */
+ public void stop() {
+ startedComponents.stream().forEach(IComponent::stopComponent);
+ }
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/AddSubmodelToAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/AddSubmodelToAAS.java
new file mode 100644
index 0000000..088cea1
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/AddSubmodelToAAS.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.aas;
+
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+
+/**
+ * This snippet showcases how to add a Submodel to an AAS,
+ * that already exists on a server
+ *
+ * @author conradi
+ *
+ */
+public class AddSubmodelToAAS {
+
+ /**
+ * Adds a Submodel to an AAS
+ *
+ * @param submodel the Submodel to be added
+ * @param aas the AAS the Submodel should be added to
+ */
+ public static void addSubmodelToAAS(Submodel submodel, IAssetAdministrationShell aas) {
+
+ // Add the submodel to the AAS
+ // If the given AAS is a ConnectedAssetAdministrationShell
+ // the Submodel will be uploaded to the server the AAS is hosted on
+ // The Submodel will NOT be registered. The RegisterSubmodel snippet can be used for that.
+ aas.addSubmodel(submodel);
+ }
+
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/CreateAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/CreateAAS.java
new file mode 100644
index 0000000..0ca30e7
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/CreateAAS.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.aas;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+/**
+ * Snippet that showcases how to create an AssetAdministrationShell
+ * with only the mandatory attributes.
+ *
+ * @author conradi
+ *
+ */
+public class CreateAAS {
+
+ /**
+ * Creates a new AAS
+ *
+ * @param idShort the idShort of the AAS to be created
+ * @param aasIdentifier the Identifier of the AAS to be created
+ * @param asset the asset to be contained in the new AAS
+ * @return the newly created AAS
+ */
+ public static AssetAdministrationShell createAAS(String idShort, IIdentifier aasIdentifier, Asset asset) {
+
+ // Create a new AssetAdministrationShell object
+ AssetAdministrationShell aas = new AssetAdministrationShell(idShort, aasIdentifier, asset);
+ return aas;
+ }
+
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/DeleteSubmodelFromAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/DeleteSubmodelFromAAS.java
new file mode 100644
index 0000000..8fcae73
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/DeleteSubmodelFromAAS.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.aas;
+
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+/**
+ * Snippet that showcases how to delete a Submodel from a server
+ *
+ * @author conradi
+ *
+ */
+public class DeleteSubmodelFromAAS {
+
+ /**
+ * Removes a Submodel from an AAS
+ *
+ * @param smIdentifier the Identifier of the Submodel to be deleted
+ * @param aas the AAS the Submodel belongs to
+ */
+ public static void deleteSubmodelFromAAS(IIdentifier smIdentifier, IAssetAdministrationShell aas) {
+
+ // Delete the Submodel from the AAS
+ // Does NOT deregisters the Submodel
+ // The DeregisterSubmodel snippet can be used to do that
+ aas.removeSubmodel(smIdentifier);
+ }
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/RetrieveSubmodelFromAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/RetrieveSubmodelFromAAS.java
new file mode 100644
index 0000000..0b52ffc
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/RetrieveSubmodelFromAAS.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.aas;
+
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+
+/**
+ * This snippet showcases how to retrieve a Submodel from an AAS
+ *
+ * @author conradi
+ *
+ */
+public class RetrieveSubmodelFromAAS {
+
+ /**
+ * Gets a Submodel from an AAS
+ *
+ * @param smIdentifier the Identifier of the requested Submodel
+ * @return the requested Submodel
+ */
+ public static ISubmodel retrieveSubmodelFromAAS(IIdentifier smIdentifier, IAssetAdministrationShell aas) {
+ // Get the requested Submodel from the AAS
+ ISubmodel submodel = aas.getSubmodel(smIdentifier);
+ return submodel;
+ }
+
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/AddSubmodelToAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/AddSubmodelToAAS.java
new file mode 100644
index 0000000..8000344
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/AddSubmodelToAAS.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.manager;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+
+/**
+ * This snippet showcases how to add a Submodel to an AAS,
+ * that already exists on a server.
+ * It uses the AASManager
+ *
+ * @author conradi
+ *
+ */
+public class AddSubmodelToAAS {
+
+ /**
+ * Adds a Submodel to an AAS and registers it
+ *
+ * @param submodel the Submodel to be added
+ * @param aasIdentifier the Identifier of the AAS the Submodel should be added to
+ * @param registryServerURL the URL of the registry server
+ */
+ public static void addSubmodelToAAS(Submodel submodel, IIdentifier aasIdentifier, String registryServerURL) {
+
+ // Create a proxy pointing to the registry server
+ AASRegistryProxy registryProxy = new AASRegistryProxy(registryServerURL);
+
+ // Create a ConnectedAASManager using the registryProxy as its registry
+ ConnectedAssetAdministrationShellManager manager =
+ new ConnectedAssetAdministrationShellManager(registryProxy);
+
+ // Add the submodel to the AAS using the ConnectedAASManager
+ // The manager pushes the submodel to the server and registers it
+ // For this to work, the Identification of the Submodel has to be set
+ manager.createSubmodel(aasIdentifier, submodel);
+
+ }
+
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/DeleteAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/DeleteAAS.java
new file mode 100644
index 0000000..228a3bf
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/DeleteAAS.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.manager;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+/**
+ * Snippet that showcases how to delete an AAS from a server using the AASManager
+ *
+ * @author conradi
+ *
+ */
+public class DeleteAAS {
+
+ /**
+ * Removes an AAS from the server
+ *
+ * @param aasIdentifier the Identifier of the AAS to be deleted
+ * @param registryServerURL the URL of the registry server (e.g. http://localhost:8080/registry)
+ */
+ public static void deleteAAS(IIdentifier aasIdentifier, String registryServerURL) {
+
+ // Create a proxy pointing to the registry server
+ AASRegistryProxy registryProxy = new AASRegistryProxy(registryServerURL);
+
+ // Create a ConnectedAASManager using the registryProxy as its registry
+ ConnectedAssetAdministrationShellManager manager =
+ new ConnectedAssetAdministrationShellManager(registryProxy);
+
+ // Delete the AAS
+ // Automatically deregisters it
+ manager.deleteAAS(aasIdentifier);
+ }
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/DeleteSubmodelFromAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/DeleteSubmodelFromAAS.java
new file mode 100644
index 0000000..10e9f67
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/DeleteSubmodelFromAAS.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.manager;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+/**
+ * Snippet that showcases how to delete a Submodel from a server using the AASManager
+ *
+ * @author conradi
+ *
+ */
+public class DeleteSubmodelFromAAS {
+
+ /**
+ * Removes a Submodel from an AAS
+ *
+ * @param smIdentifier the Identifier of the Submodel to be deleted
+ * @param aasIdentifier the Identifier of the AAS the Submodel belongs to
+ * @param registryServerURL the URL of the registry server (e.g. http://localhost:8080/registry)
+ */
+ public static void deleteSubmodelFromAAS(IIdentifier smIdentifier, IIdentifier aasIdentifier, String registryServerURL) {
+
+ // Create a proxy pointing to the registry server
+ AASRegistryProxy registryProxy = new AASRegistryProxy(registryServerURL);
+
+ // Create a ConnectedAASManager using the registryProxy as its registry
+ ConnectedAssetAdministrationShellManager manager =
+ new ConnectedAssetAdministrationShellManager(registryProxy);
+
+ // Delete the Submodel
+ // Automatically deregisters it
+ manager.deleteSubmodel(aasIdentifier, smIdentifier);
+ }
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/PushAASToServer.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/PushAASToServer.java
new file mode 100644
index 0000000..e821194
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/PushAASToServer.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.manager;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+
+
+/**
+ * This snippet showcases how to push an AAS to a server using the AASManager
+ *
+ * @author conradi
+ *
+ */
+public class PushAASToServer {
+
+ /**
+ * Pushes the AAS to a server and registers it
+ *
+ * @param aas the AssetAdministrationShell to be pushed to the server
+ * @param aasServerURL the URL of the aas server (e.g. http://localhost:8080/aasComponent)
+ * @param registryServerURL the URL of the registry server (e.g. http://localhost:8080/registry)
+ */
+ public static void pushAAS(AssetAdministrationShell aas, String aasServerURL, String registryServerURL) {
+
+ // Create a proxy pointing to the registry server
+ AASRegistryProxy registryProxy = new AASRegistryProxy(registryServerURL);
+
+ // Create a ConnectedAASManager using the registryProxy as its registry
+ ConnectedAssetAdministrationShellManager manager =
+ new ConnectedAssetAdministrationShellManager(registryProxy);
+
+ // The ConnectedAASManager automatically pushes the given AAS
+ // to the server to which the address was given
+ // It also registers the AAS in the registry it got in its ctor
+ manager.createAAS(aas, aasServerURL);
+ }
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/RetrieveAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/RetrieveAAS.java
new file mode 100644
index 0000000..9f2f6f2
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/RetrieveAAS.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.manager;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+/**
+ * This snippet showcases how to retrieve an AAS from a server using the AASManager
+ *
+ * @author conradi
+ *
+ */
+public class RetrieveAAS {
+
+ /**
+ * Get an AAS from a server
+ *
+ * @param aasIdentifier the Identifier of the requested AAS
+ * @param registryServerURL the URL of the registry server
+ * @return The requested AAS as ConnectedAAS
+ */
+ public static IAssetAdministrationShell retrieveRemoteAAS(IIdentifier aasIdentifier, String registryServerURL) {
+
+ // Create a proxy pointing to the registry server
+ AASRegistryProxy registryProxy = new AASRegistryProxy(registryServerURL);
+
+ // Create a ConnectedAASManager using the registryProxy as its registry
+ ConnectedAssetAdministrationShellManager manager =
+ new ConnectedAssetAdministrationShellManager(registryProxy);
+
+ // Get the requested AAS from the manager
+ return manager.retrieveAAS(aasIdentifier);
+ }
+
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/RetrieveSubmodelFromAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/RetrieveSubmodelFromAAS.java
new file mode 100644
index 0000000..0d05a55
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/RetrieveSubmodelFromAAS.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.manager;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+
+/**
+ * This snippet showcases how to retrieve a Submodel
+ * from an AAS on a server using the AASManager
+ *
+ * @author conradi
+ *
+ */
+public class RetrieveSubmodelFromAAS {
+
+ /**
+ * Gets a Submodel from an AAS
+ *
+ * @param smIdentifier the Identifier of the requested Submodel
+ * @param aasIdentifier the Identifier of the AAS the Submodel belongs to
+ * @param registryServerURL the URL of the registry server
+ * @return the requested Submodel as ConnectedSubmodel
+ */
+ public static ISubmodel retrieveSubmodelFromAAS(IIdentifier smIdentifier, IIdentifier aasIdentifier, String registryServerURL) {
+
+ // Create a proxy pointing to the registry server
+ AASRegistryProxy registryProxy = new AASRegistryProxy(registryServerURL);
+
+ // Create a ConnectedAASManager using the registryProxy as its registry
+ ConnectedAssetAdministrationShellManager manager =
+ new ConnectedAssetAdministrationShellManager(registryProxy);
+
+ // Get the requested Submodel from the ConnectedAASManager using the Identifiers of the AAS and the SM
+ return manager.retrieveSubmodel(aasIdentifier, smIdentifier);
+ }
+
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/property/CreateLambdaProperty.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/property/CreateLambdaProperty.java
new file mode 100644
index 0000000..029838e
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/property/CreateLambdaProperty.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.property;
+
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.AASLambdaPropertyHelper;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+
+/**
+ * This snippet showcases how create a lambda Property, i.e. a property that
+ * retrieves its value at runtime from an arbitrary backend. <br>
+ * This is for example useful if a sensor or a edge device has to be connected.
+ * It is valid to only provide a getter, i.e. in case of a sensor. <br>
+ * The lambda property will only work if it is included in a submodel and being
+ * hosted} <br>
+ * <br>
+ * Please note, that a submodel containing a dynamic property can not be pushed
+ * to another server. Instead, it has to be hosted on its own server (see
+ * {@link org.eclipse.basyx.examples.snippets.submodel.HostPreconfiguredSubmodel
+ * Host Preconfigured Submodel}).
+ *
+ * @author schnicke
+ *
+ */
+public class CreateLambdaProperty {
+
+ /**
+ * Configures the passed property so that calls to its setValue/getValue are
+ * delegated
+ *
+ * @param propertyIdShort
+ * id of the lambda property
+ * @param type
+ * type of the lambda property
+ * @param get
+ * getter to be used
+ * @param set
+ * setter to be used
+ * @return the created lambda property
+ */
+ public static Property createLambdaProperty(String propertyIdShort, ValueType type, Supplier<Object> get, Consumer<Object> set) {
+ Property prop = new Property(propertyIdShort, type);
+
+ AASLambdaPropertyHelper.setLambdaValue(prop, get, set);
+
+ return prop;
+ }
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/DeregisterAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/DeregisterAAS.java
new file mode 100644
index 0000000..f26d853
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/DeregisterAAS.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.registry;
+
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+/**
+ * Snippet that showcases how to deregister a AAS from a RegistryComponent
+ *
+ * @author conradi
+ *
+ */
+public class DeregisterAAS {
+
+ /**
+ * Deregisters a given AssetAdministrationShell from a registry.
+ *
+ * @param smIdentifier the Identifier of the AAS to be deregistered
+ * @param registryServerURL the address of the registry
+ */
+ public static void registerAAS(IIdentifier aasIdentifier, String registryServerURL) {
+
+ // Create a proxy pointing to the registry
+ AASRegistryProxy registryProxy = new AASRegistryProxy(registryServerURL);
+
+ // Delete the AAS from the registry
+ registryProxy.delete(aasIdentifier);
+ }
+
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/DeregisterSubmodel.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/DeregisterSubmodel.java
new file mode 100644
index 0000000..3d03fa8
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/DeregisterSubmodel.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.registry;
+
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+/**
+ * Snippet that showcases how to deregister a Submodel
+ *
+ * @author conradi
+ *
+ */
+public class DeregisterSubmodel {
+
+ /**
+ * Deregisters a Submodel from a registry.
+ *
+ * @param smIdentifier the Identifier of the Submodel to be deregistered
+ * @param aasIdentifier the Identifier of the AAS the Submodel belongs to
+ * @param registryServerURL the address of the registry
+ */
+ public static void registerSubmodel(IIdentifier smIdentifier, IIdentifier aasIdentifier, String registryServerURL) {
+
+ // Create a proxy pointing to the registry
+ AASRegistryProxy registryProxy = new AASRegistryProxy(registryServerURL);
+
+ // Delete the Submodel from the registry
+ registryProxy.delete(aasIdentifier, smIdentifier);
+ }
+
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/LookupAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/LookupAAS.java
new file mode 100644
index 0000000..90a38ce
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/LookupAAS.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.registry;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+/**
+ * Snippet that showcases how to look up an AAS in a RegistryComponent
+ *
+ * @author conradi
+ *
+ */
+public class LookupAAS {
+
+ /**
+ * Gets the Descriptor of the requested AAS from a registry
+ *
+ * @param aasIdentifier the Identifier of the AAS to be looked up in the registry
+ * @param registryServerURL the URL of the registry server
+ * @return the AASDescriptor looked up in the registry
+ */
+ public static AASDescriptor lookupAAS(IIdentifier aasIdentifier, String registryServerURL) {
+
+ // Create a proxy pointing to the registry
+ AASRegistryProxy registryProxy = new AASRegistryProxy(registryServerURL);
+
+ // Lookup the AAS in the registry
+ return registryProxy.lookupAAS(aasIdentifier);
+ }
+
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/LookupSubmodel.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/LookupSubmodel.java
new file mode 100644
index 0000000..5e9b554
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/LookupSubmodel.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.registry;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+/**
+ * Snippet that showcases how to look up a Submodel in a RegistryComponent
+ *
+ * @author conradi
+ *
+ */
+public class LookupSubmodel {
+
+ /**
+ * Gets the Descriptor of the requested Submodel from a registry
+ *
+ * @param smIdentifier the Identifier of the Submodel to be looked up in the registry
+ * @param aasIdentifier the Identifier of the AAS the Submodel belongs to
+ * @param registryServerURL the URL of the registry server
+ * @return the SubmodelDescriptor looked up in the registry
+ */
+ public static SubmodelDescriptor lookupSubmodel(IIdentifier smIdentifier, IIdentifier aasIdentifier, String registryServerURL) {
+
+ // Create a proxy pointing to the registry
+ AASRegistryProxy registryProxy = new AASRegistryProxy(registryServerURL);
+
+ // Lookup the Submodel in the registry
+ return registryProxy.lookupSubmodel(aasIdentifier, smIdentifier);
+ }
+
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/RegisterAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/RegisterAAS.java
new file mode 100644
index 0000000..c0e2bf1
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/RegisterAAS.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.registry;
+
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+
+/**
+ * Snippet that showcases how to register a given AAS in a RegistryComponent
+ *
+ * @author conradi
+ *
+ */
+public class RegisterAAS {
+
+ /**
+ * Registers a given AssetAdministrationShell in a registry.
+ *
+ * @param aas the AssetAdministrationShell to be registered
+ * @param aasEndpoint the address where the AAS will be hosted (e.g. http://localhost:8080/aasList/{aasId}/aas)
+ * @param registryServerURL the address of the registry
+ */
+ public static void registerAAS(IAssetAdministrationShell aas, String aasEndpoint, String registryServerURL) {
+
+ // Create a proxy pointing to the registry
+ AASRegistryProxy registryProxy = new AASRegistryProxy(registryServerURL);
+
+ // Create a Descriptor for the AAS using the endpoint where it will be hosted
+ AASDescriptor descriptor = new AASDescriptor(aas, aasEndpoint);
+
+ // Register this Descriptor in the registry
+ registryProxy.register(descriptor);
+ }
+
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/RegisterSubmodel.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/RegisterSubmodel.java
new file mode 100644
index 0000000..c723772
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/RegisterSubmodel.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.registry;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+/**
+ * Snippet that showcases how to register a given Submodel in a RegistryComponent
+ *
+ * @author conradi
+ *
+ */
+public class RegisterSubmodel {
+
+ /**
+ * Registers a given Submodel in a registry.
+ *
+ * @param submodel the Submodel to be registered
+ * @param smEndpoint the address where the SM will be hosted (e.g. http://localhost:8080/aasList/{aasId}/aas/submodels/{smId})
+ * @param aasIdentifier the Identifier of the AAS the Submodel should be registered to
+ * @param registryServerURL the address of the registry
+ */
+ public static void registerSubmodel(ISubmodel submodel, String smEndpoint, IIdentifier aasIdentifier, String registryServerURL) {
+
+ // Create a proxy pointing to the registry
+ AASRegistryProxy registryProxy = new AASRegistryProxy(registryServerURL);
+
+ // Create a Descriptor for the sm using the endpoint where it will be hosted
+ SubmodelDescriptor descriptor = new SubmodelDescriptor(submodel, smEndpoint);
+
+ // Register this Descriptor in the registry
+ registryProxy.register(aasIdentifier, descriptor);
+ }
+
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/AddSubmodelElement.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/AddSubmodelElement.java
new file mode 100644
index 0000000..ee0fdbb
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/AddSubmodelElement.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import org.eclipse.basyx.examples.snippets.manager.RetrieveSubmodelFromAAS;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
+
+/**
+ * This snippet showcases how add to a SubmodelElement to a Submodel,
+ * that already exists on a server
+ *
+ * @author conradi
+ *
+ */
+public class AddSubmodelElement {
+
+ /**
+ * Adds a SubmodelElement to a remote Submodel
+ *
+ * @param smElement the SubmodelElement to be added
+ * @param smIdentifier the Identifier of the Submodel the element should be added to
+ * @param aasIdentifier the Identifier of the AAS the Submodel belongs to
+ * @param registryServerURL the URL of the registry server
+ */
+ public static void addSubmodelElement(SubmodelElement smElement, IIdentifier smIdentifier, IIdentifier aasIdentifier, String registryServerURL) {
+
+ // Get the ConnectedSubmodel
+ ISubmodel submodel = RetrieveSubmodelFromAAS.retrieveSubmodelFromAAS(smIdentifier, aasIdentifier, registryServerURL);
+
+ // Add the element to it
+ submodel.addSubmodelElement(smElement);
+
+ }
+
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/CreateSubmodel.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/CreateSubmodel.java
new file mode 100644
index 0000000..c7804cb
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/CreateSubmodel.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+
+/**
+ * Snippet that showcases how to create a Submodel
+ * with the mandatory attributes and a Property.
+ *
+ * @author conradi
+ *
+ */
+public class CreateSubmodel {
+
+ /**
+ * Creates a new Submodel with a Property
+ *
+ * @param idShort the idShort of the Submodel to be created
+ * @param smIdentifier the Identifier of the Submodel to be created
+ * @param propertyIdShort the idShort of the Property to be created
+ * @param propertyValue the value of the Property (see PropertyValueTypeDef for allowed value types)
+ * @return the newly created Submodel
+ */
+ public static Submodel createSubmodel(String idShort, IIdentifier smIdentifier, String propertyIdShort, Object propertyValue) {
+
+ // Create a new Property with the given idShort and value
+ Property property = new Property(propertyIdShort, propertyValue);
+
+ // Create a new Submodel object
+ Submodel sm = new Submodel(idShort, smIdentifier);
+
+ // Add the Property to the Submodel
+ sm.addSubmodelElement(property);
+
+ return sm;
+ }
+
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/DeleteSubmodelElement.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/DeleteSubmodelElement.java
new file mode 100644
index 0000000..98e3e1f
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/DeleteSubmodelElement.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import org.eclipse.basyx.examples.snippets.manager.RetrieveSubmodelFromAAS;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+/**
+ * Snippet that showcases how to delete a SubmodelElement from a Submodel
+ *
+ * @author conradi
+ *
+ */
+public class DeleteSubmodelElement {
+
+ /**
+ * Removes a SubmodelElement from a Submodel
+ *
+ * @param elementId the Id of the Element to be deleted (can also be a path if the Element is in a Collection)
+ * @param smIdentifier the Identifier of the Submodel the Element belongs to
+ * @param aasIdentifier the Identifier of the AAS the Submodel belongs to
+ * @param registryServerURL the URL of the registry server (e.g. http://localhost:8080/registry)
+ */
+ public static void deleteSubmodelElement(String elementId, IIdentifier smIdentifier, IIdentifier aasIdentifier, String registryServerURL) {
+
+ // Retrieve the Submodel from the server as a ConnectedSubmodel
+ ISubmodel submodel = RetrieveSubmodelFromAAS.retrieveSubmodelFromAAS(smIdentifier, aasIdentifier, registryServerURL);
+
+ // Delete the Element from the Submodel
+ submodel.deleteSubmodelElement(elementId);
+ }
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/ExecuteOperation.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/ExecuteOperation.java
new file mode 100644
index 0000000..cdaeac8
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/ExecuteOperation.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
+
+/**
+ * Snippet that showcases how to execute an Operation contained in a Submodel
+ *
+ * @author conradi
+ *
+ */
+public class ExecuteOperation {
+
+ /**
+ * Executes an Operation with the given parameters and return the result.
+ * The execution itself is run on the remote server
+ *
+ * @param operationId the idShort of the Operation to be executed
+ * @param operationParameters the parameters for the execution
+ * @param smIdentifier the Identifier of the Submodel the Operation belongs to
+ * @param aasIdentifier the Identifier of the AAS the Submodel belongs to
+ * @param registryServerURL the URL of the registry server
+ * @return the result of the execution
+ * @throws Exception thrown if the execution of the Operation threw an Exception
+ */
+ public static Object executeOperation(String operationId, Object[] operationParameters, IIdentifier smIdentifier, IIdentifier aasIdentifier, String registryServerURL) throws Exception {
+
+ // Get the Operation from the Submodel
+ ISubmodelElement element = RetrieveSubmodelElement.retrieveSubmodelElement(operationId, smIdentifier, aasIdentifier, registryServerURL);
+
+ // Check if the element is really an Operation
+ if( ! (element instanceof IOperation)) {
+ // The element with the given Id is not an Operation
+ throw new IllegalArgumentException("The SubmodelElement '" + operationId + "' is not an Operation");
+ }
+
+ // Cast the retrieved ISubmodelElement to an IOperation
+ IOperation operation = (IOperation) element;
+
+ // Invoke the Operation and return the Result
+ return operation.invoke(operationParameters);
+ }
+
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/HostPreconfiguredSubmodel.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/HostPreconfiguredSubmodel.java
new file mode 100644
index 0000000..36db60b
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/HostPreconfiguredSubmodel.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.components.servlet.submodel.SubmodelServlet;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxHTTPServer;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
+
+/**
+ * This snippet showcases how host a submodel on a standalone server, i.e. a
+ * server that is preconfigured with a submodel and does not allow upload of
+ * additional AAS/Submodels<br>
+ * For instance, this can be used by a device manufacturer to provide a submodel
+ * containing live sensor data in combination with a dynamic property (cf.
+ * {@link org.eclipse.basyx.examples.snippets.property.CreateLambdaProperty
+ * CreateDynamicProperty}). <br>
+ *
+ * @author schnicke
+ *
+ */
+public class HostPreconfiguredSubmodel {
+
+ /**
+ * Creates, configures and starts an HTTP Server providing a preconfigured
+ * submodel
+ *
+ * @param serverContext
+ * the context configuration of the server
+ * @param sm
+ * the submodel to be hosted
+ * @return the started server
+ */
+ public static BaSyxHTTPServer hostPreconfiguredSubmodel(BaSyxContextConfiguration serverContext, Submodel sm) {
+ // Create the BaSyx context from the context configuration
+ BaSyxContext context = serverContext.createBaSyxContext();
+
+ // Create a new SubmodelServlet containing the passed submodel
+ SubmodelServlet smServlet = new SubmodelServlet(sm);
+
+ // Add the SubmodelServlet mapping to the context at the path "$SmIdShort"
+ // Here, it possible to add further submodels using the same pattern
+ context.addServletMapping("/" + sm.getIdShort() + "/*", smServlet);
+
+ // Create and start a HTTP server with the context created above
+ BaSyxHTTPServer preconfiguredSmServer = new BaSyxHTTPServer(context);
+ preconfiguredSmServer.start();
+
+ return preconfiguredSmServer;
+ }
+
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/RetrieveSubmodelElement.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/RetrieveSubmodelElement.java
new file mode 100644
index 0000000..6893d49
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/RetrieveSubmodelElement.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import org.eclipse.basyx.examples.snippets.manager.RetrieveSubmodelFromAAS;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+
+/**
+ * This snippet showcases how to retrieve a SubmodelElement from a remote Submodel
+ *
+ * @author conradi
+ *
+ */
+public class RetrieveSubmodelElement {
+
+ /**
+ * Gets a SubmodelElement from a remote Submodel
+ *
+ * @param elementId the idShort SubmodelElement to be retrieved
+ * @param smIdentifier the Identifier of the Submodel the element belongs to
+ * @param aasIdentifier the Identifier of the AAS the Submodel belongs to
+ * @param registryServerURL the URL of the registry server
+ * @return the requested SubmodelElement
+ */
+ public static ISubmodelElement retrieveSubmodelElement(String elementId, IIdentifier smIdentifier, IIdentifier aasIdentifier, String registryServerURL) {
+
+ // Get the ConnectedSubmodel
+ ISubmodel submodel = RetrieveSubmodelFromAAS.retrieveSubmodelFromAAS(smIdentifier, aasIdentifier, registryServerURL);
+
+ // Add the element to it
+ return submodel.getSubmodelElement(elementId);
+
+ }
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/ExampleAASComponent.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/ExampleAASComponent.java
new file mode 100644
index 0000000..242504a
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/ExampleAASComponent.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.support;
+
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.components.aas.AASServerComponent;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+
+/**
+ * This class is used to startup an AAS-Server using the AASServerComponent
+ *
+ * @author conradi
+ *
+ */
+public class ExampleAASComponent {
+
+ public static final String CONTEXT_PATH = "aasComponent";
+
+ private int port;
+
+ private IAASRegistry registry;
+
+ // Hold a reference to the server to be able to shut it down
+ private AASServerComponent aasServer = null;
+
+
+ public ExampleAASComponent(int port, IAASRegistry registry) {
+ this.port = port;
+ this.registry = registry;
+ }
+
+ public void startupAASServer() {
+ // Create a Configuration telling the component the port to use and the contextPath
+ // The contextPath is attached to the address of the server "http://localhost:8080/{contextPath}"
+ BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration(port, CONTEXT_PATH);
+ aasServer = new AASServerComponent(contextConfig);
+
+ // Set the registry to be used by the server
+ aasServer.setRegistry(registry);
+
+ // Startup the AASServer
+ aasServer.startComponent();
+ }
+
+ public void shutdownAASServer() {
+ // If an AASServer was started -> stop it
+ if(aasServer != null) {
+ aasServer.stopComponent();
+ }
+ }
+
+ public String getAASServerPath() {
+ return "http://localhost:" + port + "/" + CONTEXT_PATH;
+ }
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/ExampleComponentBuilder.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/ExampleComponentBuilder.java
new file mode 100644
index 0000000..e4ddd69
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/ExampleComponentBuilder.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.support;
+
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+
+/**
+ * This class is used to build AssetAdministrationShells and Submodels
+ * for the scenarios and snippets.
+ *
+ * Please note that the generated objects are just for showcasing,
+ * several mandatory attributes are missing.
+ *
+ * @author conradi
+ *
+ */
+public class ExampleComponentBuilder {
+
+ public static final String PROPERTY_ID = "prop";
+ public static final int PROPERTY_VALUE = 123;
+
+ public static final String COLLECTION_ID = "collection";
+ public static final String COLLECTION_PROPERTY_ID = "propInCollection";
+ public static final String COLLECTION_PROPERTY_VALUE = "TheValue";
+
+ /**
+ * Builds a Submodel containing a Property and a Collection with a Property
+ *
+ * @param idShort the idShort for the new Submodel
+ * @return the new Submodel
+ */
+ public static Submodel buildExampleSubmodel(String idShort, String id) {
+ Submodel submodel = new Submodel(idShort, new Identifier(IdentifierType.CUSTOM, id));
+
+ // Add a Property to the Submodel
+ Property property = new Property(PROPERTY_ID, ValueType.Int32);
+ property.setValue(PROPERTY_VALUE);
+ submodel.addSubmodelElement(property);
+
+ // Add a SubmodelElementCollection
+ SubmodelElementCollection collection = new SubmodelElementCollection(COLLECTION_ID);
+
+ // Add a Property to the SubmodelElementCollection
+ Property property2 = new Property(COLLECTION_PROPERTY_ID, ValueType.String);
+ property2.setValue(COLLECTION_PROPERTY_VALUE);
+ collection.addSubmodelElement(property2);
+ submodel.addSubmodelElement(collection);
+
+ return submodel;
+ }
+
+ /**
+ * Builds an AssetAdministrationShell
+ *
+ * @param idShort the idShort for the new AAS
+ * @param id the id to be used in Identification
+ * @return the new AAS
+ */
+ public static AssetAdministrationShell buildExampleAAS(String idShort, String id) {
+ Identifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, id);
+ Identifier assetIdentifier = new Identifier(IdentifierType.CUSTOM, id + "asset");
+ Asset asset = new Asset(idShort + "asset", assetIdentifier, AssetKind.INSTANCE);
+ AssetAdministrationShell aas = new AssetAdministrationShell(idShort, aasIdentifier, asset);
+
+ return aas;
+ }
+
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/ExampleRegistryComponent.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/ExampleRegistryComponent.java
new file mode 100644
index 0000000..e26e1eb
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/ExampleRegistryComponent.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.support;
+
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.components.registry.RegistryComponent;
+import org.eclipse.basyx.components.registry.configuration.BaSyxRegistryConfiguration;
+import org.eclipse.basyx.components.registry.configuration.RegistryBackend;
+
+/**
+ * This class is used to startup a registry using the RegistryComponent
+ *
+ * @author conradi
+ *
+ */
+public class ExampleRegistryComponent {
+
+ public static final String CONTEXT_PATH = "registry";
+
+ private int port;
+
+ // Hold a reference to the server to be able to shut it down
+ private RegistryComponent registry = null;
+
+
+ public ExampleRegistryComponent(int port) {
+ this.port = port;
+ }
+
+
+ public void startupRegistry() {
+ // Create a Configuration telling the component the port to use and the contextPath
+ // The contextPath is attached to the address of the server "http://localhost:8080/{contextPath}"
+ BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration(port, CONTEXT_PATH);
+
+ // Create a RegistrationConfiguration telling the component to hold the whole registry in memory
+ BaSyxRegistryConfiguration registryConfig = new BaSyxRegistryConfiguration(RegistryBackend.INMEMORY);
+
+ registry = new RegistryComponent(contextConfig, registryConfig);
+
+ // Startup the Registry
+ registry.startComponent();
+ }
+
+ public void shutdownRegistry() {
+ // If a registry was started -> stop it
+ if(registry != null) {
+ registry.stopComponent();
+ }
+ }
+
+ public String getRegistryPath() {
+ return "http://localhost:" + port + "/" + CONTEXT_PATH;
+ }
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/directory/ExampleAASRegistry.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/directory/ExampleAASRegistry.java
index b4f894b..4bdf572 100644
--- a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/directory/ExampleAASRegistry.java
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/directory/ExampleAASRegistry.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.support.directory;
import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
@@ -23,8 +32,8 @@
IIdentifier smId = new Identifier(IdentifierType.IRI, submodelid);
SubmodelDescriptor smDes = new SubmodelDescriptor(submodelid, smId, endpoint);
- if (descriptorMap.keySet().contains(aasUrn.getURN())) {
- aasDescriptor = descriptorMap.get(aasUrn.getURN());
+ if (handler.contains(aasUrn)) {
+ aasDescriptor = handler.get(aasUrn);
} else {
throw new RuntimeException("AASDescriptor for " + rawAASUrn + " missing");
}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/directory/ExamplesPreconfiguredDirectory.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/directory/ExamplesPreconfiguredDirectory.java
index 3dd8b66..cf0214b 100644
--- a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/directory/ExamplesPreconfiguredDirectory.java
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/directory/ExamplesPreconfiguredDirectory.java
@@ -1,6 +1,15 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.support.directory;
-import org.eclipse.basyx.vab.directory.memory.InMemoryDirectory;
+import org.eclipse.basyx.vab.registry.memory.VABInMemoryRegistry;
/**
* Implement the examples directory service with pre-configured directory entries
@@ -8,7 +17,7 @@
* @author kuhn
*
*/
-public class ExamplesPreconfiguredDirectory extends InMemoryDirectory {
+public class ExamplesPreconfiguredDirectory extends VABInMemoryRegistry {
/**
@@ -20,6 +29,6 @@
// Define mappings
// - AAS server mapping
- addMapping("AASServer", "http://localhost:8080/basys.examples/Components/BaSys/1.0/aasServer/");
+ addMapping("AASServer", "http://localhost:8080/basys.examples/Components/AasServer/");
}
}
diff --git a/examples/basys.examples/src/main/resources/CloudEdgeDeploymentScenarioAASContext.properties b/examples/basys.examples/src/main/resources/CloudEdgeDeploymentScenarioAASContext.properties
new file mode 100644
index 0000000..7151423
--- /dev/null
+++ b/examples/basys.examples/src/main/resources/CloudEdgeDeploymentScenarioAASContext.properties
@@ -0,0 +1,24 @@
+# ###############################
+# HTTP Context configuration file
+# ###############################
+
+# ###############################
+# Context Path
+# ###############################
+# Specifies the subpath in the url for this server context
+
+contextPath=/cloud
+
+# ###############################
+# Hostname
+# ###############################
+# Specifies the hostname for this server context
+
+contextHostname=localhost
+
+# ###############################
+# Port
+# ###############################
+# Specifies the port for this server context
+
+contextPort=8081
diff --git a/examples/basys.examples/src/main/resources/RegistryContext.properties b/examples/basys.examples/src/main/resources/RegistryContext.properties
new file mode 100644
index 0000000..c0c55e1
--- /dev/null
+++ b/examples/basys.examples/src/main/resources/RegistryContext.properties
@@ -0,0 +1,24 @@
+# ###############################
+# HTTP Context configuration file
+# ###############################
+
+# ###############################
+# Context Path
+# ###############################
+# Specifies the subpath in the url for this server context
+
+contextPath=/registry
+
+# ###############################
+# Hostname
+# ###############################
+# Specifies the hostname for this server context
+
+contextHostname=localhost
+
+# ###############################
+# Port
+# ###############################
+# Specifies the port for this server context
+
+contextPort=4000
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/TestContext.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/TestContext.java
deleted file mode 100644
index de4b882..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/TestContext.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.eclipse.basyx.examples;
-
-import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory;
-import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
-
-/**
- * This class is used to define test context once for all the test projects.
- * So that multiple context does not get created
- * For now, only SQL context is created here
- * @author haque
- *
- */
-public class TestContext {
-
- // A new instance of SQL context used in all test project
- public static BaSyxContext sqlContext = new BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory();
-}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/contexts/BaSyxExamplesContext.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/contexts/BaSyxExamplesContext.java
new file mode 100644
index 0000000..cd5efd0
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/contexts/BaSyxExamplesContext.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.contexts;
+
+import org.eclipse.basyx.components.aas.servlet.AASAggregatorServlet;
+import org.eclipse.basyx.components.registry.servlet.InMemoryRegistryServlet;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
+
+/**
+ * BaSyx context that contains an Industrie 4.0 Servlet infrastructure <br>
+ * - One in-memory AAS Server that receives and hosts asset administration
+ * shells and submodels<br>
+ * - One in-memory registry that manages AAS and sub model registrations<br>
+ *
+ * @author kuhn, schnicke
+ *
+ */
+public class BaSyxExamplesContext extends BaSyxContext {
+
+
+ /**
+ * Version of serialized instance
+ */
+ private static final long serialVersionUID = 1L;
+
+ private static final String CONTEXT = "/basys.examples";
+
+ private static final String AASSERVERFRAGMENT = "/Components/AasServer/";
+ public static final String AASSERVERURL = CONTEXT + AASSERVERFRAGMENT;
+
+ private static final String REGISTRYFRAGMENT = "/Components/Registry/";
+ public static final String REGISTRYURL = CONTEXT + REGISTRYFRAGMENT;
+
+ /**
+ * Constructor
+ */
+ public BaSyxExamplesContext() {
+ // Invoke base constructor to set up Tomcat server in basys.components context
+ super(CONTEXT, "");
+
+ // Define Servlet infrastucture
+ addServletMapping(REGISTRYFRAGMENT + "*", new InMemoryRegistryServlet());
+ addServletMapping(AASSERVERFRAGMENT + "*", new AASAggregatorServlet());
+ }
+}
+
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/contexts/BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/contexts/BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory.java
deleted file mode 100644
index 614da66..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/contexts/BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.eclipse.basyx.examples.contexts;
-
-import org.eclipse.basyx.components.servlet.SQLRegistryServlet;
-import org.eclipse.basyx.components.servlet.submodel.cfg.RawCFGSubModelProviderServlet;
-import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
-
-/**
- * BaSyx context that contains an Industrie 4.0 Servlet infrastructure
- * - One in-memory AAS Server that receives and hosts asset administration shells and sub models
- * - One SQL directory that manages AAS and sub model registrations
- *
- * @author kuhn
- *
- */
-public class BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory extends BaSyxContext {
-
-
- /**
- * Version of serialized instance
- */
- private static final long serialVersionUID = 1L;
-
-
-
- /**
- * Constructor
- */
- public BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory() {
- // Invoke base constructor to set up Tomcat server in basys.components context
- super("/basys.examples", "");
-
- // Define Servlet infrastucture
- addServletMapping("/Components/Directory/SQL/*", new SQLRegistryServlet().withParameter("config", "/WebContent/WEB-INF/config/directory/sqldirectory/directory.properties"));
- addServletMapping("/Components/BaSys/1.0/aasServer/*", new RawCFGSubModelProviderServlet().withParameter("config", "/WebContent/WEB-INF/config/aasServer/aasServer.properties"));
- }
-}
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/contexts/BaSyxExamplesContext_Empty.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/contexts/BaSyxExamplesContext_Empty.java
index f7ddbcb..6ff858c 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/contexts/BaSyxExamplesContext_Empty.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/contexts/BaSyxExamplesContext_Empty.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.contexts;
import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
@@ -16,14 +25,14 @@
*/
private static final long serialVersionUID = 1L;
-
+ public static final String CONTEXT = "/basys.examples";
/**
* Constructor
*/
public BaSyxExamplesContext_Empty() {
// Invoke base constructor to set up Tomcat server in basys.components context
- super("/basys.examples", "");
+ super(CONTEXT, "");
}
}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/deployment/BaSyxDeployment.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/deployment/BaSyxDeployment.java
new file mode 100644
index 0000000..5df305a
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/deployment/BaSyxDeployment.java
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.deployment;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxHTTPServer;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
+import org.eclipse.basyx.vab.service.api.BaSyxService;
+import org.junit.rules.ExternalResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+
+/**
+ * This class represents a BaSyx deployment with servers / servlets and assets for running BaSyx examples
+ *
+ * @author kuhn
+ *
+ */
+public class BaSyxDeployment extends ExternalResource {
+
+ /**
+ * Initiates a logger using the current class
+ */
+ private static final Logger logger = LoggerFactory.getLogger(BaSyxDeployment.class);
+
+
+ /**
+ * Store context objects
+ */
+ protected Object[] contextComponents = null;
+
+ /**
+ * Map runnable names to runnables
+ */
+ protected Map<String, BaSyxService> contectRunnablesByName = new HashMap<>();
+
+ /**
+ * Deployment on HTTP server
+ */
+ private BaSyxHTTPServer server;
+
+
+
+ /**
+ * Constructor - accept parameter of type BaSyxContext or Runnable
+ */
+ public BaSyxDeployment(Object... components) {
+ // Store context objects
+ contextComponents = components;
+
+ // Store runnable objects by name
+ for (Object obj: contextComponents) {
+ // Check component type
+ if (!(obj instanceof BaSyxService)) continue;
+
+ // Add BaSyxContextRunnable to context
+ // - Cast object
+ BaSyxService contextRunnable = (BaSyxService) obj;
+ // - Add context runnable to map if it is named
+ if (contextRunnable.getName() == null) continue;
+ // - Add context runnable to map
+ contectRunnablesByName.put(contextRunnable.getName(), contextRunnable);
+ }
+ }
+
+
+
+ /**
+ * Execute before a test case starts
+ */
+ @Override
+ protected void before() {
+ // Iterate context components
+ for (Object contextComponent: contextComponents) {
+ // Process BaSyx context objects that run in a tomcat server
+ if (contextComponent instanceof BaSyxContext) {
+ // Get HTTP server resource
+ server = new BaSyxHTTPServer((BaSyxContext) contextComponent);
+ // - Start the server
+ server.start();
+ // - Continue loop
+ continue;
+ }
+
+ // Process runnables
+ if (contextComponent instanceof BaSyxService) {
+ // Execute runnable
+ ((BaSyxService) contextComponent).start();
+ // - Continue loop
+ continue;
+ }
+
+ logger.error("Error:"+contextComponent);
+
+ // Unknown deployment context
+ throw new UnknownContextComponentTypeException();
+ }
+ }
+
+
+ /**
+ * Execute after test case ends
+ */
+ @Override
+ protected void after() {
+ // Iterate context components
+ for (Object contextComponent: contextComponents) {
+ // Process BaSyx context objects that run in a tomcat server
+ if (contextComponent instanceof BaSyxContext) {
+ // - Shutdown the server
+ server.shutdown();
+ // - Continue loop
+ continue;
+ }
+
+ // Process runnables
+ if (contextComponent instanceof BaSyxService) {
+ // Execute runnable
+ ((BaSyxService) contextComponent).stop();
+ // - Continue loop
+ continue;
+ }
+
+ // Unknown deployment context
+ throw new UnknownContextComponentTypeException();
+ }
+ }
+
+
+ /**
+ * Get context runnable by name
+ */
+ public BaSyxService getRunnable(String name) {
+ return contectRunnablesByName.get(name);
+ }
+}
+
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/deployment/UnknownContextComponentTypeException.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/deployment/UnknownContextComponentTypeException.java
new file mode 100644
index 0000000..d8e1bbf
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/deployment/UnknownContextComponentTypeException.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.deployment;
+
+
+/**
+ * This exception indicates the presence of an unknown component type in a BaSyx context
+ *
+ * @author kuhn
+ *
+ */
+public class UnknownContextComponentTypeException extends RuntimeException {
+
+
+ /**
+ * Version information for serialized instances
+ */
+ private static final long serialVersionUID = 1L;
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/application/ReceiveDeviceDashboardStatusApplication.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/application/ReceiveDeviceDashboardStatusApplication.java
index 303dc1c..8acf3ee 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/application/ReceiveDeviceDashboardStatusApplication.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/application/ReceiveDeviceDashboardStatusApplication.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.mockup.application;
import java.util.Map;
@@ -7,11 +16,12 @@
import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
import org.eclipse.basyx.components.service.BaseBaSyxService;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
import org.eclipse.basyx.vab.manager.VABConnectionManager;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
/**
* Example BaSys 4.0 application that monitors device (execution) status changes and device service invocation counters
@@ -34,10 +44,10 @@
*/
public ReceiveDeviceDashboardStatusApplication() {
// Create AAS registry for this service
- setRegistry(new AASRegistryProxy("http://localhost:8080/basys.examples/Components/Directory/SQL"));
+ setRegistry(new AASRegistryProxy("http://localhost:8080/" + BaSyxExamplesContext.REGISTRYURL));
// Service connection manager
- setConnectionManager(new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorProvider()));
+ setConnectionManager(new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorFactory()));
// Register URNs of used objects
addShortcut("AAS", new ModelUrn("urn:de.FHG:devices.es.iese:aas:1.0:3:x-509#001"));
@@ -56,7 +66,7 @@
// Create connection to device sub model
// - This code assumes that network location of device sub model does not change while application is running
AASDescriptor aasDescriptor = getRegistry().lookupAAS(lookupURN("AAS"));
- SubmodelDescriptor smDescriptor = aasDescriptor.getSubModelDescriptor(lookupURN("Status"));
+ SubmodelDescriptor smDescriptor = aasDescriptor.getSubmodelDescriptor(lookupURN("Status"));
// - Connect to status sub model end point
aasServerConnection = getConnectionManager().connectToVABElementByPath(smDescriptor.getFirstEndpoint());
}
@@ -69,7 +79,7 @@
public String getDeviceStatus() {
// Read the status property
Map<String, Object> property = (Map<String, Object>) aasServerConnection
- .getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/status");
+ .getValue(MultiSubmodelElementProvider.ELEMENTS + "/status");
// Return the value of the property
return property.get("value").toString();
}
@@ -82,7 +92,7 @@
public int getDeviceInvocationCounter() {
// Read the invocation counter for device default service
Map<String, Object> property = (Map<String, Object>) aasServerConnection
- .getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/invocations");
+ .getValue(MultiSubmodelElementProvider.ELEMENTS + "/invocations");
// Return the value of the property
return (int) property.get("value");
}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/application/ReceiveDeviceMaintenanceApplication.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/application/ReceiveDeviceMaintenanceApplication.java
index e298ba6..f4de335 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/application/ReceiveDeviceMaintenanceApplication.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/application/ReceiveDeviceMaintenanceApplication.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.mockup.application;
import java.util.Map;
@@ -7,11 +16,12 @@
import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
import org.eclipse.basyx.components.service.BaseBaSyxService;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
import org.eclipse.basyx.vab.manager.VABConnectionManager;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
@@ -38,10 +48,10 @@
*/
public ReceiveDeviceMaintenanceApplication() {
// Create AAS registry for this service
- setRegistry(new AASRegistryProxy("http://localhost:8080/basys.examples/Components/Directory/SQL"));
+ setRegistry(new AASRegistryProxy("http://localhost:8080/" + BaSyxExamplesContext.REGISTRYURL));
// Service connection manager
- setConnectionManager(new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorProvider()));
+ setConnectionManager(new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorFactory()));
// Register URNs of used objects
addShortcut("AAS", new ModelUrn("urn:de.FHG:devices.es.iese:aas:1.0:3:x-509#001"));
@@ -60,7 +70,7 @@
// Create connection to device sub model
// - This code assumes that network location of device sub model does not change while application is running
AASDescriptor aasDescriptor = getRegistry().lookupAAS(lookupURN("AAS"));
- SubmodelDescriptor smDescriptor = aasDescriptor.getSubModelDescriptor(lookupURN("Supply"));
+ SubmodelDescriptor smDescriptor = aasDescriptor.getSubmodelDescriptor(lookupURN("Supply"));
// - Connect to status sub model end point
aasServerConnection = getConnectionManager().connectToVABElementByPath(smDescriptor.getFirstEndpoint());
}
@@ -73,7 +83,7 @@
public int getDevicePartSupplyStatus() {
// Read the status property
Map<String, Object> property = (Map<String, Object>) aasServerConnection
- .getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/partAvailability");
+ .getValue(MultiSubmodelElementProvider.ELEMENTS + "/partAvailability");
// Return the value of the property
return Integer.parseInt(property.get("value").toString());
}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/device/ControllableTCPDeviceMockup.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/device/ControllableTCPDeviceMockup.java
index eae11ba..b183b80 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/device/ControllableTCPDeviceMockup.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/device/ControllableTCPDeviceMockup.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.mockup.device;
import org.eclipse.basyx.components.device.BaseTCPControllableDeviceAdapter;
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/device/SimpleTCPDeviceMockup.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/device/SimpleTCPDeviceMockup.java
index 04fbef3..2bbd879 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/device/SimpleTCPDeviceMockup.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/device/SimpleTCPDeviceMockup.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.mockup.device;
import org.eclipse.basyx.components.device.BaseTCPDeviceAdapter;
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/device/SmartBaSyxTCPDeviceMockup.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/device/SmartBaSyxTCPDeviceMockup.java
index 0846b5c..834e8ed 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/device/SmartBaSyxTCPDeviceMockup.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/device/SmartBaSyxTCPDeviceMockup.java
@@ -1,33 +1,46 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.mockup.device;
import java.util.Map;
+import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
import org.eclipse.basyx.components.device.BaseSmartDevice;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
import org.eclipse.basyx.models.controlcomponent.ExecutionState;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
import org.eclipse.basyx.vab.manager.VABConnectionManager;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
import org.eclipse.basyx.vab.protocol.basyx.server.BaSyxTCPServer;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
/**
* This class implements a mockup of a smart manufacturing device
*
- * The device pushes its AAS to an external asset administration shell server
- * - The sub model "statusSM" is pushed to the external asset administration shell server as well
- * - The sub model "controllerSM" is provided by an BaSyx/TCP server of the smart device
+ * The device pushes its AAS to an external asset administration shell server -
+ * The sub model "statusSM" is pushed to the external asset administration shell
+ * server as well - The sub model "controllerSM" is provided by an BaSyx/TCP
+ * server of the smart device
*
* @author kuhn
- *
+ *
*/
public class SmartBaSyxTCPDeviceMockup extends BaseSmartDevice {
@@ -49,6 +62,7 @@
*/
protected VABElementProxy aasServerConnection = null;
+ protected String aasPath;
@@ -68,8 +82,8 @@
addShortcut("Status", new ModelUrn("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#001"));
// Configure BaSyx service - registry and connection manager
- setRegistry(new AASRegistryProxy("http://localhost:8080/basys.examples/Components/Directory/SQL"));
- setConnectionManager(new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorProvider()));
+ setRegistry(new AASRegistryProxy("http://localhost:8080/" + BaSyxExamplesContext.REGISTRYURL));
+ setConnectionManager(new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorFactory()));
}
@@ -83,10 +97,9 @@
super.onServiceInvocation();
// Implement the device invocation counter - read and increment invocation counter
Map<String, Object> property = (Map<String, Object>) aasServerConnection
- .getModelPropertyValue(
- "/aas/submodels/Status/" + SubmodelElementProvider.PROPERTIES + "/invocations");
+ .getValue(aasPath + "/submodels/Status/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/invocations");
int invocations = (int) property.get("value");
- aasServerConnection.setModelPropertyValue("/aas/submodels/Status/" + SubmodelElementProvider.PROPERTIES + "/invocations/value", ++invocations);
+ aasServerConnection.setValue(aasPath + "/submodels/Status/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/invocations/value", ++invocations);
}
@@ -99,7 +112,7 @@
super.onChangedExecutionState(newExecutionState);
// Update property "properties/status" in external AAS
- aasServerConnection.setModelPropertyValue("/aas/submodels/Status/" + SubmodelElementProvider.PROPERTIES + "/status/value",
+ aasServerConnection.setValue(aasPath + "/submodels/Status/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/status/value",
newExecutionState.getValue());
}
@@ -121,27 +134,32 @@
// Create device AAS
// - Create device AAS
- AssetAdministrationShell aas = new AssetAdministrationShell().putPath("idShort", "DeviceIDShort");
+ AssetAdministrationShell aas = new AssetAdministrationShell();
+ aas.setIdShort("DeviceIDShort");
+ aas.setIdentification(lookupURN("AAS"));
+
// - Transfer device AAS to server
- aasServerConnection.createValue("/aas", aas);
+ aasServerConnection.setValue(VABPathTools.append(AASAggregatorProvider.PREFIX, VABPathTools.encodePathElement(aas.getIdentification().getId())), aas);
+
+ aasPath = VABPathTools.concatenatePaths(AASAggregatorProvider.PREFIX, lookupURN("AAS").getEncodedURN(), "aas");
// The device also brings a sub model structure with an own ID that is being pushed on the server
// - Create generic sub model and add properties
- SubModel statusSM = new SubModel();
+ Submodel statusSM = new Submodel();
statusSM.setIdShort("Status");
// - Property status: indicate device status
Property statusProp = new Property("offline");
statusProp.setIdShort("status");
- statusSM.addSubModelElement(statusProp);
+ statusSM.addSubmodelElement(statusProp);
// - Property statistics: export invocation statistics for every service
// - invocations: indicate total service invocations. Properties are not persisted in this example,
// therefore we start counting always at 0.
Property invocationsProp = new Property(0);
invocationsProp.setIdShort("invocations");
- statusSM.addSubModelElement(invocationsProp);
+ statusSM.addSubmodelElement(invocationsProp);
// - Transfer device sub model to server
- aasServerConnection.createValue("/aas/submodels", statusSM);
+ aasServerConnection.setValue(aasPath + "/submodels/" + statusSM.getIdShort(), statusSM);
// Register control component as local sub model
@@ -153,12 +171,12 @@
// Register AAS and sub models in directory (push AAS descriptor to server)
// - AAS repository server URL
- String aasRepoURL = "http://localhost:8080/basys.examples/Components/BaSys/1.0/aasServer/aas";
+ String aasRepoURL = "http://localhost:8080" + BaSyxExamplesContext.AASSERVERURL + "/" + AASAggregatorProvider.PREFIX + "/" + lookupURN("AAS").getEncodedURN() + "/aas";
// - Build an AAS descriptor, add sub model descriptors
AASDescriptor deviceAASDescriptor = new AASDescriptor(lookupURN("AAS"), aasRepoURL);
// Create sub model descriptors
SubmodelDescriptor statusSMDescriptor = new SubmodelDescriptor("Status", lookupURN("Status"),
- aasRepoURL + "/submodels/Status");
+ aasRepoURL + "/submodels/Status/submodel");
// Add sub model descriptor to AAS descriptor
deviceAASDescriptor.addSubmodelDescriptor(statusSMDescriptor);
// - Push AAS descriptor to server
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/devicemanager/BaSyxTCPControlManufacturingDeviceManager.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/devicemanager/BaSyxTCPControlManufacturingDeviceManager.java
index d7939bf..e03740a 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/devicemanager/BaSyxTCPControlManufacturingDeviceManager.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/devicemanager/BaSyxTCPControlManufacturingDeviceManager.java
@@ -1,22 +1,34 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.mockup.devicemanager;
import java.util.HashMap;
+import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
import org.eclipse.basyx.components.devicemanager.TCPControllableDeviceManagerComponent;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
import org.eclipse.basyx.models.controlcomponent.ControlComponentChangeListener;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
import org.eclipse.basyx.vab.manager.VABConnectionManager;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
import org.eclipse.basyx.vab.protocol.basyx.server.BaSyxTCPServer;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -29,7 +41,7 @@
*
*/
public class BaSyxTCPControlManufacturingDeviceManager extends TCPControllableDeviceManagerComponent implements ControlComponentChangeListener {
-
+
/**
* Initiates a logger using the current class
*/
@@ -40,6 +52,8 @@
*/
protected VABElementProxy aasServerConnection = null;
+ protected String aasPath;
+
@@ -52,18 +66,18 @@
// Set registry that will be used by this service
- setRegistry(new AASRegistryProxy("http://localhost:8080/basys.examples/Components/Directory/SQL"));
+ setRegistry(new AASRegistryProxy("http://localhost:8080/" + BaSyxExamplesContext.REGISTRYURL));
// Set service connection manager and create AAS server connection
- setConnectionManager(new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorProvider()));
+ setConnectionManager(new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorFactory()));
// - Create AAS server connection
aasServerConnection = getConnectionManager().connectToVABElement("AASServer");
// Set AAS server VAB object ID, AAS server URL, and AAS server path prefix
setAASServerObjectID("AASServer");
- setAASServerURL("http://localhost:8080/basys.examples/Components/BaSys/1.0/aasServer");
+ setAASServerURL("http://localhost:8080/" + BaSyxExamplesContext.AASSERVERURL);
}
@@ -76,7 +90,7 @@
super.start();
// Create the device AAS and sub model structure
- createDeviceAASAndSubModels();
+ createDeviceAASAndSubmodels();
// Register AAS and sub model descriptors in directory (push AAS descriptor to server)
getRegistry().register(getAASDescriptor());
@@ -87,7 +101,7 @@
/**
* Create the device AAS and sub model structure
*/
- protected void createDeviceAASAndSubModels() {
+ protected void createDeviceAASAndSubmodels() {
// Register URNs of managed VAB objects
addShortcut("AAS", new ModelUrn("urn:de.FHG:devices.es.iese:aas:1.0:3:x-509#001"));
addShortcut("Status", new ModelUrn("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#001"));
@@ -96,30 +110,32 @@
AssetAdministrationShell aas = new AssetAdministrationShell();
// - Populate AAS
aas.setIdShort("DeviceIDShort");
+ aas.setIdentification(lookupURN("AAS"));
// The device also brings a sub model structure with an own ID that is being pushed on the server
// - Create generic sub model and add properties
- SubModel statusSM = new SubModel();
+ Submodel statusSM = new Submodel();
// - Set submodel ID
statusSM.setIdShort("Status");
// - Property status: indicate device status
Property statusProp = new Property("offline");
statusProp.setIdShort("status");
- statusSM.addSubModelElement(statusProp);
+ statusSM.addSubmodelElement(statusProp);
// - Property statistics: export invocation statistics for every service
// - invocations: indicate total service invocations. Properties are not persisted in this example,
// therefore we start counting always at 0.
Property invocationsProp = new Property(0);
invocationsProp.setIdShort("invocations");
- statusSM.addSubModelElement(invocationsProp);
+ statusSM.addSubmodelElement(invocationsProp);
// - Add the submodel to the AAS
- aas.addSubModel(statusSM);
+ aas.addSubmodel(statusSM);
// Push the AAS and submodels to the server
// - Transfer device AAS to server
- aasServerConnection.createValue("/aas", aas);
+ aasServerConnection.setValue(VABPathTools.append(AASAggregatorProvider.PREFIX, VABPathTools.encodePathElement(aas.getIdentification().getId())), aas);
// - Transfer device sub model to server
- aasServerConnection.createValue("/aas/submodels", statusSM);
+ aasPath = AASAggregatorProvider.PREFIX + "/" + VABPathTools.encodePathElement(aas.getIdentification().getId()) + "/aas";
+ aasServerConnection.setValue(VABPathTools.concatenatePaths(aasPath, "submodels", statusSM.getIdShort()), statusSM);
// Register URNs of control component VAB object
addShortcut("ControlComponent", new ModelUrn("urn:de.FHG:devices.es.iese:controlComponentSM:1.0:3:x-509#001"));
@@ -146,10 +162,10 @@
protected AASDescriptor getAASDescriptor() {
// Create AAS and sub model descriptors
AASDescriptor aasDescriptor = new AASDescriptor(lookupURN("AAS"), getAASEndpoint(lookupURN("AAS")));
- addSubModelDescriptorURI(aasDescriptor, lookupURN("Status"), "Status");
+ addSubmodelDescriptorURI(aasDescriptor, lookupURN("Status"), "Status");
// Add descriptor for control component sub model
- addSubModelDescriptorURI(aasDescriptor, lookupURN("ControlComponent"),
+ addSubmodelDescriptorURI(aasDescriptor, lookupURN("ControlComponent"),
"basyx://127.0.0.1:" + controlComponentServerPort);
// Return AAS, sub model descriptors, and added control component sub model descriptor
@@ -177,15 +193,15 @@
// Check what was being received. This check is performed based on a prefix that he device has to provide);
// - Update of device status
if (hasPrefix(rxStr, "status:"))
- aasServerConnection.setModelPropertyValue("/aas/submodels/Status/" + SubmodelElementProvider.PROPERTIES + "/status/value", removePrefix(rxStr, "status"));
+ aasServerConnection.setValue(aasPath + "/submodels/Status/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/status/value", removePrefix(rxStr, "status"));
// - Device indicates service invocation
if (hasPrefix(rxStr, "invocation:")) {
// Start of process
if (hasPrefix(rxStr, "invocation:start")) {
// Read and increment invocation counter
- HashMap<String, Object> property = (HashMap<String, Object>) aasServerConnection.getModelPropertyValue("/aas/submodels/Status/" + SubmodelElementProvider.PROPERTIES + "/invocations");
+ HashMap<String, Object> property = (HashMap<String, Object>) aasServerConnection.getValue(aasPath + "/submodels/Status/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/invocations");
int invocations = (int) property.get("value");
- aasServerConnection.setModelPropertyValue("/aas/submodels/Status/" + SubmodelElementProvider.PROPERTIES + "/invocations/value", ++invocations);
+ aasServerConnection.setValue(aasPath + "/submodels/Status/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/invocations/value", ++invocations);
}
// End of process
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/devicemanager/ManufacturingDeviceActiveAASManager.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/devicemanager/ManufacturingDeviceActiveAASManager.java
index 036d15a..9c81d3e 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/devicemanager/ManufacturingDeviceActiveAASManager.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/devicemanager/ManufacturingDeviceActiveAASManager.java
@@ -1,8 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.mockup.devicemanager;
+import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.AASLambdaPropertyHelper;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
import org.eclipse.basyx.tools.aas.active.HTTPGetter;
@@ -33,9 +43,9 @@
* Create the device AAS and sub model structure
*/
@Override
- protected void createDeviceAASAndSubModels() {
+ protected void createDeviceAASAndSubmodels() {
// Invoke base implementation
- super.createDeviceAASAndSubModels();
+ super.createDeviceAASAndSubmodels();
// Register URNs of managed VAB objects
@@ -43,7 +53,7 @@
// Create sub model
- SubModel supplySM = new SubModel();
+ Submodel supplySM = new Submodel();
// - Set submodel ID
supplySM.setIdShort("Supply");
// - Property status: indicate device status
@@ -53,11 +63,11 @@
AASLambdaPropertyHelper.setLambdaValue(availabililtyProp,
new HTTPGetter("http://localhost:8080/basys.examples/Mockup/Supplier"), null);
availabililtyProp.setIdShort("partAvailability");
- supplySM.addSubModelElement(availabililtyProp);
+ supplySM.addSubmodelElement(availabililtyProp);
// Transfer device sub model to server
- aasServerConnection.createValue("/aas/submodels", supplySM);
+ aasServerConnection.setValue("/" + AASAggregatorProvider.PREFIX + "/" + lookupURN("AAS").getEncodedURN() + "/aas/submodels/" + supplySM.getIdShort(), supplySM);
}
@@ -68,8 +78,8 @@
protected AASDescriptor getAASDescriptor() {
// Create AAS and sub model descriptors
AASDescriptor aasDescriptor = new AASDescriptor(lookupURN("AAS"), getAASEndpoint(lookupURN("AAS")));
- addSubModelDescriptorURI(aasDescriptor, lookupURN("Status"), "Status");
- addSubModelDescriptorURI(aasDescriptor, lookupURN("Supply"), "Supply");
+ addSubmodelDescriptorURI(aasDescriptor, lookupURN("Status"), "Status");
+ addSubmodelDescriptorURI(aasDescriptor, lookupURN("Supply"), "Supply");
// Return AAS and sub model descriptors
return aasDescriptor;
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/devicemanager/ManufacturingDeviceManager.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/devicemanager/ManufacturingDeviceManager.java
index 054f2fe..7fda3c0 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/devicemanager/ManufacturingDeviceManager.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/devicemanager/ManufacturingDeviceManager.java
@@ -1,20 +1,32 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.mockup.devicemanager;
import java.util.HashMap;
+import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
import org.eclipse.basyx.components.configuration.CFGBaSyxProtocolType;
import org.eclipse.basyx.components.devicemanager.TCPDeviceManagerComponent;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
import org.eclipse.basyx.vab.manager.VABConnectionManager;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
/**
* Example manufacturing device manager code
@@ -57,39 +69,24 @@
// Configure this device manager
configure()
- .registryURL("http://localhost:8080/basys.examples/Components/Directory/SQL")
+ .registryURL("http://localhost:8080/" + BaSyxExamplesContext.REGISTRYURL)
.connectionManagerType(CFGBaSyxProtocolType.HTTP)
.directoryService(new ExamplesPreconfiguredDirectory())
.end();
- // configure()
- // .registryURL()
- // .connectionManagerDirectory(new ExamplesPreconfiguredDirectory())
- // .connectionManagerProtocol(HTTP)
- // .AASServerObjectID(...)
- // .addAASAAS()
- // .whateverAASProperty()
- // .addSubmodel()
- // .property()
- // .endSubModel()
- // .end();
-
-
- // configure(Map<>...)
-
// Set registry that will be used by this service
- setRegistry(new AASRegistryProxy("http://localhost:8080/basys.examples/Components/Directory/SQL"));
+ setRegistry(new AASRegistryProxy("http://localhost:8080/" + BaSyxExamplesContext.REGISTRYURL));
// Set service connection manager and create AAS server connection
- setConnectionManager(new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorProvider()));
+ setConnectionManager(new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorFactory()));
// - Create AAS server connection
aasServerConnection = getConnectionManager().connectToVABElement("AASServer");
// Set AAS server VAB object ID, AAS server URL, and AAS server path prefix
setAASServerObjectID("AASServer");
- setAASServerURL("http://localhost:8080/basys.examples/Components/BaSys/1.0/aasServer");
+ setAASServerURL("http://localhost:8080/" + BaSyxExamplesContext.AASSERVERURL);
}
@@ -103,7 +100,7 @@
super.start();
// Create the device AAS and sub model structure
- createDeviceAASAndSubModels();
+ createDeviceAASAndSubmodels();
// Register AAS and sub model descriptors in directory (push AAS descriptor to server)
getRegistry().register(getAASDescriptor());
@@ -117,7 +114,7 @@
protected AASDescriptor getAASDescriptor() {
// Create AAS and sub model descriptors
AASDescriptor aasDescriptor = new AASDescriptor(lookupURN("AAS"), getAASEndpoint(lookupURN("AAS")));
- addSubModelDescriptorURI(aasDescriptor, lookupURN("Status"), "Status");
+ addSubmodelDescriptorURI(aasDescriptor, lookupURN("Status"), "Status");
// Return AAS and sub model descriptors
return aasDescriptor;
@@ -128,7 +125,7 @@
/**
* Create the device AAS and sub model structure
*/
- protected void createDeviceAASAndSubModels() {
+ protected void createDeviceAASAndSubmodels() {
// Register URNs of managed VAB objects
addShortcut("AAS", new ModelUrn("urn:de.FHG:devices.es.iese:aas:1.0:3:x-509#001"));
addShortcut("Status", new ModelUrn("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#001"));
@@ -137,27 +134,28 @@
AssetAdministrationShell aas = new AssetAdministrationShell();
// - Populate AAS
aas.setIdShort("DeviceIDShort");
+ aas.setIdentification(lookupURN("AAS"));
// - Transfer device AAS to server
- aasServerConnection.createValue("/aas", aas);
+ aasServerConnection.setValue(VABPathTools.concatenatePaths(AASAggregatorProvider.PREFIX, VABPathTools.encodePathElement(aas.getIdentification().getId())), aas);
// The device also brings a sub model structure with an own ID that is being pushed on the server
// - Create generic sub model and add properties
- SubModel statusSM = new SubModel();
+ Submodel statusSM = new Submodel();
// - Set submodel ID
statusSM.setIdShort("Status");
// - Property status: indicate device status
Property statusProp = new Property("offline");
statusProp.setIdShort("status");
- statusSM.addSubModelElement(statusProp);
+ statusSM.addSubmodelElement(statusProp);
// - Property statistics: export invocation statistics for every service
// - invocations: indicate total service invocations. Properties are not persisted in this example,
// therefore we start counting always at 0.
Property invocationsProp = new Property(0);
invocationsProp.setIdShort("invocations");
- statusSM.addSubModelElement(invocationsProp);
+ statusSM.addSubmodelElement(invocationsProp);
// - Transfer device sub model to server
- aasServerConnection.createValue("/aas/submodels/", statusSM);
+ aasServerConnection.setValue(AASAggregatorProvider.PREFIX + "/" + VABPathTools.encodePathElement(lookupURN("AAS").getId()) + "/aas/submodels/" + statusSM.getIdShort(), statusSM);
}
@@ -174,6 +172,8 @@
// Do not process null values
if (rxData == null) return;
+ String aasPath = "/" + AASAggregatorProvider.PREFIX + "/" + VABPathTools.encodePathElement(lookupURN("AAS").getId());
+
// Convert received data to string
String rxStr = new String(rxData);
// - Trim string to remove possibly trailing and leading white spaces
@@ -182,15 +182,15 @@
// Check what was being received. This check is performed based on a prefix that he device has to provide);
// - Update of device status
if (hasPrefix(rxStr, "status:"))
- aasServerConnection.setModelPropertyValue("/aas/submodels/Status/" + SubmodelElementProvider.PROPERTIES + "/status/value", removePrefix(rxStr, "status"));
+ aasServerConnection.setValue(aasPath + "/aas/submodels/Status/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/status/value", removePrefix(rxStr, "status"));
// - Device indicates service invocation
if (hasPrefix(rxStr, "invocation:")) {
// Start of process
if (hasPrefix(rxStr, "invocation:start")) {
// Read and increment invocation counter
- HashMap<String, Object> property = (HashMap<String, Object>) aasServerConnection.getModelPropertyValue("/aas/submodels/Status/" + SubmodelElementProvider.PROPERTIES + "/invocations");
+ HashMap<String, Object> property = (HashMap<String, Object>) aasServerConnection.getValue(aasPath + "/aas/submodels/Status/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/invocations");
int invocations = (int) property.get("value");
- aasServerConnection.setModelPropertyValue("/aas/submodels/Status/" + SubmodelElementProvider.PROPERTIES + "/invocations/value", ++invocations);
+ aasServerConnection.setValue(aasPath + "/aas/submodels/Status/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/invocations/value", ++invocations);
}
// End of process
if (hasPrefix(rxStr, "invocation:end")) {
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/servers/SupplierStatusServlet.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/servers/SupplierStatusServlet.java
index 9cd4cce..37b643e 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/servers/SupplierStatusServlet.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/servers/SupplierStatusServlet.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.mockup.servers;
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/cloudedgedeployment/TestCloudEdgeDeploymentScenario.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/cloudedgedeployment/TestCloudEdgeDeploymentScenario.java
index 3459103..88a136e 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/cloudedgedeployment/TestCloudEdgeDeploymentScenario.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/cloudedgedeployment/TestCloudEdgeDeploymentScenario.java
@@ -1,8 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.scenarios.cloudedgedeployment;
-import static org.junit.Assert.fail;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import java.util.ArrayList;
import java.util.Collection;
@@ -13,8 +22,10 @@
import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -27,15 +38,22 @@
scenario = new CloudEdgeDeploymentScenario();
}
+ @AfterClass
+ public static void tearDown() {
+ scenario.stop();
+ }
+
+ private IAASRegistry getRegistry() {
+ return new AASRegistryProxy(CloudEdgeDeploymentScenario.registryPath);
+ }
+
/**
* This tests if all the expected registry entries are present
*
*/
@Test
public void testRegistry() throws Exception {
- IAASRegistryService registry = scenario.registry;
-
- List<AASDescriptor> aasDescriptors = registry.lookupAll();
+ List<AASDescriptor> aasDescriptors = getRegistry().lookupAll();
assertEquals(1, aasDescriptors.size());
AASDescriptor aasDescriptor = aasDescriptors.get(0);
@@ -44,11 +62,11 @@
checkEndpoint(ComponentBuilder.AAS_ENDPOINT, aasDescriptor.getEndpoints());
// Check if aasDescriptor has the correct number of SMDescriptors
- assertEquals(2, aasDescriptor.getSubModelDescriptors().size());
+ assertEquals(2, aasDescriptor.getSubmodelDescriptors().size());
// Iterate over the Collection of SMDescriptors and
// test if both have the expected idShort and endpoint
- for(SubmodelDescriptor smDescriptor: aasDescriptor.getSubModelDescriptors()) {
+ for(SubmodelDescriptor smDescriptor: aasDescriptor.getSubmodelDescriptors()) {
if(smDescriptor.getIdShort().equals(ComponentBuilder.EDGESM_ID_SHORT)) {
checkEndpoint(ComponentBuilder.EDGESM_ENDPOINT, smDescriptor.getEndpoints());
} else if(smDescriptor.getIdShort().equals(ComponentBuilder.DOCUSM_ID_SHORT)) {
@@ -68,15 +86,15 @@
@Test
public void testAAS() throws Exception {
ConnectedAssetAdministrationShellManager manager =
- new ConnectedAssetAdministrationShellManager(scenario.registry);
+ new ConnectedAssetAdministrationShellManager(getRegistry());
- IAssetAdministrationShell aas = manager.retrieveAAS(scenario.aasIdentifier);
+ IAssetAdministrationShell aas = manager.retrieveAAS(CloudEdgeDeploymentScenario.aasIdentifier);
// Check if it has the correct idShort
assertEquals(ComponentBuilder.AAS_ID_SHORT, aas.getIdShort());
// Get the Submodels and check if both expected SMs are present
- Map<String, ISubModel> submodels = aas.getSubModels();
+ Map<String, ISubmodel> submodels = aas.getSubmodels();
assertTrue(submodels.containsKey(ComponentBuilder.EDGESM_ID_SHORT));
assertTrue(submodels.containsKey(ComponentBuilder.DOCUSM_ID_SHORT));
@@ -90,9 +108,9 @@
@Test
public void testDocuSM() {
ConnectedAssetAdministrationShellManager manager =
- new ConnectedAssetAdministrationShellManager(scenario.registry);
+ new ConnectedAssetAdministrationShellManager(getRegistry());
- ISubModel docuSM = manager.retrieveSubModel(scenario.aasIdentifier, scenario.docuSmIdentifier);
+ ISubmodel docuSM = manager.retrieveSubmodel(CloudEdgeDeploymentScenario.aasIdentifier, CloudEdgeDeploymentScenario.docuSmIdentifier);
// Check if it has the correct idShort, and 1 SubmodelElement
assertEquals(ComponentBuilder.DOCUSM_ID_SHORT, docuSM.getIdShort());
@@ -107,9 +125,9 @@
@Test
public void testEdgeSM() {
ConnectedAssetAdministrationShellManager manager =
- new ConnectedAssetAdministrationShellManager(scenario.registry);
+ new ConnectedAssetAdministrationShellManager(getRegistry());
- ISubModel edgeSM = manager.retrieveSubModel(scenario.aasIdentifier, scenario.edgeSmIdentifier);
+ ISubmodel edgeSM = manager.retrieveSubmodel(CloudEdgeDeploymentScenario.aasIdentifier, CloudEdgeDeploymentScenario.edgeSmIdentifier);
// Check if it has the correct idShort, and 1 SubmodelElement
assertEquals(ComponentBuilder.EDGESM_ID_SHORT, edgeSM.getIdShort());
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/BaSyxExampleScenario.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/BaSyxExampleScenario.java
new file mode 100644
index 0000000..00ef945
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/BaSyxExampleScenario.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.scenarios.device;
+
+import java.util.function.Supplier;
+
+
+
+/**
+ * Base class for all BaSyx examples
+ *
+ * @author kuhn
+ */
+public class BaSyxExampleScenario {
+
+
+
+ /**
+ * Wait for a condition
+ */
+ protected void waitfor(Supplier<Boolean> function) {
+ while (!function.get()) Thread.yield();
+ }
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/RunSimpleTCPDevice.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/RunSimpleTCPDevice.java
index b9a3059..9a7dd1e 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/RunSimpleTCPDevice.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/RunSimpleTCPDevice.java
@@ -1,16 +1,24 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.scenarios.device;
import static org.junit.Assert.assertTrue;
-import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.examplescenario.BaSyxExampleScenario;
import org.eclipse.basyx.examples.mockup.application.ReceiveDeviceDashboardStatusApplication;
import org.eclipse.basyx.examples.mockup.device.SimpleTCPDeviceMockup;
import org.eclipse.basyx.examples.mockup.devicemanager.ManufacturingDeviceManager;
import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
import org.junit.ClassRule;
import org.junit.Test;
@@ -33,7 +41,7 @@
/**
* VAB connection manager backend
*/
- protected VABConnectionManager connManager = new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorProvider());
+ protected VABConnectionManager connManager = new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorFactory());
/**
@@ -44,7 +52,7 @@
public static BaSyxDeployment context = new BaSyxDeployment(
// Simulated servlets
// - BaSys topology with one AAS Server and one SQL directory
- new BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory(),
+ new BaSyxExamplesContext(),
// Simulated runnables
// - Manufacturing device manager, e.g. deployed to additonal device
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/aas/RunAASDevice.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/aas/RunAASDevice.java
index 8431a2f..8565440 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/aas/RunAASDevice.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/aas/RunAASDevice.java
@@ -1,17 +1,26 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.scenarios.device.aas;
import static org.junit.Assert.assertTrue;
-import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.examplescenario.BaSyxExampleScenario;
import org.eclipse.basyx.examples.mockup.application.ReceiveDeviceMaintenanceApplication;
import org.eclipse.basyx.examples.mockup.device.SimpleTCPDeviceMockup;
import org.eclipse.basyx.examples.mockup.devicemanager.ManufacturingDeviceActiveAASManager;
import org.eclipse.basyx.examples.mockup.servers.SupplierStatusServlet;
+import org.eclipse.basyx.examples.scenarios.device.BaSyxExampleScenario;
import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
import org.junit.ClassRule;
import org.junit.Test;
@@ -29,7 +38,7 @@
/**
* VAB connection manager backend
*/
- protected VABConnectionManager connManager = new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorProvider());
+ protected VABConnectionManager connManager = new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorFactory());
/**
@@ -40,7 +49,7 @@
public static BaSyxDeployment context = new BaSyxDeployment(
// Simulated servlets
// - BaSys topology with one AAS Server and one SQL directory
- new BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory().
+ new BaSyxExamplesContext().
// Define additional scenario specific Servlets
addServletMapping("/Mockup/Supplier/*", new SupplierStatusServlet()),
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/controllable/RunExampleSimpleControllableTCPDevice.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/controllable/RunExampleSimpleControllableTCPDevice.java
index 2559370..5318e53 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/controllable/RunExampleSimpleControllableTCPDevice.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/controllable/RunExampleSimpleControllableTCPDevice.java
@@ -1,19 +1,30 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.scenarios.device.controllable;
import static org.junit.Assert.assertTrue;
-import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.examplescenario.BaSyxExampleScenario;
import org.eclipse.basyx.examples.mockup.application.ReceiveDeviceDashboardStatusApplication;
import org.eclipse.basyx.examples.mockup.device.ControllableTCPDeviceMockup;
import org.eclipse.basyx.examples.mockup.devicemanager.BaSyxTCPControlManufacturingDeviceManager;
+import org.eclipse.basyx.examples.scenarios.device.BaSyxExampleScenario;
import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
+import org.eclipse.basyx.models.controlcomponent.ControlComponent;
import org.eclipse.basyx.models.controlcomponent.ExecutionState;
import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnector;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
import org.junit.ClassRule;
import org.junit.Test;
@@ -29,7 +40,7 @@
/**
* VAB connection manager backend
*/
- protected VABConnectionManager connManager = new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorProvider());
+ protected VABConnectionManager connManager = new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorFactory());
/**
@@ -54,7 +65,7 @@
public static BaSyxDeployment context = new BaSyxDeployment(
// BaSyx infrastructure
// - BaSys topology with one AAS Server and one SQL directory
- new BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory(),
+ new BaSyxExamplesContext(),
// Simulated runnables
// - Manufacturing device manager, e.g. deployed to additonal device
@@ -94,7 +105,7 @@
// Change device operation mode
- toControlComponent.setModelPropertyValue("status/opMode", "RegularMilling");
+ toControlComponent.setValue(VABPathTools.concatenatePaths(ControlComponent.STATUS, ControlComponent.OP_MODE), "RegularMilling");
// - Validate device operation mode
waitfor(() -> ((ControllableTCPDeviceMockup) context.getRunnable("Device")).getOpMode().equals("RegularMilling"));
@@ -103,7 +114,7 @@
// Start device service
- toControlComponent.setModelPropertyValue("cmd", "start");
+ toControlComponent.setValue("cmd", "start");
// - Application waits for status change
waitfor( () -> ((ReceiveDeviceDashboardStatusApplication) context.getRunnable("Application")).getDeviceStatus().equals("EXECUTE") );
// - Validate device status
@@ -119,7 +130,7 @@
// Reset device to enable subsequent service calls
- toControlComponent.setModelPropertyValue("cmd", "reset");
+ toControlComponent.setValue("cmd", "reset");
// - Application waits for status change
waitfor( () -> ((ReceiveDeviceDashboardStatusApplication) context.getRunnable("Application")).getDeviceStatus().equals("RESETTING") );
// - Validate device status
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/controllable/RunExampleSimpleSmartDevice.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/controllable/RunExampleSimpleSmartDevice.java
index 1309ddb..04bb917 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/controllable/RunExampleSimpleSmartDevice.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/controllable/RunExampleSimpleSmartDevice.java
@@ -1,18 +1,29 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.scenarios.device.controllable;
import static org.junit.Assert.assertTrue;
-import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.examplescenario.BaSyxExampleScenario;
import org.eclipse.basyx.examples.mockup.application.ReceiveDeviceDashboardStatusApplication;
import org.eclipse.basyx.examples.mockup.device.SmartBaSyxTCPDeviceMockup;
+import org.eclipse.basyx.examples.scenarios.device.BaSyxExampleScenario;
import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
+import org.eclipse.basyx.models.controlcomponent.ControlComponent;
import org.eclipse.basyx.models.controlcomponent.ExecutionState;
import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnector;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
import org.junit.ClassRule;
import org.junit.Test;
@@ -28,7 +39,7 @@
/**
* VAB connection manager backend
*/
- protected VABConnectionManager connManager = new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorProvider());
+ protected VABConnectionManager connManager = new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorFactory());
/**
@@ -53,7 +64,7 @@
public static BaSyxDeployment context = new BaSyxDeployment(
// BaSyx infrastructure
// - BaSys topology with one AAS Server and one SQL directory
- new BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory(),
+ new BaSyxExamplesContext(),
// Device mockups
new SmartBaSyxTCPDeviceMockup(9997).setName("Device"),
@@ -87,7 +98,7 @@
// Change device operation mode
- toControlComponent.setModelPropertyValue("status/opMode", "RegularMilling");
+ toControlComponent.setValue(VABPathTools.concatenatePaths(ControlComponent.STATUS, ControlComponent.OP_MODE), "RegularMilling");
// - Validate device control component operation mode
waitfor( () -> ((SmartBaSyxTCPDeviceMockup) context.getRunnable("Device")).getControlComponent().getOperationMode().equals("RegularMilling") );
@@ -96,7 +107,7 @@
// Start device service
- toControlComponent.setModelPropertyValue("cmd", "start");
+ toControlComponent.setValue("cmd", "start");
// - Validate control component status
waitfor( () -> ((SmartBaSyxTCPDeviceMockup) context.getRunnable("Device")).getControlComponent().getExecutionState().equals(ExecutionState.EXECUTE.getValue()) );
// - Indicate service end
@@ -106,7 +117,7 @@
// Reset device to enable subsequent service calls
- toControlComponent.setModelPropertyValue("cmd", "reset");
+ toControlComponent.setValue("cmd", "reset");
// - Device finishes reset and moves to idle state
((SmartBaSyxTCPDeviceMockup) context.getRunnable("Device")).resetCompleted();
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/staticdynamic/TestStaticDynamicScenario.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/staticdynamic/TestStaticDynamicScenario.java
new file mode 100644
index 0000000..80b7366
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/staticdynamic/TestStaticDynamicScenario.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.scenarios.staticdynamic;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Map;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test for StaticDynamicScenario
+ *
+ * @author conradi
+ *
+ */
+public class TestStaticDynamicScenario {
+
+ private static StaticDynamicScenario scenario;
+
+ @BeforeClass
+ public static void startup() throws Exception {
+ scenario = new StaticDynamicScenario();
+ }
+
+ @AfterClass
+ public static void tearDown() {
+ scenario.stop();
+ }
+
+ @Test
+ public void checkDynamicSubmodel() throws Exception {
+
+ AASRegistryProxy proxy = new AASRegistryProxy(StaticDynamicScenario.REGISTRY_URL);
+ ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(proxy);
+
+ Identifier AASIdentifier = new Identifier(IdentifierType.IRI, StaticDynamicScenario.AAS_ID);
+
+ Map<String, ISubmodel> submodels = manager.retrieveSubmodels(AASIdentifier);
+
+ // The aas should contain 6 SMs
+ assertEquals(6, submodels.size());
+
+ ISubmodel staticSM = submodels.get(ExampleDynamicSubmodel.SM_ID_SHORT);
+
+ // Get the Property from the Submodel
+ IProperty smElement = (IProperty) staticSM.getSubmodelElements().get(ExampleDynamicSubmodel.PROPERTY_ID_SHORT);
+
+ // Check if the Property contains the correct value
+ assertEquals(ExampleDynamicSubmodel.PROPERTY_VALUE, smElement.getValue());
+ }
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/AbstractSnippetTest.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/AbstractSnippetTest.java
new file mode 100644
index 0000000..d5b02a9
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/AbstractSnippetTest.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.examples.support.ExampleAASComponent;
+import org.eclipse.basyx.examples.support.ExampleComponentBuilder;
+import org.eclipse.basyx.examples.support.ExampleRegistryComponent;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.junit.After;
+import org.junit.Before;
+
+/**
+ * This class provides the server environment required by all snippet test
+ *
+ * @author conradi
+ *
+ */
+public abstract class AbstractSnippetTest {
+
+
+ protected static final String AAS_ID_SHORT = "aasIdShort";
+ protected static final String AAS_ID = "aasId";
+ protected static final String AAS_ENDPOINT = "http://localhost:8080/aasComponent/shells/" + AAS_ID + "/aas";
+
+ protected static final String SM_ID_SHORT = "smIdShort";
+ protected static final String SM_ID = "smId";
+ protected static final String SM_ENDPOINT = AAS_ENDPOINT + "/submodels/" + SM_ID_SHORT + "/submodel";
+
+ protected ExampleAASComponent aasComponent;
+ protected ExampleRegistryComponent registryComponent;
+
+ @Before
+ public void setupServers() {
+ registryComponent = new ExampleRegistryComponent(8081);
+ registryComponent.startupRegistry();
+ aasComponent = new ExampleAASComponent(8080, new AASRegistryProxy(registryComponent.getRegistryPath()));
+ aasComponent.startupAASServer();
+
+ // Populate the Server with an example AAS/SM
+ populateServer();
+ }
+
+ @After
+ public void shutdownServers() {
+ aasComponent.shutdownAASServer();
+ registryComponent.shutdownRegistry();
+ }
+
+ /**
+ * Pushes and registers an AAS and a Submodel to the test server
+ */
+ private void populateServer() {
+ ConnectedAssetAdministrationShellManager manager = getManager();
+
+ // Get the example AAS and Submodel
+ AssetAdministrationShell aas = ExampleComponentBuilder.buildExampleAAS(AAS_ID_SHORT, AAS_ID);
+ Submodel sm = ExampleComponentBuilder.buildExampleSubmodel(SM_ID_SHORT, SM_ID);
+
+ // Push and register the AAS
+ manager.createAAS(aas, aasComponent.getAASServerPath());
+
+ // Push and register the Submodel
+ manager.createSubmodel(aas.getIdentification(), sm);
+ }
+
+ /**
+ * Creates a ConnectedAASManager using the started registryComponent
+ *
+ * @return the created ConnectedAASManager
+ */
+ protected ConnectedAssetAdministrationShellManager getManager() {
+ AASRegistryProxy registryProxy = new AASRegistryProxy(registryComponent.getRegistryPath());
+ return new ConnectedAssetAdministrationShellManager(registryProxy);
+ }
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/AccessAASProperties.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/AccessAASProperties.java
deleted file mode 100644
index c6347e1..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/AccessAASProperties.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas;
-
-import static org.junit.Assert.assertTrue;
-
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.junit.Test;
-
-/**
- * This code snippet illustrates the creation of an Asset Administration Shell (AAS) data structure
- * and how to access its properties via different kinds of access operations
- *
- * @author kuhn
- *
- */
-public class AccessAASProperties {
-
-
- /**
- * Code snippet that illustrates the instantiation and use of AAS
- */
- @Test
- public void snippet() throws Exception {
-
- // Create Asset Administration Shell
- AssetAdministrationShell aas = new AssetAdministrationShell();
-
- // Access predefined AAS properties
- // - Set AAS property via generic access method. For the generic access method,
- // the user must know the name of the accessed property. This kind of access
- // is discouraged, as it is not portable to new meta model versions. However,
- // it is illustrated for completeness.
- aas.put("idShort", "DeviceIDShort");
- // - Access AAS property via the specific access operation. This is the preferred
- // approach for accessing Asset Administration Shell and sub model properties,
- // as well as meta data.
- Object deviceIDValue = aas.getIdShort();
-
-
- // Compared received value to expected value
- assertTrue(deviceIDValue.equals("DeviceIDShort"));
- }
-}
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/CreateAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/CreateAAS.java
deleted file mode 100644
index d2afd50..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/CreateAAS.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas;
-
-import static org.junit.Assert.assertEquals;
-
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.junit.Test;
-
-/**
- * Code snippet that illustrates the creation of an Asset Administration Shell (AAS) by extending an SDK class
- *
- * @author kuhn
- *
- */
-public class CreateAAS {
-
-
- /**
- * Example Asset Administration Shell
- */
- static class ExampleAssetAdministrationShell extends AssetAdministrationShell {
- /**
- * Constructor
- */
- public ExampleAssetAdministrationShell() {
- // Set Asset Administration Shell ID
- setIdShort("aas-001");
- }
- }
-
- /**
- * Run code snippet. Connect to AAS on server, access AAS properties.
- */
- @Test
- public void createAAS() throws Exception {
- // Create Asset Administration Shell
- ExampleAssetAdministrationShell aas = new ExampleAssetAdministrationShell();
-
- // Retrieve AAS ID value
- Object propertyId = aas.getIdShort();
-
-
- // Check result
- assertEquals("aas-001", propertyId);
- }
-}
-
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestAddSubmodelToAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestAddSubmodelToAAS.java
new file mode 100644
index 0000000..5af9acf
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestAddSubmodelToAAS.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.aas;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.examples.support.ExampleComponentBuilder;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.junit.Test;
+
+/**
+ * Test for the AddSubmodelToAAS snippet
+ *
+ * @author conradi
+ *
+ */
+public class TestAddSubmodelToAAS extends AbstractSnippetTest {
+
+ private static final String NEW_SM_ID_SHORT = "smIdShort_New";
+ private static final String NEW_SM_ID = "smId_New";
+
+ private static final String NEW_SM_ENDPOINT = AAS_ENDPOINT + "/submodels/" + NEW_SM_ID_SHORT + "/submodel";
+
+ @Test
+ public void testAddSubmodelToAAS() {
+
+ // Get the example AAS and Submodel
+ Submodel submodel = ExampleComponentBuilder.buildExampleSubmodel(NEW_SM_ID_SHORT, NEW_SM_ID);
+
+ // Get the Identifiers for the AAS and the Submodel
+ IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+ IIdentifier smIdentifier = submodel.getIdentification();
+
+ // Get the AAS as ConnectedAAS
+ ConnectedAssetAdministrationShellManager manager = getManager();
+ IAssetAdministrationShell aas = manager.retrieveAAS(aasIdentifier);
+
+ // Add the Submodel to the AAS
+ AddSubmodelToAAS.addSubmodelToAAS(submodel, aas);
+
+
+ // Register the new Submodel
+ // This needs to be done to be able to retrieve it again
+ AASRegistryProxy registry = new AASRegistryProxy(registryComponent.getRegistryPath());
+ registry.register(aasIdentifier, new SubmodelDescriptor(submodel, NEW_SM_ENDPOINT));
+
+
+ // Check if the Submodel was correctly added
+ ISubmodel remoteSM = manager.retrieveSubmodel(aasIdentifier, smIdentifier);
+ assertEquals(NEW_SM_ID_SHORT, remoteSM.getIdShort());
+
+ }
+
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestCreateAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestCreateAAS.java
new file mode 100644
index 0000000..57ba057
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestCreateAAS.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.aas;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.junit.Test;
+
+/**
+ * Test for the CreateAAS snippet
+ *
+ * @author conradi
+ *
+ */
+public class TestCreateAAS extends AbstractSnippetTest {
+
+ private static final String AAS_ID_SHORT = "aasIdShort";
+ private static final String AAS_ID = "aasId";
+
+ private static final String ASSET_ID_SHORT = "assetIdShort";
+ private static final String ASSET_ID = "assetId";
+
+
+ @Test
+ public void testCreateAAS() {
+
+ // Create an example Asset to be used in the AAS
+ Asset asset = new Asset(ASSET_ID_SHORT, new Identifier(IdentifierType.CUSTOM, ASSET_ID), AssetKind.INSTANCE);
+
+ // Create an AAS
+ AssetAdministrationShell aas = CreateAAS.createAAS(AAS_ID_SHORT, new Identifier(IdentifierType.CUSTOM, AAS_ID), asset);
+
+ // Check the created AAS
+ assertEquals(AAS_ID_SHORT, aas.getIdShort());
+ assertEquals(AAS_ID, aas.getIdentification().getId());
+ assertEquals(ASSET_ID_SHORT, aas.getAsset().getIdShort());
+ assertEquals(ASSET_ID, aas.getAsset().getIdentification().getId());
+ }
+
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestDeleteSubmodelFromAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestDeleteSubmodelFromAAS.java
new file mode 100644
index 0000000..3da923c
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestDeleteSubmodelFromAAS.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.aas;
+
+import static org.junit.Assert.fail;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Test;
+
+/**
+ * Test for the DeleteSubmodelFromAAS snippet
+ *
+ * @author conradi
+ *
+ */
+public class TestDeleteSubmodelFromAAS extends AbstractSnippetTest {
+
+ @Test
+ public void testDeleteSubmodel() {
+
+ // Get the Identifier of the example AAS and Submodel
+ IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+ IIdentifier smIdentifier = new Identifier(IdentifierType.CUSTOM, SM_ID);
+
+ // Get the AAS as ConnectedAAS
+ ConnectedAssetAdministrationShellManager manager = getManager();
+ IAssetAdministrationShell aas = manager.retrieveAAS(aasIdentifier);
+
+ DeleteSubmodelFromAAS.deleteSubmodelFromAAS(smIdentifier, aas);
+
+ // Try to retrieve deleted Submodel; should throw ResourceNotFoundException
+ try {
+ aas.getSubmodel(smIdentifier);
+ fail();
+ } catch (ResourceNotFoundException e) {
+ }
+
+ }
+
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestRetrieveSubmodelFromAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestRetrieveSubmodelFromAAS.java
new file mode 100644
index 0000000..0cd2cc2
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestRetrieveSubmodelFromAAS.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.aas;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.junit.Test;
+
+/**
+ * Test for the RetrieveSubmodelFromAAS snippet
+ *
+ * @author conradi
+ *
+ */
+public class TestRetrieveSubmodelFromAAS extends AbstractSnippetTest {
+
+
+ @Test
+ public void testRetrieveSubmodelFromAAS() {
+ // Get the Identifiers for the AAS and the Submodel
+ IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+ IIdentifier smIdentifier = new Identifier(IdentifierType.CUSTOM, SM_ID);
+
+ // Get the AAS as ConnectedAAS
+ ConnectedAssetAdministrationShellManager manager = getManager();
+ IAssetAdministrationShell aas = manager.retrieveAAS(aasIdentifier);
+
+ // Get the Submodel from the server
+ ISubmodel remoteSubmodel = RetrieveSubmodelFromAAS.retrieveSubmodelFromAAS(
+ smIdentifier, aas);
+
+
+ // Check if the Submodel can be used correctly
+ assertEquals(SM_ID_SHORT, remoteSubmodel.getIdShort());
+ }
+
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/RunComposedActiveModelSnippet.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/RunComposedActiveModelSnippet.java
index 7504981..410f492 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/RunComposedActiveModelSnippet.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/RunComposedActiveModelSnippet.java
@@ -1,8 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.snippets.aas.active;
import org.eclipse.basyx.examples.snippets.aas.active.tasks.AverageTask;
import org.eclipse.basyx.examples.snippets.aas.active.tasks.IncrementTask;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
import org.eclipse.basyx.tools.aas.active.ActiveModel;
import org.eclipse.basyx.tools.aas.active.VABModelTaskGroup;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
@@ -26,7 +35,7 @@
@Ignore
public void snippet() throws Exception {
// Create the model provider for the active model
- IModelProvider modelProvider = new SubModelProvider();
+ IModelProvider modelProvider = new SubmodelProvider();
modelProvider.createValue("count", 0);
modelProvider.createValue("temperature", VABLambdaProviderHelper.createSimple(() -> {
return 30d + (Math.random() * 10d - 5d);
@@ -46,8 +55,8 @@
// Runs a task group with a single task (1x per second)
VABModelTaskGroup printerGroup = activeModel.runTask(1000, model -> {
- logger.debug("Current count: " + model.getModelPropertyValue("/count"));
- logger.debug("Current average: " + model.getModelPropertyValue("/average"));
+ logger.debug("Current count: " + model.getValue("/count"));
+ logger.debug("Current average: " + model.getValue("/average"));
});
// Adds an additional task to the existing task group
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/RunInfluxDBActiveModelSnippet.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/RunInfluxDBActiveModelSnippet.java
index e6ec3db..129f058 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/RunInfluxDBActiveModelSnippet.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/RunInfluxDBActiveModelSnippet.java
@@ -1,7 +1,16 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.snippets.aas.active;
import org.eclipse.basyx.examples.snippets.aas.active.tasks.InfluxDBTask;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
import org.eclipse.basyx.tools.aas.active.ActiveModel;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProviderHelper;
@@ -28,7 +37,7 @@
@Test
public void snippet() throws Exception {
// Create the model provider for the active model
- IModelProvider modelProvider = new SubModelProvider();
+ IModelProvider modelProvider = new SubmodelProvider();
modelProvider.createValue("temperature", VABLambdaProviderHelper.createSimple(() -> {
return 30d + (Math.random() * 10d - 5d);
}, null));
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/tasks/AverageTask.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/tasks/AverageTask.java
index b4f710e..9e5fd95 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/tasks/AverageTask.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/tasks/AverageTask.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.snippets.aas.active.tasks;
import org.eclipse.basyx.tools.aas.active.VABModelTask;
@@ -23,14 +32,14 @@
@Override
public void execute(IModelProvider model) throws Exception {
- double nextValue = (double) model.getModelPropertyValue(sourcePath);
+ double nextValue = (double) model.getValue(sourcePath);
double average = lastAverage;
if ( average == 0 ) {
average = nextValue;
} else {
average = average * (1 - factor) + nextValue * factor;
}
- model.setModelPropertyValue(targetPath, average);
+ model.setValue(targetPath, average);
lastAverage = average;
}
}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/tasks/IncrementTask.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/tasks/IncrementTask.java
index ead95e7..8850659 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/tasks/IncrementTask.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/tasks/IncrementTask.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.snippets.aas.active.tasks;
import org.eclipse.basyx.tools.aas.active.VABModelTask;
@@ -18,7 +27,7 @@
@Override
public void execute(IModelProvider model) throws Exception {
- int current = (int) model.getModelPropertyValue(path);
- model.setModelPropertyValue(path, current + 1);
+ int current = (int) model.getValue(path);
+ model.setValue(path, current + 1);
}
}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/tasks/InfluxDBTask.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/tasks/InfluxDBTask.java
index 6e0c402..fb118b2 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/tasks/InfluxDBTask.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/tasks/InfluxDBTask.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.snippets.aas.active.tasks;
import java.io.IOException;
@@ -39,7 +48,7 @@
@Override
public void execute(IModelProvider model) throws Exception {
try {
- Object value = model.getModelPropertyValue(modelPath);
+ Object value = model.getValue(modelPath);
String result = value == null ? "null" : value.toString();
writeData(result);
} catch (Exception e) {
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/device/DeviceAASDeployment.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/device/DeviceAASDeployment.java
deleted file mode 100644
index e5a4db2..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/device/DeviceAASDeployment.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.deployment.device;
-
-import static org.junit.Assert.assertTrue;
-
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.aas.restapi.AASModelProvider;
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
-import org.eclipse.basyx.examples.support.directory.ExampleAASRegistry;
-import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnectorProvider;
-import org.eclipse.basyx.vab.protocol.basyx.server.BaSyxTCPServer;
-import org.junit.Test;
-
-/**
- * Code snippet that illustrates the deployment of an AAS to a device, and connects to that AAS
- *
- * The AAS is deployed to a dynamic BaSyxTCPServer that exports the AAS using the BaSyx TCP protocol.
- *
- * @author kuhn
- *
- */
-public class DeviceAASDeployment {
-
-
- /**
- * Run code snippet. Connect to AAS on server, access AAS properties.
- */
- @Test
- public void createExportAndAccessSubModel() throws Exception {
-
-
- // Create AAS sub model and sub model properties
- // - Create AAS
- AssetAdministrationShell aas = new AssetAdministrationShell();
- // - Set sub model ID
- aas.setIdShort("urn:de.FHG:devices.es.iese:AAS:1.0:3:x-509#003");
-
-
- // Export AAS via BaSyx server
- AASModelProvider modelProvider = new AASModelProvider(aas);
- VABMultiSubmodelProvider aasProvider = new VABMultiSubmodelProvider(modelProvider);
- BaSyxTCPServer<VABMultiSubmodelProvider> server = new BaSyxTCPServer<VABMultiSubmodelProvider>(aasProvider, 9998);
- // - Start local BaSyx/TCP server
- server.start();
-
-
-
- // - We pre-register the aas endpoints to the dynamic BaSyx server
- ExampleAASRegistry registry = new ExampleAASRegistry();
- registry.addAASMapping("dynamicAAS", "basyx://localhost:9998/aas");
-
- // Create connected aas manager to connect with the dynamic server
- ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(registry,
- // We connect via BaSyx TCP protocol
- new BaSyxConnectorProvider());
-
-
- // Retrieve the AAS with ID "dynamicAAS" from the AAS server with SDK connector
- // - IAssetAdministrationShell is the interface for the local AAS proxy
- IAssetAdministrationShell shell = manager.retrieveAAS(new ModelUrn("dynamicAAS"));
- // - Retrieve AAS values and compare to expected values
- Object propertyId = shell.getIdShort();
-
-
- // Check value
- assertTrue(propertyId.equals("urn:de.FHG:devices.es.iese:AAS:1.0:3:x-509#003"));
-
-
- // Stop local BaSyx/TCP server
- server.stop();
- }
-}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/device/DeviceAASDeploymentVAB.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/device/DeviceAASDeploymentVAB.java
deleted file mode 100644
index a8783db..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/device/DeviceAASDeploymentVAB.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.deployment.device;
-
-import static org.junit.Assert.assertTrue;
-
-import java.util.Map;
-
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.aas.restapi.AASModelProvider;
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
-import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
-import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnector;
-import org.eclipse.basyx.vab.protocol.basyx.server.BaSyxTCPServer;
-import org.junit.Test;
-
-/**
- * Code snippet that illustrates the deployment of an AAS to a device, and connects to that AAS
- *
- * The AAS is deployed to a dynamic BaSyxTCPServer that exports the AAS using the BaSyx TCP protocol.
- *
- * @author kuhn
- *
- */
-public class DeviceAASDeploymentVAB {
-
-
- /**
- * Run code snippet. Connect to AAS on server, access AAS properties.
- */
- @SuppressWarnings("unchecked")
- @Test
- public void createExportAndAccessSubModel() throws Exception {
-
-
- // Create AAS sub model and sub model properties
- // - Create AAS
- AssetAdministrationShell aas = new AssetAdministrationShell();
- // - Set sub model ID
- aas.setIdShort("urn:de.FHG:devices.es.iese:AAS:1.0:3:x-509#003");
-
-
- // Export AAS via BaSyx server
- AASModelProvider modelProvider = new AASModelProvider(aas);
- VABMultiSubmodelProvider aasProvider = new VABMultiSubmodelProvider(modelProvider);
- BaSyxTCPServer<VABMultiSubmodelProvider> server = new BaSyxTCPServer<VABMultiSubmodelProvider>(aasProvider, 9998);
- // - Start local BaSyx/TCP server
- server.start();
-
-
- // Access BaSyx TCP server using Virtual Automation Bus low level BaSyxConnector class
- // - Create BaSyx connector to connect with the sub model
- BaSyxConnector basyxConnector = new BaSyxConnector("localhost", 9998);
- // - Create connection to BaSyx server manager
- JSONConnector toDeviceManager = new JSONConnector(basyxConnector);
- // - Access sub model property, check value
- AssetAdministrationShell shell = AssetAdministrationShell.createAsFacade((Map<String, Object>) toDeviceManager.getModelPropertyValue("aas"));
-
-
- // Check value
- assertTrue(shell.getIdShort().equals("urn:de.FHG:devices.es.iese:AAS:1.0:3:x-509#003"));
-
-
- // Stop local BaSyx/TCP server
- server.stop();
- }
-}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/device/DeviceSubModelDeployment.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/device/DeviceSubModelDeployment.java
deleted file mode 100644
index 8dcc0b5..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/device/DeviceSubModelDeployment.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.deployment.device;
-
-import static org.junit.Assert.assertTrue;
-
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
-import org.eclipse.basyx.examples.support.directory.ExampleAASRegistry;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
-import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnectorProvider;
-import org.eclipse.basyx.vab.protocol.basyx.server.BaSyxTCPServer;
-import org.junit.Test;
-
-/**
- * Code snippet that illustrates the deployment of a AAS sub model to a device, and connects to that sub model
- *
- * The AAS sub model is deployed to a dynamic BaSyxTCPServer that exports the sub model using the BaSyx TCP protocol.
- *
- * @author kuhn
- *
- */
-public class DeviceSubModelDeployment {
-
-
- /**
- * Run code snippet. Connect to AAS sub model on server, access sub model properties.
- */
- @Test
- public void createExportAndAccessSubModel() throws Exception {
-
-
- // Create AAS sub model and sub model properties
-
- // - Create sub model
- SubModel submodel = new SubModel();
- // - Set sub model ID "SampleSM" to full qualified ID urn:de.FHG:devices.es.iese:SampleSM:1.0:3:x-509#003
- IIdentifier smId = new ModelUrn("urn:de.FHG:devices.es.iese:SampleSM:1.0:3:x-509#003");
- submodel.setIdShort("SampleSM");
- submodel.setIdentification(smId.getIdType(), smId.getId());
- // - Add example properties
- Property prop1 = new Property(7);
- prop1.setIdShort("prop1");
- submodel.addSubModelElement(prop1);
-
- Property prop2 = new Property("myStr");
- prop2.setIdShort("prop2");
- submodel.addSubModelElement(prop2);
-
-
- // Export sub model via BaSyx server
- SubModelProvider modelProvider = new SubModelProvider(submodel);
- VABMultiSubmodelProvider aasProvider = new VABMultiSubmodelProvider("SampleSM", modelProvider);
- BaSyxTCPServer<VABMultiSubmodelProvider> server = new BaSyxTCPServer<>(aasProvider, 9998);
- // - Start local BaSyx/TCP server
- server.start();
-
-
- // Create connected aas manager to connect with the dynamic server
- // We pre-register the aas endpoints to the dynamic BaSyx server
- ExampleAASRegistry registry = new ExampleAASRegistry();
- registry.addAASMapping("", ""); // No AAS is provided in this example
- registry.addSubmodelMapping("", smId.getId(), "basyx://localhost:9998/aas/submodels/SampleSM");
-
- // Create manager using the directory stub an the HTTPConnectorProvider
- ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(registry,
- // We connect via BaSyx TCP protocol
- new BaSyxConnectorProvider());
-
- // Create and connect SDK connector
- // - Retrieve sub model
- ISubModel subModel = manager.retrieveSubModel(new ModelUrn(""), smId);
-
- // Retrieve sub model values and compare to expected values
- String submodelId = subModel.getIdShort();
- String prop1Id = subModel.getProperties().get("prop1").getIdShort();
- int prop1Val = (int) ((IProperty) subModel.getProperties().get("prop1")).get();
- String prop2Id = subModel.getProperties().get("prop2").getIdShort();
- String prop2Val = (String) ((IProperty) subModel.getProperties().get("prop2")).get();
-
-
- // Compare received property values to expected values
- assertTrue(submodelId.equals("SampleSM"));
- assertTrue(prop1Id.equals("prop1"));
- assertTrue(prop1Val == 7);
- assertTrue(prop2Id.equals("prop2"));
- assertTrue(prop2Val.equals("myStr"));
-
-
- // Stop local BaSyx/TCP server
- server.stop();
- }
-}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/device/DeviceSubModelDeploymentVAB.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/device/DeviceSubModelDeploymentVAB.java
deleted file mode 100644
index be00057..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/device/DeviceSubModelDeploymentVAB.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.deployment.device;
-
-import static org.junit.Assert.assertTrue;
-
-import java.util.HashMap;
-
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
-import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnector;
-import org.eclipse.basyx.vab.protocol.basyx.server.BaSyxTCPServer;
-import org.junit.Test;
-
-/**
- * Code snippet that illustrates the deployment of a AAS sub model to a device, and connects to that sub model using
- * Virtual Automation Bus (VAB) primitives.
- *
- * The AAS sub model is deployed to a dynamic BaSyxTCPServer that exports the sub model using the BaSyx TCP protocol.
- *
- * @author kuhn
- *
- */
-public class DeviceSubModelDeploymentVAB {
-
-
- /**
- * Run code snippet. Connect to AAS sub model on server, access sub model properties using VAB properties.
- */
- @SuppressWarnings("unchecked")
- @Test
- public void createExportAndAccessSubModel() throws Exception {
-
-
- // Create AAS sub model and sub model properties
- // - Create sub model
- SubModel submodel = new SubModel();
- // - Set sub model ID
- submodel.setIdShort("dynamicSM");
- // - Add example properties
- Property prop1 = new Property(7);
- prop1.setIdShort("prop1");
- submodel.addSubModelElement(prop1);
-
- Property prop2 = new Property("myStr");
- prop2.setIdShort("prop2");
- submodel.addSubModelElement(prop2);
-
-
- // Export sub model via BaSyx server
- SubModelProvider modelProvider = new SubModelProvider(submodel);
- VABMultiSubmodelProvider aasProvider = new VABMultiSubmodelProvider("dynamicSM", modelProvider);
- BaSyxTCPServer<VABMultiSubmodelProvider> server = new BaSyxTCPServer<VABMultiSubmodelProvider>(aasProvider, 9998);
- // - Start local BaSyx/TCP server
- server.start();
-
-
- // Access BaSyx TCP server using low-level BaSyx connector instead of connection manager
- // - Create BaSyx connector to connect with the sub model
- BaSyxConnector basyxConnector = new BaSyxConnector("localhost", 9998);
- // - Create connection to BaSyx server manager
- JSONConnector toDeviceManager = new JSONConnector(basyxConnector);
- // - Access sub model property, check value
- int propVal = (int) ((HashMap<String, Object>) toDeviceManager
- .getModelPropertyValue("/aas/submodels/dynamicSM/" + SubmodelElementProvider.PROPERTIES + "/prop1/value")).get("value");
-
-
- // Check value
- assertTrue(propVal == 7);
-
-
- // Stop local BaSyx/TCP server
- server.stop();
- }
-}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/http/ConnectToRemoteAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/http/ConnectToRemoteAAS.java
deleted file mode 100644
index 04219cc..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/http/ConnectToRemoteAAS.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.deployment.http;
-
-import static org.junit.Assert.assertTrue;
-
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.components.servlet.aas.AASServlet;
-import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_Empty;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExampleAASRegistry;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-/**
- * Code snippet that illustrates the creation of an Asset Administration Shell (AAS) by extending an SDK class
- *
- * The AAS is deployed to an AASServlet instance running on a Apache Tomcat HTTP server. The AASServlet exports
- * an Asset Administration Shell via the defined BaSyx REST interface.
- *
- * @author kuhn
- *
- */
-public class ConnectToRemoteAAS {
-
-
- /**
- * Example Asset Administration Shell
- */
- static class ExampleAssetAdministrationShell extends AssetAdministrationShell {
- /**
- * Constructor
- */
- public ExampleAssetAdministrationShell() {
- // Set Asset Administration Shell ID
- setIdShort("aas-001");
- }
- }
-
-
-
- /**
- * The BaSyx Deployment instantiates and starts context elements for this example.
- *
- * This example instantiates the BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory
- * example context that creates one AAS server, and one SQL based AAS registry.
- *
- * BaSyxDeployment contexts instantiate all components on the IP address of the host.
- * Therefore, all components use the same IP address.
- */
- @ClassRule
- public static BaSyxDeployment context = new BaSyxDeployment(
- // Servlets for example snippet
- new BaSyxExamplesContext_Empty().
- // Deploy example specific servlets to Tomcat server in this context
- addServletMapping("/Testsuite/components/BaSys/1.0/SampleAAS/*", new AASServlet(new ExampleAssetAdministrationShell()))
- );
-
-
-
- /**
- * Run code snippet. Connect to AAS on server, access AAS properties.
- */
- @Test
- public void connectToAAS() throws Exception {
- // Create AAS Registry to store meta-infomation using aas descriptor
- // This is a pre-configured aas registry that resolves urn to aas-descriptor
- ExampleAASRegistry registry = new ExampleAASRegistry();
- registry.addAASMapping("aas-001",
- "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleAAS/aas");
-
- // Create manager using the directory stub an the HTTPConnectorProvider
- // - Connect to VAB object by ID. The connection manager looks up this ID in
- // its directory
- ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(registry,
- // We connect via HTTP
- new HTTPConnectorProvider());
-
- // Retrieve the AAS from the AAS server with SDK connector
- // - IAssetAdministrationShell is the interface for the local AAS proxy
- IAssetAdministrationShell shell = manager
- .retrieveAAS(new ModelUrn("aas-001"));
- // - Retrieve AAS values and compare to expected values
- Object propertyId = shell.getIdShort();
-
-
- // Check result
- assertTrue(propertyId.equals("aas-001"));
- }
-}
-
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/registry/ConnectToAASEndpoints.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/registry/ConnectToAASEndpoints.java
deleted file mode 100644
index 3abd01b..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/registry/ConnectToAASEndpoints.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.registry;
-
-import static org.junit.Assert.assertEquals;
-
-import org.basyx.components.AASServer.servlet.AASServerServlet;
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.metamodel.connected.ConnectedAssetAdministrationShell;
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
-import org.eclipse.basyx.examples.TestContext;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-/**
- * Code snippet that registers an AAS descriptor with the AAS registry and connects to the registered AAS endpoint
- *
- * The snippet communicates with a VAB element that is deployed to a VABLambdaServlet on a
- * Apache Tomcat HTTP server instance. The VABLambdaServlet provides an empty container that
- * is able to host any VAB object.
- *
- * @author kuhn
- *
- */
-public class ConnectToAASEndpoints {
-
-
- /**
- * Create VAB connection manager backend
- *
- * The connection manager uses a preconfigured directory for resolving IDs to
- * network addresses, and a HTTP connector to connect to VAB objects.
- */
- protected ConnectedAssetAdministrationShellManager connManager = new ConnectedAssetAdministrationShellManager(
- new AASRegistryProxy("http://localhost:8080/basys.examples/Components/Directory/SQL"),
- new HTTPConnectorProvider());
-
-
- /**
- * The BaSyx Deployment instantiates and starts context elements for this example.
- *
- * This example instantiates the BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory
- * example context that creates one AAS server, and one SQL based AAS registry.
- *
- * BaSyxDeployment contexts instantiate all components on the IP address of the host.
- * Therefore, all components use the same IP address.
- */
- @ClassRule
- public static BaSyxDeployment context = new BaSyxDeployment(
- // Simulated servlets
- // - BaSys topology with one AAS Server and one SQL directory
- TestContext.sqlContext.
- // Deploy example specific servlets to Tomcat server in this context
- addServletMapping("/Components/BaSys/1.0/aasServer/*", new AASServerServlet())
- );
-
-
-
-
- /**
- * Run code snippet. This code snippet illustrates the creation of an AASDescriptor, the dynamic creation and deployment of AAS,
- * the lookup of the AAS, and the access of the AAS.
- */
- @Test
- public void snippet() throws Exception {
-
- // Create AAS descriptor and sub model descriptors
- ModelUrn aasURN = new ModelUrn("urn:de.FHG:devices.es.iese:aas:1.0:3:x-509#001");
- String aasSrvURL = "http://localhost:8080/basys.examples/Components/BaSys/1.0/aasServer";
-
- // Create AAS
- AssetAdministrationShell aas = new AssetAdministrationShell();
-
- // - Set AAS ID
- aas.setIdentification(aasURN);
-
- // - Transfer AAS to server
- // - This creates the "urn:de.FHG:devices.es.iese:aas:1.0:3:x-509#001" element on the server, which is the server
- // end point that will host the AAS.
- connManager.createAAS(aas, aasURN, aasSrvURL);
-
- // Server connections
- // - Connect AAS
- ConnectedAssetAdministrationShell shell = connManager.retrieveAAS(aasURN);
-
- // Retrieve the AAS from the AAS server with SDK connector
- // - IAssetAdministrationShell is the interface for the local AAS proxy
- // - Retrieve AAS values and compare to expected values
- Object aasIDProperty = shell.getIdentification().getId();
-
- // Check property value
- assertEquals(aasURN.getURN(), aasIDProperty);
- }
-}
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/registry/ConnectToSubModelEndpoints.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/registry/ConnectToSubModelEndpoints.java
deleted file mode 100644
index c0264a0..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/registry/ConnectToSubModelEndpoints.java
+++ /dev/null
@@ -1,139 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.registry;
-
-import static org.junit.Assert.assertTrue;
-
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
-import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
-import org.eclipse.basyx.components.servlet.aas.AASServlet;
-import org.eclipse.basyx.examples.TestContext;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.vab.modelprovider.VABPathTools;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-/**
- * Code snippet that registers an AAS descriptor with the AAS registry and connects to a sub model of
- * the registered AAS endpoint
- *
- * The snippet communicates with a VAB element that is deployed to a VABLambdaServlet on a
- * Apache Tomcat HTTP server instance. The VABLambdaServlet provides an empty container that
- * is able to host any VAB object.
- *
- * @author kuhn
- *
- */
-public class ConnectToSubModelEndpoints {
- /**
- * Create VAB connection manager backend
- *
- * The connection manager uses a preconfigured directory for resolving IDs to
- * network addresses, and a HTTP connector to connect to VAB objects.
- */
- protected ConnectedAssetAdministrationShellManager connManager = new ConnectedAssetAdministrationShellManager(
- new AASRegistryProxy("http://localhost:8080/basys.examples/Components/Directory/SQL"),
- new HTTPConnectorProvider());
-
-
- /**
- * The BaSyx Deployment instantiates and starts context elements for this example.
- *
- * This example instantiates the BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory
- * example context that creates one AAS server, and one SQL based AAS registry.
- *
- * BaSyxDeployment contexts instantiate all components on the IP address of the host.
- * Therefore, all components use the same IP address.
- */
- @ClassRule
- public static BaSyxDeployment context = new BaSyxDeployment(
- // Simulated servlets
- // - BaSys topology with one AAS Server and one SQL directory
- TestContext.sqlContext.
- // Deploy example specific servlets to Tomcat server in this context
- addServletMapping("/Components/BaSys/1.0/aasServer/*",
- new AASServlet(new AssetAdministrationShell()))
- );
-
-
-
-
- /**
- * Run code snippet. This code snippet illustrates the creation of an AASDescriptor, the dynamic creation and deployment of an AAS sub model,
- * the lookup of the AAS sub model, and the access of the AAS sub model.
- */
- @Test
- public void snippet() throws Exception {
-
- // Create AAS descriptor and sub model descriptors
- ModelUrn aasURN = new ModelUrn("urn:de.FHG:devices.es.iese:aas:1.0:3:x-509#001");
- String aasSrvURL = "http://localhost:8080/basys.examples/Components/BaSys/1.0/aasServer/aas";
- // - Sub model ID
- String smIdShort = "exampleSM";
- IIdentifier smId = new Identifier(IdentifierType.CUSTOM, "exampleSMId");
- // - Create AAS descriptor and sub model descriptor
- AASDescriptor aasDescriptor = new AASDescriptor(aasURN, aasSrvURL);
- String smEndpoint = VABPathTools.concatenatePaths(aasSrvURL, "submodels", smIdShort);
- SubmodelDescriptor submodelDescriptor = new SubmodelDescriptor(smIdShort, smId, smEndpoint);
- // - Add sub model descriptor to AAS descriptor
- aasDescriptor.addSubmodelDescriptor(submodelDescriptor);
-
-
- // Register AAS and sub model descriptors in directory (push AAS descriptor to server)
- // - Connect to AAS registry
- IAASRegistryService regProxy = new AASRegistryProxy(
- "http://localhost:8080/basys.examples/Components/Directory/SQL");
- // - Register AAS descriptor with AAS and sub model endpoints in registry
- regProxy.register(aasDescriptor);
-
- // Create sub model
- SubModel submodel = new SubModel();
- submodel.setIdShort(smIdShort);
- submodel.setIdentification(smId.getIdType(), smId.getId());
-
- // - Add example properties to sub model
- Property prop1 = new Property(7);
- prop1.setIdShort("prop1");
- submodel.addSubModelElement(prop1);
-
- Property prop2 = new Property("myStr");
- prop2.setIdShort("prop2");
- submodel.addSubModelElement(prop2);
- // - Transfer sub model to server
- // - This creates the "exampleSM" element on the server, which is the server
- // end point that will host the AAS sub model.
- connManager.createSubModel(aasURN, submodel);
-
-
- // Connect to sub model using BaSyx SDK
- ISubModel connSM = connManager.retrieveSubModel(aasURN, smId);
-
-
- // Read property values from sub model
- String smID = connSM.getIdShort();
- String prop1Id = connSM.getProperties().get("prop1").getIdShort();
- int prop1Val = (int) ((IProperty) connSM.getProperties().get("prop1")).get();
- String prop2Id = connSM.getProperties().get("prop2").getIdShort();
- String prop2Val = (String) ((IProperty) connSM.getProperties().get("prop2")).get();
-
-
- // Check property values
- assertTrue(smID.equals(smIdShort));
- assertTrue(prop1Id.equals("prop1"));
- assertTrue(prop1Val == 7);
- assertTrue(prop2Id.equals("prop2"));
- assertTrue(prop2Val.equals("myStr"));
- }
-}
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/registry/RegisterRetrieveAASEndpoints.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/registry/RegisterRetrieveAASEndpoints.java
deleted file mode 100644
index ad842dd..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/registry/RegisterRetrieveAASEndpoints.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.registry;
-
-import static org.junit.Assert.assertTrue;
-
-import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
-import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
-import org.eclipse.basyx.examples.TestContext;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABPathTools;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-/**
- * Code snippet that registers an AAS descriptor with the AAS registry and accesses the registry using HTTP calls
- *
- * The snippet communicates with a VAB element that is deployed to a VABLambdaServlet on a
- * Apache Tomcat HTTP server instance. The VABLambdaServlet provides an empty container that
- * is able to host any VAB object.
- *
- * @author kuhn
- *
- */
-public class RegisterRetrieveAASEndpoints {
-
-
- /**
- * Create VAB connection manager backend
- *
- * The connection manager uses a preconfigured directory for resolving IDs to
- * network addresses, and a HTTP connector to connect to VAB objects.
- */
- protected VABConnectionManager connManager = new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorProvider());
-
-
- /**
- * The BaSyx Deployment instantiates and starts context elements for this example.
- *
- * This example instantiates the BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory
- * example context that creates one AAS server, and one SQL based AAS registry.
- *
- * BaSyxDeployment contexts instantiate all components on the IP address of the host.
- * Therefore, all components use the same IP address.
- */
- @ClassRule
- public static BaSyxDeployment context = new BaSyxDeployment(
- // Simulated servlets
- // - BaSys topology with one AAS Server and one SQL directory
- TestContext.sqlContext
- );
-
-
-
-
- /**
- * Run code snippet. This code snippet illustrates the creation of an AASDescriptor, its registration, and
- * the lookup of the AAS using HTTP REST calls
- */
- @Test
- public void snippet() throws Exception {
-
- // Create AAS descriptor and sub model descriptors
- ModelUrn aasURN = new ModelUrn("urn:de.FHG:devices.es.iese:aas:1.0:3:x-509#001");
- ModelUrn subModelURN = new ModelUrn("urn:de.FHG:devices.es.iese:exampleSM:1.0:3:x-509#001");
- String aasSrvURL = "http://localhost:8080/basys.examples/Components/BaSys/1.0/aasServer";
- String aasSrvPrefix = "/aas/submodels/aasRepository/sampleAAS";
- // - Create AAS descriptor
- AASDescriptor aasDescriptor = new AASDescriptor(aasURN,
- VABPathTools.concatenatePaths(aasSrvURL, aasSrvPrefix, aasURN.getEncodedURN()));
- // - Add sub model descriptor URI
- SubmodelDescriptor submodelDescriptor = new SubmodelDescriptor(subModelURN.getEncodedURN(), subModelURN, VABPathTools.concatenatePaths(aasSrvURL, aasSrvPrefix, subModelURN.getEncodedURN()));
- aasDescriptor.addSubmodelDescriptor(submodelDescriptor);
-
-
- // Register AAS and sub model descriptors in directory (push AAS descriptor to server)
- // - Connect to AAS registry
- IAASRegistryService regProxy = new AASRegistryProxy(
- "http://localhost:8080/basys.examples/Components/Directory/SQL");
- // - Register AAS descriptor with AAS and sub model endpoints in registry
- regProxy.register(aasDescriptor);
-
-
- // Lookup AAS descriptor
- AASDescriptor aasDesc = regProxy.lookupAAS(aasURN);
- // - AAS end sub model end points
- String aasEndpointURL = aasDesc.getFirstEndpoint();
- String smEndpointURL = aasDesc.getSubModelDescriptor(subModelURN).getFirstEndpoint();
-
-
- // Check results
- assertTrue(aasEndpointURL.equals("http://localhost:8080/basys.examples/Components/BaSys/1.0/aasServer/aas/submodels/aasRepository/sampleAAS/urn%3Ade.FHG%3Adevices.es.iese%3Aaas%3A1.0%3A3%3Ax-509%23001"));
- assertTrue(smEndpointURL.equals("http://localhost:8080/basys.examples/Components/BaSys/1.0/aasServer/aas/submodels/aasRepository/sampleAAS/urn%3Ade.FHG%3Adevices.es.iese%3AexampleSM%3A1.0%3A3%3Ax-509%23001"));
- }
-}
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/ConnectToAASSubModelSDK.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/ConnectToAASSubModelSDK.java
deleted file mode 100644
index a2f2681..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/ConnectToAASSubModelSDK.java
+++ /dev/null
@@ -1,137 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.submodels;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Map;
-
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.components.servlet.submodel.SubmodelServlet;
-import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_Empty;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExampleAASRegistry;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-/**
- * Code snippet that illustrates the use of CRUD Virtual Automation Bus (VAB) operations
- *
- * The snippet communicates with a VAB element that is deployed to a VABLambdaServlet on a
- * Apache Tomcat HTTP server instance. The VABLambdaServlet provides an empty container that
- * is able to host any VAB object.
- *
- * @author kuhn
- *
- */
-public class ConnectToAASSubModelSDK {
-
-
- /**
- * Example sub model. This example sub model is created with the BaSyx SDK factory and defines the AAS meta model properties
- */
- static class SampleSubModel extends SubModel {
- /**
- * Constructor - create sub model
- *
- * This sub model contains static properties, i.e. properties that have a static value assigned.
- */
- @SuppressWarnings("unchecked")
- public SampleSubModel() {
- // Set sub model id and name
- setIdShort("smName");
- setIdentification(IdentifierType.CUSTOM, "sm-001");
-
- // Add example properties
- // - Add simple property
- Property prop1 = new Property(234);
- prop1.setIdShort("prop1");
- addSubModelElement(prop1);
-
- Property prop11 = new Property(123);
- prop11.setIdShort("prop11");
- // - Add container property that holds other properties
- SubmodelElementCollection container = new SubmodelElementCollection();
- container.setIdShort("prop2");
- container.addElement(prop11);
- // - Add container to property map
- addSubModelElement(container);
-
- // Add another property manually to sub model container "properties"
- Property prop3 = new Property(17);
- prop3.setIdShort("prop3");
- ((Map<String, Object>) this.get("submodelElements")).put("prop3", prop3);
- }
- }
-
-
-
- /**
- * The BaSyx Deployment instantiates and starts context elements for this example.
- *
- * This example instantiates the BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory
- * example context that creates one AAS server, and one SQL based AAS registry.
- *
- * BaSyxDeployment contexts instantiate all components on the IP address of the host.
- * Therefore, all components use the same IP address.
- */
- @ClassRule
- public static BaSyxDeployment context = new BaSyxDeployment(
- // Servlets for example snippet
- new BaSyxExamplesContext_Empty().
- // Deploy example specific servlets to Tomcat server in this context
- addServletMapping("/Testsuite/components/BaSys/1.0/SampleModel/*", new SubmodelServlet(new SampleSubModel()))
- );
-
-
- /**
- * Run code snippet. Access sub model, query data
- */
- @Test
- public void accessSubModel() throws Exception {
- // Create the AAS registry
- ExampleAASRegistry registry = new ExampleAASRegistry();
- registry.addAASMapping("aas-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/")
- .addSubmodelMapping("aas-001", "sm-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/");
-
- // Create manager using the directory stub and the HTTPConnectorProvider
- ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(registry,
- // We connect via HTTP
- new HTTPConnectorProvider());
-
-
- // Retrieve sub model (created by factory) with SDK connector
- // - Create and connect SDK connector
- IIdentifier aasId = new Identifier(IdentifierType.CUSTOM, "aas-001");
- IIdentifier smId = new Identifier(IdentifierType.CUSTOM, "sm-001");
- ISubModel subModel = manager.retrieveSubModel(aasId, smId);
-
- // - Retrieve sub model values and compare to expected values
- Map<String, ISubmodelElement> smElements = subModel.getSubmodelElements();
- IProperty prop1 = (IProperty) smElements.get("prop1");
- ISubmodelElementCollection prop2 = (ISubmodelElementCollection) smElements.get("prop2");
- IProperty prop11 = (IProperty) prop2.getProperties().get("prop11");
- IProperty prop3 = (IProperty) smElements.get("prop3");
-
- assertEquals(smId.getId(), subModel.getIdentification().getId());
- assertEquals("smName", subModel.getIdShort());
- assertEquals("prop1", prop1.getIdShort());
- assertEquals(234, prop1.get());
- assertEquals("prop2", prop2.getIdShort());
- assertEquals("prop11", prop11.getIdShort());
- assertEquals(123, prop11.get());
- assertEquals("prop3", prop3.getIdShort());
- assertEquals(17, prop3.get());
- }
-}
-
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/ConnectToAASSubModelVAB.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/ConnectToAASSubModelVAB.java
deleted file mode 100644
index d48956b..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/ConnectToAASSubModelVAB.java
+++ /dev/null
@@ -1,161 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.submodels;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Map;
-
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.components.servlet.submodel.SubmodelServlet;
-import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_Empty;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExampleAASRegistry;
-import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-
-/**
- * Code snippet that illustrates the use of CRUD Virtual Automation Bus (VAB) operations
- *
- * The snippet communicates with a VAB element that is deployed to a VABLambdaServlet on a
- * Apache Tomcat HTTP server instance. The VABLambdaServlet provides an empty container that
- * is able to host any VAB object.
- *
- * @author kuhn
- *
- */
-public class ConnectToAASSubModelVAB {
-
-
- /**
- * Example sub model. This example sub model is created with the BaSyx SDK factory and defines the AAS meta model properties
- */
- static class SampleSubModel extends SubModel {
- /**
- * Constructor - create sub model
- *
- * This sub model contains static properties, i.e. properties that have a static value assigned.
- */
- @SuppressWarnings("unchecked")
- public SampleSubModel() {
- // Set sub model id and name
- setIdShort("smName");
- setIdentification(IdentifierType.CUSTOM, "sm-001");
-
- // Add example properties
- // - Add simple property
- Property prop1 = new Property(234);
- prop1.setIdShort("prop1");
- addSubModelElement(prop1);
-
- Property prop11 = new Property(123);
- prop11.setIdShort("prop11");
- // - Add container property that holds other properties
- SubmodelElementCollection container = new SubmodelElementCollection();
- container.setIdShort("prop2");
- container.addElement(prop11);
- // - Add container to property map
- addSubModelElement(container);
-
- // Add another property manually to sub model container "properties"
- Property prop3 = new Property(17);
- prop3.setIdShort("prop3");
- ((Map<String, Object>) this.get("submodelElements")).put("prop3", prop3);
- }
- }
-
-
-
- /**
- * Create VAB connection manager backend
- *
- * The connection manager uses a preconfigured directory for resolving IDs to
- * network addresses, and a HTTP connector to connect to VAB objects.
- */
- protected VABConnectionManager connManager = new VABConnectionManager(
- // Add example specific mappings
- new ExamplesPreconfiguredDirectory()
- .addMapping("aas-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/")
- .addMapping("sm-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/")
- .addMapping("sm-001VAB", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/"),
- // We connect via HTTP
- new HTTPConnectorProvider());
-
- protected ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(
- new ExampleAASRegistry()
- .addAASMapping("aas-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/")
- .addSubmodelMapping("aas-001", "sm-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/"),
- // We connect via HTTP
- new HTTPConnectorProvider());
-
-
- /**
- * The BaSyx Deployment instantiates and starts context elements for this example.
- *
- * This example instantiates the BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory
- * example context that creates one AAS server, and one SQL based AAS registry.
- *
- * BaSyxDeployment contexts instantiate all components on the IP address of the host.
- * Therefore, all components use the same IP address.
- */
- @ClassRule
- public static BaSyxDeployment context = new BaSyxDeployment(
- // Servlets for example snippet
- new BaSyxExamplesContext_Empty().
- // Deploy example specific servlets to Tomcat server in this context
- addServletMapping("/Testsuite/components/BaSys/1.0/SampleModel/*", new SubmodelServlet(new SampleSubModel()))
- );
-
-
- /**
- * Run code snippet. Access sub model, query data
- */
- @Test @SuppressWarnings("unchecked")
- public void accessSubModel() throws Exception {
- // Retrieve sub model (created by factory) with SDK connector
- // - Connect to sub model using lower-level VAB interface
- VABElementProxy connSubModel1 = this.connManager.connectToVABElement("sm-001VAB");
- Map<String, Object> submodel = (Map<String, Object>) connSubModel1.getModelPropertyValue("");
- Map<String, Object> smId = (Map<String, Object>) submodel.get(Identifiable.IDENTIFICATION);
-
- // - Read properties
- Map<String, Object> prop1 = (Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1");
- Map<String, Object> prop2 = (Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop2");
- Map<String, Object> prop11 = (Map<String, Object>) connSubModel1.getModelPropertyValue("submodelElements/prop2/prop11");
- Map<String, Object> prop3 = (Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop3");
-
- // - Change property value using VAB primitive
- connSubModel1.setModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1/value", 456);
-
- // - Read value back using VAB primitive
- Map<String, Object> changedProp1 = (Map<String, Object>) connSubModel1
- .getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1");
-
- // - Check results
- assertEquals("sm-001", smId.get(Identifier.ID));
- assertEquals("smName", submodel.get(Referable.IDSHORT));
- assertEquals("prop1", prop1.get(Referable.IDSHORT));
- assertEquals(234, prop1.get(Property.VALUE)); // old value of prop1 has been stored locally
- assertEquals(456, changedProp1.get(Property.VALUE)); // new value is 456
- assertEquals("prop2", prop2.get(Referable.IDSHORT));
- assertEquals("prop11", prop11.get(Referable.IDSHORT));
- assertEquals(123, prop11.get(Property.VALUE));
- assertEquals("prop3", prop3.get(Referable.IDSHORT));
- assertEquals(17, prop3.get(Property.VALUE));
-
- }
-}
-
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/CreateAASSubModelSDK.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/CreateAASSubModelSDK.java
deleted file mode 100644
index a349f50..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/CreateAASSubModelSDK.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.submodels;
-
-import static org.junit.Assert.assertTrue;
-
-import java.util.Map;
-
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.junit.Test;
-
-
-
-/**
- * Code snippet that illustrates the creation of an AAS sub model
- *
- * @author kuhn
- *
- */
-public class CreateAASSubModelSDK {
-
-
- /**
- * Example sub model. This example sub model is created with the BaSyx SDK factory and defines the AAS meta model properties
- */
- static class SampleSubModel extends SubModel {
- /**
- * Constructor - create sub model
- *
- * This sub model contains static properties, i.e. properties that have a static value assigned.
- */
- @SuppressWarnings("unchecked")
- public SampleSubModel() {
- // Set sub model ID
- setIdShort("sm-001");
-
- // Add example properties
- // - Add simple property
- Property prop1 = new Property(234);
- prop1.setIdShort("prop1");
- addSubModelElement(prop1);
-
- Property prop11 = new Property(123);
- prop11.setIdShort("prop11");
- // - Add container property that holds other properties
- SubmodelElementCollection container = new SubmodelElementCollection();
- container.setIdShort("prop2");
- container.addElement(prop11);
- // - Add container to property map
- addSubModelElement(container);
-
- // Add another property manually to sub model container "properties"
- Property prop3 = new Property(17);
- prop3.setIdShort("prop3");
- {
- ((Map<String, Object>) this.get("submodelElements")).put("prop3", prop3);
- }
- }
- }
-
-
- /**
- * Run code snippet. Instantiate AAS sub model.
- */
- @Test
- public void accessSubModel() throws Exception {
- // Instantiate AAS sub model
- SampleSubModel sampleSM = new SampleSubModel();
-
- // Access sub model property
- int propertyVal = (int) sampleSM.getPath("submodelElements/prop1/value");
-
- // Check property value
- assertTrue(propertyVal == 234);
- }
-}
-
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/CreateAASSubModelVAB.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/CreateAASSubModelVAB.java
deleted file mode 100644
index 84327cd..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/CreateAASSubModelVAB.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.submodels;
-
-import static org.junit.Assert.assertTrue;
-
-import java.util.Map;
-
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDefHelper;
-import org.junit.Test;
-
-
-
-/**
- * Code snippet that illustrates the creation of an AAS sub model
- *
- * @author kuhn
- *
- */
-public class CreateAASSubModelVAB {
-
-
- /**
- * Example sub model. This example sub model is created with the BaSyx SDK factory and defines the AAS meta model properties
- */
- static class SampleSubModel extends SubModel {
- /**
- * Constructor - create sub model property
- *
- * This sub model contains static properties, i.e. properties that have a static value assigned.
- */
- @SuppressWarnings("unchecked")
- public SampleSubModel() {
- // Set sub model ID
- setIdShort("sm-001M");
-
- // Add example properties
- // - Add simple property with value and idShort meta elements
- this.putPath("properties/prop1/value", 234);
- this.putPath("properties/prop1/valueType", PropertyValueTypeDefHelper.getTypeWrapperFromObject(234));
- this.putPath("properties/prop1/idShort", "prop1");
-
- // Add container property that holds other properties
- this.putPath("properties/prop2/idShort", "prop2");
- // - Add contained property
- this.putPath("properties/prop2/properties/prop11/value", 123);
- this.putPath("properties/prop2/properties/prop11/valueType", PropertyValueTypeDefHelper.getTypeWrapperFromObject(123).toString());
- this.putPath("properties/prop2/properties/prop11/idShort", "prop11");
-
- // Add another property manually to sub model container "properties"
- // - Using the Property class ensures presence of all meta properties
- Property addedProperty = new Property();
- addedProperty.set(17);
- addedProperty.setIdShort("prop3");
- // - Add property to sub model container "properties"
- {((Map<String, Object>) this.get("properties")).put("prop3", addedProperty);}
- }
- }
-
-
- /**
- * Run code snippet. Instantiate AAS sub model.
- */
- @Test
- public void accessSubModel() throws Exception {
- // Instantiate AAS sub model
- SampleSubModel sampleSM = new SampleSubModel();
-
- // Access sub model property
- int propertyVal = (int) sampleSM.getPath("properties/prop1/value");
-
- // Check property value
- assertTrue(propertyVal == 234);
- }
-}
-
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/DynamicSubModelDeployment.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/DynamicSubModelDeployment.java
deleted file mode 100644
index 2a57024..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/DynamicSubModelDeployment.java
+++ /dev/null
@@ -1,113 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.submodels;
-
-import static org.junit.Assert.assertTrue;
-
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.components.servlet.aas.AASServlet;
-import org.eclipse.basyx.examples.TestContext;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExampleAASRegistry;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-/**
- * Code snippet that illustrates the creation of an AAS sub model
- *
- * @author kuhn
- *
- */
-public class DynamicSubModelDeployment {
-
- private static final String AAS = "de.FHG:devices.es.iese:aas:1.0:3:x-509#003";
- private static final String STATUS_SM = "de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003";
-
- protected ConnectedAssetAdministrationShellManager aasManager = new ConnectedAssetAdministrationShellManager(
- new ExampleAASRegistry()
- .addAASMapping(AAS,
- "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/dynamicModelRepository/aas/")
- // Ass Example specific mappings
- .addSubmodelMapping(AAS, STATUS_SM,
- "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/dynamicModelRepository/aas/submodels/Status"),
- new HTTPConnectorProvider());
-
- /**
- * The BaSyx Deployment instantiates and starts context elements for this example.
- *
- * This example instantiates the BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory
- * example context that creates one AAS server, and one SQL based AAS registry.
- *
- * BaSyxDeployment contexts instantiate all components on the IP address of the host.
- * Therefore, all components use the same IP address.
- */
- @ClassRule
- public static BaSyxDeployment context = new BaSyxDeployment(
- // Simulated servlets
- // - BaSys topology with one AAS Server and one SQL directory
- TestContext.sqlContext.
- // Deploy example specific servlets to Apache Tomcat server in this context
- addServletMapping("/Testsuite/components/BaSys/1.0/dynamicModelRepository/*",
- new AASServlet(new AssetAdministrationShell()))
- );
-
-
-
-
- /**
- * Run code snippet. This code snippet illustrates the use of CRUD operations to
- * access Virtual Automation Bus objects
- */
- @Test
- public void snippet() throws Exception {
- // Instantiate sub model
- SubModel submodel = new SubModel();
- // - Add example properties to sub model
- submodel.setIdShort("Status");
- Property prop1 = new Property(7);
- prop1.setIdShort("prop1");
- submodel.addSubModelElement(prop1);
-
- Property prop2 = new Property("myStr");
- prop2.setIdShort("prop2");
- submodel.addSubModelElement(prop2);
-
-
-
- // Transfer sub model to server
- aasManager.createSubModel(new ModelUrn(AAS), submodel);
-
-
- // Retrieve sub model with SDK connector
- {
-
- // Server connections
- // - Connect to sub model. Connecting to a sub model by its ID is discouraged, because a sub
- // model ID is not necessarily unique outside the scope of its AAS. If users want to connect
- // directly to sub models, the registry needs to support this, and unique identifies (as here)
- // must be used. For portability, users should connect to sub models instead via an AAS ID and
- // sub model ID tuple, as illustrated in the registry examples.
- ISubModel subModel = aasManager.retrieveSubModel(new ModelUrn(AAS), new ModelUrn(STATUS_SM));
-
- // Read sub model properties
- String smId = subModel.getIdShort();
- String prop1Id = subModel.getProperties().get("prop1").getIdShort();
- int prop1Val = (int) ((IProperty) subModel.getProperties().get("prop1")).get();
- String prop2Id = subModel.getProperties().get("prop2").getIdShort();
- String prop2Val = (String) ((IProperty) subModel.getProperties().get("prop2")).get();
-
- // Compare sub model property values
- assertTrue(smId.equals("Status"));
- assertTrue(prop1Id.equals("prop1"));
- assertTrue(prop1Val == 7);
- assertTrue(prop2Id.equals("prop2"));
- assertTrue(prop2Val.equals("myStr"));
- }
- }
-}
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/DynamicSubModelDeploymentHTTP.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/DynamicSubModelDeploymentHTTP.java
deleted file mode 100644
index 36b27c2..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/DynamicSubModelDeploymentHTTP.java
+++ /dev/null
@@ -1,117 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.submodels;
-
-import static org.junit.Assert.assertTrue;
-
-import java.util.Map;
-
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.components.servlet.aas.AASServlet;
-import org.eclipse.basyx.examples.TestContext;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.tools.webserviceclient.WebServiceJSONClient;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-/**
- * Code snippet that illustrates the creation of an AAS sub model, and the access to the sub model via HTTP REST calls
- *
- * @author kuhn
- *
- */
-public class DynamicSubModelDeploymentHTTP {
-
-
- /**
- * Create VAB connection manager backend
- *
- * The connection manager uses a preconfigured directory for resolving IDs to
- * network addresses, and a HTTP connector to connect to VAB objects.
- */
- protected VABConnectionManager connManager = new VABConnectionManager(
- new ExamplesPreconfiguredDirectory()
- // Add example specific mappings
- .addMapping("urn:de.FHG:devices.es.iese:aas:1.0:3:x-509:003",
- "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/dynamicModelRepository/aas"),
- new HTTPConnectorProvider());
-
-
- /**
- * The BaSyx Deployment instantiates and starts context elements for this example.
- *
- * This example instantiates the BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory
- * example context that creates one AAS server, and one SQL based AAS registry.
- *
- * BaSyxDeployment contexts instantiate all components on the IP address of the host.
- * Therefore, all components use the same IP address.
- */
- @ClassRule
- public static BaSyxDeployment context = new BaSyxDeployment(
- // Simulated servlets
- // - BaSys topology with one AAS Server and one SQL directory
- TestContext.sqlContext.
- // Deploy example specific servlets to Apache Tomcat server in this context
- addServletMapping("/Testsuite/components/BaSys/1.0/dynamicModelRepository/*",
- new AASServlet(new AssetAdministrationShell()))
- );
-
-
-
-
- /**
- * Run code snippet. This code snippet illustrates the dynamic deployment of a sub model and the use of HTTP REST operations to
- * access the sub model
- */
- @Test @SuppressWarnings("unchecked")
- public void snippet() throws Exception {
-
- // Server connections
- // - Connect to sub model. Connecting to a sub model by its ID is discouraged, because a sub
- // model ID is not necessarily unique outside the scope of its AAS. If users want to connect
- // directly to sub models, the registry needs to support this, and unique identifies (as here)
- // must be used. For portability, users should connect to sub models instead via an AAS ID and
- // sub model ID tuple, as illustrated in the registry examples.
- VABElementProxy connSubModels = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:aas:1.0:3:x-509:003");
-
- // Add example properties
- SubModel submodel = new SubModel();
- submodel.setIdShort("Status");
- Property prop1 = new Property(7);
- prop1.setIdShort("prop1");
- submodel.addSubModelElement(prop1);
-
- Property prop2 = new Property("myStr");
- prop2.setIdShort("prop2");
- submodel.addSubModelElement(prop2);
-
- // Transfer sub model to server
- connSubModels.createValue("/submodels", submodel);
-
-
- // Web service client accesses AAS using HTTP REST calls
- WebServiceJSONClient jsonClient = new WebServiceJSONClient();
-
- // Read property values using the WebServiceJSONClient class.
- // - Returned property contains meta data. The actual property is stored in property "entity", property value is in entity property "value"
- String smEndpoint = "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/dynamicModelRepository/aas/submodels/Status";
- Map<String, Object> sm = ((Map<String, Object>) jsonClient.get(smEndpoint));
- String smId = (String) sm.get("idShort");
- int prop1Val = (int) ((Map<String, Object>) jsonClient.get(smEndpoint + "/" + SubmodelElementProvider.PROPERTIES + "/prop1")).get("value");
- String prop1Id = (String) ((Map<String, Object>) jsonClient.get(smEndpoint + "/" + SubmodelElementProvider.PROPERTIES + "/prop1")).get("idShort");
- String prop2Val = (String) ((Map<String, Object>) jsonClient.get(smEndpoint + "/" + SubmodelElementProvider.PROPERTIES + "/prop2")).get("value");
-
-
- // Check results
- assertTrue(smId.equals("Status"));
- assertTrue(prop1Val == 7);
- assertTrue(prop1Id.equals("prop1"));
- assertTrue(prop2Val.equals("myStr"));
- }
-}
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/InvokeSubModelOperationSDK.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/InvokeSubModelOperationSDK.java
deleted file mode 100644
index d608f14..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/InvokeSubModelOperationSDK.java
+++ /dev/null
@@ -1,144 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.submodels;
-
-import static org.junit.Assert.assertTrue;
-
-import java.util.Map;
-import java.util.function.Function;
-
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.components.servlet.submodel.SubmodelServlet;
-import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_Empty;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExampleAASRegistry;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-/**
- * Code snippet that illustrates the definition and invocation of sub model operations
- *
- * The snippet communicates with a VAB element that is deployed to a VABLambdaServlet on a
- * Apache Tomcat HTTP server instance. The VABLambdaServlet provides an empty container that
- * is able to host any VAB object.
- *
- * @author kuhn
- *
- */
-public class InvokeSubModelOperationSDK {
-
-
- /**
- * Example sub model. This example sub model is created with the BaSyx SDK factory and defines the AAS meta model properties
- */
- static class SampleSubModel extends SubModel {
- /**
- * Constructor - create sub model
- *
- * This sub model contains operations
- */
- public SampleSubModel() {
- // Set sub model ID
- setIdShort("sm-001");
-
- // Define operations
- Operation op1 = new Operation((Function<Object[], Object>) v -> {
- return operation1();
- });
- op1.setIdShort("operation1");
- addSubModelElement(op1);
-
- Operation op2 = new Operation((Function<Object[], Object>) v -> {
- return operation2((int) v[0], (int) v[1]);
- });
- op2.setIdShort("operation2");
- addSubModelElement(op2);
-
- }
-
- /**
- * Example operation implementation
- */
- public int operation1() {
- return 4;
- }
-
- /**
- * Example operation with parameter
- */
- public int operation2(int par1, int par2) {
- return par1+par2;
- }
- }
-
-
-
- /**
- * Create VAB connection manager backend
- *
- * The connection manager uses a preconfigured directory for resolving IDs to
- * network addresses, and a HTTP connector to connect to VAB objects.
- */
- protected ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(
- // Add example specific mappings
- new ExampleAASRegistry()
- .addAASMapping("aas-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/")
- .addSubmodelMapping("aas-001", "sm-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/"),
- // We connect via HTTP
- new HTTPConnectorProvider());
-
-
- /**
- * The BaSyx Deployment instantiates and starts context elements for this example.
- *
- * This example instantiates the BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory
- * example context that creates one AAS server, and one SQL based AAS registry.
- *
- * BaSyxDeployment contexts instantiate all components on the IP address of the host.
- * Therefore, all components use the same IP address.
- */
- @ClassRule
- public static BaSyxDeployment context = new BaSyxDeployment(
- // Servlets for example snippet
- new BaSyxExamplesContext_Empty().
- // Deploy example specific servlets to Tomcat server in this context
- addServletMapping("/Testsuite/components/BaSys/1.0/SampleModel/*", new SubmodelServlet(new SampleSubModel()))
- );
-
-
- /**
- * Run code snippet. Access sub model, query data
- */
- @Test
- public void accessSubModel() throws Exception {
- // Retrieve sub model (created by factory) with SDK connector
- {
- // Create and connect SDK connector
- ISubModel subModel = manager.retrieveSubModel(new ModelUrn("aas-001"), new ModelUrn("sm-001"));
-
- // Sub model operations
- Map<String, IOperation> operations = subModel.getOperations();
-
- // Get first operation by name
- IOperation op1 = operations.get("operation1");
- // - Invoke operation
- int result1 = (int) op1.invoke();
-
- // Get second operation by name
- IOperation op2 = operations.get("operation2");
- // - Invoke operation
- int result2 = (int) op2.invoke(7, 5);
-
-
- // Check results
- assertTrue(result1 == 4);
- assertTrue(result2 == 12);
- }
- }
-}
-
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestAddSubmodelToAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestAddSubmodelToAAS.java
new file mode 100644
index 0000000..1bdd3ae
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestAddSubmodelToAAS.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.manager;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.examples.support.ExampleComponentBuilder;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.junit.Test;
+
+/**
+ * Test for the AddSubmodelToAAS snippet
+ *
+ * @author conradi
+ *
+ */
+public class TestAddSubmodelToAAS extends AbstractSnippetTest {
+
+ private static final String NEW_SM_ID_SHORT = "smIdShort_New";
+ private static final String NEW_SM_ID = "smId_New";
+
+ @Test
+ public void testAddSubmodelToAAS() {
+
+ // Get the example AAS and Submodel
+ Submodel submodel = ExampleComponentBuilder.buildExampleSubmodel(NEW_SM_ID_SHORT, NEW_SM_ID);
+
+ // Get the Identifiers for the AAS and the Submodel
+ IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+ IIdentifier smIdentifier = submodel.getIdentification();
+
+ // Add the Submodel to the AAS
+ AddSubmodelToAAS.addSubmodelToAAS(submodel, aasIdentifier, registryComponent.getRegistryPath());
+
+ // Check if the Submodel was correctly added
+ ConnectedAssetAdministrationShellManager manager = getManager();
+ ISubmodel remoteSM = manager.retrieveSubmodel(aasIdentifier, smIdentifier);
+ assertEquals(NEW_SM_ID_SHORT, remoteSM.getIdShort());
+
+ }
+
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestDeleteAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestDeleteAAS.java
new file mode 100644
index 0000000..4ec5bbd
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestDeleteAAS.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.manager;
+
+import static org.junit.Assert.fail;
+
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Test;
+
+/**
+ * Test for the DeleteAAS snippet
+ *
+ * @author conradi
+ *
+ */
+public class TestDeleteAAS extends AbstractSnippetTest {
+
+ @Test
+ public void testDeleteAAS() {
+
+ // Get the Identifier of the example AAS
+ IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+
+ // Delete the AAS
+ DeleteAAS.deleteAAS(aasIdentifier, registryComponent.getRegistryPath());
+
+ // Try to retrieve deleted AAS; should throw ResourceNotFoundException
+ try {
+ RetrieveAAS.retrieveRemoteAAS(aasIdentifier, registryComponent.getRegistryPath());
+ fail();
+ } catch (ResourceNotFoundException e) {
+ }
+
+ }
+
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestDeleteSubmodelFromAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestDeleteSubmodelFromAAS.java
new file mode 100644
index 0000000..ed8cdbf
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestDeleteSubmodelFromAAS.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.manager;
+
+import static org.junit.Assert.fail;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Test;
+
+/**
+ * Test for the DeleteSubmodelFromAAS snippet
+ *
+ * @author conradi
+ *
+ */
+public class TestDeleteSubmodelFromAAS extends AbstractSnippetTest {
+
+ @Test
+ public void testDeleteSubmodel() {
+
+ // Get the Identifier of the example AAS and Submodel
+ IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+ IIdentifier smIdentifier = new Identifier(IdentifierType.CUSTOM, SM_ID);
+
+ // Delete the Submodel
+ DeleteSubmodelFromAAS.deleteSubmodelFromAAS(smIdentifier, aasIdentifier, registryComponent.getRegistryPath());
+
+ // Get the AAS as ConnectedAAS
+ ConnectedAssetAdministrationShellManager manager = getManager();
+ IAssetAdministrationShell aas = manager.retrieveAAS(aasIdentifier);
+
+ // Try to retrieve deleted Submodel; should throw ResourceNotFoundException
+ try {
+ aas.getSubmodel(smIdentifier);
+ fail();
+ } catch (ResourceNotFoundException e) {
+ }
+
+ }
+
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestPushAASToServer.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestPushAASToServer.java
new file mode 100644
index 0000000..383db6f
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestPushAASToServer.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.manager;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.examples.support.ExampleComponentBuilder;
+import org.junit.Test;
+
+/**
+ * Test for the PushAASToServer snippet
+ *
+ * @author conradi
+ *
+ */
+public class TestPushAASToServer extends AbstractSnippetTest {
+
+ protected static final String NEW_AAS_ID_SHORT = "aasIdShort_New";
+ protected static final String NEW_AAS_ID = "aasId_New";
+
+ @Test
+ public void testPushAAS() throws Exception {
+
+ // Get the example AAS
+ AssetAdministrationShell aas = ExampleComponentBuilder.buildExampleAAS(NEW_AAS_ID_SHORT, NEW_AAS_ID);
+
+ // Push the AAS to the server
+ PushAASToServer.pushAAS(aas, aasComponent.getAASServerPath(), registryComponent.getRegistryPath());
+
+ // Check if the AAS is present on the server
+ ConnectedAssetAdministrationShellManager manager = getManager();
+ IAssetAdministrationShell remoteAAS = manager.retrieveAAS(aas.getIdentification());
+ assertEquals(NEW_AAS_ID_SHORT, remoteAAS.getIdShort());
+ }
+
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestRetrieveAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestRetrieveAAS.java
new file mode 100644
index 0000000..5cfd00f
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestRetrieveAAS.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.manager;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.junit.Test;
+
+/**
+ * Test for the RetrieveRemoteAAS snippet
+ *
+ * @author conradi
+ *
+ */
+public class TestRetrieveAAS extends AbstractSnippetTest {
+
+ @Test
+ public void testRetrieveRemoteAAS() {
+
+ // Get the Identifier of the example AAS
+ IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+
+ // Retrieve the AAS from the server
+ IAssetAdministrationShell remoteAAS =
+ RetrieveAAS.retrieveRemoteAAS(aasIdentifier, registryComponent.getRegistryPath());
+
+ // Check if the retrieved AAS can be used correctly
+ assertEquals(AAS_ID_SHORT, remoteAAS.getIdShort());
+ }
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestRetrieveSubmodelFromAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestRetrieveSubmodelFromAAS.java
new file mode 100644
index 0000000..2a12e39
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestRetrieveSubmodelFromAAS.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.manager;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.junit.Test;
+
+/**
+ * Test for the RetrieveSubmodelFromAAS snippet
+ *
+ * @author conradi
+ *
+ */
+public class TestRetrieveSubmodelFromAAS extends AbstractSnippetTest {
+
+
+ @Test
+ public void testRetrieveSubmodelFromAAS() {
+
+ // Get the Identifiers of the AAS and Submodel
+ IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+ IIdentifier smIdentifier = new Identifier(IdentifierType.CUSTOM, SM_ID);
+
+ // Get the Submodel from the server
+ ISubmodel remoteSubmodel = RetrieveSubmodelFromAAS.retrieveSubmodelFromAAS(
+ smIdentifier, aasIdentifier, registryComponent.getRegistryPath());
+
+ // Check if the Submodel can be used correctly
+ assertEquals(SM_ID_SHORT, remoteSubmodel.getIdShort());
+ }
+
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/property/TestCreateLambdaProperty.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/property/TestCreateLambdaProperty.java
new file mode 100644
index 0000000..a34153c
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/property/TestCreateLambdaProperty.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.property;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.CustomId;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.examples.snippets.submodel.HostPreconfiguredSubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.connected.ConnectedSubmodel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnector;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxHTTPServer;
+import org.junit.After;
+import org.junit.Test;
+
+/**
+ * Test for the CreateLambdaProperty snippet
+ *
+ * @author schnicke
+ *
+ */
+public class TestCreateLambdaProperty {
+
+ // Value to be facaded by the lambda property
+ private int testValue = 15;
+
+ // Used for test case tear down
+ private BaSyxHTTPServer server;
+
+ @Test
+ public void testCreateLambdaProperty() {
+ // The type cast in the setter is necessary due to the Consumer<Object> definition
+ Property lambdaProp = CreateLambdaProperty.createLambdaProperty("lambdaProp", ValueType.Integer, () -> testValue, (v) -> testValue = (int) v);
+
+ // Package it in a test submodel and host it
+ Submodel sm = new Submodel("testSubmodelIdShort", new CustomId("testSubmodelId"));
+ sm.addSubmodelElement(lambdaProp);
+
+ // Create the context configuration and host the submodel containg the lambda property
+ BaSyxContextConfiguration config = new BaSyxContextConfiguration(4040, "");
+ server = HostPreconfiguredSubmodel.hostPreconfiguredSubmodel(config, sm);
+
+ // Here, for simplicity reason of the test, the ConnectedSubmodel is created by hand.
+ // In a real-world application, the AASManager would be used instead.
+ String smPath = "http://localhost:4040/" + sm.getIdShort() + "/submodel";
+
+ ConnectedSubmodel cSm = new ConnectedSubmodel(new VABElementProxy("", new JSONConnector(new HTTPConnector(smPath))));
+ IProperty cLambdaProp = (IProperty) cSm.getSubmodelElement(lambdaProp.getIdShort());
+
+ // Test getting
+ assertEquals(testValue, cLambdaProp.getValue());
+
+ // Test setting
+ int newVal = 100;
+ cLambdaProp.setValue(newVal);
+ assertEquals(newVal, cLambdaProp.getValue());
+ assertEquals(newVal, testValue);
+ }
+
+ // Ensures that the started server is shut down regardless of test result
+ @After
+ public void tearDown() {
+ if (server != null) {
+ server.shutdown();
+ }
+ }
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestDeregisterAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestDeregisterAAS.java
new file mode 100644
index 0000000..b8ea95b
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestDeregisterAAS.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.registry;
+
+import static org.junit.Assert.fail;
+
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Test;
+
+/**
+ * Test for the DeregisterAAS Snippet
+ *
+ * @author conradi
+ *
+ */
+public class TestDeregisterAAS extends AbstractSnippetTest {
+
+ @Test
+ public void testDeregisterAAS() {
+
+ // Get the Identifier of the example AAS
+ IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+
+ DeregisterAAS.registerAAS(aasIdentifier, registryComponent.getRegistryPath());
+
+ // Lookup the AAS in the registry
+ AASRegistryProxy registry = new AASRegistryProxy(registryComponent.getRegistryPath());
+
+ try {
+ registry.lookupAAS(aasIdentifier);
+ fail();
+ } catch (ResourceNotFoundException e) {
+ }
+ }
+
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestDeregisterSubmodel.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestDeregisterSubmodel.java
new file mode 100644
index 0000000..ba106d4
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestDeregisterSubmodel.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.registry;
+
+import static org.junit.Assert.fail;
+
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Test;
+
+/**
+ * Test for the DeregisterSubmodel Snippet
+ *
+ * @author conradi
+ *
+ */
+public class TestDeregisterSubmodel extends AbstractSnippetTest {
+
+ @Test
+ public void testDeregisterSubmodel() {
+
+ // Get the Identifier of the example AAS
+ IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+ IIdentifier smIdentifier = new Identifier(IdentifierType.CUSTOM, SM_ID);
+
+ DeregisterSubmodel.registerSubmodel(smIdentifier, aasIdentifier, registryComponent.getRegistryPath());
+
+ // Lookup the AAS in the registry
+ AASRegistryProxy registry = new AASRegistryProxy(registryComponent.getRegistryPath());
+
+ try {
+ registry.lookupSubmodel(aasIdentifier, smIdentifier);
+ fail();
+ } catch (ResourceNotFoundException e) {
+ }
+ }
+
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestLookupAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestLookupAAS.java
new file mode 100644
index 0000000..8f06ac0
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestLookupAAS.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.registry;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.junit.Test;
+
+/**
+ * Test for the LookupAAS snippet
+ *
+ * @author conradi
+ *
+ */
+public class TestLookupAAS extends AbstractSnippetTest {
+
+ @Test
+ public void testLookupAAS() {
+
+ // Get the Identifier of the example AAS
+ IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+
+ // Lookup the AAS in the registry
+ AASDescriptor descriptor = LookupAAS.lookupAAS(aasIdentifier, registryComponent.getRegistryPath());
+
+ // Check if the returned Descriptor is as expected
+ assertEquals(AAS_ENDPOINT, descriptor.getFirstEndpoint());
+
+ }
+
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestLookupSubmodel.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestLookupSubmodel.java
new file mode 100644
index 0000000..f456fbc
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestLookupSubmodel.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.registry;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.junit.Test;
+
+/**
+ * Test for the LookupSubmodel snippet
+ *
+ * @author conradi
+ *
+ */
+public class TestLookupSubmodel extends AbstractSnippetTest {
+
+ @Test
+ public void testLookupSubmodel() {
+
+ // Get the Identifiers of the AAS and Submodel
+ IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+ IIdentifier smIdentifier = new Identifier(IdentifierType.CUSTOM, SM_ID);
+
+ // Lookup the Submodel in the registry
+ SubmodelDescriptor descriptor = LookupSubmodel.lookupSubmodel(
+ smIdentifier, aasIdentifier, registryComponent.getRegistryPath());
+
+ // Check if the returned Descriptor is as expected
+ assertEquals(SM_ENDPOINT, descriptor.getFirstEndpoint());
+
+ }
+
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestRegisterAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestRegisterAAS.java
new file mode 100644
index 0000000..fe42cdb
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestRegisterAAS.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.registry;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.examples.support.ExampleComponentBuilder;
+import org.junit.Test;
+
+/**
+ * Test for the RegisterAAS snippet
+ *
+ * @author conradi
+ *
+ */
+public class TestRegisterAAS extends AbstractSnippetTest {
+
+ protected static final String NEW_AAS_ID_SHORT = "aasIdShort_New";
+ protected static final String NEW_AAS_ID = "aasId_New";
+ protected static final String NEW_AAS_ENDPOINT = "http://localhost:8080/aasComponent/shells/" + NEW_AAS_ID + "/aas";
+
+ @Test
+ public void testRegisterAAS() {
+
+ // Get the example AAS
+ AssetAdministrationShell aas = ExampleComponentBuilder.buildExampleAAS(NEW_AAS_ID_SHORT, NEW_AAS_ID);
+
+ // Register this AAS
+ RegisterAAS.registerAAS(aas, NEW_AAS_ENDPOINT, registryComponent.getRegistryPath());
+
+ // Check if the AAS was correctly registered
+ AASRegistryProxy registryProxy = new AASRegistryProxy(registryComponent.getRegistryPath());
+ AASDescriptor descriptor = registryProxy.lookupAAS(aas.getIdentification());
+ assertEquals(NEW_AAS_ENDPOINT, descriptor.getFirstEndpoint());
+
+ }
+
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestRegisterSubmodel.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestRegisterSubmodel.java
new file mode 100644
index 0000000..e9b02ba
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestRegisterSubmodel.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.registry;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.examples.support.ExampleComponentBuilder;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.junit.Test;
+
+/**
+ * Test for the RegisterSubmodel snippet
+ *
+ * @author conradi
+ *
+ */
+public class TestRegisterSubmodel extends AbstractSnippetTest {
+
+ private static final String NEW_SM_ID_SHORT = "smIdShort_New";
+ private static final String NEW_SM_ID = "smId_New";
+ private static final String NEW_SM_ENDPOINT = "http://localhost:8080/aasComponent/" + NEW_SM_ID_SHORT + "/submodel";
+
+ @Test
+ public void testRegisterSubmodel() {
+
+ // Get the example AAS and Submodel
+ AssetAdministrationShell aas = ExampleComponentBuilder.buildExampleAAS(AAS_ID_SHORT, AAS_ID);
+ Submodel sm = ExampleComponentBuilder.buildExampleSubmodel(NEW_SM_ID_SHORT, NEW_SM_ID);
+
+ // Register this AAS
+ RegisterAAS.registerAAS(aas, AAS_ENDPOINT, registryComponent.getRegistryPath());
+
+ // Register this Submodel
+ RegisterSubmodel.registerSubmodel(sm, NEW_SM_ENDPOINT, aas.getIdentification(), registryComponent.getRegistryPath());
+
+ // Check if the Submodel was correctly registered
+ AASRegistryProxy registryProxy = new AASRegistryProxy(registryComponent.getRegistryPath());
+ SubmodelDescriptor descriptor = registryProxy.lookupSubmodel(aas.getIdentification(), sm.getIdentification());
+ assertEquals(NEW_SM_ENDPOINT, descriptor.getFirstEndpoint());
+
+ }
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestAddSubmodelElement.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestAddSubmodelElement.java
new file mode 100644
index 0000000..ae32c33
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestAddSubmodelElement.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.junit.Test;
+
+/**
+ * Test for the AddSubmodelElement snippet
+ *
+ * @author conradi
+ *
+ */
+public class TestAddSubmodelElement extends AbstractSnippetTest {
+
+ private static final String NEW_PROPERTY_ID = "new_prop";
+ private static final int NEW_PROPERTY_VALUE = 321;
+
+ @Test
+ public void testAddSubmodelElement() {
+
+ // Get the Identifiers of the AAS and Submodel
+ IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+ IIdentifier smIdentifier = new Identifier(IdentifierType.CUSTOM, SM_ID);
+
+ // Build a new SubmodelElement
+ Property newProperty = new Property();
+ newProperty.setIdShort(NEW_PROPERTY_ID);
+ newProperty.setValue(NEW_PROPERTY_VALUE);
+
+ // Add the new Element to the Submodel
+ AddSubmodelElement.addSubmodelElement(newProperty, smIdentifier, aasIdentifier, registryComponent.getRegistryPath());
+
+ // Get the Element from the server
+ ConnectedAssetAdministrationShellManager manager = getManager();
+ ISubmodel remoteSubmodel = manager.retrieveSubmodel(aasIdentifier, smIdentifier);
+ ISubmodelElement remoteElement = remoteSubmodel.getSubmodelElement(NEW_PROPERTY_ID);
+
+ // Check if its value is as expected
+ assertEquals(NEW_PROPERTY_VALUE, remoteElement.getValue());
+ }
+
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestCreateSubmodel.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestCreateSubmodel.java
new file mode 100644
index 0000000..f6a71c2
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestCreateSubmodel.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.junit.Test;
+
+/**
+ * Test for the CreateSubmodel snippet
+ *
+ * @author conradi
+ *
+ */
+public class TestCreateSubmodel extends AbstractSnippetTest {
+
+ private static final String SM_ID_SHORT = "smIdShort";
+ private static final String SM_ID = "smId";
+
+ private static final String PROPERTY_ID_SHORT = "propIdShort";
+ private static final String PROPERTY_VALUE = "value";
+
+
+ @Test
+ public void testCreateSubmodel() {
+
+ // Create a Submodel
+ Submodel sm = CreateSubmodel.createSubmodel(SM_ID_SHORT, new Identifier(IdentifierType.CUSTOM, SM_ID), PROPERTY_ID_SHORT, PROPERTY_VALUE);
+
+ // Check the created Submodel
+ assertEquals(SM_ID_SHORT, sm.getIdShort());
+ assertEquals(SM_ID, sm.getIdentification().getId());
+
+ // Get the Property from the Submodel
+ // This will throw an Exception if an Element with the given Id does not exist
+ ISubmodelElement property = sm.getSubmodelElement(PROPERTY_ID_SHORT);
+
+ // Check the Property
+ assertEquals(property.getIdShort(), PROPERTY_ID_SHORT);
+ assertEquals(property.getValue(), PROPERTY_VALUE);
+ }
+
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestDeleteSubmodelElement.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestDeleteSubmodelElement.java
new file mode 100644
index 0000000..e54c605
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestDeleteSubmodelElement.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import static org.junit.Assert.fail;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.examples.support.ExampleComponentBuilder;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Test;
+
+/**
+ * Test for the DeleteSubmodelElement snippet
+ *
+ * @author conradi
+ *
+ */
+public class TestDeleteSubmodelElement extends AbstractSnippetTest {
+
+ @Test
+ public void testDeleteSubmodelElement() {
+
+ // Get the Identifier of the example AAS and Submodel
+ IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+ IIdentifier smIdentifier = new Identifier(IdentifierType.CUSTOM, SM_ID);
+
+ // Delete the SubmodelElement
+ DeleteSubmodelElement.deleteSubmodelElement(ExampleComponentBuilder.PROPERTY_ID, smIdentifier, aasIdentifier, registryComponent.getRegistryPath());
+
+ // Create a proxy pointing to the registry server
+ AASRegistryProxy registryProxy = new AASRegistryProxy(registryComponent.getRegistryPath());
+
+ // Create a ConnectedAASManager using the registryProxy as its registry
+ ConnectedAssetAdministrationShellManager manager =
+ new ConnectedAssetAdministrationShellManager(registryProxy);
+
+ // Retrieve the Submodel from the server as a ConnectedSubmodel
+ ISubmodel submodel = manager.retrieveSubmodel(aasIdentifier, smIdentifier);
+
+ // Try to retrieve deleted SubmodelElement; should throw ResourceNotFoundException
+ try {
+ submodel.getSubmodelElement(ExampleComponentBuilder.PROPERTY_ID);
+ fail();
+ } catch (ResourceNotFoundException e) {
+ }
+
+ }
+
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestExecuteOperation.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestExecuteOperation.java
new file mode 100644
index 0000000..e532841
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestExecuteOperation.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.function.Function;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.components.servlet.submodel.SubmodelServlet;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.examples.support.ExampleComponentBuilder;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxHTTPServer;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
+import org.junit.After;
+import org.junit.Test;
+
+/**
+ * Test for the ExecuteOperation snippet
+ *
+ * @author conradi
+ *
+ */
+public class TestExecuteOperation extends AbstractSnippetTest {
+
+ private static final String NEW_SM_ID_SHORT = "smIdShort_New";
+ private static final String NEW_SM_ID = "smId_New";
+
+ private static final String OPERATION_ID = "operation";
+
+ private static final Object[] PARAMETERS = {2, 3};
+ private static final int EXPECTED_RESULT = 5;
+
+ private BaSyxHTTPServer server;
+
+ @After
+ public void shutdownServer() {
+ server.shutdown();
+ }
+
+ @Test
+ public void testExecuteOperation() throws Exception {
+
+ Submodel submodel = ExampleComponentBuilder.buildExampleSubmodel(NEW_SM_ID_SHORT, NEW_SM_ID);
+
+ // Add an Operation which calculates the sum of the two parameters
+ Operation operation = new Operation((Function<Object[], Object>) v -> {
+ return (int) v[0] + (int) v[1];
+ });
+ OperationVariable a = new OperationVariable(new Property("a", 1));
+ OperationVariable b = new OperationVariable(new Property("b", 2));
+ OperationVariable r = new OperationVariable(new Property("r", 3));
+ operation.setInputVariables(Arrays.asList(a, b));
+ operation.setOutputVariables(Collections.singletonList(r));
+ operation.setIdShort(OPERATION_ID);
+ submodel.addSubmodelElement(operation);
+
+ // Startup a Server hosting this Submodel
+ provideSubmodel(submodel);
+
+
+ // Get the Identifiers of the AAS and Submodel
+ IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+ IIdentifier smIdentifier = new Identifier(IdentifierType.CUSTOM, NEW_SM_ID);
+
+ // Execute the Operation and get the result
+ Object result = ExecuteOperation.executeOperation(OPERATION_ID, PARAMETERS, smIdentifier, aasIdentifier, registryComponent.getRegistryPath());
+
+ // Check if the result is the expected value
+ assertEquals(EXPECTED_RESULT, result);
+
+ }
+
+ /**
+ * Starts a new server hosting a given Submodel
+ * This is necessary as an Operation can not be transfered to a server via serialization
+ *
+ * @param submodel the Submodel to be hosted
+ */
+ private void provideSubmodel(Submodel submodel) {
+ // Create a BaSyxConetxt for port 8082 with an empty endpoint
+ BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration(8082, "");
+ BaSyxContext context = contextConfig.createBaSyxContext();
+
+ // Create a new SubmodelServlet containing the submodel
+ SubmodelServlet smServlet = new SubmodelServlet(submodel);
+
+ // Add the SubmodelServlet mapping to the context at the path "/submodel"
+ context.addServletMapping("/submodel/*", smServlet);
+
+
+ // Create and start a HTTP server with the context created above
+ server = new BaSyxHTTPServer(context);
+ server.start();
+
+ IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+ SubmodelDescriptor descriptor = new SubmodelDescriptor(submodel, "http://localhost:8082/submodel");
+
+ // Register the new Submodel
+ AASRegistryProxy registry = new AASRegistryProxy(registryComponent.getRegistryPath());
+ registry.register(aasIdentifier, descriptor);
+ }
+
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestHostPreconfiguredSubmodel.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestHostPreconfiguredSubmodel.java
new file mode 100644
index 0000000..7be629b
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestHostPreconfiguredSubmodel.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.submodel;
+
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.CustomId;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.submodel.metamodel.connected.ConnectedSubmodel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnector;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxHTTPServer;
+import org.junit.After;
+import org.junit.Test;
+
+/**
+ * Test for the HostPreconfiguredSubmodel snippet
+ *
+ * @author schnicke
+ *
+ */
+public class TestHostPreconfiguredSubmodel {
+
+ // Used for test case tear down
+ private BaSyxHTTPServer server;
+
+ @Test
+ public void testHostPreconfiguredSubmodel() {
+ Submodel sm = new Submodel("testSubmodelIdShort", new CustomId("testSubmodel"));
+ BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration(4040, "");
+ server = HostPreconfiguredSubmodel.hostPreconfiguredSubmodel(contextConfig, sm);
+ String smPath = "http://localhost:4040/" + sm.getIdShort() + "/submodel";
+
+ // Here, for simplicity reason of the test, the ConnectedSubmodel is created by hand.
+ // In a real-world application, the AASManager would be used instead.
+ ConnectedSubmodel cSm = new ConnectedSubmodel(new VABElementProxy("", new JSONConnector(new HTTPConnector(smPath))));
+ assertEquals(sm.getIdentification(), cSm.getIdentification());
+ }
+
+ // Ensures that the started server is shut down regardless of test result
+ @After
+ public void tearDown() {
+ if (server != null) {
+ server.shutdown();
+ }
+ }
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestRetrieveSubmodelElement.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestRetrieveSubmodelElement.java
new file mode 100644
index 0000000..c8b6deb
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestRetrieveSubmodelElement.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.examples.support.ExampleComponentBuilder;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.junit.Test;
+
+/**
+ * Test for the RetrieveSubmodelElement snippet
+ *
+ * @author conradi
+ *
+ */
+public class TestRetrieveSubmodelElement extends AbstractSnippetTest {
+
+
+ @Test
+ public void testRetrieveSubmodelElement() {
+
+ // Get the Identifiers of the AAS and Submodel
+ IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+ IIdentifier smIdentifier = new Identifier(IdentifierType.CUSTOM, SM_ID);
+
+ // Get the idShort and value of the element to be retrieved
+ String elementId = ExampleComponentBuilder.PROPERTY_ID;
+ int elementValue = ExampleComponentBuilder.PROPERTY_VALUE;
+
+ // Get the SubmodelElement
+ ISubmodelElement element = RetrieveSubmodelElement.retrieveSubmodelElement(
+ elementId, smIdentifier, aasIdentifier, registryComponent.getRegistryPath());
+
+ // Check if the SubmodelElement contains the expected value
+ assertEquals(elementValue, element.getValue());
+ }
+
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/code/BaSyxCreateProvideUseExampleAASSubmodel.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/code/BaSyxCreateProvideUseExampleAASSubmodel.java
deleted file mode 100644
index dc700af..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/code/BaSyxCreateProvideUseExampleAASSubmodel.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package org.eclipse.basyx.examples.snippets.undoc.aas.code;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Map;
-
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
-import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnector;
-import org.eclipse.basyx.vab.protocol.basyx.server.BaSyxTCPServer;
-import org.junit.Test;
-
-/**
- * Illustrate manual creation and providing of AAS sub model
- *
- * @author kuhn
- *
- */
-public class BaSyxCreateProvideUseExampleAASSubmodel {
-
-
- /**
- * Create, export, and access an example AAS sub model
- */
- @SuppressWarnings("unchecked")
- @Test
- public void createExportAndAccessSubModel() throws Exception {
-
- // Create sub model and add properties
- SubModel statusSM = new SubModel();
- // - Property status: indicate device status
- Property statusProp = new Property("offline");
- statusProp.setIdShort("status");
- statusSM.addSubModelElement(statusProp);
- // - Property statistics: export invocation statistics for every service
- // - invocations: indicate total service invocations. Properties are not persisted in this example,
- // therefore we start counting always at 0.
- Property invocationsProp = new Property(0);
- invocationsProp.setIdShort("invocations");
- statusSM.addSubModelElement(invocationsProp);
-
-
- // Provide sub model via BaSyx server
- BaSyxTCPServer<SubModelProvider> server = new BaSyxTCPServer<>(new SubModelProvider(statusSM), 9998);
- // - Start local BaSyx/TCP server
- server.start();
-
-
- // Access BaSyx TCP server
- // - Create BaSyx connector to connect with the sub model
- BaSyxConnector basyxConnector = new BaSyxConnector("localhost", 9998);
- // - Create connection to device manager
- JSONConnector toDeviceManager = new JSONConnector(basyxConnector);
- // - Access sub model property, check value
- Map<String, Object> property = (Map<String, Object>) toDeviceManager
- .getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/status");
- assertEquals("offline", property.get("value"));
-
-
- // Stop local BaSyx/TCP server
- server.stop();
- }
-}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnection.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnection.java
deleted file mode 100644
index 59b886f..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnection.java
+++ /dev/null
@@ -1,142 +0,0 @@
-package org.eclipse.basyx.examples.snippets.undoc.aas.connection.servlet;
-
-import static org.junit.Assert.assertTrue;
-
-import java.util.Map;
-
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.components.servlet.submodel.SubmodelServlet;
-import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_Empty;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExampleAASRegistry;
-import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-/**
- * Export sub model through a servlet and connect to that servlet
- *
- * @author kuhn
- *
- */
-public class AASServletConnection {
-
-
- /**
- * Example sub model. This example sub model is created with the BaSyx SDK factory and defines the AAS meta model properties
- */
- static class SampleSubModelFactory extends SubModel {
- /**
- * Constructor - create sub model property
- */
- @SuppressWarnings("unchecked")
- public SampleSubModelFactory() {
- // Set sub model ID
- setIdShort("sm-001");
-
- // Add example properties
- // - Add simple property
- Property prop1 = new Property(234);
- prop1.setIdShort("prop1");
- addSubModelElement(prop1);
-
- Property prop11 = new Property(123);
- prop11.setIdShort("prop11");
- // - Add container property that holds other properties
- SubmodelElementCollection container = new SubmodelElementCollection();
- container.setIdShort("prop2");
- container.addElement(prop11);
- // - Add container to property map
- addSubModelElement(container);
-
- // Add another property manually to sub model container "properties"
- Property prop3 = new Property(17);
- prop3.setIdShort("prop3");
- {
- ((Map<String, Object>) this.get("submodelElements")).put("prop3", prop3);
- }
- }
- }
-
- /**
- * Create manager using the directory stub an the HTTPConnectorProvider
- */
- ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(
- // Add example specific mappings
- new ExampleAASRegistry()
- .addAASMapping("aas-001", "") // No AAS is provided in this example
- .addSubmodelMapping("aas-001", "sm-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/"),
- // We connect via HTTP
- new HTTPConnectorProvider());
-
-
-
- /**
- * VAB connection manager backend
- */
- protected VABConnectionManager connManager = new VABConnectionManager(
- // Add example specific mappings
- new ExamplesPreconfiguredDirectory()
- // - VAB needs to know the relative path of the sub model that is defined by AAS meta model
- .addMapping("sm-001VAB", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/"),
- // We connect via HTTP
- new HTTPConnectorProvider());
-
-
-
- /**
- * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
- * components on the IP address of the host. Therefore, all components use the same IP address.
- */
- @ClassRule
- public static BaSyxDeployment context = new BaSyxDeployment(
- // Servlets for example snippet
- new BaSyxExamplesContext_Empty().
- // Deploy example specific servlets to Tomcat server in this context
- addServletMapping("/Testsuite/components/BaSys/1.0/SampleModel/*", new SubmodelServlet(new SampleSubModelFactory())));
-
-
- /**
- * Connect to sub model, query, and set property values
- */
- @Test @SuppressWarnings("unchecked")
- public void accessSubModel() throws Exception {
- // Create and connect SDK connector
- ISubModel subModel = manager.retrieveSubModel(new ModelUrn("aas-001"), new ModelUrn("sm-001"));
- // - Retrieve sub model values and compare to expected values
- assertTrue(subModel.getIdShort().equals("sm-001"));
- assertTrue(subModel.getProperties().get("prop1").getIdShort().equals("prop1"));
- assertTrue((int) subModel.getProperties().get("prop1").get() == 234);
- assertTrue((int) subModel.getProperties().get("prop3").get() == 17);
- assertTrue(subModel.getSubmodelElements().get("prop2").getIdShort().equals("prop2"));
- assertTrue((int) ((ISubmodelElementCollection) subModel.getSubmodelElements().get("prop2")).getProperties().get("prop11").get() == 123);
-
- // Connect to sub model using lower-level VAB interface
- VABElementProxy connSubModel1 = this.connManager.connectToVABElement("sm-001VAB");
- // - Read property values and compare with expected values
- assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1")).get("value") == 234);
- assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop3")).get("value") == 17);
- assertTrue(((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1")).get("idShort").equals("prop1"));
- assertTrue(((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop2")).get("idShort").equals("prop2"));
- assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue("submodelElements/prop2/prop11")).get("value") == 123);
- // - Change property value using VAB primitive
- connSubModel1.setModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1/value", 456);
- // - Read value back using VAB primitive
- assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1")).get("value") == 456);
-
- // Read changed value back using SDK connector
- assertTrue((int) subModel.getProperties().get("prop1").get() == 456);
- }
-}
-
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnectionFull.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnectionFull.java
deleted file mode 100644
index 9e919e8..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnectionFull.java
+++ /dev/null
@@ -1,150 +0,0 @@
-package org.eclipse.basyx.examples.snippets.undoc.aas.connection.servlet;
-
-import static org.junit.Assert.assertTrue;
-
-import java.util.Map;
-
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.components.servlet.submodel.SubmodelServlet;
-import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_Empty;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExampleAASRegistry;
-import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-
-/**
- * Export sub model through a servlet and connect to that servlet
- *
- * @author kuhn
- *
- */
-public class AASServletConnectionFull {
-
-
- /**
- * Example sub model. This example sub model is created with the BaSyx SDK factory and defines the AAS meta model properties
- */
- static class SampleSubModelFactory extends SubModel {
-
- /**
- * Constructor - create sub model property
- */
- @SuppressWarnings("unchecked")
- public SampleSubModelFactory() {
- // Set sub model ID
- setIdShort("sm-001");
-
- // Add example properties
- // - Add simple property
- Property prop1 = new Property(234);
- prop1.setIdShort("prop1");
- addSubModelElement(prop1);
-
- Property prop11 = new Property(123);
- prop11.setIdShort("prop11");
- // - Add container property that holds other properties
- SubmodelElementCollection container = new SubmodelElementCollection();
- container.setIdShort("prop2");
- container.addElement(prop11);
- // - Add container to property map
- addSubModelElement(container);
-
- // Add another property manually to sub model container "properties"
- Property prop3 = new Property(17);
- prop3.setIdShort("prop3");
- {
- ((Map<String, Object>) this.get("submodelElements")).put("prop3", prop3);
- }
- }
- }
-
- /**
- * VAB connection manager backend
- */
- protected VABConnectionManager connManager = new VABConnectionManager(
- // Add example specific mappings
- new ExamplesPreconfiguredDirectory()
- // - VAB needs to know the relative path of the sub model that is defined by AAS
- // meta model
- .addMapping("sm-001VAB", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/")
- // - VAB needs to know the relative path of the sub model that is defined by AAS
- // meta model
- .addMapping("sm-001MVAB", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModelManual/"),
- // We connect via HTTP
- new HTTPConnectorProvider());
-
-
-
- /**
- * VAB connection manager backend
- */
- protected ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(
- // Add example specific mappings
- new ExampleAASRegistry()
- .addAASMapping("aas-001", "") // no AAS is provided in this example
- .addSubmodelMapping("aas-001", "sm-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/"),
- // We connect via HTTP
- new HTTPConnectorProvider());
-
-
-
- /**
- * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
- * components on the IP address of the host. Therefore, all components use the same IP address.
- */
- @ClassRule
- public static BaSyxDeployment context = new BaSyxDeployment(
- // Servlets for example snippet
- new BaSyxExamplesContext_Empty().
- // Deploy example specific servlets to Tomcat server in this context
- addServletMapping("/Testsuite/components/BaSys/1.0/SampleModel/*", new SubmodelServlet(new SampleSubModelFactory())));
-
-
- /**
- * Connect to sub model, query, and set property values
- */
- @Test @SuppressWarnings("unchecked")
- public void accessSubModel() throws Exception {
- // Create and connect SDK connector
- ISubModel subModel = manager.retrieveSubModel(new ModelUrn("aas-001"), new ModelUrn("sm-001"));
- // - Retrieve sub model values and compare to expected values
- assertTrue(subModel.getIdShort().equals("sm-001"));
- assertTrue(subModel.getProperties().get("prop1").getIdShort().equals("prop1"));
- assertTrue((int) subModel.getProperties().get("prop1").get() == 234);
- assertTrue((int) subModel.getProperties().get("prop3").get() == 17);
- assertTrue(subModel.getSubmodelElements().get("prop2").getIdShort().equals("prop2"));
- assertTrue((int) ((ISubmodelElementCollection) subModel.getSubmodelElements().get("prop2")).getProperties().get("prop11").get() == 123);
-
-
- // Connect to sub model using lower-level VAB interface
- VABElementProxy connSubModel1 = this.connManager.connectToVABElement("sm-001VAB");
- // - Read property values and compare with expected values
- assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1")).get("value") == 234);
- assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop3")).get("value") == 17);
- assertTrue(((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1")).get("idShort").equals("prop1"));
- assertTrue(((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop2")).get("idShort").equals("prop2"));
- assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue("submodelElements/prop2/prop11")).get("value") == 123);
- // - Change property value using VAB primitive
- connSubModel1.setModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1/value", 456);
- // - Read value back using VAB primitive
- assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1")).get("value") == 456);
-
- // Read changed value back using SDK connector
- assertTrue((int) subModel.getProperties().get("prop1").get() == 456);
- }
-}
-
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletConnectorConnection.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletConnectorConnection.java
deleted file mode 100644
index d3f4e0e..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletConnectorConnection.java
+++ /dev/null
@@ -1,133 +0,0 @@
-package org.eclipse.basyx.examples.snippets.undoc.aas.connection.servlet;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Map;
-
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.components.servlet.submodel.SubmodelServlet;
-import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_Empty;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExampleAASRegistry;
-import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-
-/**
- * Export sub model through a servlet and connect to that servlet
- *
- * @author kuhn
- *
- */
-public class AASSubModelServletConnectorConnection {
-
-
- /**
- * Example sub model. This example sub model is created with the BaSyx SDK factory and defines the AAS meta model properties
- */
- static class SampleSubModel extends SubModel {
- /**
- * Constructor - create sub model property
- */
- @SuppressWarnings("unchecked")
- public SampleSubModel() {
- // Set sub model ID
- setIdShort("sm-001");
-
- // Add example properties
- // - Add simple property
- Property prop1 = new Property(234);
- prop1.setIdShort("prop1");
- addSubModelElement(prop1);
-
- Property prop11 = new Property(123);
- prop11.setIdShort("prop11");
- // - Add container property that holds other properties
- SubmodelElementCollection container = new SubmodelElementCollection();
- container.setIdShort("prop2");
- container.addElement(prop11);
- // - Add container to property map
- addSubModelElement(container);
-
- // Add another property manually to sub model container "properties"
- Property prop3 = new Property(17);
- prop3.setIdShort("prop3");
- {
- ((Map<String, Object>) this.get("submodelElements")).put("prop3", prop3);
- }
- }
- }
-
- /**
- * Create manager using the directory stub an the HTTPConnectorProvider
- */
- ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(
- // Add example specific mappings
- new ExampleAASRegistry()
- // - SDK connectors encapsulate relative path to sub model (/aas/submodels/sm-001)
- .addAASMapping("aas-001", "") // No AAS is provided in this example
- .addSubmodelMapping("aas-001", "sm-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel"),
- // We connect via HTTP
- new HTTPConnectorProvider());
-
- /**
- * VAB connection manager backend
- */
- protected VABConnectionManager connManager = new VABConnectionManager(
- // Add example specific mappings
- new ExamplesPreconfiguredDirectory()
- // - VAB needs to know the relative path of the sub model that is defined by AAS meta model
- .addMapping("sm-001VAB", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/aas/submodels/sm-001"),
- // We connect via HTTP
- new HTTPConnectorProvider());
-
-
-
- /**
- * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
- * components on the IP address of the host. Therefore, all components use the same IP address.
- */
- @ClassRule
- public static BaSyxDeployment context = new BaSyxDeployment(
- // Servlets for example snippet
- new BaSyxExamplesContext_Empty().
- // Deploy example specific servlets to Tomcat server in this context
- addServletMapping("/Testsuite/components/BaSys/1.0/SampleModel/*", new SubmodelServlet(new SampleSubModel()))
- );
-
-
- /**
- * Application code: Connect to sub model, query, and set property values
- */
- @Test
- public void accessSubModel() throws Exception {
-
- // Create and connect SDK connector
- ISubModel subModel = manager.retrieveSubModel(new ModelUrn("aas-001"), new ModelUrn("sm-001"));
-
- // - Retrieve sub model values and compare to expected values
- assertTrue(subModel.getIdShort().equals("sm-001"));
- assertTrue(subModel.getProperties().get("prop1").getIdShort().equals("prop1"));
- assertTrue((int) subModel.getProperties().get("prop1").get() == 234);
- assertTrue((int) subModel.getProperties().get("prop3").get() == 17);
-
- ISubmodelElementCollection prop2 = (ISubmodelElementCollection) subModel.getSubmodelElements().get("prop2");
- assertEquals("prop2", prop2.getIdShort());
- Map<String, IProperty> properties = prop2.getProperties();
- assertEquals(123, properties.get("prop11").get());
- }
-}
-
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletVABConnection.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletVABConnection.java
deleted file mode 100644
index 6138225..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletVABConnection.java
+++ /dev/null
@@ -1,118 +0,0 @@
-package org.eclipse.basyx.examples.snippets.undoc.aas.connection.servlet;
-
-import static org.junit.Assert.assertTrue;
-
-import java.util.Map;
-
-import org.eclipse.basyx.components.servlet.submodel.SubmodelServlet;
-import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_Empty;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-
-/**
- * Export sub model through a servlet and connect to that servlet
- *
- * @author kuhn
- *
- */
-public class AASSubModelServletVABConnection {
-
-
- /**
- * Example sub model. This example sub model is created with the BaSyx SDK factory and defines the AAS meta model properties
- */
- static class SampleSubModel extends SubModel {
- /**
- * Constructor - create sub model property
- */
- @SuppressWarnings("unchecked")
- public SampleSubModel() {
- // Set sub model ID
- setIdShort("sm-001");
-
- // Add example properties
- // - Add simple property
- Property prop1 = new Property(234);
- prop1.setIdShort("prop1");
- addSubModelElement(prop1);
-
- Property prop11 = new Property(123);
- prop11.setIdShort("prop11");
- // - Add container property that holds other properties
- SubmodelElementCollection container = new SubmodelElementCollection();
- container.setIdShort("prop2");
- container.addElement(prop11);
- // - Add container to property map
- addSubModelElement(container);
-
- // Add another property manually to sub model container "properties"
- Property prop3 = new Property(17);
- prop3.setIdShort("prop3");
- {
- ((Map<String, Object>) this.get("submodelElements")).put("prop3", prop3);
- }
- }
- }
-
-
-
- /**
- * VAB connection manager backend
- */
- protected VABConnectionManager connManager = new VABConnectionManager(
- // Add example specific mappings
- new ExamplesPreconfiguredDirectory()
- // Entries map directly at the SubmodelServlet
- .addMapping("aas-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel")
- .addMapping("sm-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel")
- .addMapping("sm-001VAB", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel"),
- // We connect via HTTP
- new HTTPConnectorProvider());
-
-
-
- /**
- * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
- * components on the IP address of the host. Therefore, all components use the same IP address.
- */
- @ClassRule
- public static BaSyxDeployment context = new BaSyxDeployment(
- // Servlets for example snippet
- new BaSyxExamplesContext_Empty().
- // Deploy example specific servlets to Tomcat server in this context
- addServletMapping("/Testsuite/components/BaSys/1.0/SampleModel/*", new SubmodelServlet(new SampleSubModel()))
- );
-
-
- /**
- * Connect to sub model, query, and set property values
- */
- @Test @SuppressWarnings("unchecked")
- public void accessSubModel() throws Exception {
- // Connect to sub model using lower-level VAB interface
- VABElementProxy connSubModel1 = this.connManager.connectToVABElement("sm-001VAB");
- // - Read property values and compare with expected values
- assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1")).get("value") == 234);
- assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop3")).get("value") == 17);
- assertTrue(((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1")).get("idShort").equals("prop1"));
- assertTrue(((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop2")).get("idShort").equals("prop2"));
- assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue("submodelElements/prop2/prop11/value")).get("value") == 123);
- // - Change property value using VAB primitive
- connSubModel1.setModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1/value", 456);
- // - Read value back using VAB primitive
- assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1/value")).get("value") == 456);
- }
-}
-
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASDynamicOperationSnippet.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASDynamicOperationSnippet.java
deleted file mode 100644
index cd59adf..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASDynamicOperationSnippet.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package org.eclipse.basyx.examples.snippets.undoc.aas.dynamic;
-
-import static org.junit.Assert.assertTrue;
-
-import java.io.Serializable;
-import java.util.Map;
-import java.util.function.Supplier;
-
-import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
-import org.eclipse.basyx.examples.TestContext;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProviderHelper;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-
-/**
- * Illustrate the dynamic deployment of AAS operations
- *
- * @author kuhn
- *
- */
-public class RunAASDynamicOperationSnippet {
-
-
- /**
- * VAB connection manager backend
- */
- protected VABConnectionManager connManager = new VABConnectionManager(
- new ExamplesPreconfiguredDirectory()
- // Add example specific mappings
- .addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
- new HTTPConnectorProvider());
-
-
- /**
- * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
- * components on the IP address of the host. Therefore, all components use the same IP address.
- */
- @ClassRule
- public static BaSyxDeployment context = new BaSyxDeployment(
- // Simulated servlets
- // - BaSys topology with one AAS Server and one SQL directory
- TestContext.sqlContext.
- // Deploy example specific servlets to Tomcat server in this context
- addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
- );
-
-
-
-
- /**
- * Test basic queries
- */
- @Test
- public void snippet() throws Exception {
-
- // Server connections
- // - Connect to device (VAB object)
- VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
-
-
- // Create properties on AAS
-
- // - Add example properties
- SubModel submodel = new SubModel();
- submodel.setIdShort("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
- Property prop1 = new Property(7);
- prop1.setIdShort("prop1");
- submodel.addSubModelElement(prop1);
-
- Property prop2 = new Property("myStr");
- prop2.setIdShort("prop2");
- submodel.addSubModelElement(prop2);
- // - Transfer sub model to server
- connSubModel1.setModelPropertyValue("/", submodel);
-
-
- // Read property values
- String prop2Val = (String) connSubModel1.getModelPropertyValue("submodelElements/prop2/value");
- // - Check property values
- assertTrue(prop2Val.equals("myStr"));
-
-
- // Create dynamic get/set operation as lambda expression
- Map<String, Object> dynamicPropertyVal = VABLambdaProviderHelper.createSimple((Supplier<Object> & Serializable) () -> {
- return "dynamicExampleValue";
- }, null);
- // - Update property properties/dynamicExample with dynamic get/set operation
- connSubModel1.setModelPropertyValue("submodelElements/prop2/value", dynamicPropertyVal);
-
-
- // Read dynamicExample property
- prop2Val = (String) connSubModel1.getModelPropertyValue("submodelElements/prop2/value");
- // - Check property values
- assertTrue(prop2Val.equals("dynamicExampleValue"));
- }
-}
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASManualHTTPOperationsSnippet.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASManualHTTPOperationsSnippet.java
deleted file mode 100644
index 8da4b52..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASManualHTTPOperationsSnippet.java
+++ /dev/null
@@ -1,99 +0,0 @@
-package org.eclipse.basyx.examples.snippets.undoc.aas.dynamic;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Map;
-
-import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
-import org.eclipse.basyx.examples.TestContext;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.tools.webserviceclient.WebServiceJSONClient;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-
-/**
- * Illustrate the use of AAS operations using HTTP REST calls
- *
- * @author kuhn
- *
- */
-public class RunAASManualHTTPOperationsSnippet {
-
-
- /**
- * VAB connection manager backend
- */
- protected VABConnectionManager connManager = new VABConnectionManager(
- new ExamplesPreconfiguredDirectory()
- // Add example specific mappings
- .addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
- new HTTPConnectorProvider());
-
-
- /**
- * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
- * components on the IP address of the host. Therefore, all components use the same IP address.
- */
- @ClassRule
- public static BaSyxDeployment context = new BaSyxDeployment(
- // Simulated servlets
- // - BaSys topology with one AAS Server and one SQL directory
- TestContext.sqlContext.
- // Deploy example specific servlets to Tomcat server in this context
- addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
- );
-
-
-
-
- /**
- * Test basic queries
- */
- @Test @SuppressWarnings("unchecked")
- public void snippet() throws Exception {
-
- // Server connections
- // - Connect to device (VAB object)
- VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
-
- int prop1Val = 7;
- String prop1IdShort = "prop1";
- String prop2Val = "myStr";
- // Add example properties
- SubModel submodel = new SubModel();
- submodel.setIdShort("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
- Property prop1 = new Property(prop1Val);
- prop1.setIdShort(prop1IdShort);
- submodel.addSubModelElement(prop1);
-
- Property prop2 = new Property(prop2Val);
- prop2.setIdShort("prop2");
- submodel.addSubModelElement(prop2);
-
- // Transfer sub model to server
- connSubModel1.setModelPropertyValue("/", submodel);
-
- // Web service client accesses AAS using HTTP REST calls
- WebServiceJSONClient jsonClient = new WebServiceJSONClient();
-
- // Read property values
- // - Use WebServiceJSONClient class. Returned property contains meta data. The actual property is stored in property "entity", property value is in entity property "value"
- int retrievedProp1Val = (int) ((Map<String, Object>) jsonClient.get("http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/submodelElements/prop1")).get("value");
- String retrievedProp1Id = (String) ((Map<String, Object>) jsonClient.get("http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/submodelElements/prop1")).get("idShort");
- String retrievedProp2Val = (String) ((Map<String, Object>) jsonClient.get("http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/submodelElements/prop2")).get("value");
-
- // Check results
- assertEquals(prop1Val, retrievedProp1Val);
- assertEquals(prop1IdShort, retrievedProp1Id);
- assertEquals(prop2Val, retrievedProp2Val);
- }
-}
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASPropertiesCRUDAccessSnippet.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASPropertiesCRUDAccessSnippet.java
deleted file mode 100644
index 74adbfa..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASPropertiesCRUDAccessSnippet.java
+++ /dev/null
@@ -1,114 +0,0 @@
-package org.eclipse.basyx.examples.snippets.undoc.aas.dynamic;
-
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
-import org.eclipse.basyx.examples.TestContext;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-
-/**
- * Illustrate the use of AAS operations
- *
- * @author kuhn
- *
- */
-public class RunAASPropertiesCRUDAccessSnippet {
-
-
- /**
- * VAB connection manager backend
- */
- protected VABConnectionManager connManager = new VABConnectionManager(
- new ExamplesPreconfiguredDirectory()
- // Add example specific mappings
- .addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
- new HTTPConnectorProvider());
-
-
- /**
- * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
- * components on the IP address of the host. Therefore, all components use the same IP address.
- */
- @ClassRule
- public static BaSyxDeployment context = new BaSyxDeployment(
- // Simulated servlets
- // - BaSys topology with one AAS Server and one SQL directory
- TestContext.sqlContext.
- // Deploy example specific servlets to Tomcat server in this context
- addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
- );
-
-
-
-
- /**
- * Test basic queries
- */
- @Test
- public void snippet() throws Exception {
-
- // Server connections
- // - Connect to device (VAB object)
- VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
-
-
- // Create properties on AAS
- // - Add example properties
- SubModel submodel = new SubModel();
- submodel.setIdShort("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
- Property prop1 = new Property(7);
- prop1.setIdShort("prop1");
- submodel.addSubModelElement(prop1);
-
- Property prop2 = new Property("myStr");
- prop2.setIdShort("prop2");
- submodel.addSubModelElement(prop2);
- // - Transfer sub model to server
- connSubModel1.setModelPropertyValue("/", submodel);
-
- // Read property values
- int prop1Val = (int) connSubModel1.getModelPropertyValue("submodelElements/prop1/value");
- String prop2Val = (String) connSubModel1.getModelPropertyValue("submodelElements/prop2/value");
- // - Check property values
- assertTrue(prop1Val == 7);
- assertTrue(prop2Val.equals("myStr"));
-
- // Update property values
- connSubModel1.setModelPropertyValue("submodelElements/prop1/value", 8);
- connSubModel1.setModelPropertyValue("submodelElements/prop2/value", "stillMine");
-
- // Read property values again
- prop1Val = (int) connSubModel1.getModelPropertyValue("submodelElements/prop1/value");
- prop2Val = (String) connSubModel1.getModelPropertyValue("submodelElements/prop2/value");
- // - Check property values
- assertTrue(prop1Val == 8);
- assertTrue(prop2Val.equals("stillMine"));
-
- // Delete property values
- connSubModel1.deleteValue("submodelElements/prop1");
- connSubModel1.deleteValue("submodelElements/prop2");
-
- // Read property values again
- try {
- connSubModel1.getModelPropertyValue("submodelElements/prop1");
- fail();
- } catch (ResourceNotFoundException e) {}
- try {
- connSubModel1.getModelPropertyValue("submodelElements/prop2");
- fail();
- } catch (ResourceNotFoundException e) {}
- }
-}
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASTailoredSupplierSnippet.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASTailoredSupplierSnippet.java
deleted file mode 100644
index 379a696..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASTailoredSupplierSnippet.java
+++ /dev/null
@@ -1,141 +0,0 @@
-package org.eclipse.basyx.examples.snippets.undoc.aas.dynamic;
-
-import static org.junit.Assert.assertTrue;
-
-import java.io.Serializable;
-import java.util.Map;
-import java.util.function.Supplier;
-
-import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
-import org.eclipse.basyx.examples.TestContext;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProviderHelper;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-
-/**
- * Example for a tailored BaSyx supplier
- *
- * - BaSyx will serialize this class (and all contained references) and transmit it to the AAS server
- *
- * @author kuhn
- *
- */
-class TailoredBaSyxSupplier implements Supplier<Object>, Serializable {
-
- /**
- * Version number of serialized instances
- */
- private static final long serialVersionUID = 1L;
-
-
- /**
- * Return value
- */
- @Override
- public Object get() {
- // Delegate call to tailored BaSyx supplier base class
- return getInternal();
- }
-
-
- /**
- * Example function of tailored BaSyx supplier base class
- */
- protected String getInternal() {
- return "BaSyxSupplier!";
- }
-}
-
-
-
-
-/**
- * Illustrate the dynamic deployment of AAS operations with a tailored consumer
- *
- * @author kuhn
- *
- */
-public class RunAASTailoredSupplierSnippet {
-
-
- /**
- * VAB connection manager backend
- */
- protected VABConnectionManager connManager = new VABConnectionManager(
- new ExamplesPreconfiguredDirectory()
- // Add example specific mappings
- .addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
- new HTTPConnectorProvider());
-
-
- /**
- * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
- * components on the IP address of the host. Therefore, all components use the same IP address.
- */
- @ClassRule
- public static BaSyxDeployment context = new BaSyxDeployment(
- // Simulated servlets
- // - BaSys topology with one AAS Server and one SQL directory
- TestContext.sqlContext.
- // Deploy example specific servlets to Tomcat server in this context
- addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
- );
-
-
-
- /**
- * Test basic queries
- */
- @Test
- public void snippet() throws Exception {
-
- // Server connections
- // - Connect to device (VAB object)
- VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
-
-
- // Create properties on AAS
-
- // - Add example properties
- SubModel submodel = new SubModel();
- submodel.setIdShort("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
- Property prop1 = new Property(7);
- prop1.setIdShort("prop1");
- submodel.addSubModelElement(prop1);
-
- Property prop2 = new Property("myStr");
- prop2.setIdShort("prop2");
- submodel.addSubModelElement(prop2);
-
- // - Transfer sub model to server
- connSubModel1.setModelPropertyValue("/", submodel);
-
-
- // Read property values
- String prop2Val = (String) connSubModel1.getModelPropertyValue("submodelElements/prop2/value");
- // - Check property values
- assertTrue(prop2Val.equals("myStr"));
-
-
- // Create dynamic get/set operation as lambda expression
- Map<String, Object> dynamicPropertyVal = VABLambdaProviderHelper.createSimple(new TailoredBaSyxSupplier(), null);
- // - Update property properties/dynamicExample with dynamic get/set operation
- connSubModel1.setModelPropertyValue("submodelElements/prop2/value", dynamicPropertyVal);
-
- // Read dynamicExample property
- prop2Val = (String) connSubModel1.getModelPropertyValue("submodelElements/prop2/value");
-
- // - Check value
- assertTrue(prop2Val.equals("BaSyxSupplier!"));
- }
-}
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASManualHTTPOperationsSnippet.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASManualHTTPOperationsSnippet.java
deleted file mode 100644
index 3fb38c5..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASManualHTTPOperationsSnippet.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package org.eclipse.basyx.examples.snippets.undoc.vab.connection;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.HashMap;
-
-import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
-import org.eclipse.basyx.examples.TestContext;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.tools.webserviceclient.WebServiceJSONClient;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-
-
-
-/**
- * Illustrate the use of AAS operations using HTTP REST calls
- *
- * @author kuhn
- *
- */
-public class RunAASManualHTTPOperationsSnippet {
-
-
- /**
- * VAB connection manager backend
- */
- protected VABConnectionManager connManager = new VABConnectionManager(
- new ExamplesPreconfiguredDirectory()
- // Add example specific mappings
- .addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
- new HTTPConnectorProvider());
-
-
- /**
- * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
- * components on the IP address of the host. Therefore, all components use the same IP address.
- */
- @ClassRule
- public static BaSyxDeployment context = new BaSyxDeployment(
- // Simulated servlets
- // - BaSys topology with one AAS Server and one SQL directory
- TestContext.sqlContext.
- // Deploy example specific servlets to Tomcat server in this context
- addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
- );
-
-
-
-
- /**
- * Test basic queries
- */
- public void snippet() throws Exception {
-
- // Server connections
- // - Connect to device (VAB object)
- VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
-
- int prop1Val = 7;
- String prop2Val = "myStr";
- // Create properties on AAS using connection
- connSubModel1.createValue("properties", new HashMap<String, Object>());
- connSubModel1.createValue("properties/prop1", prop1Val);
- connSubModel1.createValue("properties/prop2", prop2Val);
-
-
- // Web service client accesses AAS using HTTP REST calls
- WebServiceJSONClient jsonClient = new WebServiceJSONClient();
-
-
- // Read property values
- // - Use WebServiceJSONClient class. Returned property contains meta data. The actual value is stored in property "entity"
- assertEquals(prop1Val, jsonClient.get("http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/properties/prop1"));
- assertEquals(prop2Val, jsonClient.get("http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/properties/prop2"));
- }
-}
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASPropertiesSnippet.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASPropertiesSnippet.java
deleted file mode 100644
index ed3a544..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASPropertiesSnippet.java
+++ /dev/null
@@ -1,99 +0,0 @@
-package org.eclipse.basyx.examples.snippets.undoc.vab.connection;
-
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.HashMap;
-
-import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
-import org.eclipse.basyx.examples.TestContext;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-
-/**
- * Illustrate the use of AAS operations
- *
- * @author kuhn
- *
- */
-public class RunAASPropertiesSnippet {
-
-
- /**
- * VAB connection manager backend
- */
- protected VABConnectionManager connManager = new VABConnectionManager(
- new ExamplesPreconfiguredDirectory()
- // Add example specific mappings
- .addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
- new HTTPConnectorProvider());
-
-
- /**
- * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
- * components on the IP address of the host. Therefore, all components use the same IP address.
- */
- @ClassRule
- public static BaSyxDeployment context = new BaSyxDeployment(
- // Simulated servlets
- // - BaSys topology with one AAS Server and one SQL directory
- TestContext.sqlContext.
- // Deploy example specific servlets to Tomcat server in this context
- addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
- );
-
-
-
-
- /**
- * Test basic queries
- */
- @Test
- public void snippet() throws Exception {
-
- // Server connections
- // - Connect to device (VAB object)
- VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
-
-
- // Create properties on AAS
- connSubModel1.createValue("properties", new HashMap<String, Object>());
- connSubModel1.createValue("properties/prop1", 7);
- connSubModel1.createValue("properties/prop2", "myStr");
-
- // Read property values
- assertTrue((int) connSubModel1.getModelPropertyValue("properties/prop1") == 7);
- assertTrue(connSubModel1.getModelPropertyValue("properties/prop2").equals("myStr"));
-
- // Update property values
- connSubModel1.setModelPropertyValue("properties/prop1", 8);
- connSubModel1.setModelPropertyValue("properties/prop2", "stillMine");
-
- // Read property values again
- assertTrue((int) connSubModel1.getModelPropertyValue("properties/prop1") == 8);
- assertTrue(connSubModel1.getModelPropertyValue("properties/prop2").equals("stillMine"));
-
- // Delete property values
- connSubModel1.deleteValue("properties/prop1");
- connSubModel1.deleteValue("properties/prop2");
-
- // Read property values again
- try {
- connSubModel1.getModelPropertyValue("properties/prop1");
- fail();
- } catch (ResourceNotFoundException e) {}
- try {
- connSubModel1.getModelPropertyValue("properties/prop2");
- fail();
- } catch (ResourceNotFoundException e) {}
- }
-}
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/urn/ConstructURNs.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/urn/ConstructURNs.java
index 7ec783a..807b3df 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/urn/ConstructURNs.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/urn/ConstructURNs.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.snippets.urn;
import static org.junit.Assert.assertTrue;
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/CRUDOperations.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/CRUDOperations.java
index d9636b4..3c1e831 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/CRUDOperations.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/CRUDOperations.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.snippets.vab;
import static org.junit.Assert.assertTrue;
@@ -6,13 +15,13 @@
import java.util.HashMap;
import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
-import org.eclipse.basyx.examples.TestContext;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
import org.eclipse.basyx.vab.manager.VABConnectionManager;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
import org.junit.ClassRule;
import org.junit.Test;
@@ -41,9 +50,9 @@
new ExamplesPreconfiguredDirectory()
// Add example specific mappings
.addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
- new HTTPConnectorProvider());
+ new HTTPConnectorFactory());
-
+
/**
* The BaSyx Deployment instantiates and starts context elements for this example.
*
@@ -57,7 +66,7 @@
public static BaSyxDeployment context = new BaSyxDeployment(
// Simulated servlets
// - BaSys topology with one AAS Server and one SQL directory
- TestContext.sqlContext.
+ new BaSyxExamplesContext().
// Deploy example specific servlets to Tomcat server in this context
addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
);
@@ -73,7 +82,7 @@
// Server connections
// - Connect to VAB object by ID. The connection manager looks up this ID in
// its directory
- VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
+ VABElementProxy connSubmodel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
// Create properties on AAS
@@ -81,33 +90,33 @@
// properties "prop1" and "prop2". Container and properties lack the
// required properties for AAS and AAS sub models. They are therefore
// not compliant to Asset Administration Shells.
- connSubModel1.createValue("properties", new HashMap<String, Object>());
- connSubModel1.createValue("properties/prop1", 7);
- connSubModel1.createValue("properties/prop2", "myStr");
+ connSubmodel1.createValue("properties", new HashMap<String, Object>());
+ connSubmodel1.createValue("properties/prop1", 7);
+ connSubmodel1.createValue("properties/prop2", "myStr");
// Read property values
- int prop1Val = (int) connSubModel1.getModelPropertyValue("properties/prop1");
- String prop2Val = (String) connSubModel1.getModelPropertyValue("properties/prop2");
+ int prop1Val = (int) connSubmodel1.getValue("properties/prop1");
+ String prop2Val = (String) connSubmodel1.getValue("properties/prop2");
// Update property values
- connSubModel1.setModelPropertyValue("properties/prop1", 8);
- connSubModel1.setModelPropertyValue("properties/prop2", "stillMine");
+ connSubmodel1.setValue("properties/prop1", 8);
+ connSubmodel1.setValue("properties/prop2", "stillMine");
// Read property values again
- int prop1Val_2 = (int) connSubModel1.getModelPropertyValue("properties/prop1");
- String prop2Val_2 = (String) connSubModel1.getModelPropertyValue("properties/prop2");
+ int prop1Val_2 = (int) connSubmodel1.getValue("properties/prop1");
+ String prop2Val_2 = (String) connSubmodel1.getValue("properties/prop2");
// Delete property values
- connSubModel1.deleteValue("properties/prop1");
- connSubModel1.deleteValue("properties/prop2");
+ connSubmodel1.deleteValue("properties/prop1");
+ connSubmodel1.deleteValue("properties/prop2");
// Read property values again
try {
- connSubModel1.getModelPropertyValue("properties/prop1");
+ connSubmodel1.getValue("properties/prop1");
fail();
} catch (ResourceNotFoundException e) {}
try {
- connSubModel1.getModelPropertyValue("properties/prop2");
+ connSubmodel1.getValue("properties/prop2");
fail();
} catch (ResourceNotFoundException e) {}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/DynamicPropertyClass.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/DynamicPropertyClass.java
index 7dcbee1..8f6b4b4 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/DynamicPropertyClass.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/DynamicPropertyClass.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.snippets.vab;
import static org.junit.Assert.assertTrue;
@@ -7,13 +16,13 @@
import java.util.function.Supplier;
import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
-import org.eclipse.basyx.examples.TestContext;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
import org.eclipse.basyx.vab.manager.VABConnectionManager;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProviderHelper;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
import org.junit.ClassRule;
import org.junit.Test;
@@ -84,9 +93,9 @@
new ExamplesPreconfiguredDirectory()
// Add example specific mappings
.addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
- new HTTPConnectorProvider());
+ new HTTPConnectorFactory());
-
+
/**
* The BaSyx Deployment instantiates and starts context elements for this example.
*
@@ -100,7 +109,7 @@
public static BaSyxDeployment context = new BaSyxDeployment(
// Simulated servlets
// - BaSys topology with one AAS Server and one SQL directory
- TestContext.sqlContext.
+ new BaSyxExamplesContext().
// Deploy example specific servlets to Tomcat server in this context
addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
);
@@ -116,17 +125,17 @@
// Server connections
// - Connect to device (VAB object)
- VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
+ VABElementProxy connSubmodel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
// Create dynamic get/set operation. Instantiate class TailoredBaSyxSupplier as getter,
// no setter (null) is provided.
Map<String, Object> dynamicPropertyVal = VABLambdaProviderHelper.createSimple(new TailoredBaSyxSupplier(), null);
// - Update property properties/dynamicExample with dynamic get/set operation
- connSubModel1.createValue("dynamicExampleProperty", dynamicPropertyVal);
+ connSubmodel1.createValue("dynamicExampleProperty", dynamicPropertyVal);
// Read dynamicExample property
- Object propertyValue = connSubModel1.getModelPropertyValue("dynamicExampleProperty");
+ Object propertyValue = connSubmodel1.getValue("dynamicExampleProperty");
// Compare returned to expected values
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/DynamicPropertyLambda.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/DynamicPropertyLambda.java
index 9511199..0cc6b92 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/DynamicPropertyLambda.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/DynamicPropertyLambda.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.snippets.vab;
import static org.junit.Assert.assertTrue;
@@ -7,13 +16,13 @@
import java.util.function.Supplier;
import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
-import org.eclipse.basyx.examples.TestContext;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
import org.eclipse.basyx.vab.manager.VABConnectionManager;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProviderHelper;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
import org.junit.ClassRule;
import org.junit.Test;
@@ -35,7 +44,7 @@
*/
public class DynamicPropertyLambda {
-
+
/**
* VAB connection manager backend
*
@@ -46,7 +55,7 @@
new ExamplesPreconfiguredDirectory()
// Add example specific mappings
.addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
- new HTTPConnectorProvider());
+ new HTTPConnectorFactory());
/**
@@ -62,7 +71,7 @@
public static BaSyxDeployment context = new BaSyxDeployment(
// Simulated servlets
// - BaSys topology with one AAS Server and one SQL directory
- TestContext.sqlContext.
+ new BaSyxExamplesContext().
// Deploy example specific servlets to Tomcat server in this context
addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
);
@@ -80,7 +89,7 @@
// Server connections
// - Connect to VAB object by ID. The connection manager looks up this ID in
// its directory
- VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
+ VABElementProxy connSubmodel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
// Create dynamic get/operation as Lambda expression, no set operation (null) is provided.
@@ -88,11 +97,11 @@
return "dynamicExampleValue";
}, null);
// - Update property properties/dynamicExample with dynamic get/set operation
- connSubModel1.createValue("dynamicExampleProperty", dynamicPropertyVal);
+ connSubmodel1.createValue("dynamicExampleProperty", dynamicPropertyVal);
// Read dynamicExample property
// - This will invoke the previously uploaded Lambda expression
- Object propertyValue = connSubModel1.getModelPropertyValue("dynamicExampleProperty");
+ Object propertyValue = connSubmodel1.getValue("dynamicExampleProperty");
// Compare returned to expected values
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/ManualHTTPCalls.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/ManualHTTPCalls.java
index ed63416..25f2e84 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/ManualHTTPCalls.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/ManualHTTPCalls.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.snippets.vab;
import static org.junit.Assert.assertEquals;
@@ -5,13 +14,13 @@
import java.util.HashMap;
import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
-import org.eclipse.basyx.examples.TestContext;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
import org.eclipse.basyx.tools.webserviceclient.WebServiceJSONClient;
import org.eclipse.basyx.vab.manager.VABConnectionManager;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
import org.junit.ClassRule;
/**
@@ -26,7 +35,7 @@
*/
public class ManualHTTPCalls {
-
+
/**
* Create VAB connection manager backend
*
@@ -37,7 +46,7 @@
new ExamplesPreconfiguredDirectory()
// Add example specific mappings
.addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
- new HTTPConnectorProvider());
+ new HTTPConnectorFactory());
/**
@@ -53,7 +62,7 @@
public static BaSyxDeployment context = new BaSyxDeployment(
// Simulated servlets
// - BaSys topology with one AAS Server and one SQL directory
- TestContext.sqlContext.
+ new BaSyxExamplesContext().
// Deploy example specific servlets to Tomcat server in this context
addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
);
@@ -70,7 +79,7 @@
// Server connections
// - Connect to VAB object by ID. The connection manager looks up this ID in
// its directory
- VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
+ VABElementProxy connSubmodel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
int prop1Val = 7;
String prop2Val = "myStr";
@@ -79,9 +88,9 @@
// properties "prop1" and "prop2". Container and properties lack the
// required properties for AAS and AAS sub models. They are therefore
// not compliant to Asset Administration Shells.
- connSubModel1.createValue("properties", new HashMap<String, Object>());
- connSubModel1.createValue("properties/prop1", prop1Val);
- connSubModel1.createValue("properties/prop2", prop2Val);
+ connSubmodel1.createValue("properties", new HashMap<String, Object>());
+ connSubmodel1.createValue("properties/prop1", prop1Val);
+ connSubmodel1.createValue("properties/prop2", prop2Val);
// Web service client
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/FileSystemProviderClass.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/FileSystemProviderClass.java
index 086f3e2..34ad776 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/FileSystemProviderClass.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/FileSystemProviderClass.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.snippets.vab.provider;
import static org.junit.Assert.assertEquals;
@@ -47,7 +56,7 @@
IModelProvider provider = new FileSystemProvider(fs, basePath, rootElement, true);
// The interface is equal to the interface used in e.g. the HashMapProvider
- int previouslyCreated = (Integer) provider.getModelPropertyValue("/myInteger");
+ int previouslyCreated = (Integer) provider.getValue("/myInteger");
assertEquals(3, previouslyCreated);
// When creating elements, the internal directory and file structure represent the changes
@@ -55,7 +64,7 @@
// Properties are serialized and stored in the file that corresponds to their path
String expected = "Max Mustermann";
- String byProvider = (String) provider.getModelPropertyValue("/name");
+ String byProvider = (String) provider.getValue("/name");
String byFileSystem = fs.readFile(basePath + "/name");
String byFSDeserialized = (String) gsonTools.deserialize(byFileSystem);
assertEquals(expected, byProvider);
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/VABLambdaProviderClass.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/VABLambdaProviderClass.java
index 713f484..714cba5 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/VABLambdaProviderClass.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/VABLambdaProviderClass.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.snippets.vab.provider;
import static org.junit.Assert.assertEquals;
@@ -50,17 +59,17 @@
IModelProvider provider = new VABLambdaProvider(rootElement);
// Static and dynamic properties are resolved to their primitive object value
- assertEquals("myStaticString", provider.getModelPropertyValue("/static"));
- assertEquals("myDynamicString", provider.getModelPropertyValue("/dynamic"));
+ assertEquals("myStaticString", provider.getValue("/static"));
+ assertEquals("myDynamicString", provider.getValue("/dynamic"));
// Now each time the dynamic property is read, it resolves its value through the given get operation
// - modify the source of the dynamic property
dynamicString = "newValue";
// - resolve the property
- assertEquals("newValue", provider.getModelPropertyValue("/dynamic"));
+ assertEquals("newValue", provider.getValue("/dynamic"));
// The custom setter of the dynamic property in this example only allows string types...
- provider.setModelPropertyValue("/dynamic", true);
- assertEquals("newValue", provider.getModelPropertyValue("/dynamic"));
+ provider.setValue("/dynamic", true);
+ assertEquals("newValue", provider.getValue("/dynamic"));
}
}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/VABMapProviderClass.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/VABMapProviderClass.java
index 92a7188..ee9d103 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/VABMapProviderClass.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/VABMapProviderClass.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.examples.snippets.vab.provider;
import static org.junit.Assert.assertEquals;
@@ -48,13 +57,13 @@
IModelProvider provider = new VABMapProvider(rootElement);
// Child elements can now be accessed with a path that is mapped to actual data structure
- assertEquals("myElement", provider.getModelPropertyValue("/name"));
- assertEquals("boolean", provider.getModelPropertyValue("/data/type"));
- assertEquals(true, provider.getModelPropertyValue("/data/value"));
+ assertEquals("myElement", provider.getValue("/name"));
+ assertEquals("boolean", provider.getValue("/data/type"));
+ assertEquals(true, provider.getValue("/data/value"));
// Future modifications are now applied using the IModelProvider interface.
- provider.setModelPropertyValue("/name", "yourElement");
- assertEquals("yourElement", provider.getModelPropertyValue("/name"));
+ provider.setValue("/name", "yourElement");
+ assertEquals("yourElement", provider.getValue("/name"));
// The creation of nested elements within an existing provider is also possible
// HashMaps and Collections are supported for this purpose
@@ -64,6 +73,6 @@
provider.createValue("/description", description);
// The path is again mapped to the HashMap structure
- assertEquals("This is a generic VAB element", provider.getModelPropertyValue("/description/EN"));
+ assertEquals("This is a generic VAB element", provider.getValue("/description/EN"));
}
}
diff --git a/examples/basys.examples/src/test/resources/registry.properties b/examples/basys.examples/src/test/resources/registry.properties
index 60e38d9..1cdb398 100644
--- a/examples/basys.examples/src/test/resources/registry.properties
+++ b/examples/basys.examples/src/test/resources/registry.properties
@@ -1,43 +1,35 @@
-# ##############################################################
-# Directory configuration file
-# ##############################################################
+# ###############################
+# SQL database configuration file
+# ###############################
+
+# ###############################
+# Credentials
+# ###############################
+# Specifies the credentials for connecting to the SQL database
+
+dbuser=postgres
+dbpass=admin
+
+# ###############################
+# Database URL
+# ###############################
+# The direct SQL database url for connection
+
+dburl=//localhost:5432/basyx-directory?
+
+# ###############################
+# SQL driver information
+# ###############################
+# Java Driver and connection prefix for using the driver
+
+sqlDriver=org.postgresql.Driver
+sqlPrefix=jdbc:postgresql:
+# ###############################
+# Microsoft SQL Server Example
+# ###############################
+# dburl=//localhost:1234;databaseName=mydb
+# sqlDriver=com.microsoft.sqlserver.jdbc.SQLServerDriver
+# sqlPrefix=jdbc:sqlserver:
-
-# ##############################################################
-# Directory server configuration
-
-
-# URL and type of uplink server. Forward all requests that we cannot satisfy here to uplink
-# - URL of uplink directory server
-# - Type of uplink server. Currently supported is BASYS (BaSys registry API) or DNS (DNS server processing legalBody tag)
-cfg.uplink =
-cfg.uplink.type = DNS
-
-
-# Downlink servers, forward matching URI patterns to downlink servers
-# - Match all subunits that end with "is.iese", including "is.iese"
-cfg.downlink.is.pattern = is.iese
-cfg.downlink.is.directory = http://wherever1
-
-# - Match all subunits that end with "pm.iese", including "pm.iese"
-cfg.downlink.pm.pattern = pm.iese
-cfg.downlink.pm.directory = http://wherever2
-
-# - Match all subunits that end with ".es.iese", but not "es.iese"
-cfg.downlink.es.pattern = .es.iese
-cfg.downlink.es.directory = http://wherever3
-
-
-
-
-# ##############################################################
-# SQL database configuration
-
-dbuser = postgres
-dbpass = admin
-dburl = //localhost/basyx-directory?
-
-sqlDriver = org.postgresql.Driver
-sqlPrefix = jdbc:postgresql:
diff --git a/examples/basys.registry/.classpath b/examples/basys.registry/.classpath
deleted file mode 100644
index 76b9877..0000000
--- a/examples/basys.registry/.classpath
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
- <attributes>
- <attribute name="maven.pomderived" value="true"/>
- </attributes>
- </classpathentry>
- <classpathentry kind="con" path="org.eclipse.jst.server.core.container/org.eclipse.jst.server.tomcat.runtimeTarget/Apache Tomcat v8.5">
- <attributes>
- <attribute name="owner.project.facets" value="jst.web"/>
- </attributes>
- </classpathentry>
- <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
- <attributes>
- <attribute name="maven.pomderived" value="true"/>
- <attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
- </attributes>
- </classpathentry>
- <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/5"/>
- <classpathentry kind="src" output="target/classes" path="src/main/java">
- <attributes>
- <attribute name="optional" value="true"/>
- <attribute name="maven.pomderived" value="true"/>
- </attributes>
- </classpathentry>
- <classpathentry kind="src" output="target/test-classes" path="src/test/java">
- <attributes>
- <attribute name="optional" value="true"/>
- <attribute name="maven.pomderived" value="true"/>
- <attribute name="test" value="true"/>
- </attributes>
- </classpathentry>
- <classpathentry kind="output" path="target/classes"/>
-</classpath>
diff --git a/examples/basys.registry/.gitignore b/examples/basys.registry/.gitignore
deleted file mode 100644
index f232a6d..0000000
--- a/examples/basys.registry/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-# ignore output
-target/
-
diff --git a/examples/basys.registry/.project b/examples/basys.registry/.project
deleted file mode 100644
index 63d98e4..0000000
--- a/examples/basys.registry/.project
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>basys.registry</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>org.eclipse.jdt.core.javabuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.wst.common.project.facet.core.builder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.wst.validation.validationbuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.m2e.core.maven2Builder</name>
- <arguments>
- </arguments>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.eclipse.m2e.core.maven2Nature</nature>
- <nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
- <nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
- <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
- <nature>org.eclipse.jdt.core.javanature</nature>
- <nature>org.eclipse.wst.jsdt.core.jsNature</nature>
- </natures>
-</projectDescription>
diff --git a/examples/basys.registry/.settings/.jsdtscope b/examples/basys.registry/.settings/.jsdtscope
deleted file mode 100644
index 92e666d..0000000
--- a/examples/basys.registry/.settings/.jsdtscope
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
- <classpathentry excluding="**/bower_components/*|**/node_modules/*|**/*.min.js" kind="src" path="WebContent"/>
- <classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
- <classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.WebProject">
- <attributes>
- <attribute name="hide" value="true"/>
- </attributes>
- </classpathentry>
- <classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
- <classpathentry kind="output" path=""/>
-</classpath>
diff --git a/examples/basys.registry/.settings/org.eclipse.jdt.core.prefs b/examples/basys.registry/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index 4e4a3ad..0000000
--- a/examples/basys.registry/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,9 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
-org.eclipse.jdt.core.compiler.compliance=1.8
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.release=disabled
-org.eclipse.jdt.core.compiler.source=1.8
diff --git a/examples/basys.registry/.settings/org.eclipse.m2e.core.prefs b/examples/basys.registry/.settings/org.eclipse.m2e.core.prefs
deleted file mode 100644
index f897a7f..0000000
--- a/examples/basys.registry/.settings/org.eclipse.m2e.core.prefs
+++ /dev/null
@@ -1,4 +0,0 @@
-activeProfiles=
-eclipse.preferences.version=1
-resolveWorkspaceProjects=true
-version=1
diff --git a/examples/basys.registry/.settings/org.eclipse.wst.common.component b/examples/basys.registry/.settings/org.eclipse.wst.common.component
deleted file mode 100644
index 4d29a2b..0000000
--- a/examples/basys.registry/.settings/org.eclipse.wst.common.component
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
- <wb-module deploy-name="registry-0.0.3-SNAPSHOT">
- <wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
- <wb-resource deploy-path="/" source-path="/WebContent" tag="defaultRootSource"/>
- <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
- <dependent-module archiveName="basyx.components-0.0.1-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/basyx.components/basyx.components">
- <dependency-type>uses</dependency-type>
- </dependent-module>
- <dependent-module archiveName="basyx.sdk-0.0.1-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/basyx.sdk/basyx.sdk">
- <dependency-type>uses</dependency-type>
- </dependent-module>
- <property name="java-output-path" value="/basys.registry/target/classes"/>
- <property name="context-root" value="registry"/>
- </wb-module>
-</project-modules>
diff --git a/examples/basys.registry/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml b/examples/basys.registry/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml
deleted file mode 100644
index cc81385..0000000
--- a/examples/basys.registry/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<root>
- <facet id="jst.jaxrs">
- <node name="libprov">
- <attribute name="provider-id" value="jaxrs-no-op-library-provider"/>
- </node>
- </facet>
-</root>
diff --git a/examples/basys.registry/.settings/org.eclipse.wst.common.project.facet.core.xml b/examples/basys.registry/.settings/org.eclipse.wst.common.project.facet.core.xml
deleted file mode 100644
index 5f0749f..0000000
--- a/examples/basys.registry/.settings/org.eclipse.wst.common.project.facet.core.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<faceted-project>
- <runtime name="Apache Tomcat v8.5"/>
- <fixed facet="wst.jsdt.web"/>
- <fixed facet="java"/>
- <fixed facet="jst.web"/>
- <installed facet="java" version="1.8"/>
- <installed facet="jst.web" version="3.1"/>
- <installed facet="wst.jsdt.web" version="1.0"/>
- <installed facet="jst.jaxrs" version="2.0"/>
-</faceted-project>
diff --git a/examples/basys.registry/.settings/org.eclipse.wst.jsdt.ui.superType.container b/examples/basys.registry/.settings/org.eclipse.wst.jsdt.ui.superType.container
deleted file mode 100644
index 3bd5d0a..0000000
--- a/examples/basys.registry/.settings/org.eclipse.wst.jsdt.ui.superType.container
+++ /dev/null
@@ -1 +0,0 @@
-org.eclipse.wst.jsdt.launching.baseBrowserLibrary
\ No newline at end of file
diff --git a/examples/basys.registry/.settings/org.eclipse.wst.jsdt.ui.superType.name b/examples/basys.registry/.settings/org.eclipse.wst.jsdt.ui.superType.name
deleted file mode 100644
index 05bd71b..0000000
--- a/examples/basys.registry/.settings/org.eclipse.wst.jsdt.ui.superType.name
+++ /dev/null
@@ -1 +0,0 @@
-Window
\ No newline at end of file
diff --git a/examples/basys.registry/.settings/org.eclipse.wst.validation.prefs b/examples/basys.registry/.settings/org.eclipse.wst.validation.prefs
deleted file mode 100644
index 04cad8c..0000000
--- a/examples/basys.registry/.settings/org.eclipse.wst.validation.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-disabled=06target
-eclipse.preferences.version=1
diff --git a/examples/basys.registry/Dockerfile b/examples/basys.registry/Dockerfile
deleted file mode 100644
index 11fef4f..0000000
--- a/examples/basys.registry/Dockerfile
+++ /dev/null
@@ -1,8 +0,0 @@
-# Dockerfile
-
-FROM tomcat:8-jdk8
-
-#Copy war file
-COPY target/registry-0.0.3*.war $CATALINA_HOME/webapps/registry.war
-
-CMD /usr/local/tomcat/bin/catalina.sh run && tail -f /usr/local/MYAPP.log
\ No newline at end of file
diff --git a/examples/basys.registry/WebContent/META-INF/MANIFEST.MF b/examples/basys.registry/WebContent/META-INF/MANIFEST.MF
deleted file mode 100644
index 254272e..0000000
--- a/examples/basys.registry/WebContent/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,3 +0,0 @@
-Manifest-Version: 1.0
-Class-Path:
-
diff --git a/examples/basys.registry/WebContent/WEB-INF/config/directory/sqldirectory/directory.properties b/examples/basys.registry/WebContent/WEB-INF/config/directory/sqldirectory/directory.properties
deleted file mode 100644
index 1fc05b8..0000000
--- a/examples/basys.registry/WebContent/WEB-INF/config/directory/sqldirectory/directory.properties
+++ /dev/null
@@ -1,45 +0,0 @@
-# ##############################################################
-# Directory configuration file
-# ##############################################################
-
-
-
-
-# ##############################################################
-# Directory server configuration
-
-
-# URL and type of uplink server. Forward all requests that we cannot satisfy here to uplink
-# - URL of uplink directory server
-# - Type of uplink server. Currently supported is BASYS (BaSys registry API) or DNS (DNS server processing legalBody tag)
-cfg.uplink =
-cfg.uplink.type = DNS
-
-
-# Downlink servers, forward matching URI patterns to downlink servers
-# - Match all subunits that end with "is.iese", including "is.iese"
-cfg.downlink.is.pattern = is.iese
-cfg.downlink.is.directory = http://wherever1
-
-# - Match all subunits that end with "pm.iese", including "pm.iese"
-cfg.downlink.pm.pattern = pm.iese
-cfg.downlink.pm.directory = http://wherever2
-
-# - Match all subunits that end with ".es.iese", but not "es.iese"
-cfg.downlink.es.pattern = .es.iese
-cfg.downlink.es.directory = http://wherever3
-
-
-
-
-# ##############################################################
-# SQL database configuration
-
-dbuser = postgres
-dbpass = admin
-#dburl = //localhost/basyx-directory?
-# use container link "postgres" instead of localhost when running with docker-compose
-dburl = //postgres:5432/basyx-directory?
-
-sqlDriver = org.postgresql.Driver
-sqlPrefix = jdbc:postgresql:
diff --git a/examples/basys.registry/WebContent/WEB-INF/config/postgres/init.sql b/examples/basys.registry/WebContent/WEB-INF/config/postgres/init.sql
deleted file mode 100644
index b2930bc..0000000
--- a/examples/basys.registry/WebContent/WEB-INF/config/postgres/init.sql
+++ /dev/null
@@ -1,9 +0,0 @@
-\c basyx-directory
-CREATE SCHEMA directory;
-CREATE TABLE directory.directory ( "ElementRef" varchar(999999), "ElementID" varchar(999999) primary key );
-INSERT INTO directory.directory ( "ElementID", "ElementRef" ) VALUES ( 'urn:de.FHG:es.iese:aas:0.98:5:lab/microscope#A-19', 'content.aas1' );
-INSERT INTO directory.directory ( "ElementID", "ElementRef" ) VALUES ( 'urn:de.FHG:es.iese:aas:0.98:5:lab/microscope#A-18', 'content.aas2' );
-INSERT INTO directory.directory ( "ElementID", "ElementRef" ) VALUES ( 'urn:de.FHG:es.iese:aas:0.98:5:lab/microscope#A-17', 'content.aas3' );
-INSERT INTO directory.directory ( "ElementID", "ElementRef" ) VALUES ( 'urn:de.FHG:es.iese:aas:0.98:5:lab/microscope#A-16', 'content.aas4' );
-INSERT INTO directory.directory ( "ElementID", "ElementRef" ) VALUES ( 'urn:de.FHG:es.iese:aas:0.98:5:lab/microscope#A-15', 'content.aas5' );
-
diff --git a/examples/basys.registry/WebContent/WEB-INF/web.xml b/examples/basys.registry/WebContent/WEB-INF/web.xml
deleted file mode 100644
index f42e738..0000000
--- a/examples/basys.registry/WebContent/WEB-INF/web.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
- <display-name>registry</display-name>
- <welcome-file-list>
- <welcome-file>index.html</welcome-file>
- <welcome-file>index.htm</welcome-file>
- <welcome-file>index.jsp</welcome-file>
- <welcome-file>default.html</welcome-file>
- <welcome-file>default.htm</welcome-file>
- <welcome-file>default.jsp</welcome-file>
- </welcome-file-list>
- <servlet>
- <description></description>
- <display-name>SQLDirectoryServlet</display-name>
- <servlet-name>SQLDirectoryServlet</servlet-name>
- <servlet-class>main.java.registry.CustomSQLDirectoryServlet</servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>SQLDirectoryServlet</servlet-name>
- <url-pattern>/*</url-pattern>
- </servlet-mapping>
-</web-app>
\ No newline at end of file
diff --git a/examples/basys.registry/docker-compose.yml b/examples/basys.registry/docker-compose.yml
deleted file mode 100644
index e547619..0000000
--- a/examples/basys.registry/docker-compose.yml
+++ /dev/null
@@ -1,31 +0,0 @@
-version: '3'
-services:
-
- registry:
- image: basys:0.0.3-SNAPSHOT
- container_name: aasRegistry
- ports:
- - 8081:8080
- depends_on:
- - postgres
- volumes:
- - .\WebContent\WEB-INF\config\directory\sqldirectory\directory.properties:/basys/directory.properties
- links:
- - postgres
-
- postgres:
- image: postgres:9.4
- container_name: postgres
- environment:
- - POSTGRES_USER:'postgres'
- - POSTGRES_PASSWORD:'admin'
- - POSTGRES_DB=basyx-directory
- volumes:
- - ./WebContent/WEB-INF/config/postgres/init.sql:/docker-entrypoint-initdb.d/init.sql
- ports:
- - 5433:5432
- expose:
- - 5432
-
-
-
\ No newline at end of file
diff --git a/examples/basys.registry/how-to-use-this-project.txt b/examples/basys.registry/how-to-use-this-project.txt
deleted file mode 100644
index 7bddff0..0000000
--- a/examples/basys.registry/how-to-use-this-project.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-@author pschorn, 07.08.2019
-
-This project demonstrates how to use Maven to create "parameterized" Docker images and how to start multiple containers interacting with each other in a docker-compose file.
-The most important files you need to look at are:
-- /Dockerfile
-- /pom.xml
-- /docker-compose.yml
-- /WebContent/WEB-INF/config/directory/sqldirectory/directory.properties
-- /WebContent/WEB-INF/config/directory/postgres/init.sql
-- /WebContent/WEB-INF/web.xml
-
-
-In detail, the project will create a self-sustained, containerized version of the Registry with SQL backend. For this, we need a PostgreSQL
-server and the SQLDirectoryServlet from the basys.components project, that processes and forwards requests to the SQL server.
-
-The build process is automated with Maven, which will do the following steps:
- 1) After running unit tests a .war file will be created
- 2) Maven will build a docker image based on the provided Dockerfile. It will make sure that the .war file of our app is deployed to a TomCat image.
- 3) Before running the integration tests, Maven will run the docker-compose script. "docker-compose up" is used to start a number of containers in a virtual network that can interact with each other.
- - Due to the "depends_on" command, docker-compose will start the postgres service first
- - The postgres image takes environment variables such as user, password and a database to be created, and we mount a file called init.sql to the postgres' /docker-entrypoint-initdb.d folder that contains the insert
- statements required to setup the test suite. On startup, postgres will execute all sql scripts that it can find in this directory.
- - The "ports" - 5433:5432 command defines that the container should be available for the outside world at port 5433 and forward requests to port 5432 of the application running inside it.
- - The "expose" - 5432 commands defines that the other containers started by docker-compose can find the postgres server at this port. Further, together with the "links" - postgres command in
- the registry service definition, the registry can reach the postgres database at //postgres:5432/basyx-directory.
- - When the postgres service is started, the registry service will start in the same manner, mounting a directory.properties file to the tomcat container. A Java Implementation trying to access the file should
- do so by creating an InputStream witht the absolute path to this file.
-4) Now, Maven will start the integration tests, running against the outside-world address of the registry service at http://localhost:8081/registry/
-5) After the tests complete, Maven will tear down the containers with the docker-compose down command.
-
-
-
-# What you should do before production use?
-- make the sql data persistent by mounting a volume to postgres as described here https://stackoverflow.com/questions/41637505/how-to-persist-data-in-a-dockerized-postgres-database-using-volumes
-and be ready to enter the stormy seas of distributed systems.
-
-
-
-
-
-
diff --git a/examples/basys.registry/pom.xml b/examples/basys.registry/pom.xml
deleted file mode 100644
index 37bb38a..0000000
--- a/examples/basys.registry/pom.xml
+++ /dev/null
@@ -1,145 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>org.eclipse.basys</groupId>
- <artifactId>registry</artifactId>
- <version>0.0.3-SNAPSHOT</version>
- <packaging>war</packaging>
- <build>
- <plugins>
- <plugin>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>3.7.0</version>
- <configuration>
- <source>1.8</source>
- <target>1.8</target>
- </configuration>
- </plugin>
- <plugin>
- <artifactId>maven-war-plugin</artifactId>
- <version>3.0.0</version>
- <configuration>
- <warSourceDirectory>WebContent</warSourceDirectory>
- </configuration>
- </plugin>
- <!-- Build docker image -->
- <plugin>
- <groupId>com.spotify</groupId>
- <artifactId>dockerfile-maven-plugin</artifactId>
- <version>1.4.3</version>
- <executions>
- <execution>
- <id>default</id>
- <goals>
- <goal>build</goal>
- </goals>
- </execution>
- </executions>
- <configuration>
- <imageName>registry</imageName>
- <repository>basys</repository>
- <tag>${project.version}</tag>
- </configuration>
- </plugin>
- <!-- exclude sql tests from unit tests -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <version>2.12.1</version>
- <configuration>
- <excludes>
- <exclude>**/*SQL*</exclude>
- </excludes>
- </configuration>
- </plugin>
- <!-- Create Integration Test environment -->
- <plugin>
- <groupId>com.dkanejs.maven.plugins</groupId>
- <artifactId>docker-compose-maven-plugin</artifactId>
- <version>1.0.1</version>
- <configuration>
- <composeFile>${project.basedir}/docker-compose.yml</composeFile>
- <detachedMode>true</detachedMode>
- </configuration>
- <executions>
- <execution>
- <id>docker-compose-up</id>
- <phase>pre-integration-test</phase>
- <goals>
- <goal>up</goal>
- </goals>
- </execution>
- <execution>
- <id>docker-compose-down</id>
- <phase>post-integration-test</phase>
- <goals>
- <goal>down</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
-
- <!-- run integration tests -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-failsafe-plugin</artifactId>
- <version>2.20.1</version>
- <dependencies>
- <dependency>
- <groupId>org.apache.maven.surefire</groupId>
- <artifactId>surefire-junit47</artifactId>
- <version>2.20.1</version>
- </dependency>
- </dependencies>
- <configuration>
- <includes>
- <include>TestDirectorySQLProviderExtension.java</include>
- </includes>
- </configuration>
- <executions>
- <execution>
- <id>integration-test</id>
- <phase>integration-test</phase>
- <goals>
- <goal>integration-test</goal>
- </goals>
- </execution>
- <execution>
- <id>verify</id>
- <phase>verify</phase>
- <goals>
- <goal>verify</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
-
- </plugins>
- </build>
- <dependencies>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.12</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.basyx</groupId>
- <artifactId>basyx.components</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.basyx</groupId>
- <artifactId>basyx.components</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- </dependency>
- <!-- Adds additional classes of the BaSys Components for tests -->
- <dependency>
- <groupId>org.eclipse.basyx</groupId>
- <artifactId>basyx.components</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <classifier>tests</classifier>
- <scope>test</scope>
- </dependency>
- </dependencies>
- <name>BaSys Registry Server</name>
- <description>...</description>
-</project>
\ No newline at end of file
diff --git a/examples/basys.registry/src/main/java/registry/CustomSQLDirectoryServlet.java b/examples/basys.registry/src/main/java/registry/CustomSQLDirectoryServlet.java
deleted file mode 100644
index 9ec4623..0000000
--- a/examples/basys.registry/src/main/java/registry/CustomSQLDirectoryServlet.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package registry;
-
-
-import org.eclipse.basyx.components.servlets.SQLDirectoryServlet;
-
-
-/**
- * SQL database based directory provider
- *
- * This directory provider provides a static directory. It therefore only
- * supports get() operations. Modification of the directory via
- * PUT/POST/PATCH/DELETE operations is not supported.
- *
- * @author kuhn, pschorn
- *
- */
-public class CustomSQLDirectoryServlet extends SQLDirectoryServlet {
-
-
- private static final long serialVersionUID = 1L;
-
- /**
- * Path to the directory.properties file, that contains config data for the SQL
- * connection
- */
- private static String configFilePath = "/basys/directory.properties";
-
-
- /**
- * Provide HTTP interface with JSONProvider to handle serialization and
- * SQLDirectoryProvider as backend
- */
- public CustomSQLDirectoryServlet() {
- super(configFilePath);
-
- }
-
-
-}
-
diff --git a/examples/basys.registry/src/test/java/TestDirectorySQLProviderExtension.java b/examples/basys.registry/src/test/java/TestDirectorySQLProviderExtension.java
deleted file mode 100644
index 9d3a244..0000000
--- a/examples/basys.registry/src/test/java/TestDirectorySQLProviderExtension.java
+++ /dev/null
@@ -1,27 +0,0 @@
-import org.eclipse.basyx.regression.directory.sql.TestDirectorySQLProvider;
-
-/**
- * Test queries to SQL directory provider. Tomcat server and postgres db is
- * started by docker compose
- *
- * @author kuhn, ps
- *
- */
-public class TestDirectorySQLProviderExtension extends TestDirectorySQLProvider {
-
- // Directory web service URL
- @Override
- public void setUp() {
- this.wsURL = "http://localhost:8081/registry";
-
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
-
- public TestDirectorySQLProviderExtension() {
- super();
- }
-}
diff --git a/examples/basyx.aasWrapper/.gitignore b/examples/basyx.aasWrapper/.gitignore
new file mode 100644
index 0000000..02eeb17
--- /dev/null
+++ b/examples/basyx.aasWrapper/.gitignore
@@ -0,0 +1,69 @@
+.classpath
+.project
+
+regressiontest/
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+.mvn/wrapper/maven-wrapper.jar
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.settings/
+.loadpath
+.recommenders
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# PyDev specific (Python IDE for Eclipse)
+*.pydevproject
+
+# CDT-specific (C/C++ Development Tooling)
+.cproject
+
+# CDT- autotools
+.autotools
+
+# Java annotation processor (APT)
+.factorypath
+
+# PDT-specific (PHP Development Tools)
+.buildpath
+
+# sbteclipse plugin
+.target
+
+# Tern plugin
+.tern-project
+
+# TeXlipse plugin
+.texlipse
+
+# STS (Spring Tool Suite)
+.springBeans
+
+# Code Recommenders
+.recommenders/
+
+# Annotation Processing
+.apt_generated/
+
+# Scala IDE specific (Scala & Java development for Eclipse)
+.cache-main
+.scala_dependencies
+.worksheet
\ No newline at end of file
diff --git a/examples/basyx.aasWrapper/Dockerfile b/examples/basyx.aasWrapper/Dockerfile
new file mode 100644
index 0000000..5c98c98
--- /dev/null
+++ b/examples/basyx.aasWrapper/Dockerfile
@@ -0,0 +1,23 @@
+# Add java runtime environment for execution
+FROM java:8-jdk-alpine
+
+# Copy built jar to image using the jar name specified in the pom.xml (JAR_FILE)
+ARG JAR_FILE
+COPY target/${JAR_FILE} /usr/share/basyxExecutable.jar
+COPY target/lib /usr/share/lib
+COPY src/main/resources/context.properties /usr/share/config/context.properties
+COPY src/main/resources/wrapper.properties /usr/share/config/wrapper.properties
+
+# Expose the appropriate port. In case of Tomcat, this is 8080.
+ARG PORT
+EXPOSE ${PORT}
+
+# Set the path for the context configuration file
+ARG CONTEXT_CONFIG_KEY
+ENV ${CONTEXT_CONFIG_KEY} "/usr/share/config/context.properties"
+
+# Set the path for the context configuration file
+ENV BASYX_WRAPPER "/usr/share/config/wrapper.properties"
+
+# Start the jar
+CMD java -jar "/usr/share/basyxExecutable.jar"
\ No newline at end of file
diff --git a/examples/basyx.aasWrapper/build.bat b/examples/basyx.aasWrapper/build.bat
new file mode 100644
index 0000000..0977f37
--- /dev/null
+++ b/examples/basyx.aasWrapper/build.bat
@@ -0,0 +1 @@
+.././mvnw clean install -U -Pdocker
\ No newline at end of file
diff --git a/examples/basyx.aasWrapper/build.sh b/examples/basyx.aasWrapper/build.sh
new file mode 100644
index 0000000..d223f82
--- /dev/null
+++ b/examples/basyx.aasWrapper/build.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+.././mvnw clean install -U -Pdocker -DskipTests
\ No newline at end of file
diff --git a/examples/basyx.aasWrapper/docker-compose.yml b/examples/basyx.aasWrapper/docker-compose.yml
new file mode 100644
index 0000000..fe990ac
--- /dev/null
+++ b/examples/basyx.aasWrapper/docker-compose.yml
@@ -0,0 +1,23 @@
+version: '3'
+services:
+
+ registry:
+ image: eclipsebasyx/aas-registry:1.0.1
+ container_name: dashboard-registry
+ ports:
+ - 4000:4000
+
+ dashboard-aas:
+ image: eclipsebasyx/dashboard-aas:0.1.0-SNAPSHOT
+ container_name: dashboard-aas
+ environment:
+ - BaSyxDashboardSubmodel_Min=15
+# - BaSyxDashboardSubmodel_Max=30
+ ports:
+ - 6400:6400
+
+ aas-wrapper:
+ image: eclipsebasyx/aas-wrapper:0.1.0-SNAPSHOT
+ container_name: aas-wrapper
+ ports:
+ - 6500:6500
\ No newline at end of file
diff --git a/examples/basyx.aasWrapper/pom.xml b/examples/basyx.aasWrapper/pom.xml
new file mode 100644
index 0000000..599b939
--- /dev/null
+++ b/examples/basyx.aasWrapper/pom.xml
@@ -0,0 +1,66 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.eclipse.basyx</groupId>
+ <artifactId>basyx.components.docker</artifactId>
+ <version>1.0.0</version>
+ </parent>
+
+ <artifactId>basyx.components.AASWrapper</artifactId>
+ <name>BaSyx AAS Wrapper</name>
+
+ <properties>
+ <!--
+ basyx.components.executable is the executable class with the definition of the public void main(String[]).
+ It is needed when building the jar in the maven-jar-plugin (see basyx.components.docker/pom.xml)
+ -->
+ <basyx.components.executable>org.eclipse.basyx.wrapper.AASWrapperExecutable</basyx.components.executable>
+ </properties>
+
+ <packaging>jar</packaging>
+
+ <!-- Define additional plugins that are not included by default -->
+ <!-- Plugin configuration is done in parent project(s) -->
+ <build>
+ <plugins>
+ <!-- Attach sources to jar file -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <!--
+ "Docker" profile - do not build & install docker images by default
+ Run "mvn install -Pdocker" in order to include docker
+ -->
+ <id>docker</id>
+ <build>
+ <plugins>
+ <!-- Read maven properties from file -->
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>properties-maven-plugin</artifactId>
+ </plugin>
+
+ <!-- Copy the dependencies necessary to run the jar -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ </plugin>
+
+ <!-- Build the docker image -->
+ <plugin>
+ <groupId>com.spotify</groupId>
+ <artifactId>dockerfile-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
\ No newline at end of file
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/AASWrapperExecutable.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/AASWrapperExecutable.java
new file mode 100644
index 0000000..36e1bc3
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/AASWrapperExecutable.java
@@ -0,0 +1,209 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.components.configuration.BaSyxConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxHTTPServer;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
+import org.eclipse.basyx.wrapper.provider.GenericHTTPInterface;
+import org.eclipse.basyx.wrapper.provider.GenericWrapperProvider;
+import org.eclipse.basyx.wrapper.provider.IWrapperProvider;
+import org.eclipse.basyx.wrapper.provider.aas.AASWrapperProvider;
+import org.eclipse.basyx.wrapper.provider.grafana.GrafanaProvider;
+import org.eclipse.basyx.wrapper.provider.streamsheets.StreamsheetsProvider;
+import org.eclipse.basyx.wrapper.receiver.IPropertyWrapperService;
+import org.eclipse.basyx.wrapper.receiver.SeparateAASService;
+import org.eclipse.basyx.wrapper.receiver.configuration.AASPropertyConfiguration;
+import org.eclipse.basyx.wrapper.receiver.configuration.PropertyConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Runs the AAS wrapper for the given configuration. The configuration is loaded
+ * from the wrapper.properties by default, but can also be given by an external file.
+ * For this, the path has to be specified in the BASYX_WRAPPER java property or system
+ * environment variable.
+ *
+ * @author espen
+ *
+ */
+public class AASWrapperExecutable {
+ private static final Logger logger = LoggerFactory.getLogger(AASWrapperExecutable.class);
+ public static final int PORT = 6500;
+ public static final String HOST = "aas-wrapper";
+
+ private static String registryAddress;
+ private static Map<String, PropertyConfiguration> propertyConfigs;
+ private static Map<String, String> activeProviders = new HashMap<>();
+ private static Map<String, String> providerPaths = new HashMap<>();
+
+ public static void main(String[] args) throws Exception {
+ logger.info("Wrapper started, waiting for other components");
+ // Use docker-compose health check for registry and aas instead
+ Thread.sleep(6000);
+
+ logger.info("Loading configuration...");
+ loadConfigs("wrapper.properties");
+
+ logger.info("Creating proxy for " + propertyConfigs.size() + " properties...");
+ IAASRegistry registry = new AASRegistryProxy(registryAddress);
+ IPropertyWrapperService connector = new SeparateAASService(registry, propertyConfigs.values());
+
+ logger.info("Creating " + activeProviders.size() + " providers...");
+ List<IWrapperProvider> providers = createProxyProviders();
+ providers.forEach(p -> p.initialize(connector, registry, propertyConfigs.values()));
+
+ if (!providers.isEmpty()) {
+ logger.info("Starting property proxy service...");
+ connector.start();
+ logger.info("Starting proxy providers...");
+ createServlet(providers);
+ } else {
+ logger.info("No providers have been created!");
+ }
+
+ logger.info("Finished");
+ }
+
+ private static List<IWrapperProvider> createProxyProviders() {
+ List<IWrapperProvider> providers = new ArrayList<>();
+ for (Entry<String, String> entry : activeProviders.entrySet()) {
+ String providerId = entry.getKey();
+ String providerType = entry.getValue();
+ IWrapperProvider newProvider;
+ switch (providerType) {
+ case (AASWrapperProvider.TYPE):
+ newProvider = new AASWrapperProvider(HOST, PORT);
+ break;
+ case (GrafanaProvider.TYPE):
+ newProvider = new GrafanaProvider();
+ break;
+ case (StreamsheetsProvider.TYPE):
+ newProvider = new StreamsheetsProvider();
+ break;
+ default:
+ newProvider = new GenericWrapperProvider();
+ }
+ String newPath = providerPaths.get(providerId);
+ if (newPath != null) {
+ newProvider.setProviderPath(newPath);
+ }
+ providers.add(newProvider);
+ }
+ return providers;
+ }
+
+ private static void loadConfigs(String resourceFileName) {
+ // Load resource file
+ logger.info("Loading proxy property file " + resourceFileName);
+ Map<String, String> configMap = new HashMap<>();
+ BaSyxConfiguration config = new BaSyxConfiguration(configMap);
+ config.loadFileOrDefaultResource("BASYX_WRAPPER", "wrapper.properties");
+
+ loadRegistryConfig(config);
+ propertyConfigs = loadPropertyConfigs(configMap);
+ loadProviderConfigs(configMap);
+ }
+
+ private static void loadRegistryConfig(BaSyxConfiguration config) {
+ registryAddress = config.getProperty("registry.endpoint");
+ logger.info("Registry address: " + registryAddress);
+ }
+
+ private static Map<String, PropertyConfiguration> loadPropertyConfigs(Map<String, String> configMap) {
+ Map<String, PropertyConfiguration> configs = new HashMap<>();
+ for (Entry<String, String> entry : configMap.entrySet()) {
+ String key = entry.getKey();
+ String[] propKeys = key.split("\\.");
+ if (propKeys.length != 3 || !propKeys[0].equals(PropertyConfiguration.INDEX)) {
+ continue;
+ }
+
+ String propId = propKeys[1];
+ String parameter = propKeys[2];
+ String value = entry.getValue();
+ if (!configs.containsKey(propId)) {
+ logger.info("Creating property " + propId);
+ PropertyConfiguration propConfig = new PropertyConfiguration();
+ propConfig.setId(propId);
+ configs.put(propId, propConfig);
+ }
+ setPropertyParameter(configs, propId, parameter, value);
+ }
+ return configs;
+ }
+
+ private static void loadProviderConfigs(Map<String, String> configMap) {
+ for (Entry<String, String> entry : configMap.entrySet()) {
+ String key = entry.getKey();
+ String[] propKeys = key.split("\\.");
+ if (propKeys.length != 3 || !propKeys[0].equals(GenericWrapperProvider.INDEX)) {
+ continue;
+ }
+
+ String providerId = propKeys[1];
+ String parameter = propKeys[2];
+ String value = entry.getValue();
+
+ switch (parameter) {
+ case ("type"):
+ activeProviders.put(providerId, value);
+ logger.info("Setting provider '" + providerId + "': type=" + value);
+ break;
+ case ("path"):
+ providerPaths.put(providerId, value);
+ logger.info("Setting provider '" + providerId + "': path=" + value);
+ break;
+ default:
+ logger.info("Invalid config for provider '" + providerId + "': " + parameter + "=" + value);
+ }
+
+ }
+ }
+
+ private static void setPropertyParameter(Map<String, PropertyConfiguration> configs, String propId,
+ String parameter, String value) {
+ logger.info("Setting property '" + propId + "': " + parameter + "=" + value);
+ PropertyConfiguration prop = configs.get(propId);
+ prop.put(parameter, value);
+ if (parameter.equals(PropertyConfiguration.TYPE)) {
+ // Possibility to add more property types
+ switch (value) {
+ case (AASPropertyConfiguration.TYPE):
+ configs.put(propId, new AASPropertyConfiguration(prop));
+ break;
+ default:
+ logger.error("Unknown property type: " + value);
+ }
+ }
+ }
+
+ private static void createServlet(List<IWrapperProvider> providers) {
+ BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
+ contextConfig.loadFromDefaultSource();
+ BaSyxContext context = contextConfig.createBaSyxContext();
+ for (IWrapperProvider provider : providers) {
+ context.addServletMapping(provider.getProviderPath() + "/*",
+ new GenericHTTPInterface(provider));
+ }
+ BaSyxHTTPServer server = new BaSyxHTTPServer(context);
+ server.start();
+ }
+}
+
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/exception/WrapperRequestException.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/exception/WrapperRequestException.java
new file mode 100644
index 0000000..87c90d0
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/exception/WrapperRequestException.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.exception;
+
+/**
+ * Exception that is thrown when the wrapper cannot request a value from its datasource
+ *
+ * @author espen
+ *
+ */
+public class WrapperRequestException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+
+ public WrapperRequestException(String message) {
+ super(message);
+ }
+
+ public WrapperRequestException(String message, Throwable error) {
+ super(message, error);
+ }
+
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/GenericHTTPInterface.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/GenericHTTPInterface.java
new file mode 100644
index 0000000..0d8f4eb
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/GenericHTTPInterface.java
@@ -0,0 +1,252 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.provider;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.StringJoiner;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.protocol.http.server.BasysHTTPServlet;
+import org.eclipse.basyx.vab.protocol.http.server.ExceptionToHTTPCodeMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.io.ByteSource;
+
+/**
+ * Implements a generic HTTP interface based on a JSONProvider that implements
+ * GET, PUT, POST, PATCH and DELETE and supports returning objects for each of the
+ * primitive. For PUT, POST and PATCH, it also supports passing objects.
+ *
+ * @author espen
+ *
+ */
+public class GenericHTTPInterface extends BasysHTTPServlet {
+ private static Logger logger = LoggerFactory.getLogger(GenericHTTPInterface.class);
+
+ private static final String CHARSET = "UTF-8";
+ private static final String MIMETYPE = "application/json";
+
+ /**
+ * Version information to identify the version of serialized instances
+ */
+ private static final long serialVersionUID = 1L;
+
+ private final JSONProvider provider;
+
+ /**
+ * Constructor
+ */
+ public GenericHTTPInterface(IWrapperProvider backend) {
+ this.provider = new JSONProvider(backend);
+ }
+
+ /**
+ * Implement "Get" operation
+ *
+ * Process HTTP get request - get sub model property value
+ */
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ try {
+ String path = extractPath(req);
+ prepareResponse(resp);
+ provider.processGet(path, resp.getOutputStream());
+ } catch (IOException e) {
+ logger.warn("Exception in HTTP-GET", e);
+ } catch (ProviderException e) {
+ int httpCode = ExceptionToHTTPCodeMapper.mapFromException(e);
+ resp.setStatus(httpCode);
+ logger.debug("Exception in GET request - response-code: " + httpCode, e);
+ }
+ }
+
+ /**
+ * Implement "Set" operation
+ */
+ @Override
+ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ try {
+ String path = extractPath(req);
+ String serValue = extractSerializedValue(req);
+ prepareResponse(resp);
+ provider.processPut(path, serValue, resp.getOutputStream());
+ } catch (IOException e) {
+ logger.warn("Exception in HTTP-PUT", e);
+ } catch (ProviderException e) {
+ int httpCode = ExceptionToHTTPCodeMapper.mapFromException(e);
+ resp.setStatus(httpCode);
+ logger.debug("Exception in PUT request - response-code: " + httpCode, e);
+ }
+ }
+
+
+ /**
+ * <pre>
+ * Handle HTTP POST operation. Creates a new Property, Operation, Event,
+ * Submodel or AAS or invokes an operation.
+ */
+ @Override
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ try {
+ String path = extractPath(req);
+ String serValue = extractSerializedValue(req);
+ prepareResponse(resp);
+ provider.processPost(path, serValue, resp.getOutputStream());
+ } catch (IOException e) {
+ logger.warn("Exception in HTTP-POST", e);
+ } catch (ProviderException e) {
+ int httpCode = ExceptionToHTTPCodeMapper.mapFromException(e);
+ resp.setStatus(httpCode);
+ logger.debug("Exception in POST request - response-code: " + httpCode, e);
+ }
+ }
+
+
+ /**
+ * Handle a HTTP PATCH operation. Updates a map or collection
+ *
+ */
+ @Override
+ protected void doPatch(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ try {
+ String path = extractPath(req);
+ String serValue = extractSerializedValue(req);
+ prepareResponse(resp);
+ provider.processPatch(path, serValue, resp.getOutputStream());
+ } catch (IOException e) {
+ logger.warn("Exception in HTTP-PATCH", e);
+ } catch (ProviderException e) {
+ int httpCode = ExceptionToHTTPCodeMapper.mapFromException(e);
+ resp.setStatus(httpCode);
+ logger.debug("Exception in PATCH request - response-code: " + httpCode, e);
+ }
+ }
+
+
+ /**
+ * Implement "Delete" operation. Deletes any resource under the given path.
+ */
+ @Override
+ protected void doDelete(HttpServletRequest req, HttpServletResponse resp) {
+ try {
+ String path = extractPath(req);
+ prepareResponse(resp);
+ provider.processDelete(path, resp.getOutputStream());
+ } catch (IOException e) {
+ logger.warn("Exception in HTTP-DELETE", e);
+ } catch (ProviderException e) {
+ int httpCode = ExceptionToHTTPCodeMapper.mapFromException(e);
+ resp.setStatus(httpCode);
+ logger.debug("Exception in DELETE request - response-code: " + httpCode, e);
+ }
+ }
+
+
+ private String extractPath(HttpServletRequest req) {
+ // Extract path
+ String uri = req.getRequestURI();
+
+ // Normalizes URI
+ String nUri = "/" + VABPathTools.stripSlashes(uri);
+ String contextPath = req.getContextPath();
+ if (nUri.startsWith(contextPath) && nUri.length() > getEnvironmentPathSize(req) - 1) {
+ String path = nUri.substring(getEnvironmentPathSize(req));
+ String extractedParameters = extractParameters(req);
+
+ path = VABPathTools.stripSlashes(path);
+
+ if (extractedParameters.isEmpty()) {
+ path += "/";
+ } else {
+ path += extractedParameters;
+ }
+ return path;
+ }
+ throw new MalformedRequestException("The passed path " + uri + " is not a possbile path for this server.");
+ }
+
+ /**
+ * Extracts request parameters from the request
+ *
+ * @param req
+ * @return
+ */
+ private String extractParameters(HttpServletRequest req) {
+ Enumeration<String> parameterNames = req.getParameterNames();
+
+ // Collect list of parameters
+ List<String> parameters = new ArrayList<>();
+ while (parameterNames.hasMoreElements()) {
+
+ StringBuilder ret = new StringBuilder();
+ String paramName = parameterNames.nextElement();
+ ret.append(paramName);
+ ret.append("=");
+
+ String[] paramValues = req.getParameterValues(paramName);
+ for (int i = 0; i < paramValues.length; i++) {
+ ret.append(paramValues[i]);
+ }
+ parameters.add(ret.toString());
+
+ }
+
+ // If no parameter is existing, return an empty string. Else join the parameters
+ // and return them prefixed with a ?
+ if (parameters.isEmpty()) {
+ return "";
+ } else {
+ StringJoiner joiner = new StringJoiner("&");
+ parameters.stream().forEach(joiner::add);
+ return "?" + joiner.toString();
+ }
+ }
+
+ private int getEnvironmentPathSize(HttpServletRequest req) {
+ return req.getContextPath().length() + req.getServletPath().length();
+ }
+
+
+ /**
+ * Read serialized value
+ * @param req
+ * @return
+ * @throws IOException
+ */
+ private String extractSerializedValue(HttpServletRequest req) throws IOException {
+ // https://www.baeldung.com/convert-input-stream-to-string#guava
+ ByteSource byteSource = new ByteSource() {
+ @Override
+ public InputStream openStream() throws IOException {
+ return req.getInputStream();
+ }
+ };
+
+ return byteSource.asCharSource(StandardCharsets.UTF_8).read();
+ }
+
+ private void prepareResponse(HttpServletResponse resp) {
+ resp.setContentType(MIMETYPE);
+ resp.setCharacterEncoding(CHARSET);
+ resp.setStatus(200);
+ }
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/GenericWrapperProvider.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/GenericWrapperProvider.java
new file mode 100644
index 0000000..3e173d0
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/GenericWrapperProvider.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.provider;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.wrapper.receiver.IPropertyWrapperService;
+import org.eclipse.basyx.wrapper.receiver.configuration.PropertyConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Wraps any connector API with a ModelProvider
+ *
+ * @author espen
+ *
+ */
+public class GenericWrapperProvider implements IWrapperProvider {
+ public static final String INDEX = "providers";
+ private static final Logger logger = LoggerFactory.getLogger(GenericWrapperProvider.class);
+
+ protected IPropertyWrapperService proxyService;
+ protected String providerPath = "provider";
+ protected Set<String> passiveProperties = new HashSet<>();
+
+ @Override
+ public void initialize(IPropertyWrapperService wrapperService, IAASRegistry registry,
+ Collection<PropertyConfiguration> configs) {
+ logger.info(
+ "Initializing provider '" + this.getClass().getSimpleName() + "' on path " + this.getProviderPath());
+ this.proxyService = wrapperService;
+ for (PropertyConfiguration config : configs) {
+ if (!config.getActive()) {
+ passiveProperties.add(config.getId());
+ }
+ }
+ }
+
+ @Override
+ public Object get(String path) {
+ path = preparePath(path);
+ if ( passiveProperties.contains(path) ) {
+ proxyService.generatePassiveValue(path);
+ }
+ return proxyService.getPropertyValue(path);
+ }
+
+ @Override
+ public Object post(String path, Object newValue) {
+ path = preparePath(path);
+ proxyService.setPropertyValue(path, newValue);
+ return newValue;
+ }
+
+ protected String preparePath(String path) {
+ VABPathTools.checkPathForNull(path);
+ path = VABPathTools.stripSlashes(path);
+ return path;
+ }
+
+ @Override
+ public String getProviderPath() {
+ return providerPath;
+ }
+
+ @Override
+ public void setProviderPath(String path) {
+ this.providerPath = path;
+ }
+
+ @Override
+ public Object delete(String path) {
+ throw new MalformedRequestException("Deleting elements is not supported");
+ }
+
+ @Override
+ public Object put(String path, Object data) {
+ throw new MalformedRequestException("Setting elements is not supported");
+ }
+
+ @Override
+ public Object patch(String path, Object data) {
+ throw new MalformedRequestException("Patching elements is not supported");
+ }
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/HTTPModelProvider.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/HTTPModelProvider.java
new file mode 100644
index 0000000..a50d307
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/HTTPModelProvider.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.provider;
+
+/**
+ * A simple, generic HTTP-REST model provider
+ *
+ * @author espen
+ *
+ */
+public interface HTTPModelProvider {
+ public Object get(String path);
+
+ public Object delete(String path);
+
+ public Object put(String path, Object data);
+
+ public Object post(String path, Object data);
+
+ public Object patch(String path, Object data);
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/IWrapperProvider.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/IWrapperProvider.java
new file mode 100644
index 0000000..6d4eaa9
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/IWrapperProvider.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.provider;
+
+import java.util.Collection;
+
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.wrapper.receiver.IPropertyWrapperService;
+import org.eclipse.basyx.wrapper.receiver.configuration.PropertyConfiguration;
+
+/**
+ * Interface for a generic connector that makes use of the HTTPModelProvider interface
+ *
+ * @author espen
+ *
+ */
+public interface IWrapperProvider extends HTTPModelProvider {
+
+ /**
+ * Returns the path for this provider
+ *
+ * @return
+ */
+ public String getProviderPath();
+
+ /**
+ * Sets the path for this provider
+ *
+ * @param path
+ */
+ public void setProviderPath(String path);
+
+ /**
+ * Initialize the provider
+ *
+ * @param proxyService
+ * @param registry
+ */
+ public void initialize(IPropertyWrapperService proxyService, IAASRegistry registry,
+ Collection<PropertyConfiguration> configs);
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/JSONProvider.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/JSONProvider.java
new file mode 100644
index 0000000..f7b4268
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/JSONProvider.java
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.provider;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+
+import org.eclipse.basyx.vab.coder.json.metaprotocol.Result;
+import org.eclipse.basyx.vab.coder.json.serialization.DefaultTypeFactory;
+import org.eclipse.basyx.vab.coder.json.serialization.GSONTools;
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implementation variant of the JSONProvider for a generic HTTPModelProvider backend
+ *
+ * @author espen
+ *
+ */
+public class JSONProvider {
+
+ private static Logger logger = LoggerFactory.getLogger(JSONProvider.class);
+
+ /**
+ * Reference to serializer / deserializer
+ */
+ protected GSONTools serializer = null;
+
+ private HTTPModelProvider backend;
+
+ /**
+ * Constructor
+ */
+ public JSONProvider(HTTPModelProvider backend) {
+ this.backend = backend;
+ serializer = new GSONTools(new DefaultTypeFactory());
+ }
+
+ /**
+ * Marks success as false and delivers exception cause messages
+ * @param e
+ * @return
+ */
+ private String serialize(Exception e) {
+ // Create Ack
+ Result result = new Result(e);
+
+ // Serialize the whole thing
+ return serialize(result);
+ }
+
+
+ /**
+ * Serialize IResult (HashMap)
+ * @param string
+ * @return
+ */
+ private String serialize(Result string) {
+ // Serialize the whole thing
+ return serializer.serialize(string);
+ }
+
+
+ /**
+ * Send Error
+ * @param e
+ * @param path
+ * @param resp
+ */
+ private void sendException(OutputStream resp, Exception e) {
+
+ // Serialize Exception
+ String jsonString = serialize(e);
+ try {
+ resp.write(jsonString.getBytes(StandardCharsets.UTF_8));
+ } catch(IOException innerE) {
+ throw new ProviderException("Failed to send Exception '" + e.getMessage() + "' to client", innerE);
+ }
+
+ //If the Exception is a ProviderException, just rethrow it
+ if(e instanceof ProviderException) {
+ throw (ProviderException) e;
+ }
+
+ //If the Exception is not a ProviderException encapsulate it in one and log it
+ logger.error("Unknown Exception in JSONProvider", e);
+ throw new ProviderException(e);
+ }
+
+
+ /**
+ * Extracts parameter from JSON and handles de-serialization errors
+ */
+ private Object extractParameter(String serializedJSONValue) {
+ // Return value
+ Object result = null;
+ try {
+ // Deserialize json body
+ result = serializer.deserialize(serializedJSONValue);
+ } catch (Exception e) {
+ //JSON could not be deserialized
+ throw new MalformedRequestException(e);
+ }
+
+ return result;
+ }
+
+
+ public void processGet(String path, OutputStream outputStream) {
+ try {
+ logger.info("GET '" + path + "'");
+ Object value = backend.get(path);
+ String jsonString = serializer.serialize(value);
+ outputStream.write(jsonString.getBytes(StandardCharsets.UTF_8));
+ } catch (Exception e) {
+ sendException(outputStream, e);
+ }
+ }
+
+ public void processDelete(String path, OutputStream outputStream) {
+ try {
+ logger.info("DELETE '" + path + "'");
+ Object value = backend.delete(path);
+ String jsonString = serializer.serialize(value);
+ outputStream.write(jsonString.getBytes(StandardCharsets.UTF_8));
+ } catch (Exception e) {
+ sendException(outputStream, e);
+ }
+ }
+
+ public void processPost(String path, String serializedJSONValue, OutputStream outputStream) {
+ try {
+ Object parameter = extractParameter(serializedJSONValue);
+ Object value = backend.post(path, parameter);
+ String jsonString = serializer.serialize(value);
+ outputStream.write(jsonString.getBytes(StandardCharsets.UTF_8));
+ } catch (Exception e) {
+ sendException(outputStream, e);
+ }
+ }
+
+ public void processPatch(String path, String serializedJSONValue, OutputStream outputStream) {
+ try {
+ logger.info("PATCH " + path + "'");
+ Object parameter = extractParameter(serializedJSONValue);
+ Object value = backend.patch(path, parameter);
+ String jsonString = serializer.serialize(value);
+ outputStream.write(jsonString.getBytes(StandardCharsets.UTF_8));
+ } catch (Exception e) {
+ sendException(outputStream, e);
+ }
+ }
+
+ public void processPut(String path, String serializedJSONValue, OutputStream outputStream) {
+ try {
+ logger.info("PUT " + path + "'");
+ Object parameter = extractParameter(serializedJSONValue);
+ Object value = backend.put(path, parameter);
+ String jsonString = serializer.serialize(value);
+ outputStream.write(jsonString.getBytes(StandardCharsets.UTF_8));
+ } catch (Exception e) {
+ sendException(outputStream, e);
+ }
+ }
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/aas/AASWrapperProvider.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/aas/AASWrapperProvider.java
new file mode 100644
index 0000000..917d15f
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/aas/AASWrapperProvider.java
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.provider.aas;
+
+import java.util.Collection;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.restapi.AASModelProvider;
+import org.eclipse.basyx.aas.restapi.MultiSubmodelProvider;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.eclipse.basyx.wrapper.provider.IWrapperProvider;
+import org.eclipse.basyx.wrapper.receiver.IPropertyWrapperService;
+import org.eclipse.basyx.wrapper.receiver.configuration.PropertyConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * AAS Provider for the wrapper that exposes the GET-Part of the AAS interface
+ *
+ * @author espen
+ *
+ */
+public class AASWrapperProvider implements IWrapperProvider {
+ private static final Logger logger = LoggerFactory.getLogger(AASWrapperProvider.class);
+ public static final String TYPE = "AAS";
+
+ private final String host;
+ private final int port;
+
+ private MultiSubmodelProvider provider;
+
+ private String providerPath = "/aas";
+
+ /**
+ * Standard constructor for the AASWrapperProvider. Needs to know the wrapper endpoint to be able to register the
+ * created AAS interface
+ *
+ * @param host Host of the wrapper
+ * @param port Port for the wrapper
+ */
+ public AASWrapperProvider(String host, int port) {
+ this.host = host;
+ this.port = port;
+ }
+
+ @Override
+ public void initialize(IPropertyWrapperService wrapperService, IAASRegistry registry,
+ Collection<PropertyConfiguration> configs) {
+ logger.info("Initializing provider '" + this.getClass().getSimpleName() + "' on path " + this.getProviderPath());
+
+ // Create the VABMultiSubmodelProvider
+ AssetAdministrationShell aas = new WrapperAssetAdministrationShell();
+ Asset asset = new WrapperAsset();
+ aas.setAsset(asset);
+ Submodel sm = new WrapperSubmodel("Wrapper", new Identifier(IdentifierType.CUSTOM, "WrapperSubmodel"),
+ wrapperService,
+ configs);
+ aas.addSubmodel(sm);
+
+ provider = new MultiSubmodelProvider(new AASModelProvider(aas));
+ provider.addSubmodel(new SubmodelProvider(sm));
+
+ // Register the aas
+ AASDescriptor desc = createDescriptor(aas, sm);
+ registerAAS(registry, desc);
+ }
+
+ private AASDescriptor createDescriptor(AssetAdministrationShell aas, Submodel... submodels) {
+ AASDescriptor descriptor = new AASDescriptor(aas, "http://" + host + ":" + port + "/aas");
+ for (Submodel sm : submodels) {
+ descriptor.addSubmodelDescriptor(
+ new SubmodelDescriptor(sm,
+ "http://" + host + ":" + port + "/aas/submodels/" + sm.getIdShort() + "/"));
+ }
+ return descriptor;
+ }
+
+ private static void registerAAS(IAASRegistry registry, AASDescriptor descriptor) {
+ // Quick & dirty, try to register until registry is up
+ for (int i = 0; i < 10; i++) {
+ try {
+ registry.register(descriptor);
+ break;
+ } catch (Exception e) {
+ try {
+ Thread.sleep(2000);
+ } catch (InterruptedException e1) {
+ logger.warn("Interrupted", e1);
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+ }
+
+ @Override
+ public String getProviderPath() {
+ return providerPath;
+ }
+
+ @Override
+ public void setProviderPath(String path) {
+ this.providerPath = path;
+ }
+
+ @Override
+ public Object post(String path, Object data) {
+ throw new MalformedRequestException("Creating elements is not supported");
+ }
+
+ /**
+ * Only expose the get-Part of the HTTP-REST Interface of the AAS
+ */
+ @Override
+ public Object get(String path) {
+ return provider.getValue(path);
+ }
+
+ @Override
+ public Object delete(String path) {
+ throw new MalformedRequestException("Deleting elements is not supported");
+ }
+
+ @Override
+ public Object put(String path, Object data) {
+ throw new MalformedRequestException("Setting elements is not supported");
+ }
+
+ @Override
+ public Object patch(String path, Object data) {
+ throw new MalformedRequestException("Patching elements is not supported");
+ }
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/aas/WrapperAsset.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/aas/WrapperAsset.java
new file mode 100644
index 0000000..f69cbc7
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/aas/WrapperAsset.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.provider.aas;
+
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+
+/**
+ * Dummy asset for the wrapper AAS interface
+ *
+ * @author espen
+ *
+ */
+public class WrapperAsset extends Asset {
+ public WrapperAsset() {
+ setIdShort("WrapperAsset");
+ setIdentification(IdentifierType.CUSTOM, "WrapperAsset");
+ setAssetKind(AssetKind.INSTANCE);
+ }
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/aas/WrapperAssetAdministrationShell.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/aas/WrapperAssetAdministrationShell.java
new file mode 100644
index 0000000..9e3c77a
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/aas/WrapperAssetAdministrationShell.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.provider.aas;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+
+/**
+ * Dummy AAS for the wrapper AAS interface
+ *
+ * @author espen
+ *
+ */
+public class WrapperAssetAdministrationShell extends AssetAdministrationShell {
+ public WrapperAssetAdministrationShell() {
+ setIdShort("WrapperAAS");
+ setIdentification(IdentifierType.CUSTOM, "WrapperAAS");
+ }
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/aas/WrapperSubmodel.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/aas/WrapperSubmodel.java
new file mode 100644
index 0000000..d539a21
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/aas/WrapperSubmodel.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.provider.aas;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProviderHelper;
+import org.eclipse.basyx.wrapper.receiver.IPropertyWrapperService;
+import org.eclipse.basyx.wrapper.receiver.PropertyResult;
+import org.eclipse.basyx.wrapper.receiver.configuration.PropertyConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A submodel for wrapping the data
+ *
+ * @author espen
+ *
+ */
+public class WrapperSubmodel extends Submodel {
+ private static final Logger logger = LoggerFactory.getLogger(WrapperSubmodel.class);
+
+ protected Map<String, SubmodelElementCollection> collections = new HashMap<>();
+ private IPropertyWrapperService proxyService;
+
+ public WrapperSubmodel(String idShort, IIdentifier id, IPropertyWrapperService connector,
+ Collection<PropertyConfiguration> config) {
+ super();
+ setIdShort(idShort);
+ setIdentification(id.getIdType(), id.getId());
+ setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, true, "0112/2///61360_4#AAF891#001", KeyType.IRDI)));
+
+ proxyService = connector;
+ proxyService.addProxyListener((String propId, PropertyResult result) -> {
+ SubmodelElementCollection coll = collections.get(propId);
+ if (coll != null) {
+ Collection<ISubmodelElement> smElements = generateSubmodelElements(propId, result);
+ coll.setValue(smElements);
+ } else {
+ logger.error("Invalid property '" + propId + "' has been updated");
+ }
+ });
+ initialize(config, connector);
+ }
+
+ private void initialize(Collection<PropertyConfiguration> configs, IPropertyWrapperService connector) {
+ for ( PropertyConfiguration config : configs ) {
+ String propId = config.getId();
+ if ( config.getActive() ) {
+ setActiveProperty(propId);
+ } else {
+ setPassiveProperty(propId);
+ }
+ }
+ }
+
+ private Collection<ISubmodelElement> generateSubmodelElements(String idShort, PropertyResult result) {
+ Collection<ISubmodelElement> elements = new ArrayList<>();
+ List<Object> data = result.getData();
+ List<String> dates = result.getTimestamps();
+ for (int i = data.size() - 1; i >= 0; i--) {
+ Property dateProp = new Property();
+ dateProp.setIdShort("time" + i);
+ dateProp.setValue(dates.get(i).toString());
+ elements.add(dateProp);
+ Property valueProp = new Property();
+ valueProp.setIdShort("value" + i);
+ valueProp.setValue(data.get(i));
+ elements.add(valueProp);
+ }
+ Operation setOperation = new Operation();
+ setOperation.setIdShort("set" + idShort);
+ Function<Object[], Object> fillInvokable = (params) -> {
+ // not supported, yet
+ return params;
+ };
+ setOperation.setInvokable(fillInvokable);
+ elements.add(setOperation);
+ return elements;
+ }
+
+ private void setActiveProperty(String propId) {
+ SubmodelElementCollection coll = new SubmodelElementCollection();
+ coll.setIdShort(propId);
+ collections.put(propId, coll);
+ addSubmodelElement(coll);
+ }
+
+ private void setPassiveProperty(final String propId) {
+ SubmodelElementCollection coll = new SubmodelElementCollection();
+ coll.setIdShort(propId);
+ collections.put(propId, new SubmodelElementCollection());
+ addSubmodelElement(coll);
+
+ coll.put(Property.VALUE, VABLambdaProviderHelper.createSimple(() -> {
+ proxyService.generatePassiveValue(propId);
+ return collections.get(propId).getValue();
+ }, null));
+ }
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/grafana/GrafanaProvider.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/grafana/GrafanaProvider.java
new file mode 100644
index 0000000..041401f
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/grafana/GrafanaProvider.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.provider.grafana;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.eclipse.basyx.wrapper.provider.GenericWrapperProvider;
+import org.eclipse.basyx.wrapper.receiver.PropertyResult;
+
+/**
+ * Grafana-specific proxy provider. Is based on a SimpleJson interface for grafana
+ *
+ * @author espen
+ */
+public class GrafanaProvider extends GenericWrapperProvider {
+ public static final String TYPE = "GRAFANA";
+
+ public GrafanaProvider() {
+ this.providerPath = "/grafana";
+ }
+
+ @Override
+ public Object get(String path) {
+ return true;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Object post(String path, Object value) {
+ path = preparePath(path);
+
+ String idShort = null;
+ if (path.equals("search")) {
+ Map<String, Object> request = (Map<String, Object>) value;
+ idShort = (String) request.get("target");
+ Set<String> results = getSearchResults(idShort);
+ return results;
+ } else if (path.equals("query")) {
+ Map<String, Object> request = (Map<String, Object>) value;
+ List<Object> targets = (List<Object>) request.get("targets");
+ Map<String, Object> targetMap = (Map<String, Object>) targets.get(0);
+ idShort = (String) targetMap.get("target");
+ }
+
+ if (idShort == null || idShort.isEmpty()) {
+ return false;
+ }
+
+ PropertyResult result = (PropertyResult) super.get(idShort);
+ GrafanaTimeseries response = new GrafanaTimeseries();
+ response.addTarget(idShort, result);
+ return response;
+ }
+
+ private Set<String> getSearchResults(String term) {
+ Set<String> validProperties = proxyService.getValidProperties();
+ return validProperties.stream()
+ .filter(s -> s.toLowerCase().contains(term.toLowerCase()))
+ .collect(Collectors.toSet());
+ }
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/grafana/GrafanaTimeseries.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/grafana/GrafanaTimeseries.java
new file mode 100644
index 0000000..ebd18a5
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/grafana/GrafanaTimeseries.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.provider.grafana;
+
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.wrapper.receiver.PropertyResult;
+
+/**
+ * Conversion class for Grafana timeseries response
+ *
+ * @author espen
+ *
+ */
+public class GrafanaTimeseries extends ArrayList<Object> {
+ private static final long serialVersionUID = 1L;
+ public GrafanaTimeseries() {
+ super();
+ }
+
+ public void addTarget(String idShort, PropertyResult result) {
+ Map<String, Object> targetData = new HashMap<>();
+
+ List<Object> values = result.getData();
+ List<String> timestamps = result.getTimestamps();
+ List<List<Object>> dataPoints = new ArrayList<>(values.size());
+ for ( int i = 0; i < values.size(); i++ ) {
+ List<Object> entry = new ArrayList<>(2);
+ entry.add(values.get(i));
+ try {
+ Date date = PropertyResult.DATE_FORMAT.parse(timestamps.get(i));
+ long ms = date.getTime();
+ entry.add(ms);
+ } catch (ParseException e) {
+ e.printStackTrace();
+ break;
+ }
+ // entry.add(Integer.parseInt(timestamps.get(i))); // add string formatted timestamp
+ dataPoints.add(entry);
+ }
+ targetData.put("target", idShort);
+ targetData.put("datapoints", dataPoints);
+ this.add(targetData);
+ }
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/streamsheets/StreamsheetsProvider.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/streamsheets/StreamsheetsProvider.java
new file mode 100644
index 0000000..5c0ca5b
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/streamsheets/StreamsheetsProvider.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.provider.streamsheets;
+
+import org.eclipse.basyx.wrapper.provider.GenericWrapperProvider;
+
+/**
+ * Streamsheets-specific proxy provider
+ *
+ * @author espen
+ */
+public class StreamsheetsProvider extends GenericWrapperProvider {
+ public static final String TYPE = "STREAMSHEETS";
+
+ public StreamsheetsProvider() {
+ this.providerPath = "/streamsheets";
+ }
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/DataPoint.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/DataPoint.java
new file mode 100644
index 0000000..fe6ba96
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/DataPoint.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.receiver;
+
+import java.util.Date;
+
+/**
+ * Represents a single datapoint for a property
+ *
+ * @author espen
+ *
+ */
+public class DataPoint {
+ private Date timestamp;
+ private Object value;
+
+ public DataPoint(Object value) {
+ this.timestamp = new Date();
+ this.value = value;
+ }
+
+ public DataPoint(Date timestamp, Object value) {
+ this.timestamp = timestamp;
+ this.value = value;
+ }
+
+ public Date getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(Date timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ public Object getValue() {
+ return value;
+ }
+
+ public void setValue(Object value) {
+ this.value = value;
+ }
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/IPropertyEndpoint.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/IPropertyEndpoint.java
new file mode 100644
index 0000000..41f0c6d
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/IPropertyEndpoint.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.receiver;
+
+/**
+ * Represents a single property endpoint
+ *
+ * @author espen
+ *
+ */
+public interface IPropertyEndpoint {
+ public DataPoint retrieveValue();
+
+ public void setValue(Object newValue);
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/IPropertyWrapperService.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/IPropertyWrapperService.java
new file mode 100644
index 0000000..08a4145
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/IPropertyWrapperService.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.receiver;
+
+import java.util.Set;
+
+import org.eclipse.basyx.wrapper.receiver.configuration.PropertyConfiguration;
+
+/**
+ * Interface for a property service to get and set properties
+ *
+ * @author espen
+ *
+ */
+public interface IPropertyWrapperService {
+ /**
+ * Adds a property configuration to the service
+ *
+ * @param config
+ */
+ public void addPropertyConfig(PropertyConfiguration config);
+
+ /**
+ * Returns a list of valid properties that have been configured
+ */
+ public Set<String> getValidProperties();
+
+ /**
+ * Gets the current result for a property
+ *
+ * @param propId
+ * @return
+ */
+ public PropertyResult getPropertyValue(String propId);
+
+ /**
+ * Explicitely generates a new value for a passive property.
+ *
+ * @param propId
+ * @return
+ */
+ public void generatePassiveValue(String propId);
+
+ /**
+ * Sets a remote data point to a new value
+ *
+ * @param propId
+ * @param newValue
+ */
+ public void setPropertyValue(String propId, Object newValue);
+
+ public void addProxyListener(IWrapperListener listener);
+
+ /**
+ * Start collecting data for all active properties
+ */
+ public void start();
+
+ /**
+ * Stop collecting data for all active properties
+ */
+ public void stop();
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/IWrapperListener.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/IWrapperListener.java
new file mode 100644
index 0000000..5040d05
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/IWrapperListener.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.receiver;
+
+/**
+ * A listener for values that have been generated by the wrapper
+ *
+ * @author espen
+ *
+ */
+public interface IWrapperListener {
+ /**
+ * Informs the listener about a new value that has been generated
+ *
+ * @param result
+ */
+ public void newValue(String propId, PropertyResult result);
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/PropertyResult.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/PropertyResult.java
new file mode 100644
index 0000000..a947aa1
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/PropertyResult.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.receiver;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Represents a property result with multiple datapoints
+ *
+ * @author espen
+ *
+ */
+public class PropertyResult extends HashMap<String, Object> {
+ private static final long serialVersionUID = 1L;
+ public static final String CONTENT = "content";
+ public static final String DATES = "timestamp";
+ public static final String TITLE = "title";
+ public static final String SUCCESS = "success";
+
+ protected int maxValues = 10;
+ protected List<Object> content = new ArrayList<>();
+ // VAB can't serialize dates, yet
+ protected List<String> timestamp = new ArrayList<>();
+
+ public static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
+
+ public PropertyResult(String title, int maxValues) {
+ this.maxValues = maxValues;
+ put(CONTENT, content);
+ put(DATES, timestamp);
+ put(SUCCESS, true);
+ put(TITLE, "Value of property '" + title + "'");
+ }
+
+ public PropertyResult(PropertyResult clone) {
+ this.maxValues = clone.maxValues;
+ content = new ArrayList<>(clone.getData());
+ timestamp = new ArrayList<>(clone.getTimestamps());
+ put(CONTENT, content);
+ put(DATES, timestamp);
+ put(SUCCESS, clone.getSuccess());
+ put(TITLE, "Value of property '" + clone.getTitle() + "'");
+ }
+
+ public void setSuccess(boolean success) {
+ put(SUCCESS, success);
+ }
+
+ public boolean getSuccess() {
+ return (boolean) get(SUCCESS);
+ }
+
+ public void setTitle(String title) {
+ put(TITLE, title);
+ }
+
+ public String getTitle() {
+ return (String) get(TITLE);
+ }
+
+ public List<Object> getData() {
+ return content;
+ }
+
+ public List<String> getTimestamps() {
+ return timestamp;
+ }
+
+ public synchronized void addDataPoint(DataPoint value) {
+ content.add(value.getValue());
+ timestamp.add(DATE_FORMAT.format(value.getTimestamp()));
+ while (content.size() > maxValues) {
+ content.remove(0);
+ timestamp.remove(0);
+ }
+ }
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/SeparateAASService.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/SeparateAASService.java
new file mode 100644
index 0000000..48c0ef7
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/SeparateAASService.java
@@ -0,0 +1,223 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.receiver;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedProperty;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
+import org.eclipse.basyx.vab.factory.java.ModelProxyFactory;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
+import org.eclipse.basyx.wrapper.exception.WrapperRequestException;
+import org.eclipse.basyx.wrapper.receiver.configuration.AASPropertyConfiguration;
+import org.eclipse.basyx.wrapper.receiver.configuration.PropertyConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Wrapper service for seperately querying the configured properties.
+ *
+ * @author espen
+ *
+ */
+public class SeparateAASService implements IPropertyWrapperService {
+ private static final Logger logger = LoggerFactory.getLogger(SeparateAASService.class);
+
+ // Registry
+ protected IAASRegistry registry;
+
+ // Property configurations
+ protected Map<String, String> aasIds = new HashMap<>();
+ protected Map<String, String> submodelIds = new HashMap<>();
+ protected Map<String, String> shortIds = new HashMap<>();
+ protected Map<String, Integer> maxValues = new HashMap<>();
+ protected Set<String> activeProperties = new HashSet<>();
+
+ // Current data
+ protected Map<String, PropertyResult> propertyResults = new HashMap<>();
+
+ // Additional
+ protected Map<String, String> submodelCachedEndpoints = new HashMap<>();
+ protected Map<String, Thread> threads = new HashMap<>();
+ protected List<IWrapperListener> listeners = new ArrayList<>();
+
+ public SeparateAASService(IAASRegistry registry, Collection<PropertyConfiguration> configs) {
+ this.registry = registry;
+ configs.forEach(this::addPropertyConfig);
+ }
+
+ @Override
+ public void addPropertyConfig(PropertyConfiguration config) {
+ if (config instanceof AASPropertyConfiguration) {
+ AASPropertyConfiguration aasConfig = (AASPropertyConfiguration) config;
+
+ String propId = config.getId();
+ logger.info("Initialize " + propId);
+ aasIds.put(propId, aasConfig.getAAS());
+ submodelIds.put(propId, aasConfig.getSubmodel());
+ shortIds.put(propId, aasConfig.getShortId());
+ propertyResults.put(propId, new PropertyResult(propId, config.getMaxValues()));
+ if (config.getActive()) {
+ activeProperties.add(propId);
+ int interval = config.getInterval(); // => in ms
+ threads.put(propId, createPropertyThread(propId, interval));
+ }
+ }
+ }
+
+ private AASDescriptor getAASDescriptorFromRegistry(String aasId) {
+ // Assume custom AAS identifier => aas identifier type doesn't really matter for lookup
+ IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, aasId);
+ return registry.lookupAAS(aasIdentifier);
+ }
+
+ private String getSubmodelEndpoint(String aasId, String submodelId) {
+ String aasSmId = aasId + "::" + submodelId;
+ String smEndpoint = submodelCachedEndpoints.get(aasSmId);
+
+ if (smEndpoint == null) {
+ // Retrieve AAS descriptor from the registry to parse the submodel endpoint
+ try {
+ AASDescriptor aasDescriptor = getAASDescriptorFromRegistry(aasId);
+ SubmodelDescriptor smDescriptor = aasDescriptor.getSubmodelDescriptorFromIdShort(submodelId);
+
+ if (smDescriptor == null) {
+ throw new WrapperRequestException("Could not look up descriptor for SubModel '" + submodelId
+ + "' since it does not exist in AAS '" + aasId + "'");
+ }
+
+ smEndpoint = smDescriptor.getFirstEndpoint();
+
+ // Cache retrieved submodel endpoints
+ submodelCachedEndpoints.put(aasSmId, smEndpoint);
+ } catch (Exception e) {
+ throw new WrapperRequestException("Could not look up descriptor for AAS '" + aasId
+ + "' since it does not exist or is not available");
+ }
+ }
+
+ return smEndpoint;
+ }
+
+ private IProperty getConnectedProperty(String smEndpoint, String shortId) {
+ // Build the property address from that (and assume it's there)
+ String propEndpoint = VABPathTools.concatenatePaths(smEndpoint, MultiSubmodelElementProvider.ELEMENTS, shortId);
+
+ // Create a "ConnectedProperty" that gives access to the property
+ ModelProxyFactory mpf = new ModelProxyFactory(new HTTPConnectorFactory());
+ return new ConnectedProperty(mpf.createProxy(propEndpoint));
+ }
+
+ private Object getSinglePropertyValue(String propId) {
+ try {
+ String aasId = aasIds.get(propId);
+ String submodelId = submodelIds.get(propId);
+ String shortId = shortIds.get(propId);
+ String smEndpoint = getSubmodelEndpoint(aasId, submodelId);
+ IProperty property = getConnectedProperty(smEndpoint, shortId);
+ return property.getValue();
+ } catch (Exception e) {
+ throw new WrapperRequestException(e.getLocalizedMessage(), e);
+ }
+ }
+
+ @Override
+ public PropertyResult getPropertyValue(String propId) {
+ // Clone a result to prevent changes in the returned value
+ return new PropertyResult(propertyResults.get(propId));
+ }
+
+ @Override
+ public void setPropertyValue(String propId, Object newValue) {
+ try {
+ String aasId = aasIds.get(propId);
+ String submodelId = submodelIds.get(propId);
+ String shortId = shortIds.get(propId);
+ String smEndpoint = getSubmodelEndpoint(aasId, submodelId);
+ IProperty property = getConnectedProperty(smEndpoint, shortId);
+ property.setValue(newValue);
+ } catch (Exception e) {
+ throw new WrapperRequestException(e.getLocalizedMessage(), e);
+ }
+ }
+
+ @Override
+ public void generatePassiveValue(String propId) {
+ if (activeProperties.contains(propId)) {
+ throw new WrapperRequestException("Property with id '" + propId + "' is active");
+ }
+ retrieveValue(propId);
+ }
+
+ private Thread createPropertyThread(final String propId, final int intervalTime) {
+ return new Thread(() -> {
+ Thread thisThread = Thread.currentThread();
+ while (thisThread == threads.get(propId)) {
+ retrieveValue(propId);
+ try {
+ Thread.sleep(intervalTime);
+ } catch (InterruptedException e) {
+ }
+ }
+ });
+ }
+
+ private void retrieveValue(String propId) {
+ PropertyResult values = propertyResults.get(propId);
+ if (values == null) {
+ throw new WrapperRequestException("Property with id '" + propId + "' does not exist");
+ }
+ Object newValue = getSinglePropertyValue(propId);
+ DataPoint dataPoint = new DataPoint(newValue);
+ values.addDataPoint(dataPoint);
+
+ // inform listeners
+ for (IWrapperListener listener : listeners) {
+ listener.newValue(propId, new PropertyResult(values));
+ }
+ }
+
+ @Override
+ public void start() {
+ logger.info("Starting " + threads.size() + " threads");
+ for (Thread t : threads.values()) {
+ t.start();
+ }
+ }
+
+ @Override
+ public void stop() {
+ threads.clear();
+ }
+
+ @Override
+ public void addProxyListener(IWrapperListener listener) {
+ this.listeners.add(listener);
+ }
+
+ @Override
+ public Set<String> getValidProperties() {
+ return propertyResults.keySet();
+ }
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/configuration/AASPropertyConfiguration.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/configuration/AASPropertyConfiguration.java
new file mode 100644
index 0000000..46c50f1
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/configuration/AASPropertyConfiguration.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.receiver.configuration;
+
+/**
+ * Represents a single configuration for a property. The datasource for this
+ * property is an AAS property.
+ *
+ * @author espen
+ *
+ */
+public class AASPropertyConfiguration extends PropertyConfiguration {
+ private static final long serialVersionUID = 1L;
+
+ public static final String TYPE = "AAS";
+
+ // indices in the configuration file
+ public static final String AAS = "aas";
+ public static final String SUBMODEL = "submodel";
+ public static final String SHORTID = "shortId";
+
+ public AASPropertyConfiguration() {
+ super();
+ }
+
+ public AASPropertyConfiguration(PropertyConfiguration config) {
+ putAll(config);
+ }
+
+ public String getAAS() {
+ return get(AAS);
+ }
+
+ public void setAAS(String aas) {
+ put(AAS, aas);
+ }
+
+ public String getSubmodel() {
+ return get(SUBMODEL);
+ }
+
+ public void setSubmodel(String submodel) {
+ put(SUBMODEL, submodel);
+ }
+
+ public String getShortId() {
+ return get(SHORTID);
+ }
+
+ public void setShortId(String shortId) {
+ put(SHORTID, shortId);
+ }
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/configuration/PropertyConfiguration.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/configuration/PropertyConfiguration.java
new file mode 100644
index 0000000..460777e
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/configuration/PropertyConfiguration.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.receiver.configuration;
+
+import java.util.HashMap;
+import java.util.StringJoiner;
+
+/**
+ * Represents a single configuration for a proxy property.
+ *
+ * @author espen
+ *
+ */
+public class PropertyConfiguration extends HashMap<String, String> {
+ private static final long serialVersionUID = 1L;
+
+ // configuration indices
+ public static final String INDEX = "properties";
+ public static final String ID = "id";
+ public static final String TYPE = "type";
+ public static final String ACTIVE = "active";
+ public static final String INTERVAL = "interval";
+ public static final String MAX_VALUES = "maxValues";
+
+ public boolean getActive() {
+ return "true".equals(get(ACTIVE));
+ }
+
+ public void setActive(Boolean active) {
+ put(ACTIVE, active.toString());
+ }
+
+ /**
+ * Get active update interval in ms
+ *
+ * @return
+ */
+ public int getInterval() {
+ if (get(INTERVAL) != null) {
+ return Integer.parseInt(get(INTERVAL));
+ } else {
+ return 0;
+ }
+ }
+
+ public void setInterval(int interval) {
+ put(INTERVAL, String.valueOf(interval));
+ }
+
+ public int getMaxValues() {
+ if (get(MAX_VALUES) != null) {
+ return Integer.parseInt(get(MAX_VALUES));
+ } else {
+ return 1;
+ }
+ }
+
+ public void setMaxValues(int maxValues) {
+ put(INTERVAL, String.valueOf(maxValues));
+ }
+
+ public String getId() {
+ return get(ID);
+ }
+
+ public void setId(String id) {
+ put(ID, id);
+ }
+
+ public String getType() {
+ return get(TYPE);
+ }
+
+ public void setType(String type) {
+ put(TYPE, type);
+ }
+
+ @Override
+ public String toString() {
+ StringJoiner joiner = new StringJoiner(", ");
+ entrySet().forEach((Entry<String, String> e) -> {
+ joiner.add(e.getKey() + "=" + e.getValue());
+ });
+ return "{ " + joiner.toString() + " }";
+ }
+}
diff --git a/examples/basyx.aasWrapper/src/main/resources/context.properties b/examples/basyx.aasWrapper/src/main/resources/context.properties
new file mode 100644
index 0000000..6429487
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/resources/context.properties
@@ -0,0 +1,17 @@
+# ###############################
+# HTTP Context configuration file
+# ###############################
+
+# ###############################
+# Context Path
+# ###############################
+# Specifies the subpath in the url for this server context
+
+contextPath=/
+
+# ###############################
+# Port
+# ###############################
+# Specifies the port for this server context
+
+contextPort=6500
\ No newline at end of file
diff --git a/examples/basyx.aasWrapper/src/main/resources/wrapper.properties b/examples/basyx.aasWrapper/src/main/resources/wrapper.properties
new file mode 100644
index 0000000..957dc39
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/resources/wrapper.properties
@@ -0,0 +1,25 @@
+registry.endpoint=http://registry:4000/registry/
+
+properties.temp.type=AAS
+properties.temp.active=true
+properties.temp.aas=DashboardAAS
+properties.temp.submodel=DashboardSubmodel
+properties.temp.shortId=temperature
+properties.temp.interval=1000
+properties.temp.maxValues=10
+
+properties.dummy.type=AAS
+properties.dummy.active=false
+properties.dummy.aas=DashboardAAS
+properties.dummy.submodel=DashboardSubmodel
+properties.dummy.shortId=dummy
+properties.dummy.maxValues=3
+
+providers.simplified.type=STREAMSHEETS
+providers.simplified.path=/streamsheets
+
+providers.aas.type=AAS
+providers.aas.path=/proxyAAS
+
+providers.asdf.type=GRAFANA
+providers.asdf.path=/grafana
diff --git a/examples/basyx.aasWrapper/src/test/resources/.env b/examples/basyx.aasWrapper/src/test/resources/.env
new file mode 100644
index 0000000..4ca39a7
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/test/resources/.env
@@ -0,0 +1,39 @@
+# ##################
+# Docker Environment
+# ##################
+
+# ##################
+# Host Port
+# ##################
+# Specifies the port for the Docker HOST the container port is mapped to
+
+BASYX_HOST_PORT=6500
+
+# ##################
+# Container Port
+# ##################
+# Specifies the port for the Docker CONTAINER that is be mapped for the host
+
+BASYX_CONTAINER_PORT=6500
+
+# ##################
+# Image Name
+# ##################
+# The image of the image that is build for this component
+
+BASYX_IMAGE_NAME=basyx/aas-wrapper
+
+# ##################
+# Image Tag
+# ##################
+# The image tag of the image that is build for this component
+
+BASYX_IMAGE_TAG=1.0.0
+
+# ##################
+# Container Name
+# ##################
+# The name of the container used for the default environment
+
+BASYX_CONTAINER_NAME=aas-wrapper
+
diff --git a/examples/basyx.aasWrapper/start.bat b/examples/basyx.aasWrapper/start.bat
new file mode 100644
index 0000000..7d0dc6c
--- /dev/null
+++ b/examples/basyx.aasWrapper/start.bat
@@ -0,0 +1 @@
+docker-compose up
\ No newline at end of file
diff --git a/examples/basyx.aasWrapper/start.sh b/examples/basyx.aasWrapper/start.sh
new file mode 100644
index 0000000..d935e43
--- /dev/null
+++ b/examples/basyx.aasWrapper/start.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+docker-compose up
\ No newline at end of file
diff --git a/examples/basyx.aasWrapper/stop.bat b/examples/basyx.aasWrapper/stop.bat
new file mode 100644
index 0000000..58694d0
--- /dev/null
+++ b/examples/basyx.aasWrapper/stop.bat
@@ -0,0 +1 @@
+docker-compose down
\ No newline at end of file
diff --git a/examples/basyx.aasWrapper/stop.sh b/examples/basyx.aasWrapper/stop.sh
new file mode 100644
index 0000000..f5139e2
--- /dev/null
+++ b/examples/basyx.aasWrapper/stop.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+docker-compose down
\ No newline at end of file
diff --git a/examples/basyx.dashboardAAS/.gitignore b/examples/basyx.dashboardAAS/.gitignore
new file mode 100644
index 0000000..02eeb17
--- /dev/null
+++ b/examples/basyx.dashboardAAS/.gitignore
@@ -0,0 +1,69 @@
+.classpath
+.project
+
+regressiontest/
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+.mvn/wrapper/maven-wrapper.jar
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.settings/
+.loadpath
+.recommenders
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# PyDev specific (Python IDE for Eclipse)
+*.pydevproject
+
+# CDT-specific (C/C++ Development Tooling)
+.cproject
+
+# CDT- autotools
+.autotools
+
+# Java annotation processor (APT)
+.factorypath
+
+# PDT-specific (PHP Development Tools)
+.buildpath
+
+# sbteclipse plugin
+.target
+
+# Tern plugin
+.tern-project
+
+# TeXlipse plugin
+.texlipse
+
+# STS (Spring Tool Suite)
+.springBeans
+
+# Code Recommenders
+.recommenders/
+
+# Annotation Processing
+.apt_generated/
+
+# Scala IDE specific (Scala & Java development for Eclipse)
+.cache-main
+.scala_dependencies
+.worksheet
\ No newline at end of file
diff --git a/examples/basyx.dashboardAAS/Dockerfile b/examples/basyx.dashboardAAS/Dockerfile
new file mode 100644
index 0000000..1a26b27
--- /dev/null
+++ b/examples/basyx.dashboardAAS/Dockerfile
@@ -0,0 +1,23 @@
+# Add java runtime environment for execution
+FROM java:8-jdk-alpine
+
+# Copy built jar to image using the jar name specified in the pom.xml (JAR_FILE)
+ARG JAR_FILE
+COPY target/${JAR_FILE} /usr/share/basyxExecutable.jar
+COPY target/lib /usr/share/lib
+COPY src/main/resources/context.properties /usr/share/config/context.properties
+COPY src/main/resources/dashboardsubmodel.properties /usr/share/config/dashboardsubmodel.properties
+
+# Expose the appropriate port. In case of Tomcat, this is 8080.
+ARG PORT
+EXPOSE ${PORT}
+
+# Set the path for the context configuration file
+ARG CONTEXT_CONFIG_KEY
+ENV ${CONTEXT_CONFIG_KEY} "/usr/share/config/context.properties"
+
+# Set the path for the submodel config
+ENV BASYX_DASHBOARDSUBMODEL "/usr/share/config/dashboardsubmodel.properties"
+
+# Start the jar
+CMD java -jar "/usr/share/basyxExecutable.jar"
\ No newline at end of file
diff --git a/examples/basyx.dashboardAAS/build.bat b/examples/basyx.dashboardAAS/build.bat
new file mode 100644
index 0000000..0977f37
--- /dev/null
+++ b/examples/basyx.dashboardAAS/build.bat
@@ -0,0 +1 @@
+.././mvnw clean install -U -Pdocker
\ No newline at end of file
diff --git a/examples/basyx.dashboardAAS/build.sh b/examples/basyx.dashboardAAS/build.sh
new file mode 100644
index 0000000..d223f82
--- /dev/null
+++ b/examples/basyx.dashboardAAS/build.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+.././mvnw clean install -U -Pdocker -DskipTests
\ No newline at end of file
diff --git a/examples/basyx.dashboardAAS/docker-compose.yml b/examples/basyx.dashboardAAS/docker-compose.yml
new file mode 100644
index 0000000..a52f474
--- /dev/null
+++ b/examples/basyx.dashboardAAS/docker-compose.yml
@@ -0,0 +1,17 @@
+version: '3'
+services:
+
+ registry:
+ image: eclipsebasyx/aas-registry:1.0.1
+ container_name: dashboard-registry
+ ports:
+ - 4000:4000
+
+ dashboard-aas:
+ image: eclipsebasyx/dashboard-aas:0.1.0-SNAPSHOT
+ container_name: dashboard-aas
+ environment:
+ - BaSyxDashboardSubmodel_Min=15
+# - BaSyxDashboardSubmodel_Max=30
+ ports:
+ - 6400:6400
\ No newline at end of file
diff --git a/examples/basyx.dashboardAAS/pom.xml b/examples/basyx.dashboardAAS/pom.xml
new file mode 100644
index 0000000..183dff4
--- /dev/null
+++ b/examples/basyx.dashboardAAS/pom.xml
@@ -0,0 +1,66 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.eclipse.basyx</groupId>
+ <artifactId>basyx.components.docker</artifactId>
+ <version>1.0.0</version>
+ </parent>
+
+ <artifactId>basyx.components.dashboardAAS</artifactId>
+ <name>BaSyx Dashboard AAS</name>
+
+ <properties>
+ <!--
+ basyx.components.executable is the executable class with the definition of the public void main(String[]).
+ It is needed when building the jar in the maven-jar-plugin (see basyx.components.docker/pom.xml)
+ -->
+ <basyx.components.executable>org.eclipse.basyx.dashboard.AASExecutable</basyx.components.executable>
+ </properties>
+
+ <packaging>jar</packaging>
+
+ <!-- Define additional plugins that are not included by default -->
+ <!-- Plugin configuration is done in parent project(s) -->
+ <build>
+ <plugins>
+ <!-- Attach sources to jar file -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <!--
+ "Docker" profile - do not build & install docker images by default
+ Run "mvn install -Pdocker" in order to include docker
+ -->
+ <id>docker</id>
+ <build>
+ <plugins>
+ <!-- Read maven properties from file -->
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>properties-maven-plugin</artifactId>
+ </plugin>
+
+ <!-- Copy the dependencies necessary to run the jar -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ </plugin>
+
+ <!-- Build the docker image -->
+ <plugin>
+ <groupId>com.spotify</groupId>
+ <artifactId>dockerfile-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
\ No newline at end of file
diff --git a/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/AASExecutable.java b/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/AASExecutable.java
new file mode 100644
index 0000000..3f03e3d
--- /dev/null
+++ b/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/AASExecutable.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.dashboard;
+
+import java.util.ArrayList;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.aas.restapi.AASModelProvider;
+import org.eclipse.basyx.aas.restapi.MultiSubmodelProvider;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxHTTPServer;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
+import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Executable for a very basic, dynamic AAS, that is meant to be used in an example about how
+ * to integrate properties of "real" AAS in a dashboard.
+ *
+ * @author espen
+ *
+ */
+public class AASExecutable {
+ private static final Logger logger = LoggerFactory.getLogger(AASExecutable.class);
+
+ public static final String HOST = "dashboard-aas";
+ public static final int PORT = 6400;
+ public static final String REGISTRY_ENDPOINT = "http://registry:4000/registry/";
+
+ public static void main(String[] args) throws Exception {
+ // Use docker-compose health check for registry instead
+ Thread.sleep(3000);
+
+ logger.info("Creating AAS...");
+ AssetAdministrationShell aas = new DashboardAssetAdministrationShell();
+ Asset asset = new DashboardAsset();
+ aas.setAsset(asset);
+ Submodel sm = new DashboardSubmodel();
+ aas.setConceptDictionary(new ArrayList<>());
+ aas.addSubmodel(sm);
+
+ logger.info("Starting aas servlet...");
+ createServlet(aas, sm);
+ logger.info("Registering aas...");
+ AASDescriptor descriptor = new AASDescriptor(aas, "http://" + HOST + ":" + PORT + "/aas");
+ descriptor.addSubmodelDescriptor(
+ new SubmodelDescriptor(sm, "http://" + HOST + ":" + PORT + "/aas/submodels/DashboardSubmodel/"));
+ registerAAS(descriptor, REGISTRY_ENDPOINT);
+
+ logger.info("Finished");
+ }
+
+ private static void registerAAS(AASDescriptor descriptor, String registryEndpoint) throws InterruptedException {
+ IAASRegistry registry = new AASRegistryProxy(registryEndpoint);
+ // Quick & dirty, try to register until registry is up
+ for (int i = 0; i < 10; i++) {
+ try {
+ registry.register(descriptor);
+ break;
+ } catch (Exception e) {
+ Thread.sleep(2000);
+ }
+ }
+ }
+
+ private static void createServlet(AssetAdministrationShell aas, Submodel... submodels) {
+ MultiSubmodelProvider provider = new MultiSubmodelProvider();
+ provider.setAssetAdministrationShell(new AASModelProvider(aas));
+ for (Submodel sm : submodels) {
+ provider.addSubmodel(new SubmodelProvider(sm));
+ }
+ BaSyxContextConfiguration config = new BaSyxContextConfiguration();
+ config.loadFromDefaultSource();
+ BaSyxContext context = config.createBaSyxContext();
+ context.addServletMapping("/*", new VABHTTPInterface<IModelProvider>(provider));
+ BaSyxHTTPServer server = new BaSyxHTTPServer(context);
+ server.start();
+ }
+}
diff --git a/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/DashboardAsset.java b/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/DashboardAsset.java
new file mode 100644
index 0000000..747c6b5
--- /dev/null
+++ b/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/DashboardAsset.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.dashboard;
+
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+
+/**
+ * A dummy Asset for the dashboar AAS
+ *
+ * @author espen
+ *
+ */
+public class DashboardAsset extends Asset {
+ public DashboardAsset() {
+ setIdShort("DashboardAsset");
+ setIdentification(IdentifierType.CUSTOM, "DashboardAsset");
+ setAssetKind(AssetKind.INSTANCE);
+ }
+}
diff --git a/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/DashboardAssetAdministrationShell.java b/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/DashboardAssetAdministrationShell.java
new file mode 100644
index 0000000..71d4407
--- /dev/null
+++ b/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/DashboardAssetAdministrationShell.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.dashboard;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+
+/**
+ * A minimal AAS header for the dashboard AAS
+ *
+ * @author espen
+ *
+ */
+public class DashboardAssetAdministrationShell extends AssetAdministrationShell {
+ public DashboardAssetAdministrationShell() {
+ setIdShort("DashboardAAS");
+ setIdentification(IdentifierType.CUSTOM, "DashboardAAS");
+ }
+}
diff --git a/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/DashboardSubmodel.java b/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/DashboardSubmodel.java
new file mode 100644
index 0000000..c342810
--- /dev/null
+++ b/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/DashboardSubmodel.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.dashboard;
+
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProviderHelper;
+
+/**
+ * Dummy Submodel with two dynamic values. A configurable temperature value that randomly
+ * returns values in a specific range. And a random boolean value.
+ *
+ * @author espen
+ *
+ */
+public class DashboardSubmodel extends Submodel {
+ private int minValue;
+ private int maxValue;
+
+ public DashboardSubmodel() {
+ setIdShort("DashboardSubmodel");
+ setIdentification(IdentifierType.CUSTOM, "DashboardTemperatureSubmodel");
+ setSemanticId(new Reference(
+ new Key(KeyElements.CONCEPTDESCRIPTION, true, "0112/2///61360_4#AAF891#001", KeyType.IRDI)));
+ setTemperatureProperty();
+ setDummyProperty();
+
+ DashboardSubmodelConfiguration config = new DashboardSubmodelConfiguration();
+ config.loadFromDefaultSource();
+ minValue = config.getMin();
+ maxValue = config.getMax();
+ }
+
+ private void setTemperatureProperty() {
+ Property temperatureProperty = new Property();
+ temperatureProperty.setIdShort("temperature");
+ temperatureProperty.set(VABLambdaProviderHelper.createSimple(() -> {
+ return Math.random() * (maxValue - minValue) + minValue;
+ }, null), ValueType.Double);
+ // Adds a reference to a semantic ID to specify the property semantics (see CDD)
+ // Ref by identifier:
+ Key key = new Key(KeyElements.CONCEPTDESCRIPTION, true, "0112/2///61360_4#AAF891#001", KeyType.IRDI);
+ IReference refByIdentifier = new Reference(key);
+ temperatureProperty.setSemanticId(refByIdentifier);
+ addSubmodelElement(temperatureProperty);
+ }
+
+ private void setDummyProperty() {
+ Property dummyProperty = new Property();
+ dummyProperty.setIdShort("dummy");
+ dummyProperty.set(VABLambdaProviderHelper.createSimple(() -> {
+ return (Math.random() > 0.5);
+ }, null), ValueType.Boolean);
+ addSubmodelElement(dummyProperty);
+ }
+}
diff --git a/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/DashboardSubmodelConfiguration.java b/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/DashboardSubmodelConfiguration.java
new file mode 100644
index 0000000..f2c3c97
--- /dev/null
+++ b/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/DashboardSubmodelConfiguration.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.dashboard;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.basyx.components.configuration.BaSyxConfiguration;
+
+/**
+ * Simple configuration for setting minimal and maxmimal values for the dashboard submodel
+ *
+ * @author espen
+ *
+ */
+public class DashboardSubmodelConfiguration extends BaSyxConfiguration {
+ // Prefix for environment variables
+ public static final String ENV_PREFIX = "BaSyxDashboardSubmodel_";
+
+ // Default BaSyx Context configuration
+ public static final int DEFAULT_MIN = 10;
+ public static final int DEFAULT_MAX = 30;
+
+ public static final String MIN = "Min";
+ public static final String MAX = "Max";
+
+ // The default path for the context properties file
+ public static final String DEFAULT_CONFIG_PATH = "dashboardsubmodel.properties";
+
+ // The default key for variables pointing to the configuration file
+ public static final String DEFAULT_FILE_KEY = "BASYX_DASHBOARDSUBMODEL";
+
+ public static Map<String, String> getDefaultProperties() {
+ Map<String, String> defaultProps = new HashMap<>();
+ defaultProps.put(MIN, Integer.toString(DEFAULT_MIN));
+ defaultProps.put(MAX, Integer.toString(DEFAULT_MAX));
+ return defaultProps;
+ }
+
+ /**
+ * Empty Constructor - use default values
+ */
+ public DashboardSubmodelConfiguration() {
+ super(getDefaultProperties());
+ }
+
+ /**
+ * Constructor with predefined value map
+ */
+ public DashboardSubmodelConfiguration(Map<String, String> values) {
+ super(values);
+ }
+
+ /**
+ * Constructor with initial configuration - docBasePath and hostname are default values
+ *
+ * @param min The minimal temperature value
+ * @param max The maximal temperature value
+ */
+ public DashboardSubmodelConfiguration(int min, int max) {
+ this();
+ setMin(min);
+ setMax(max);
+ }
+
+ public void loadFromEnvironmentVariables() {
+ String[] properties = { MIN, MAX };
+ loadFromEnvironmentVariables(ENV_PREFIX, properties);
+ }
+
+ public void loadFromDefaultSource() {
+ loadFileOrDefaultResource(DEFAULT_FILE_KEY, DEFAULT_CONFIG_PATH);
+ loadFromEnvironmentVariables();
+ }
+
+ public void setMin(int min) {
+ setProperty(MIN, Integer.toString(min));
+ }
+
+ public void setMax(int max) {
+ setProperty(MIN, Integer.toString(max));
+ }
+
+ public int getMin() {
+ return Integer.parseInt(getProperty(MIN));
+ }
+
+ public int getMax() {
+ return Integer.parseInt(getProperty(MAX));
+ }
+}
diff --git a/examples/basyx.dashboardAAS/src/main/resources/context.properties b/examples/basyx.dashboardAAS/src/main/resources/context.properties
new file mode 100644
index 0000000..9e4461a
--- /dev/null
+++ b/examples/basyx.dashboardAAS/src/main/resources/context.properties
@@ -0,0 +1,17 @@
+# ###############################
+# HTTP Context configuration file
+# ###############################
+
+# ###############################
+# Context Path
+# ###############################
+# Specifies the subpath in the url for this server context
+
+contextPath=/
+
+# ###############################
+# Port
+# ###############################
+# Specifies the port for this server context
+
+contextPort=6400
\ No newline at end of file
diff --git a/examples/basyx.dashboardAAS/src/main/resources/dashboardsubmodel.properties b/examples/basyx.dashboardAAS/src/main/resources/dashboardsubmodel.properties
new file mode 100644
index 0000000..63bbaa6
--- /dev/null
+++ b/examples/basyx.dashboardAAS/src/main/resources/dashboardsubmodel.properties
@@ -0,0 +1,17 @@
+# ###############################
+# Dashboard submodel configuration
+# ###############################
+
+# ###############################
+# Min temperature value
+# ###############################
+# Specifies the min value for the dynamic random temperature
+
+Min=10
+
+# ###############################
+# Max temperature value
+# ###############################
+# Specifies the max value for the dynamic random temperature
+
+Max=30
\ No newline at end of file
diff --git a/examples/basyx.dashboardAAS/src/test/resources/.env b/examples/basyx.dashboardAAS/src/test/resources/.env
new file mode 100644
index 0000000..f71a8db
--- /dev/null
+++ b/examples/basyx.dashboardAAS/src/test/resources/.env
@@ -0,0 +1,39 @@
+# ##################
+# Docker Environment
+# ##################
+
+# ##################
+# Host Port
+# ##################
+# Specifies the port for the Docker HOST the container port is mapped to
+
+BASYX_HOST_PORT=6400
+
+# ##################
+# Container Port
+# ##################
+# Specifies the port for the Docker CONTAINER that is be mapped for the host
+
+BASYX_CONTAINER_PORT=6400
+
+# ##################
+# Image Name
+# ##################
+# The image of the image that is build for this component
+
+BASYX_IMAGE_NAME=basyx/dashboard-aas
+
+# ##################
+# Image Tag
+# ##################
+# The image tag of the image that is build for this component
+
+BASYX_IMAGE_TAG=1.0.0
+
+# ##################
+# Container Name
+# ##################
+# The name of the container used for the default environment
+
+BASYX_CONTAINER_NAME=dashboard-aas
+
diff --git a/examples/basyx.dashboardAAS/start.bat b/examples/basyx.dashboardAAS/start.bat
new file mode 100644
index 0000000..7d0dc6c
--- /dev/null
+++ b/examples/basyx.dashboardAAS/start.bat
@@ -0,0 +1 @@
+docker-compose up
\ No newline at end of file
diff --git a/examples/basyx.dashboardAAS/start.sh b/examples/basyx.dashboardAAS/start.sh
new file mode 100644
index 0000000..d935e43
--- /dev/null
+++ b/examples/basyx.dashboardAAS/start.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+docker-compose up
\ No newline at end of file
diff --git a/examples/basyx.dashboardAAS/stop.bat b/examples/basyx.dashboardAAS/stop.bat
new file mode 100644
index 0000000..58694d0
--- /dev/null
+++ b/examples/basyx.dashboardAAS/stop.bat
@@ -0,0 +1 @@
+docker-compose down
\ No newline at end of file
diff --git a/examples/basyx.dashboardAAS/stop.sh b/examples/basyx.dashboardAAS/stop.sh
new file mode 100644
index 0000000..f5139e2
--- /dev/null
+++ b/examples/basyx.dashboardAAS/stop.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+docker-compose down
\ No newline at end of file
diff --git a/examples/basyx.grafana/.gitignore b/examples/basyx.grafana/.gitignore
new file mode 100644
index 0000000..a5271c0
--- /dev/null
+++ b/examples/basyx.grafana/.gitignore
@@ -0,0 +1 @@
+/lib/plugins/*
\ No newline at end of file
diff --git a/examples/basyx.grafana/dashboard.json b/examples/basyx.grafana/dashboard.json
new file mode 100644
index 0000000..624f1a5
--- /dev/null
+++ b/examples/basyx.grafana/dashboard.json
@@ -0,0 +1,110 @@
+{
+ "annotations": {
+ "list": [
+ {
+ "builtIn": 1,
+ "datasource": "-- Grafana --",
+ "enable": true,
+ "hide": true,
+ "iconColor": "rgba(0, 211, 255, 1)",
+ "name": "Annotations & Alerts",
+ "type": "dashboard"
+ }
+ ]
+ },
+ "editable": true,
+ "gnetId": null,
+ "graphTooltip": 0,
+ "id": 1,
+ "links": [],
+ "panels": [
+ {
+ "datasource": null,
+ "description": "",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "thresholds"
+ },
+ "custom": {},
+ "mappings": [],
+ "min": 0,
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "#EAB839",
+ "value": 20
+ },
+ {
+ "color": "red",
+ "value": 27
+ }
+ ]
+ },
+ "unit": "celsius"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 6,
+ "x": 0,
+ "y": 0
+ },
+ "id": 2,
+ "options": {
+ "colorMode": "value",
+ "graphMode": "area",
+ "justifyMode": "auto",
+ "orientation": "auto",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "text": {},
+ "textMode": "auto"
+ },
+ "pluginVersion": "7.4.0",
+ "targets": [
+ {
+ "refId": "A",
+ "target": "temp",
+ "type": "timeserie"
+ }
+ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Temperature",
+ "transparent": true,
+ "type": "stat"
+ }
+ ],
+ "refresh": "1s",
+ "schemaVersion": 27,
+ "style": "dark",
+ "tags": [],
+ "templating": {
+ "list": []
+ },
+ "time": {
+ "from": "now-10s",
+ "to": "now"
+ },
+ "timepicker": {
+ "refresh_intervals": [
+ "1s"
+ ]
+ },
+ "timezone": "",
+ "title": "BaSyx Temperature",
+ "uid": "forkaVEGz",
+ "version": 5
+}
\ No newline at end of file
diff --git a/examples/basyx.grafana/docker-compose.yml b/examples/basyx.grafana/docker-compose.yml
new file mode 100644
index 0000000..81b38ac
--- /dev/null
+++ b/examples/basyx.grafana/docker-compose.yml
@@ -0,0 +1,32 @@
+version: '2.1'
+services:
+
+ registry:
+ image: eclipsebasyx/aas-registry:1.0.1
+ container_name: dashboard-registry
+ ports:
+ - 4000:4000
+
+ dashboard-aas:
+ image: eclipsebasyx/dashboard-aas:0.1.0-SNAPSHOT
+ container_name: dashboard-aas
+ environment:
+ - BaSyxDashboardSubmodel_Min=15
+# - BaSyxDashboardSubmodel_Max=30
+ ports:
+ - 6400:6400
+
+ aas-wrapper:
+ image: eclipsebasyx/aas-wrapper:0.1.0-SNAPSHOT
+ container_name: aas-wrapper
+ ports:
+ - 6500:6500
+
+ grafana:
+ image: grafana/grafana:7.4.0
+ container_name: grafana
+ ports:
+ - 3000:3000
+ volumes:
+ - ./lib:/var/lib/grafana
+ - ./grafana.ini:/etc/grafana/grafana.ini
\ No newline at end of file
diff --git a/examples/basyx.grafana/grafana.ini b/examples/basyx.grafana/grafana.ini
new file mode 100644
index 0000000..098e757
--- /dev/null
+++ b/examples/basyx.grafana/grafana.ini
@@ -0,0 +1,902 @@
+##################### Grafana Configuration Defaults #####################
+#
+# Do not modify this file in grafana installs
+#
+
+# possible values : production, development
+app_mode = production
+
+# instance name, defaults to HOSTNAME environment variable value or hostname if HOSTNAME var is empty
+instance_name = ${HOSTNAME}
+
+#################################### Paths ###############################
+[paths]
+# Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used)
+data = data
+
+# Temporary files in `data` directory older than given duration will be removed
+temp_data_lifetime = 24h
+
+# Directory where grafana can store logs
+logs = data/log
+
+# Directory where grafana will automatically scan and look for plugins
+plugins = data/plugins
+
+# folder that contains provisioning config files that grafana will apply on startup and while running.
+provisioning = conf/provisioning
+
+#################################### Server ##############################
+[server]
+# Protocol (http, https, h2, socket)
+protocol = http
+
+# The ip address to bind to, empty will bind to all interfaces
+http_addr =
+
+# The http port to use
+http_port = 3000
+
+# The public facing domain name used to access grafana from a browser
+domain = localhost
+
+# Redirect to correct domain if host header does not match domain
+# Prevents DNS rebinding attacks
+enforce_domain = false
+
+# The full public facing url
+root_url = %(protocol)s://%(domain)s:%(http_port)s/
+
+# Serve Grafana from subpath specified in `root_url` setting. By default it is set to `false` for compatibility reasons.
+serve_from_sub_path = false
+
+# Log web requests
+router_logging = false
+
+# the path relative working path
+static_root_path = public
+
+# enable gzip
+enable_gzip = false
+
+# https certs & key file
+cert_file =
+cert_key =
+
+# Unix socket path
+socket = /tmp/grafana.sock
+
+# CDN Url
+cdn_url =
+
+#################################### Database ############################
+[database]
+# You can configure the database connection by specifying type, host, name, user and password
+# as separate properties or as on string using the url property.
+
+# Either "mysql", "postgres" or "sqlite3", it's your choice
+type = sqlite3
+host = 127.0.0.1:3306
+name = grafana
+user = root
+# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;"""
+password =
+# Use either URL or the previous fields to configure the database
+# Example: mysql://user:secret@host:port/database
+url =
+
+# Max idle conn setting default is 2
+max_idle_conn = 2
+
+# Max conn setting default is 0 (mean not set)
+max_open_conn =
+
+# Connection Max Lifetime default is 14400 (means 14400 seconds or 4 hours)
+conn_max_lifetime = 14400
+
+# Set to true to log the sql calls and execution times.
+log_queries =
+
+# For "postgres", use either "disable", "require" or "verify-full"
+# For "mysql", use either "true", "false", or "skip-verify".
+ssl_mode = disable
+
+ca_cert_path =
+client_key_path =
+client_cert_path =
+server_cert_name =
+
+# For "sqlite3" only, path relative to data_path setting
+path = grafana.db
+
+# For "sqlite3" only. cache mode setting used for connecting to the database
+cache_mode = private
+
+#################################### Cache server #############################
+[remote_cache]
+# Either "redis", "memcached" or "database" default is "database"
+type = database
+
+# cache connectionstring options
+# database: will use Grafana primary database.
+# redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=0,ssl=false`. Only addr is required. ssl may be 'true', 'false', or 'insecure'.
+# memcache: 127.0.0.1:11211
+connstr =
+
+#################################### Data proxy ###########################
+[dataproxy]
+
+# This enables data proxy logging, default is false
+logging = false
+
+# How long the data proxy waits before timing out, default is 30 seconds.
+# This setting also applies to core backend HTTP data sources where query requests use an HTTP client with timeout set.
+timeout = 30
+
+# How many seconds the data proxy waits before sending a keepalive request.
+keep_alive_seconds = 30
+
+# How many seconds the data proxy waits for a successful TLS Handshake before timing out.
+tls_handshake_timeout_seconds = 10
+
+# How many seconds the data proxy will wait for a server's first response headers after
+# fully writing the request headers if the request has an "Expect: 100-continue"
+# header. A value of 0 will result in the body being sent immediately, without
+# waiting for the server to approve.
+expect_continue_timeout_seconds = 1
+
+# The maximum number of idle connections that Grafana will keep alive.
+max_idle_connections = 100
+
+# How many seconds the data proxy keeps an idle connection open before timing out.
+idle_conn_timeout_seconds = 90
+
+# If enabled and user is not anonymous, data proxy will add X-Grafana-User header with username into the request.
+send_user_header = false
+
+#################################### Analytics ###########################
+[analytics]
+# Server reporting, sends usage counters to stats.grafana.org every 24 hours.
+# No ip addresses are being tracked, only simple counters to track
+# running instances, dashboard and error counts. It is very helpful to us.
+# Change this option to false to disable reporting.
+reporting_enabled = true
+
+# Set to false to disable all checks to https://grafana.com
+# for new versions (grafana itself and plugins), check is used
+# in some UI views to notify that grafana or plugin update exists
+# This option does not cause any auto updates, nor send any information
+# only a GET request to https://grafana.com to get latest versions
+check_for_updates = true
+
+# Google Analytics universal tracking code, only enabled if you specify an id here
+google_analytics_ua_id =
+
+# Google Tag Manager ID, only enabled if you specify an id here
+google_tag_manager_id =
+
+#################################### Security ############################
+[security]
+# disable creation of admin user on first start of grafana
+disable_initial_admin_creation = false
+
+# default admin user, created on startup
+admin_user = admin
+
+# default admin password, can be changed before first start of grafana, or in profile settings
+admin_password = admin
+
+# used for signing
+secret_key = SW2YcwTIb9zpOOhoPsMm
+
+# disable gravatar profile images
+disable_gravatar = false
+
+# data source proxy whitelist (ip_or_domain:port separated by spaces)
+data_source_proxy_whitelist =
+
+# disable protection against brute force login attempts
+disable_brute_force_login_protection = false
+
+# set to true if you host Grafana behind HTTPS. default is false.
+cookie_secure = false
+
+# set cookie SameSite attribute. defaults to `lax`. can be set to "lax", "strict", "none" and "disabled"
+cookie_samesite = lax
+
+# set to true if you want to allow browsers to render Grafana in a <frame>, <iframe>, <embed> or <object>. default is false.
+allow_embedding = false
+
+# Set to true if you want to enable http strict transport security (HSTS) response header.
+# This is only sent when HTTPS is enabled in this configuration.
+# HSTS tells browsers that the site should only be accessed using HTTPS.
+strict_transport_security = false
+
+# Sets how long a browser should cache HSTS. Only applied if strict_transport_security is enabled.
+strict_transport_security_max_age_seconds = 86400
+
+# Set to true if to enable HSTS preloading option. Only applied if strict_transport_security is enabled.
+strict_transport_security_preload = false
+
+# Set to true if to enable the HSTS includeSubDomains option. Only applied if strict_transport_security is enabled.
+strict_transport_security_subdomains = false
+
+# Set to true to enable the X-Content-Type-Options response header.
+# The X-Content-Type-Options response HTTP header is a marker used by the server to indicate that the MIME types advertised
+# in the Content-Type headers should not be changed and be followed.
+x_content_type_options = true
+
+# Set to true to enable the X-XSS-Protection header, which tells browsers to stop pages from loading
+# when they detect reflected cross-site scripting (XSS) attacks.
+x_xss_protection = true
+
+# Enable adding the Content-Security-Policy header to your requests.
+# CSP allows to control resources the user agent is allowed to load and helps prevent XSS attacks.
+content_security_policy = false
+
+# Set Content Security Policy template used when adding the Content-Security-Policy header to your requests.
+# $NONCE in the template includes a random nonce.
+content_security_policy_template = """script-src 'unsafe-eval' 'strict-dynamic' $NONCE;object-src 'none';font-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data:;base-uri 'self';connect-src 'self' grafana.com;manifest-src 'self';media-src 'none';form-action 'self';"""
+
+#################################### Snapshots ###########################
+[snapshots]
+# snapshot sharing options
+external_enabled = true
+external_snapshot_url = https://snapshots-origin.raintank.io
+external_snapshot_name = Publish to snapshot.raintank.io
+
+# Set to true to enable this Grafana instance act as an external snapshot server and allow unauthenticated requests for
+# creating and deleting snapshots.
+public_mode = false
+
+# remove expired snapshot
+snapshot_remove_expired = true
+
+#################################### Dashboards ##################
+
+[dashboards]
+# Number dashboard versions to keep (per dashboard). Default: 20, Minimum: 1
+versions_to_keep = 20
+
+# Minimum dashboard refresh interval. When set, this will restrict users to set the refresh interval of a dashboard lower than given interval. Per default this is 5 seconds.
+# The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
+min_refresh_interval = 1s
+
+# Path to the default home dashboard. If this value is empty, then Grafana uses StaticRootPath + "dashboards/home.json"
+default_home_dashboard_path =
+
+################################### Data sources #########################
+[datasources]
+# Upper limit of data sources that Grafana will return. This limit is a temporary configuration and it will be deprecated when pagination will be introduced on the list data sources API.
+datasource_limit = 5000
+
+#################################### Users ###############################
+[users]
+# disable user signup / registration
+allow_sign_up = false
+
+# Allow non admin users to create organizations
+allow_org_create = false
+
+# Set to true to automatically assign new users to the default organization (id 1)
+auto_assign_org = true
+
+# Set this value to automatically add new users to the provided organization (if auto_assign_org above is set to true)
+auto_assign_org_id = 1
+
+# Default role new users will be automatically assigned (if auto_assign_org above is set to true)
+auto_assign_org_role = Viewer
+
+# Require email validation before sign up completes
+verify_email_enabled = false
+
+# Background text for the user field on the login page
+login_hint = email or username
+password_hint = password
+
+# Default UI theme ("dark" or "light")
+default_theme = dark
+
+# External user management
+external_manage_link_url =
+external_manage_link_name =
+external_manage_info =
+
+# Viewers can edit/inspect dashboard settings in the browser. But not save the dashboard.
+viewers_can_edit = false
+
+# Editors can administrate dashboard, folders and teams they create
+editors_can_admin = false
+
+# The duration in time a user invitation remains valid before expiring. This setting should be expressed as a duration. Examples: 6h (hours), 2d (days), 1w (week). Default is 24h (24 hours). The minimum supported duration is 15m (15 minutes).
+user_invite_max_lifetime_duration = 24h
+
+# Enter a comma-separated list of usernames to hide them in the Grafana UI. These users are shown to Grafana admins and to themselves.
+hidden_users =
+
+[auth]
+# Login cookie name
+login_cookie_name = grafana_session
+
+# The maximum lifetime (duration) an authenticated user can be inactive before being required to login at next visit. Default is 7 days (7d). This setting should be expressed as a duration, e.g. 5m (minutes), 6h (hours), 10d (days), 2w (weeks), 1M (month). The lifetime resets at each successful token rotation (token_rotation_interval_minutes).
+login_maximum_inactive_lifetime_duration =
+
+# The maximum lifetime (duration) an authenticated user can be logged in since login time before being required to login. Default is 30 days (30d). This setting should be expressed as a duration, e.g. 5m (minutes), 6h (hours), 10d (days), 2w (weeks), 1M (month).
+login_maximum_lifetime_duration =
+
+# How often should auth tokens be rotated for authenticated users when being active. The default is each 10 minutes.
+token_rotation_interval_minutes = 10
+
+# Set to true to disable (hide) the login form, useful if you use OAuth
+disable_login_form = false
+
+# Set to true to disable the signout link in the side menu. useful if you use auth.proxy
+disable_signout_menu = false
+
+# URL to redirect the user to after sign out
+signout_redirect_url =
+
+# Set to true to attempt login with OAuth automatically, skipping the login screen.
+# This setting is ignored if multiple OAuth providers are configured.
+oauth_auto_login = false
+
+# OAuth state max age cookie duration in seconds. Defaults to 600 seconds.
+oauth_state_cookie_max_age = 600
+
+# limit of api_key seconds to live before expiration
+api_key_max_seconds_to_live = -1
+
+# Set to true to enable SigV4 authentication option for HTTP-based datasources
+sigv4_auth_enabled = false
+
+#################################### Anonymous Auth ######################
+[auth.anonymous]
+# enable anonymous access
+enabled = false
+
+# specify organization name that should be used for unauthenticated users
+org_name = Main Org.
+
+# specify role for unauthenticated users
+org_role = Viewer
+
+# mask the Grafana version number for unauthenticated users
+hide_version = false
+
+#################################### GitHub Auth #########################
+[auth.github]
+enabled = false
+allow_sign_up = true
+client_id = some_id
+client_secret =
+scopes = user:email,read:org
+auth_url = https://github.com/login/oauth/authorize
+token_url = https://github.com/login/oauth/access_token
+api_url = https://api.github.com/user
+allowed_domains =
+team_ids =
+allowed_organizations =
+
+#################################### GitLab Auth #########################
+[auth.gitlab]
+enabled = false
+allow_sign_up = true
+client_id = some_id
+client_secret =
+scopes = api
+auth_url = https://gitlab.com/oauth/authorize
+token_url = https://gitlab.com/oauth/token
+api_url = https://gitlab.com/api/v4
+allowed_domains =
+allowed_groups =
+
+#################################### Google Auth #########################
+[auth.google]
+enabled = false
+allow_sign_up = true
+client_id = some_client_id
+client_secret =
+scopes = https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email
+auth_url = https://accounts.google.com/o/oauth2/auth
+token_url = https://accounts.google.com/o/oauth2/token
+api_url = https://www.googleapis.com/oauth2/v1/userinfo
+allowed_domains =
+hosted_domain =
+
+#################################### Grafana.com Auth ####################
+# legacy key names (so they work in env variables)
+[auth.grafananet]
+enabled = false
+allow_sign_up = true
+client_id = some_id
+client_secret =
+scopes = user:email
+allowed_organizations =
+
+[auth.grafana_com]
+enabled = false
+allow_sign_up = true
+client_id = some_id
+client_secret =
+scopes = user:email
+allowed_organizations =
+
+#################################### Azure AD OAuth #######################
+[auth.azuread]
+name = Azure AD
+enabled = false
+allow_sign_up = true
+client_id = some_client_id
+client_secret =
+scopes = openid email profile
+auth_url = https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize
+token_url = https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token
+allowed_domains =
+allowed_groups =
+
+#################################### Okta OAuth #######################
+[auth.okta]
+name = Okta
+enabled = false
+allow_sign_up = true
+client_id = some_id
+client_secret =
+scopes = openid profile email groups
+auth_url = https://<tenant-id>.okta.com/oauth2/v1/authorize
+token_url = https://<tenant-id>.okta.com/oauth2/v1/token
+api_url = https://<tenant-id>.okta.com/oauth2/v1/userinfo
+allowed_domains =
+allowed_groups =
+role_attribute_path =
+
+#################################### Generic OAuth #######################
+[auth.generic_oauth]
+name = OAuth
+enabled = false
+allow_sign_up = true
+client_id = some_id
+client_secret =
+scopes = user:email
+email_attribute_name = email:primary
+email_attribute_path =
+login_attribute_path =
+name_attribute_path =
+role_attribute_path =
+id_token_attribute_name =
+auth_url =
+token_url =
+api_url =
+allowed_domains =
+team_ids =
+allowed_organizations =
+tls_skip_verify_insecure = false
+tls_client_cert =
+tls_client_key =
+tls_client_ca =
+
+#################################### Basic Auth ##########################
+[auth.basic]
+enabled = true
+
+#################################### Auth Proxy ##########################
+[auth.proxy]
+enabled = false
+header_name = X-WEBAUTH-USER
+header_property = username
+auto_sign_up = true
+# Deprecated, use sync_ttl instead
+ldap_sync_ttl = 60
+sync_ttl = 60
+whitelist =
+headers =
+enable_login_token = false
+
+#################################### Auth LDAP ###########################
+[auth.ldap]
+enabled = false
+config_file = /etc/grafana/ldap.toml
+allow_sign_up = true
+
+# LDAP background sync (Enterprise only)
+# At 1 am every day
+sync_cron = "0 0 1 * * *"
+active_sync_enabled = true
+
+#################################### SMTP / Emailing #####################
+[smtp]
+enabled = false
+host = localhost:25
+user =
+# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;"""
+password =
+cert_file =
+key_file =
+skip_verify = false
+from_address = admin@grafana.localhost
+from_name = Grafana
+ehlo_identity =
+startTLS_policy =
+
+[emails]
+welcome_email_on_sign_up = false
+templates_pattern = emails/*.html
+
+#################################### Logging ##########################
+[log]
+# Either "console", "file", "syslog". Default is console and file
+# Use space to separate multiple modes, e.g. "console file"
+mode = console file
+
+# Either "debug", "info", "warn", "error", "critical", default is "info"
+level = info
+
+# optional settings to set different levels for specific loggers. Ex filters = sqlstore:debug
+filters =
+
+# For "console" mode only
+[log.console]
+level =
+
+# log line format, valid options are text, console and json
+format = console
+
+# For "file" mode only
+[log.file]
+level =
+
+# log line format, valid options are text, console and json
+format = text
+
+# This enables automated log rotate(switch of following options), default is true
+log_rotate = true
+
+# Max line number of single file, default is 1000000
+max_lines = 1000000
+
+# Max size shift of single file, default is 28 means 1 << 28, 256MB
+max_size_shift = 28
+
+# Segment log daily, default is true
+daily_rotate = true
+
+# Expired days of log file(delete after max days), default is 7
+max_days = 7
+
+[log.syslog]
+level =
+
+# log line format, valid options are text, console and json
+format = text
+
+# Syslog network type and address. This can be udp, tcp, or unix. If left blank, the default unix endpoints will be used.
+network =
+address =
+
+# Syslog facility. user, daemon and local0 through local7 are valid.
+facility =
+
+# Syslog tag. By default, the process' argv[0] is used.
+tag =
+
+[log.frontend]
+# Should Sentry javascript agent be initialized
+enabled = false
+
+# Sentry DSN if you want to send events to Sentry.
+sentry_dsn =
+
+# Custom HTTP endpoint to send events captured by the Sentry agent to. Default will log the events to stdout.
+custom_endpoint = /log
+
+# Rate of events to be reported between 0 (none) and 1 (all), float
+sample_rate = 1.0
+
+# Requests per second limit enforced per an extended period, for Grafana backend log ingestion endpoint (/log).
+log_endpoint_requests_per_second_limit = 3
+
+# Max requests accepted per short interval of time for Grafana backend log ingestion endpoint (/log)
+log_endpoint_burst_limit = 15
+
+#################################### Usage Quotas ########################
+[quota]
+enabled = false
+
+#### set quotas to -1 to make unlimited. ####
+# limit number of users per Org.
+org_user = 10
+
+# limit number of dashboards per Org.
+org_dashboard = 100
+
+# limit number of data_sources per Org.
+org_data_source = 10
+
+# limit number of api_keys per Org.
+org_api_key = 10
+
+# limit number of orgs a user can create.
+user_org = 10
+
+# Global limit of users.
+global_user = -1
+
+# global limit of orgs.
+global_org = -1
+
+# global limit of dashboards
+global_dashboard = -1
+
+# global limit of api_keys
+global_api_key = -1
+
+# global limit on number of logged in users.
+global_session = -1
+
+#################################### Alerting ############################
+[alerting]
+# Disable alerting engine & UI features
+enabled = true
+# Makes it possible to turn off alert rule execution but alerting UI is visible
+execute_alerts = true
+
+# Default setting for new alert rules. Defaults to categorize error and timeouts as alerting. (alerting, keep_state)
+error_or_timeout = alerting
+
+# Default setting for how Grafana handles nodata or null values in alerting. (alerting, no_data, keep_state, ok)
+nodata_or_nullvalues = no_data
+
+# Alert notifications can include images, but rendering many images at the same time can overload the server
+# This limit will protect the server from render overloading and make sure notifications are sent out quickly
+concurrent_render_limit = 5
+
+# Default setting for alert calculation timeout. Default value is 30
+evaluation_timeout_seconds = 30
+
+# Default setting for alert notification timeout. Default value is 30
+notification_timeout_seconds = 30
+
+# Default setting for max attempts to sending alert notifications. Default value is 3
+max_attempts = 3
+
+# Makes it possible to enforce a minimal interval between evaluations, to reduce load on the backend
+min_interval_seconds = 1
+
+# Configures for how long alert annotations are stored. Default is 0, which keeps them forever.
+# This setting should be expressed as an duration. Ex 6h (hours), 10d (days), 2w (weeks), 1M (month).
+max_annotation_age =
+
+# Configures max number of alert annotations that Grafana stores. Default value is 0, which keeps all alert annotations.
+max_annotations_to_keep =
+
+#################################### Annotations #########################
+
+[annotations.dashboard]
+# Dashboard annotations means that annotations are associated with the dashboard they are created on.
+
+# Configures how long dashboard annotations are stored. Default is 0, which keeps them forever.
+# This setting should be expressed as a duration. Examples: 6h (hours), 10d (days), 2w (weeks), 1M (month).
+max_age =
+
+# Configures max number of dashboard annotations that Grafana stores. Default value is 0, which keeps all dashboard annotations.
+max_annotations_to_keep =
+
+[annotations.api]
+# API annotations means that the annotations have been created using the API without any
+# association with a dashboard.
+
+# Configures how long Grafana stores API annotations. Default is 0, which keeps them forever.
+# This setting should be expressed as a duration. Examples: 6h (hours), 10d (days), 2w (weeks), 1M (month).
+max_age =
+
+# Configures max number of API annotations that Grafana keeps. Default value is 0, which keeps all API annotations.
+max_annotations_to_keep =
+
+#################################### Explore #############################
+[explore]
+# Enable the Explore section
+enabled = true
+
+#################################### Internal Grafana Metrics ############
+# Metrics available at HTTP API Url /metrics
+[metrics]
+enabled = true
+interval_seconds = 10
+# Disable total stats (stat_totals_*) metrics to be generated
+disable_total_stats = false
+
+#If both are set, basic auth will be required for the metrics endpoint.
+basic_auth_username =
+basic_auth_password =
+
+# Metrics environment info adds dimensions to the `grafana_environment_info` metric, which
+# can expose more information about the Grafana instance.
+[metrics.environment_info]
+#exampleLabel1 = exampleValue1
+#exampleLabel2 = exampleValue2
+
+# Send internal Grafana metrics to graphite
+[metrics.graphite]
+# Enable by setting the address setting (ex localhost:2003)
+address =
+prefix = prod.grafana.%(instance_name)s.
+
+#################################### Grafana.com integration ##########################
+[grafana_net]
+url = https://grafana.com
+
+[grafana_com]
+url = https://grafana.com
+
+#################################### Distributed tracing ############
+[tracing.jaeger]
+# jaeger destination (ex localhost:6831)
+address =
+# tag that will always be included in when creating new spans. ex (tag1:value1,tag2:value2)
+always_included_tag =
+# Type specifies the type of the sampler: const, probabilistic, rateLimiting, or remote
+sampler_type = const
+# jaeger samplerconfig param
+# for "const" sampler, 0 or 1 for always false/true respectively
+# for "probabilistic" sampler, a probability between 0 and 1
+# for "rateLimiting" sampler, the number of spans per second
+# for "remote" sampler, param is the same as for "probabilistic"
+# and indicates the initial sampling rate before the actual one
+# is received from the mothership
+sampler_param = 1
+# sampling_server_url is the URL of a sampling manager providing a sampling strategy.
+sampling_server_url =
+# Whether or not to use Zipkin span propagation (x-b3- HTTP headers).
+zipkin_propagation = false
+# Setting this to true disables shared RPC spans.
+# Not disabling is the most common setting when using Zipkin elsewhere in your infrastructure.
+disable_shared_zipkin_spans = false
+
+#################################### External Image Storage ##############
+[external_image_storage]
+# Used for uploading images to public servers so they can be included in slack/email messages.
+# You can choose between (s3, webdav, gcs, azure_blob, local)
+provider =
+
+[external_image_storage.s3]
+endpoint =
+path_style_access =
+bucket_url =
+bucket =
+region =
+path =
+access_key =
+secret_key =
+
+[external_image_storage.webdav]
+url =
+username =
+password =
+public_url =
+
+[external_image_storage.gcs]
+key_file =
+bucket =
+path =
+enable_signed_urls = false
+signed_url_expiration =
+
+[external_image_storage.azure_blob]
+account_name =
+account_key =
+container_name =
+
+[external_image_storage.local]
+# does not require any configuration
+
+[rendering]
+# Options to configure a remote HTTP image rendering service, e.g. using https://github.com/grafana/grafana-image-renderer.
+# URL to a remote HTTP image renderer service, e.g. http://localhost:8081/render, will enable Grafana to render panels and dashboards to PNG-images using HTTP requests to an external service.
+server_url =
+# If the remote HTTP image renderer service runs on a different server than the Grafana server you may have to configure this to a URL where Grafana is reachable, e.g. http://grafana.domain/.
+callback_url =
+# Concurrent render request limit affects when the /render HTTP endpoint is used. Rendering many images at the same time can overload the server,
+# which this setting can help protect against by only allowing a certain amount of concurrent requests.
+concurrent_render_request_limit = 30
+
+[panels]
+# here for to support old env variables, can remove after a few months
+enable_alpha = false
+disable_sanitize_html = false
+
+[plugins]
+enable_alpha = false
+app_tls_skip_verify_insecure = false
+# Enter a comma-separated list of plugin identifiers to identify plugins that are allowed to be loaded even if they lack a valid signature.
+allow_loading_unsigned_plugins =
+marketplace_url = https://grafana.com/grafana/plugins/
+
+#################################### Grafana Image Renderer Plugin ##########################
+[plugin.grafana-image-renderer]
+# Instruct headless browser instance to use a default timezone when not provided by Grafana, e.g. when rendering panel image of alert.
+# See ICU’s metaZones.txt (https://cs.chromium.org/chromium/src/third_party/icu/source/data/misc/metaZones.txt) for a list of supported
+# timezone IDs. Fallbacks to TZ environment variable if not set.
+rendering_timezone =
+
+# Instruct headless browser instance to use a default language when not provided by Grafana, e.g. when rendering panel image of alert.
+# Please refer to the HTTP header Accept-Language to understand how to format this value, e.g. 'fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5'.
+rendering_language =
+
+# Instruct headless browser instance to use a default device scale factor when not provided by Grafana, e.g. when rendering panel image of alert.
+# Default is 1. Using a higher value will produce more detailed images (higher DPI), but will require more disk space to store an image.
+rendering_viewport_device_scale_factor =
+
+# Instruct headless browser instance whether to ignore HTTPS errors during navigation. Per default HTTPS errors are not ignored. Due to
+# the security risk it's not recommended to ignore HTTPS errors.
+rendering_ignore_https_errors =
+
+# Instruct headless browser instance whether to capture and log verbose information when rendering an image. Default is false and will
+# only capture and log error messages. When enabled, debug messages are captured and logged as well.
+# For the verbose information to be included in the Grafana server log you have to adjust the rendering log level to debug, configure
+# [log].filter = rendering:debug.
+rendering_verbose_logging =
+
+# Instruct headless browser instance whether to output its debug and error messages into running process of remote rendering service.
+# Default is false. This can be useful to enable (true) when troubleshooting.
+rendering_dumpio =
+
+# Additional arguments to pass to the headless browser instance. Default is --no-sandbox. The list of Chromium flags can be found
+# here (https://peter.sh/experiments/chromium-command-line-switches/). Multiple arguments is separated with comma-character.
+rendering_args =
+
+# You can configure the plugin to use a different browser binary instead of the pre-packaged version of Chromium.
+# Please note that this is not recommended, since you may encounter problems if the installed version of Chrome/Chromium is not
+# compatible with the plugin.
+rendering_chrome_bin =
+
+# Instruct how headless browser instances are created. Default is 'default' and will create a new browser instance on each request.
+# Mode 'clustered' will make sure that only a maximum of browsers/incognito pages can execute concurrently.
+# Mode 'reusable' will have one browser instance and will create a new incognito page on each request.
+rendering_mode =
+
+# When rendering_mode = clustered you can instruct how many browsers or incognito pages can execute concurrently. Default is 'browser'
+# and will cluster using browser instances.
+# Mode 'context' will cluster using incognito pages.
+rendering_clustering_mode =
+# When rendering_mode = clustered you can define maximum number of browser instances/incognito pages that can execute concurrently..
+rendering_clustering_max_concurrency =
+
+# Limit the maximum viewport width, height and device scale factor that can be requested.
+rendering_viewport_max_width =
+rendering_viewport_max_height =
+rendering_viewport_max_device_scale_factor =
+
+# Change the listening host and port of the gRPC server. Default host is 127.0.0.1 and default port is 0 and will automatically assign
+# a port not in use.
+grpc_host =
+grpc_port =
+
+[enterprise]
+license_path =
+
+[feature_toggles]
+# enable features, separated by spaces
+enable =
+
+[date_formats]
+# For information on what formatting patterns that are supported https://momentjs.com/docs/#/displaying/
+
+# Default system date format used in time range picker and other places where full time is displayed
+full_date = YYYY-MM-DD HH:mm:ss
+
+# Used by graph and other places where we only show small intervals
+interval_second = HH:mm:ss
+interval_minute = HH:mm
+interval_hour = MM/DD HH:mm
+interval_day = MM/DD
+interval_month = YYYY-MM
+interval_year = YYYY
+
+# Experimental feature
+use_browser_locale = false
+
+# Default timezone for user preferences. Options are 'browser' for the browser local timezone or a timezone name from IANA Time Zone database, e.g. 'UTC' or 'Europe/Amsterdam' etc.
+default_timezone = browser
+
+[expressions]
+# Enable or disable the expressions functionality.
+enabled = true
diff --git a/examples/basyx.grafana/lib/grafana.db b/examples/basyx.grafana/lib/grafana.db
new file mode 100644
index 0000000..3677257
--- /dev/null
+++ b/examples/basyx.grafana/lib/grafana.db
Binary files differ
diff --git a/examples/basyx.grafana/readme.txt b/examples/basyx.grafana/readme.txt
new file mode 100644
index 0000000..cd5669e
--- /dev/null
+++ b/examples/basyx.grafana/readme.txt
@@ -0,0 +1,28 @@
+HowTo: First Setup
+------------------
+
+1. Download SimpleJSON datasource from Grafana
+- Download .zip-file at
+ https://grafana.com/grafana/plugins/grafana-simple-json-datasource/installation
+- Unzip it in /lib/plugins:
+ /lib/plugins/grafana-simple-json-datasource/ should directly contain its files (e.g. package.json)
+
+2. Start docker-compose
+- Run "docker-compose up" in the /grafana/ folder
+
+3. Login (admin/admin)
+- http://localhost:3000/
+
+4. Add datasource
+- Configuration -> Datasources -> Add datasource -> Others: SimpleJson
+
+5. Set URL Configuration in SimpleJson Datasource:
+URL -> http://aas-wrapper:6500/grafana/
+
+6. Import Dashboard
+- Dashboards -> Manage -> Import -> Upload dashboard.json
+
+7. Open BaSyx Dashboard
+- Dashboards -> Manage -> BaSyx Temperature
+- Optional: Set auto-refresh to 1s
+
diff --git a/examples/basyx.grafana/start.bat b/examples/basyx.grafana/start.bat
new file mode 100644
index 0000000..7d0dc6c
--- /dev/null
+++ b/examples/basyx.grafana/start.bat
@@ -0,0 +1 @@
+docker-compose up
\ No newline at end of file
diff --git a/examples/basyx.grafana/start.sh b/examples/basyx.grafana/start.sh
new file mode 100644
index 0000000..d935e43
--- /dev/null
+++ b/examples/basyx.grafana/start.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+docker-compose up
\ No newline at end of file
diff --git a/examples/basyx.grafana/stop.bat b/examples/basyx.grafana/stop.bat
new file mode 100644
index 0000000..58694d0
--- /dev/null
+++ b/examples/basyx.grafana/stop.bat
@@ -0,0 +1 @@
+docker-compose down
\ No newline at end of file
diff --git a/examples/basyx.grafana/stop.sh b/examples/basyx.grafana/stop.sh
new file mode 100644
index 0000000..f5139e2
--- /dev/null
+++ b/examples/basyx.grafana/stop.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+docker-compose down
\ No newline at end of file
diff --git a/examples/basyx.hello_world/.gitignore b/examples/basyx.hello_world/.gitignore
new file mode 100644
index 0000000..02eeb17
--- /dev/null
+++ b/examples/basyx.hello_world/.gitignore
@@ -0,0 +1,69 @@
+.classpath
+.project
+
+regressiontest/
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+.mvn/wrapper/maven-wrapper.jar
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.settings/
+.loadpath
+.recommenders
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# PyDev specific (Python IDE for Eclipse)
+*.pydevproject
+
+# CDT-specific (C/C++ Development Tooling)
+.cproject
+
+# CDT- autotools
+.autotools
+
+# Java annotation processor (APT)
+.factorypath
+
+# PDT-specific (PHP Development Tools)
+.buildpath
+
+# sbteclipse plugin
+.target
+
+# Tern plugin
+.tern-project
+
+# TeXlipse plugin
+.texlipse
+
+# STS (Spring Tool Suite)
+.springBeans
+
+# Code Recommenders
+.recommenders/
+
+# Annotation Processing
+.apt_generated/
+
+# Scala IDE specific (Scala & Java development for Eclipse)
+.cache-main
+.scala_dependencies
+.worksheet
\ No newline at end of file
diff --git a/examples/basyx.hello_world/pom.xml b/examples/basyx.hello_world/pom.xml
new file mode 100644
index 0000000..d5aa122
--- /dev/null
+++ b/examples/basyx.hello_world/pom.xml
@@ -0,0 +1,61 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.eclipse.basyx</groupId>
+ <artifactId>basyx.hello_world</artifactId>
+ <version>1.0.0</version>
+ <name>BaSyx Hello World</name>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+ </properties>
+
+ <build>
+ <sourceDirectory>src/main/java</sourceDirectory>
+ <testSourceDirectory>src/test/java</testSourceDirectory>
+
+ <plugins>
+ <!-- Compile Sources using Java 8 -->
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.8.1</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <!-- Add BaSys components from local repository. This contains the dependency to the basyx.sdk-->
+ <dependency>
+ <groupId>org.eclipse.basyx</groupId>
+ <artifactId>basyx.components.lib</artifactId>
+ <version>1.0.0</version>
+ </dependency>
+
+ <!-- Add Registry Server component dependency -->
+ <dependency>
+ <groupId>org.eclipse.basyx</groupId>
+ <artifactId>basyx.components.registry</artifactId>
+ <version>1.0.2</version>
+ </dependency>
+
+ <!-- Add AAS Server component dependency -->
+ <dependency>
+ <groupId>org.eclipse.basyx</groupId>
+ <artifactId>basyx.components.AASServer</artifactId>
+ <version>1.0.0</version>
+ </dependency>
+
+
+ <!-- JUnit 4 for running JUnit tests -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.12</version>
+ </dependency>
+ </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/examples/basyx.hello_world/src/main/java/org/eclipse/basyx/hello_world/Client.java b/examples/basyx.hello_world/src/main/java/org/eclipse/basyx/hello_world/Client.java
new file mode 100644
index 0000000..3235f5a
--- /dev/null
+++ b/examples/basyx.hello_world/src/main/java/org/eclipse/basyx/hello_world/Client.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.hello_world;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+
+/**
+ * This class connects to the server created in Server
+ *
+ * It retrieves the Submodel and prints the
+ * idShort and Value of the contained Property to the console
+ *
+ * @author schnicke, conradi
+ *
+ */
+public class Client {
+ public static void main(String[] args) {
+ // Create Manager
+ ConnectedAssetAdministrationShellManager manager =
+ new ConnectedAssetAdministrationShellManager(new AASRegistryProxy(Server.REGISTRYPATH));
+
+ // Retrieve submodel
+ ISubmodel submodel = manager.retrieveSubmodel(Server.OVENAASID, Server.DOCUSMID);
+
+ // Retrieve MaxTemp Property
+ ISubmodelElement maxTemp = submodel.getSubmodelElement(Server.MAXTEMPID);
+
+ // Print value
+ System.out.println(maxTemp.getIdShort() + " is " + maxTemp.getValue());
+ }
+}
diff --git a/examples/basyx.hello_world/src/main/java/org/eclipse/basyx/hello_world/Server.java b/examples/basyx.hello_world/src/main/java/org/eclipse/basyx/hello_world/Server.java
new file mode 100644
index 0000000..b2615cc
--- /dev/null
+++ b/examples/basyx.hello_world/src/main/java/org/eclipse/basyx/hello_world/Server.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.hello_world;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.CustomId;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.components.aas.AASServerComponent;
+import org.eclipse.basyx.components.aas.configuration.AASServerBackend;
+import org.eclipse.basyx.components.aas.configuration.BaSyxAASServerConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.components.registry.RegistryComponent;
+import org.eclipse.basyx.components.registry.configuration.BaSyxRegistryConfiguration;
+import org.eclipse.basyx.components.registry.configuration.RegistryBackend;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+
+/**
+ * This class starts an AAS server and a Registry server
+ *
+ * An AAS and a Submodel containing a Property "maxTemp"
+ * is uploaded to the AAS server and registered in the Registry server.
+ *
+ * @author schnicke, conradi
+ *
+ */
+public class Server {
+ // Server URLs
+ public static final String REGISTRYPATH = "http://localhost:4000/registry";
+ public static final String AASSERVERPATH = "http://localhost:4001/aasServer";
+
+ // AAS/Submodel/Property Ids
+ public static final IIdentifier OVENAASID = new CustomId("eclipse.basyx.aas.oven");
+ public static final IIdentifier DOCUSMID = new CustomId("eclipse.basyx.submodel.documentation");
+ public static final String MAXTEMPID = "maxTemp";
+
+ public static void main(String[] args) {
+ // Create Infrastructure
+ startRegistry();
+ startAASServer();
+
+ // Create Manager - This manager is used to interact with an AAS server
+ ConnectedAssetAdministrationShellManager manager =
+ new ConnectedAssetAdministrationShellManager(new AASRegistryProxy(REGISTRYPATH));
+
+ // Create AAS and push it to server
+ Asset asset = new Asset("ovenAsset", new CustomId("eclipse.basyx.asset.oven"), AssetKind.INSTANCE);
+ AssetAdministrationShell shell = new AssetAdministrationShell("oven", OVENAASID, asset);
+
+ // The manager uploads the AAS and registers it in the Registry server
+ manager.createAAS(shell, AASSERVERPATH);
+
+ // Create submodel
+ Submodel documentationSubmodel = new Submodel("documentationSm", DOCUSMID);
+
+ // - Create property
+ Property maxTemp = new Property(MAXTEMPID, 1000);
+
+ // Add the property to the Submodel
+ documentationSubmodel.addSubmodelElement(maxTemp);
+
+ // - Push the Submodel to the AAS server
+ manager.createSubmodel(shell.getIdentification(), documentationSubmodel);
+ }
+
+ /**
+ * Starts an empty registry at "http://localhost:4000"
+ */
+ private static void startRegistry() {
+ BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration(4000, "/registry");
+ BaSyxRegistryConfiguration registryConfig = new BaSyxRegistryConfiguration(RegistryBackend.INMEMORY);
+ RegistryComponent registry = new RegistryComponent(contextConfig, registryConfig);
+
+ // Start the created server
+ registry.startComponent();
+ }
+
+ /**
+ * Startup an empty server at "http://localhost:4001/"
+ */
+ private static void startAASServer() {
+ BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration(4001, "/aasServer");
+ BaSyxAASServerConfiguration aasServerConfig = new BaSyxAASServerConfiguration(AASServerBackend.INMEMORY, "", REGISTRYPATH);
+ AASServerComponent aasServer = new AASServerComponent(contextConfig, aasServerConfig);
+
+ // Start the created server
+ aasServer.startComponent();
+ }
+}
diff --git a/examples/basyx.nodered/.gitignore b/examples/basyx.nodered/.gitignore
new file mode 100644
index 0000000..c5294d7
--- /dev/null
+++ b/examples/basyx.nodered/.gitignore
@@ -0,0 +1,3 @@
+/mosquitto/log/mosquitto.log
+/node-red/.flows.json.backup
+/node-red/.flows_cred.json.backup
\ No newline at end of file
diff --git a/examples/basyx.nodered/Dockerfile b/examples/basyx.nodered/Dockerfile
new file mode 100644
index 0000000..4ccce8f
--- /dev/null
+++ b/examples/basyx.nodered/Dockerfile
@@ -0,0 +1,17 @@
+FROM nodered/node-red
+USER root
+
+# Copy package.json to the WORKDIR so npm builds all
+# of your added nodes modules for Node-RED
+COPY package.json .
+COPY ./node-red-contrib-aas-connect ./node-red-contrib-aas-connect
+RUN npm install --unsafe-perm --no-update-notifier --no-fund --only=production --quiet
+RUN npm install ./node-red-contrib-aas-connect
+
+# Copy _your_ Node-RED project files into place
+# NOTE: This will only work if you DO NOT later mount /data as an external volume.
+# If you need to use an external volume for persistence then
+# copy your settings and flows files to that volume instead.
+COPY settings.js /data/settings.js
+# COPY flows_cred.json /data/flows_cred.json
+COPY flows.json /data/flows.json
\ No newline at end of file
diff --git a/examples/basyx.nodered/build.bat b/examples/basyx.nodered/build.bat
new file mode 100644
index 0000000..6e3726f
--- /dev/null
+++ b/examples/basyx.nodered/build.bat
@@ -0,0 +1 @@
+docker build -t basyx/node-red:0.1.0-SNAPSHOT .
\ No newline at end of file
diff --git a/examples/basyx.nodered/build.sh b/examples/basyx.nodered/build.sh
new file mode 100644
index 0000000..ce0a3c0
--- /dev/null
+++ b/examples/basyx.nodered/build.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+docker build -t basyx/node-red:0.1.0-SNAPSHOT .
\ No newline at end of file
diff --git a/examples/basyx.nodered/docker-compose.yml b/examples/basyx.nodered/docker-compose.yml
new file mode 100644
index 0000000..abf88fc
--- /dev/null
+++ b/examples/basyx.nodered/docker-compose.yml
@@ -0,0 +1,41 @@
+version: '3'
+services:
+
+ registry:
+ image: eclipsebasyx/aas-registry:1.0.1
+ container_name: dashboard-registry
+ ports:
+ - 4000:4000
+
+ dashboard-aas:
+ image: eclipsebasyx/dashboard-aas:0.1.0-SNAPSHOT
+ container_name: dashboard-aas
+ environment:
+ - BaSyxDashboardSubmodel_Min=15
+# - BaSyxDashboardSubmodel_Max=30
+ ports:
+ - 6400:6400
+
+ aas-wrapper:
+ image: eclipsebasyx/aas-wrapper:0.1.0-SNAPSHOT
+ container_name: aas-wrapper
+ ports:
+ - 6500:6500
+
+ node-red:
+ image: eclipsebasyx/examples-dataflow-nodered:0.1.0-SNAPSHOT
+ container_name: node-red
+ ports:
+ - 1880:1880
+ volumes:
+ - ./node-red:/data
+
+ mosquitto:
+ image: eclipse-mosquitto:latest
+ container_name: mosquitto
+ ports:
+ - 1883:1883
+ - 9001:9001
+ volumes:
+ - ./mosquitto/config:/mosquitto/config
+ - ./mosquitto/log:/mosquitto/log
\ No newline at end of file
diff --git a/examples/basyx.nodered/flows.json b/examples/basyx.nodered/flows.json
new file mode 100644
index 0000000..0e22486
--- /dev/null
+++ b/examples/basyx.nodered/flows.json
@@ -0,0 +1 @@
+[{"id":"ac89e902.a48598","type":"tab","label":"AAS Temperature","disabled":false,"info":""},{"id":"91383a96.5b2e48","type":"tab","label":"Test","disabled":false,"info":""},{"id":"1b4daff8.52358","type":"mqtt-broker","z":"","name":"Streamsheets Mosquitto","broker":"http://streamsheets","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"2289cf21.0a21b","type":"inject","z":"ac89e902.a48598","name":"Start","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":110,"y":120,"wires":[["c3659321.46995"]]},{"id":"c3659321.46995","type":"get-aas-property","z":"ac89e902.a48598","name":"Get Temperature","property":"temp","period":1,"x":270,"y":120,"wires":[["a56bd8e1.1777c8","2c13d59c.208cea","8c41e115.ac913"]]},{"id":"4e72f0db.c2a7a","type":"inject","z":"91383a96.5b2e48","name":"Data","props":[{"p":"values","v":"[22.344,23.434,24.342,21.098]","vt":"json"},{"p":"timestamp","v":"[121323,2112231,321331,321321]","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":140,"y":100,"wires":[["a53d7930.6109f8","4a734a5f.b22314","ab2d648a.1767f8"]]},{"id":"a53d7930.6109f8","type":"debug","z":"91383a96.5b2e48","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":250,"y":240,"wires":[]},{"id":"4a734a5f.b22314","type":"function","z":"91383a96.5b2e48","name":"Calculate Average","func":"msg.avg = msg.values.reduce((a,b) => a + b, 0) / msg.values.length;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":450,"y":120,"wires":[["6b28c27b.5547bc"]]},{"id":"6b28c27b.5547bc","type":"debug","z":"91383a96.5b2e48","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":710,"y":120,"wires":[]},{"id":"ab2d648a.1767f8","type":"function","z":"91383a96.5b2e48","name":"Calculate Fahrenheit","func":"msg.fahrenheit = msg.values.map(v => v * 1.8 + 32);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":460,"y":180,"wires":[["5e614070.a223f"]]},{"id":"5e614070.a223f","type":"debug","z":"91383a96.5b2e48","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":710,"y":180,"wires":[]},{"id":"e733d05.63a9c3","type":"iot-datasource","z":"ac89e902.a48598","name":"Temperature Datasource","tstampField":"tstamp","dataField":"data","disableDiscover":false,"x":730,"y":240,"wires":[[]]},{"id":"8e627da8.65b74","type":"mqtt out","z":"ac89e902.a48598","name":"MQTT Avg Temp Publisher","topic":"temperature/average","qos":"","retain":"","broker":"1b4daff8.52358","x":740,"y":120,"wires":[]},{"id":"7aa9e937.6575c8","type":"mqtt in","z":"ac89e902.a48598","name":"MQTT Avg Temp Consumer","topic":"temperature/average","qos":"2","datatype":"json","broker":"1b4daff8.52358","x":160,"y":360,"wires":[["f96c72b.3be659"]]},{"id":"f96c72b.3be659","type":"debug","z":"ac89e902.a48598","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload.average","targetType":"msg","statusVal":"","statusType":"auto","x":420,"y":360,"wires":[]},{"id":"a56bd8e1.1777c8","type":"function","z":"ac89e902.a48598","name":"Calculate Average","func":"const payload = msg.payload;\nlet average = payload.data.reduce((a,b) => a + b, 0) / payload.data.length;\npayload.average = average;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":490,"y":120,"wires":[["8e627da8.65b74"]]},{"id":"2c13d59c.208cea","type":"function","z":"ac89e902.a48598","name":"Calculate Fahrenheit","func":"const payload = msg.payload;\nlet fahrenheit = payload.data.map(v => v * 1.8 + 32);\npayload.fahrenheit = fahrenheit;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":500,"y":180,"wires":[["a3733cf8.97468"]]},{"id":"a3733cf8.97468","type":"mqtt out","z":"ac89e902.a48598","name":"MQTT Fahrenheit Temp Publisher","topic":"temperature/fahrenheit","qos":"","retain":"","broker":"1b4daff8.52358","x":760,"y":180,"wires":[]},{"id":"8c41e115.ac913","type":"function","z":"ac89e902.a48598","name":"Get most recent","func":"msg.payload.tstamp = new Date(msg.payload.tstamp.pop()).getTime();\nmsg.payload.data = msg.payload.data.pop();\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":480,"y":240,"wires":[["e733d05.63a9c3"]]}]
\ No newline at end of file
diff --git a/examples/basyx.nodered/mosquitto/config/mosquitto.conf b/examples/basyx.nodered/mosquitto/config/mosquitto.conf
new file mode 100644
index 0000000..9bf5429
--- /dev/null
+++ b/examples/basyx.nodered/mosquitto/config/mosquitto.conf
@@ -0,0 +1,988 @@
+# Config file for mosquitto
+#
+# See mosquitto.conf(5) for more information.
+#
+# Default values are shown, uncomment to change.
+#
+# Use the # character to indicate a comment, but only if it is the
+# very first character on the line.
+
+# =================================================================
+# General configuration
+# =================================================================
+
+# Use per listener security settings.
+#
+# It is recommended this option be set before any other options.
+#
+# If this option is set to true, then all authentication and access control
+# options are controlled on a per listener basis. The following options are
+# affected:
+#
+# password_file acl_file psk_file auth_plugin auth_opt_* allow_anonymous
+# auto_id_prefix allow_zero_length_clientid
+#
+# Note that if set to true, then a durable client (i.e. with clean session set
+# to false) that has disconnected will use the ACL settings defined for the
+# listener that it was most recently connected to.
+#
+# The default behaviour is for this to be set to false, which maintains the
+# setting behaviour from previous versions of mosquitto.
+#per_listener_settings false
+
+
+# If a client is subscribed to multiple subscriptions that overlap, e.g. foo/#
+# and foo/+/baz , then MQTT expects that when the broker receives a message on
+# a topic that matches both subscriptions, such as foo/bar/baz, then the client
+# should only receive the message once.
+# Mosquitto keeps track of which clients a message has been sent to in order to
+# meet this requirement. The allow_duplicate_messages option allows this
+# behaviour to be disabled, which may be useful if you have a large number of
+# clients subscribed to the same set of topics and are very concerned about
+# minimising memory usage.
+# It can be safely set to true if you know in advance that your clients will
+# never have overlapping subscriptions, otherwise your clients must be able to
+# correctly deal with duplicate messages even when then have QoS=2.
+#allow_duplicate_messages false
+
+# This option controls whether a client is allowed to connect with a zero
+# length client id or not. This option only affects clients using MQTT v3.1.1
+# and later. If set to false, clients connecting with a zero length client id
+# are disconnected. If set to true, clients will be allocated a client id by
+# the broker. This means it is only useful for clients with clean session set
+# to true.
+#allow_zero_length_clientid true
+
+# If allow_zero_length_clientid is true, this option allows you to set a prefix
+# to automatically generated client ids to aid visibility in logs.
+# Defaults to 'auto-'
+#auto_id_prefix auto-
+
+# This option affects the scenario when a client subscribes to a topic that has
+# retained messages. It is possible that the client that published the retained
+# message to the topic had access at the time they published, but that access
+# has been subsequently removed. If check_retain_source is set to true, the
+# default, the source of a retained message will be checked for access rights
+# before it is republished. When set to false, no check will be made and the
+# retained message will always be published. This affects all listeners.
+#check_retain_source true
+
+# QoS 1 and 2 messages will be allowed inflight per client until this limit
+# is exceeded. Defaults to 0. (No maximum)
+# See also max_inflight_messages
+#max_inflight_bytes 0
+
+# The maximum number of QoS 1 and 2 messages currently inflight per
+# client.
+# This includes messages that are partway through handshakes and
+# those that are being retried. Defaults to 20. Set to 0 for no
+# maximum. Setting to 1 will guarantee in-order delivery of QoS 1
+# and 2 messages.
+#max_inflight_messages 20
+
+# For MQTT v5 clients, it is possible to have the server send a "server
+# keepalive" value that will override the keepalive value set by the client.
+# This is intended to be used as a mechanism to say that the server will
+# disconnect the client earlier than it anticipated, and that the client should
+# use the new keepalive value. The max_keepalive option allows you to specify
+# that clients may only connect with keepalive less than or equal to this
+# value, otherwise they will be sent a server keepalive telling them to use
+# max_keepalive. This only applies to MQTT v5 clients. The maximum value
+# allowable is 65535. Do not set below 10.
+#max_keepalive 65535
+
+# For MQTT v5 clients, it is possible to have the server send a "maximum packet
+# size" value that will instruct the client it will not accept MQTT packets
+# with size greater than max_packet_size bytes. This applies to the full MQTT
+# packet, not just the payload. Setting this option to a positive value will
+# set the maximum packet size to that number of bytes. If a client sends a
+# packet which is larger than this value, it will be disconnected. This applies
+# to all clients regardless of the protocol version they are using, but v3.1.1
+# and earlier clients will of course not have received the maximum packet size
+# information. Defaults to no limit. Setting below 20 bytes is forbidden
+# because it is likely to interfere with ordinary client operation, even with
+# very small payloads.
+#max_packet_size 0
+
+# QoS 1 and 2 messages above those currently in-flight will be queued per
+# client until this limit is exceeded. Defaults to 0. (No maximum)
+# See also max_queued_messages.
+# If both max_queued_messages and max_queued_bytes are specified, packets will
+# be queued until the first limit is reached.
+#max_queued_bytes 0
+
+# The maximum number of QoS 1 and 2 messages to hold in a queue per client
+# above those that are currently in-flight. Defaults to 100. Set
+# to 0 for no maximum (not recommended).
+# See also queue_qos0_messages.
+# See also max_queued_bytes.
+#max_queued_messages 100
+#
+# This option sets the maximum number of heap memory bytes that the broker will
+# allocate, and hence sets a hard limit on memory use by the broker. Memory
+# requests that exceed this value will be denied. The effect will vary
+# depending on what has been denied. If an incoming message is being processed,
+# then the message will be dropped and the publishing client will be
+# disconnected. If an outgoing message is being sent, then the individual
+# message will be dropped and the receiving client will be disconnected.
+# Defaults to no limit.
+#memory_limit 0
+
+# This option sets the maximum publish payload size that the broker will allow.
+# Received messages that exceed this size will not be accepted by the broker.
+# The default value is 0, which means that all valid MQTT messages are
+# accepted. MQTT imposes a maximum payload size of 268435455 bytes.
+#message_size_limit 0
+
+# This option allows persistent clients (those with clean session set to false)
+# to be removed if they do not reconnect within a certain time frame.
+#
+# This is a non-standard option in MQTT V3.1 but allowed in MQTT v3.1.1.
+#
+# Badly designed clients may set clean session to false whilst using a randomly
+# generated client id. This leads to persistent clients that will never
+# reconnect. This option allows these clients to be removed.
+#
+# The expiration period should be an integer followed by one of h d w m y for
+# hour, day, week, month and year respectively. For example
+#
+# persistent_client_expiration 2m
+# persistent_client_expiration 14d
+# persistent_client_expiration 1y
+#
+# The default if not set is to never expire persistent clients.
+#persistent_client_expiration
+
+# Write process id to a file. Default is a blank string which means
+# a pid file shouldn't be written.
+# This should be set to /var/run/mosquitto.pid if mosquitto is
+# being run automatically on boot with an init script and
+# start-stop-daemon or similar.
+#pid_file
+
+# Set to true to queue messages with QoS 0 when a persistent client is
+# disconnected. These messages are included in the limit imposed by
+# max_queued_messages and max_queued_bytes
+# Defaults to false.
+# This is a non-standard option for the MQTT v3.1 spec but is allowed in
+# v3.1.1.
+#queue_qos0_messages false
+
+# Set to false to disable retained message support. If a client publishes a
+# message with the retain bit set, it will be disconnected if this is set to
+# false.
+#retain_available true
+
+# Disable Nagle's algorithm on client sockets. This has the effect of reducing
+# latency of individual messages at the potential cost of increasing the number
+# of packets being sent.
+#set_tcp_nodelay false
+
+# Time in seconds between updates of the $SYS tree.
+# Set to 0 to disable the publishing of the $SYS tree.
+#sys_interval 10
+
+# The MQTT specification requires that the QoS of a message delivered to a
+# subscriber is never upgraded to match the QoS of the subscription. Enabling
+# this option changes this behaviour. If upgrade_outgoing_qos is set true,
+# messages sent to a subscriber will always match the QoS of its subscription.
+# This is a non-standard option explicitly disallowed by the spec.
+#upgrade_outgoing_qos false
+
+# When run as root, drop privileges to this user and its primary
+# group.
+# Set to root to stay as root, but this is not recommended.
+# If run as a non-root user, this setting has no effect.
+# Note that on Windows this has no effect and so mosquitto should
+# be started by the user you wish it to run as.
+#user mosquitto
+
+# =================================================================
+# Default listener
+# =================================================================
+
+# IP address/hostname to bind the default listener to. If not
+# given, the default listener will not be bound to a specific
+# address and so will be accessible to all network interfaces.
+# bind_address ip-address/host name
+#bind_address
+
+# Port to use for the default listener.
+#port 1883
+
+# Bind the listener to a specific interface. This is similar to
+# bind_address above but is useful when an interface has multiple addresses or
+# the address may change. It is valid to use this with the bind_address option,
+# but take care that the interface you are binding to contains the address you
+# are binding to, otherwise you will not be able to connect.
+# Example: bind_interface eth0
+#bind_interface
+
+# When a listener is using the websockets protocol, it is possible to serve
+# http data as well. Set http_dir to a directory which contains the files you
+# wish to serve. If this option is not specified, then no normal http
+# connections will be possible.
+#http_dir
+
+# The maximum number of client connections to allow. This is
+# a per listener setting.
+# Default is -1, which means unlimited connections.
+# Note that other process limits mean that unlimited connections
+# are not really possible. Typically the default maximum number of
+# connections possible is around 1024.
+#max_connections -1
+
+# Choose the protocol to use when listening.
+# This can be either mqtt or websockets.
+# Websockets support is currently disabled by default at compile time.
+# Certificate based TLS may be used with websockets, except that
+# only the cafile, certfile, keyfile and ciphers options are supported.
+#protocol mqtt
+
+# Set use_username_as_clientid to true to replace the clientid that a client
+# connected with with its username. This allows authentication to be tied to
+# the clientid, which means that it is possible to prevent one client
+# disconnecting another by using the same clientid.
+# If a client connects with no username it will be disconnected as not
+# authorised when this option is set to true.
+# Do not use in conjunction with clientid_prefixes.
+# See also use_identity_as_username.
+#use_username_as_clientid
+
+# -----------------------------------------------------------------
+# Certificate based SSL/TLS support
+# -----------------------------------------------------------------
+# The following options can be used to enable SSL/TLS support for
+# this listener. Note that the recommended port for MQTT over TLS
+# is 8883, but this must be set manually.
+#
+# See also the mosquitto-tls man page.
+
+# At least one of cafile or capath must be defined. They both
+# define methods of accessing the PEM encoded Certificate
+# Authority certificates that have signed your server certificate
+# and that you wish to trust.
+# cafile defines the path to a file containing the CA certificates.
+# capath defines a directory that will be searched for files
+# containing the CA certificates. For capath to work correctly, the
+# certificate files must have ".crt" as the file ending and you must run
+# "openssl rehash <path to capath>" each time you add/remove a certificate.
+#cafile
+#capath
+
+# Path to the PEM encoded server certificate.
+#certfile
+
+# Path to the PEM encoded keyfile.
+#keyfile
+
+
+# If you have require_certificate set to true, you can create a certificate
+# revocation list file to revoke access to particular client certificates. If
+# you have done this, use crlfile to point to the PEM encoded revocation file.
+#crlfile
+
+# If you wish to control which encryption ciphers are used, use the ciphers
+# option. The list of available ciphers can be obtained using the "openssl
+# ciphers" command and should be provided in the same format as the output of
+# that command.
+# If unset defaults to DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2:@STRENGTH
+#ciphers DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2:@STRENGTH
+
+# To allow the use of ephemeral DH key exchange, which provides forward
+# security, the listener must load DH parameters. This can be specified with
+# the dhparamfile option. The dhparamfile can be generated with the command
+# e.g. "openssl dhparam -out dhparam.pem 2048"
+#dhparamfile
+
+# By default a TLS enabled listener will operate in a similar fashion to a
+# https enabled web server, in that the server has a certificate signed by a CA
+# and the client will verify that it is a trusted certificate. The overall aim
+# is encryption of the network traffic. By setting require_certificate to true,
+# the client must provide a valid certificate in order for the network
+# connection to proceed. This allows access to the broker to be controlled
+# outside of the mechanisms provided by MQTT.
+#require_certificate false
+
+# This option defines the version of the TLS protocol to use for this listener.
+# The default value allows all of v1.3, v1.2 and v1.1. The valid values are
+# tlsv1.3 tlsv1.2 and tlsv1.1.
+#tls_version
+
+# If require_certificate is true, you may set use_identity_as_username to true
+# to use the CN value from the client certificate as a username. If this is
+# true, the password_file option will not be used for this listener.
+# This takes priority over use_subject_as_username.
+# See also use_subject_as_username.
+#use_identity_as_username false
+
+# If require_certificate is true, you may set use_subject_as_username to true
+# to use the complete subject value from the client certificate as a username.
+# If this is true, the password_file option will not be used for this listener.
+# See also use_identity_as_username
+#use_subject_as_username false
+
+# -----------------------------------------------------------------
+# Pre-shared-key based SSL/TLS support
+# -----------------------------------------------------------------
+# The following options can be used to enable PSK based SSL/TLS support for
+# this listener. Note that the recommended port for MQTT over TLS is 8883, but
+# this must be set manually.
+#
+# See also the mosquitto-tls man page and the "Certificate based SSL/TLS
+# support" section. Only one of certificate or PSK encryption support can be
+# enabled for any listener.
+
+# The psk_hint option enables pre-shared-key support for this listener and also
+# acts as an identifier for this listener. The hint is sent to clients and may
+# be used locally to aid authentication. The hint is a free form string that
+# doesn't have much meaning in itself, so feel free to be creative.
+# If this option is provided, see psk_file to define the pre-shared keys to be
+# used or create a security plugin to handle them.
+#psk_hint
+
+# When using PSK, the encryption ciphers used will be chosen from the list of
+# available PSK ciphers. If you want to control which ciphers are available,
+# use the "ciphers" option. The list of available ciphers can be obtained
+# using the "openssl ciphers" command and should be provided in the same format
+# as the output of that command.
+#ciphers
+
+# Set use_identity_as_username to have the psk identity sent by the client used
+# as its username. Authentication will be carried out using the PSK rather than
+# the MQTT username/password and so password_file will not be used for this
+# listener.
+#use_identity_as_username false
+
+
+# =================================================================
+# Extra listeners
+# =================================================================
+
+# Listen on a port/ip address combination. By using this variable
+# multiple times, mosquitto can listen on more than one port. If
+# this variable is used and neither bind_address nor port given,
+# then the default listener will not be started.
+# The port number to listen on must be given. Optionally, an ip
+# address or host name may be supplied as a second argument. In
+# this case, mosquitto will attempt to bind the listener to that
+# address and so restrict access to the associated network and
+# interface. By default, mosquitto will listen on all interfaces.
+# Note that for a websockets listener it is not possible to bind to a host
+# name.
+# listener port-number [ip address/host name]
+#listener
+
+# Bind the listener to a specific interface. This is similar to
+# the [ip address/host name] part of the listener definition, but is useful
+# when an interface has multiple addresses or the address may change. It is
+# valid to use this with the [ip address/host name] part of the listener
+# definition, but take care that the interface you are binding to contains the
+# address you are binding to, otherwise you will not be able to connect.
+# Only available on Linux and requires elevated privileges.
+#
+# Example: bind_interface eth0
+#bind_interface
+
+# When a listener is using the websockets protocol, it is possible to serve
+# http data as well. Set http_dir to a directory which contains the files you
+# wish to serve. If this option is not specified, then no normal http
+# connections will be possible.
+#http_dir
+
+# The maximum number of client connections to allow. This is
+# a per listener setting.
+# Default is -1, which means unlimited connections.
+# Note that other process limits mean that unlimited connections
+# are not really possible. Typically the default maximum number of
+# connections possible is around 1024.
+#max_connections -1
+
+# The listener can be restricted to operating within a topic hierarchy using
+# the mount_point option. This is achieved be prefixing the mount_point string
+# to all topics for any clients connected to this listener. This prefixing only
+# happens internally to the broker; the client will not see the prefix.
+#mount_point
+
+# Choose the protocol to use when listening.
+# This can be either mqtt or websockets.
+# Certificate based TLS may be used with websockets, except that only the
+# cafile, certfile, keyfile and ciphers options are supported.
+#protocol mqtt
+
+# Set use_username_as_clientid to true to replace the clientid that a client
+# connected with with its username. This allows authentication to be tied to
+# the clientid, which means that it is possible to prevent one client
+# disconnecting another by using the same clientid.
+# If a client connects with no username it will be disconnected as not
+# authorised when this option is set to true.
+# Do not use in conjunction with clientid_prefixes.
+# See also use_identity_as_username.
+#use_username_as_clientid
+
+# Change the websockets headers size. This is a global option, it is not
+# possible to set per listener. This option sets the size of the buffer used in
+# the libwebsockets library when reading HTTP headers. If you are passing large
+# header data such as cookies then you may need to increase this value. If left
+# unset, or set to 0, then the default of 1024 bytes will be used.
+#websockets_headers_size
+
+# -----------------------------------------------------------------
+# Certificate based SSL/TLS support
+# -----------------------------------------------------------------
+# The following options can be used to enable certificate based SSL/TLS support
+# for this listener. Note that the recommended port for MQTT over TLS is 8883,
+# but this must be set manually.
+#
+# See also the mosquitto-tls man page and the "Pre-shared-key based SSL/TLS
+# support" section. Only one of certificate or PSK encryption support can be
+# enabled for any listener.
+
+# At least one of cafile or capath must be defined to enable certificate based
+# TLS encryption. They both define methods of accessing the PEM encoded
+# Certificate Authority certificates that have signed your server certificate
+# and that you wish to trust.
+# cafile defines the path to a file containing the CA certificates.
+# capath defines a directory that will be searched for files
+# containing the CA certificates. For capath to work correctly, the
+# certificate files must have ".crt" as the file ending and you must run
+# "openssl rehash <path to capath>" each time you add/remove a certificate.
+#cafile
+#capath
+
+# Path to the PEM encoded server certificate.
+#certfile
+
+# Path to the PEM encoded keyfile.
+#keyfile
+
+
+# If you wish to control which encryption ciphers are used, use the ciphers
+# option. The list of available ciphers can be optained using the "openssl
+# ciphers" command and should be provided in the same format as the output of
+# that command.
+#ciphers
+
+# If you have require_certificate set to true, you can create a certificate
+# revocation list file to revoke access to particular client certificates. If
+# you have done this, use crlfile to point to the PEM encoded revocation file.
+#crlfile
+
+# To allow the use of ephemeral DH key exchange, which provides forward
+# security, the listener must load DH parameters. This can be specified with
+# the dhparamfile option. The dhparamfile can be generated with the command
+# e.g. "openssl dhparam -out dhparam.pem 2048"
+#dhparamfile
+
+# By default an TLS enabled listener will operate in a similar fashion to a
+# https enabled web server, in that the server has a certificate signed by a CA
+# and the client will verify that it is a trusted certificate. The overall aim
+# is encryption of the network traffic. By setting require_certificate to true,
+# the client must provide a valid certificate in order for the network
+# connection to proceed. This allows access to the broker to be controlled
+# outside of the mechanisms provided by MQTT.
+#require_certificate false
+
+# If require_certificate is true, you may set use_identity_as_username to true
+# to use the CN value from the client certificate as a username. If this is
+# true, the password_file option will not be used for this listener.
+#use_identity_as_username false
+
+# -----------------------------------------------------------------
+# Pre-shared-key based SSL/TLS support
+# -----------------------------------------------------------------
+# The following options can be used to enable PSK based SSL/TLS support for
+# this listener. Note that the recommended port for MQTT over TLS is 8883, but
+# this must be set manually.
+#
+# See also the mosquitto-tls man page and the "Certificate based SSL/TLS
+# support" section. Only one of certificate or PSK encryption support can be
+# enabled for any listener.
+
+# The psk_hint option enables pre-shared-key support for this listener and also
+# acts as an identifier for this listener. The hint is sent to clients and may
+# be used locally to aid authentication. The hint is a free form string that
+# doesn't have much meaning in itself, so feel free to be creative.
+# If this option is provided, see psk_file to define the pre-shared keys to be
+# used or create a security plugin to handle them.
+#psk_hint
+
+# When using PSK, the encryption ciphers used will be chosen from the list of
+# available PSK ciphers. If you want to control which ciphers are available,
+# use the "ciphers" option. The list of available ciphers can be optained
+# using the "openssl ciphers" command and should be provided in the same format
+# as the output of that command.
+#ciphers
+
+# Set use_identity_as_username to have the psk identity sent by the client used
+# as its username. Authentication will be carried out using the PSK rather than
+# the MQTT username/password and so password_file will not be used for this
+# listener.
+#use_identity_as_username false
+
+
+# =================================================================
+# Persistence
+# =================================================================
+
+# If persistence is enabled, save the in-memory database to disk
+# every autosave_interval seconds. If set to 0, the persistence
+# database will only be written when mosquitto exits. See also
+# autosave_on_changes.
+# Note that writing of the persistence database can be forced by
+# sending mosquitto a SIGUSR1 signal.
+#autosave_interval 1800
+
+# If true, mosquitto will count the number of subscription changes, retained
+# messages received and queued messages and if the total exceeds
+# autosave_interval then the in-memory database will be saved to disk.
+# If false, mosquitto will save the in-memory database to disk by treating
+# autosave_interval as a time in seconds.
+#autosave_on_changes false
+
+# Save persistent message data to disk (true/false).
+# This saves information about all messages, including
+# subscriptions, currently in-flight messages and retained
+# messages.
+# retained_persistence is a synonym for this option.
+#persistence false
+
+# The filename to use for the persistent database, not including
+# the path.
+#persistence_file mosquitto.db
+
+# Location for persistent database. Must include trailing /
+# Default is an empty string (current directory).
+# Set to e.g. /var/lib/mosquitto/ if running as a proper service on Linux or
+# similar.
+#persistence_location
+
+
+# =================================================================
+# Logging
+# =================================================================
+
+# Places to log to. Use multiple log_dest lines for multiple
+# logging destinations.
+# Possible destinations are: stdout stderr syslog topic file
+#
+# stdout and stderr log to the console on the named output.
+#
+# syslog uses the userspace syslog facility which usually ends up
+# in /var/log/messages or similar.
+#
+# topic logs to the broker topic '$SYS/broker/log/<severity>',
+# where severity is one of D, E, W, N, I, M which are debug, error,
+# warning, notice, information and message. Message type severity is used by
+# the subscribe/unsubscribe log_types and publishes log messages to
+# $SYS/broker/log/M/susbcribe or $SYS/broker/log/M/unsubscribe.
+#
+# The file destination requires an additional parameter which is the file to be
+# logged to, e.g. "log_dest file /var/log/mosquitto.log". The file will be
+# closed and reopened when the broker receives a HUP signal. Only a single file
+# destination may be configured.
+#
+# Note that if the broker is running as a Windows service it will default to
+# "log_dest none" and neither stdout nor stderr logging is available.
+# Use "log_dest none" if you wish to disable logging.
+log_dest file /mosquitto/log/mosquitto.log
+
+# Types of messages to log. Use multiple log_type lines for logging
+# multiple types of messages.
+# Possible types are: debug, error, warning, notice, information,
+# none, subscribe, unsubscribe, websockets, all.
+# Note that debug type messages are for decoding the incoming/outgoing
+# network packets. They are not logged in "topics".
+#log_type error
+#log_type warning
+#log_type notice
+#log_type information
+
+
+# If set to true, client connection and disconnection messages will be included
+# in the log.
+#connection_messages true
+
+# If using syslog logging (not on Windows), messages will be logged to the
+# "daemon" facility by default. Use the log_facility option to choose which of
+# local0 to local7 to log to instead. The option value should be an integer
+# value, e.g. "log_facility 5" to use local5.
+#log_facility
+
+# If set to true, add a timestamp value to each log message.
+#log_timestamp true
+
+# Set the format of the log timestamp. If left unset, this is the number of
+# seconds since the Unix epoch.
+# This is a free text string which will be passed to the strftime function. To
+# get an ISO 8601 datetime, for example:
+# log_timestamp_format %Y-%m-%dT%H:%M:%S
+#log_timestamp_format
+
+# Change the websockets logging level. This is a global option, it is not
+# possible to set per listener. This is an integer that is interpreted by
+# libwebsockets as a bit mask for its lws_log_levels enum. See the
+# libwebsockets documentation for more details. "log_type websockets" must also
+# be enabled.
+#websockets_log_level 0
+
+
+# =================================================================
+# Security
+# =================================================================
+
+# If set, only clients that have a matching prefix on their
+# clientid will be allowed to connect to the broker. By default,
+# all clients may connect.
+# For example, setting "secure-" here would mean a client "secure-
+# client" could connect but another with clientid "mqtt" couldn't.
+#clientid_prefixes
+
+# Boolean value that determines whether clients that connect
+# without providing a username are allowed to connect. If set to
+# false then a password file should be created (see the
+# password_file option) to control authenticated client access.
+#
+# Defaults to true if no other security options are set. If `password_file` or
+# `psk_file` is set, or if an authentication plugin is loaded which implements
+# username/password or TLS-PSK checks, then `allow_anonymous` defaults to
+# false.
+#
+#allow_anonymous true
+
+# -----------------------------------------------------------------
+# Default authentication and topic access control
+# -----------------------------------------------------------------
+
+# Control access to the broker using a password file. This file can be
+# generated using the mosquitto_passwd utility. If TLS support is not compiled
+# into mosquitto (it is recommended that TLS support should be included) then
+# plain text passwords are used, in which case the file should be a text file
+# with lines in the format:
+# username:password
+# The password (and colon) may be omitted if desired, although this
+# offers very little in the way of security.
+#
+# See the TLS client require_certificate and use_identity_as_username options
+# for alternative authentication options. If an auth_plugin is used as well as
+# password_file, the auth_plugin check will be made first.
+#password_file
+
+# Access may also be controlled using a pre-shared-key file. This requires
+# TLS-PSK support and a listener configured to use it. The file should be text
+# lines in the format:
+# identity:key
+# The key should be in hexadecimal format without a leading "0x".
+# If an auth_plugin is used as well, the auth_plugin check will be made first.
+#psk_file
+
+# Control access to topics on the broker using an access control list
+# file. If this parameter is defined then only the topics listed will
+# have access.
+# If the first character of a line of the ACL file is a # it is treated as a
+# comment.
+# Topic access is added with lines of the format:
+#
+# topic [read|write|readwrite] <topic>
+#
+# The access type is controlled using "read", "write" or "readwrite". This
+# parameter is optional (unless <topic> contains a space character) - if not
+# given then the access is read/write. <topic> can contain the + or #
+# wildcards as in subscriptions.
+#
+# The first set of topics are applied to anonymous clients, assuming
+# allow_anonymous is true. User specific topic ACLs are added after a
+# user line as follows:
+#
+# user <username>
+#
+# The username referred to here is the same as in password_file. It is
+# not the clientid.
+#
+#
+# If is also possible to define ACLs based on pattern substitution within the
+# topic. The patterns available for substition are:
+#
+# %c to match the client id of the client
+# %u to match the username of the client
+#
+# The substitution pattern must be the only text for that level of hierarchy.
+#
+# The form is the same as for the topic keyword, but using pattern as the
+# keyword.
+# Pattern ACLs apply to all users even if the "user" keyword has previously
+# been given.
+#
+# If using bridges with usernames and ACLs, connection messages can be allowed
+# with the following pattern:
+# pattern write $SYS/broker/connection/%c/state
+#
+# pattern [read|write|readwrite] <topic>
+#
+# Example:
+#
+# pattern write sensor/%u/data
+#
+# If an auth_plugin is used as well as acl_file, the auth_plugin check will be
+# made first.
+#acl_file
+
+# -----------------------------------------------------------------
+# External authentication and topic access plugin options
+# -----------------------------------------------------------------
+
+# External authentication and access control can be supported with the
+# auth_plugin option. This is a path to a loadable plugin. See also the
+# auth_opt_* options described below.
+#
+# The auth_plugin option can be specified multiple times to load multiple
+# plugins. The plugins will be processed in the order that they are specified
+# here. If the auth_plugin option is specified alongside either of
+# password_file or acl_file then the plugin checks will be made first.
+#
+#auth_plugin
+
+# If the auth_plugin option above is used, define options to pass to the
+# plugin here as described by the plugin instructions. All options named
+# using the format auth_opt_* will be passed to the plugin, for example:
+#
+# auth_opt_db_host
+# auth_opt_db_port
+# auth_opt_db_username
+# auth_opt_db_password
+
+
+# =================================================================
+# Bridges
+# =================================================================
+
+# A bridge is a way of connecting multiple MQTT brokers together.
+# Create a new bridge using the "connection" option as described below. Set
+# options for the bridges using the remaining parameters. You must specify the
+# address and at least one topic to subscribe to.
+#
+# Each connection must have a unique name.
+#
+# The address line may have multiple host address and ports specified. See
+# below in the round_robin description for more details on bridge behaviour if
+# multiple addresses are used. Note that if you use an IPv6 address, then you
+# are required to specify a port.
+#
+# The direction that the topic will be shared can be chosen by
+# specifying out, in or both, where the default value is out.
+# The QoS level of the bridged communication can be specified with the next
+# topic option. The default QoS level is 0, to change the QoS the topic
+# direction must also be given.
+#
+# The local and remote prefix options allow a topic to be remapped when it is
+# bridged to/from the remote broker. This provides the ability to place a topic
+# tree in an appropriate location.
+#
+# For more details see the mosquitto.conf man page.
+#
+# Multiple topics can be specified per connection, but be careful
+# not to create any loops.
+#
+# If you are using bridges with cleansession set to false (the default), then
+# you may get unexpected behaviour from incoming topics if you change what
+# topics you are subscribing to. This is because the remote broker keeps the
+# subscription for the old topic. If you have this problem, connect your bridge
+# with cleansession set to true, then reconnect with cleansession set to false
+# as normal.
+#connection <name>
+#address <host>[:<port>] [<host>[:<port>]]
+#topic <topic> [[[out | in | both] qos-level] local-prefix remote-prefix]
+
+
+# If a bridge has topics that have "out" direction, the default behaviour is to
+# send an unsubscribe request to the remote broker on that topic. This means
+# that changing a topic direction from "in" to "out" will not keep receiving
+# incoming messages. Sending these unsubscribe requests is not always
+# desirable, setting bridge_attempt_unsubscribe to false will disable sending
+# the unsubscribe request.
+#bridge_attempt_unsubscribe true
+
+# Set the version of the MQTT protocol to use with for this bridge. Can be one
+# of mqttv311 or mqttv11. Defaults to mqttv311.
+#bridge_protocol_version mqttv311
+
+# Set the clean session variable for this bridge.
+# When set to true, when the bridge disconnects for any reason, all
+# messages and subscriptions will be cleaned up on the remote
+# broker. Note that with cleansession set to true, there may be a
+# significant amount of retained messages sent when the bridge
+# reconnects after losing its connection.
+# When set to false, the subscriptions and messages are kept on the
+# remote broker, and delivered when the bridge reconnects.
+#cleansession false
+
+# Set the amount of time a bridge using the lazy start type must be idle before
+# it will be stopped. Defaults to 60 seconds.
+#idle_timeout 60
+
+# Set the keepalive interval for this bridge connection, in
+# seconds.
+#keepalive_interval 60
+
+# Set the clientid to use on the local broker. If not defined, this defaults to
+# 'local.<clientid>'. If you are bridging a broker to itself, it is important
+# that local_clientid and clientid do not match.
+#local_clientid
+
+# If set to true, publish notification messages to the local and remote brokers
+# giving information about the state of the bridge connection. Retained
+# messages are published to the topic $SYS/broker/connection/<clientid>/state
+# unless the notification_topic option is used.
+# If the message is 1 then the connection is active, or 0 if the connection has
+# failed.
+# This uses the last will and testament feature.
+#notifications true
+
+# Choose the topic on which notification messages for this bridge are
+# published. If not set, messages are published on the topic
+# $SYS/broker/connection/<clientid>/state
+#notification_topic
+
+# Set the client id to use on the remote end of this bridge connection. If not
+# defined, this defaults to 'name.hostname' where name is the connection name
+# and hostname is the hostname of this computer.
+# This replaces the old "clientid" option to avoid confusion. "clientid"
+# remains valid for the time being.
+#remote_clientid
+
+# Set the password to use when connecting to a broker that requires
+# authentication. This option is only used if remote_username is also set.
+# This replaces the old "password" option to avoid confusion. "password"
+# remains valid for the time being.
+#remote_password
+
+# Set the username to use when connecting to a broker that requires
+# authentication.
+# This replaces the old "username" option to avoid confusion. "username"
+# remains valid for the time being.
+#remote_username
+
+# Set the amount of time a bridge using the automatic start type will wait
+# until attempting to reconnect.
+# This option can be configured to use a constant delay time in seconds, or to
+# use a backoff mechanism based on "Decorrelated Jitter", which adds a degree
+# of randomness to when the restart occurs.
+#
+# Set a constant timeout of 20 seconds:
+# restart_timeout 20
+#
+# Set backoff with a base (start value) of 10 seconds and a cap (upper limit) of
+# 60 seconds:
+# restart_timeout 10 30
+#
+# Defaults to jitter with a base of 5 and cap of 30
+#restart_timeout 5 30
+
+# If the bridge has more than one address given in the address/addresses
+# configuration, the round_robin option defines the behaviour of the bridge on
+# a failure of the bridge connection. If round_robin is false, the default
+# value, then the first address is treated as the main bridge connection. If
+# the connection fails, the other secondary addresses will be attempted in
+# turn. Whilst connected to a secondary bridge, the bridge will periodically
+# attempt to reconnect to the main bridge until successful.
+# If round_robin is true, then all addresses are treated as equals. If a
+# connection fails, the next address will be tried and if successful will
+# remain connected until it fails
+#round_robin false
+
+# Set the start type of the bridge. This controls how the bridge starts and
+# can be one of three types: automatic, lazy and once. Note that RSMB provides
+# a fourth start type "manual" which isn't currently supported by mosquitto.
+#
+# "automatic" is the default start type and means that the bridge connection
+# will be started automatically when the broker starts and also restarted
+# after a short delay (30 seconds) if the connection fails.
+#
+# Bridges using the "lazy" start type will be started automatically when the
+# number of queued messages exceeds the number set with the "threshold"
+# parameter. It will be stopped automatically after the time set by the
+# "idle_timeout" parameter. Use this start type if you wish the connection to
+# only be active when it is needed.
+#
+# A bridge using the "once" start type will be started automatically when the
+# broker starts but will not be restarted if the connection fails.
+#start_type automatic
+
+# Set the number of messages that need to be queued for a bridge with lazy
+# start type to be restarted. Defaults to 10 messages.
+# Must be less than max_queued_messages.
+#threshold 10
+
+# If try_private is set to true, the bridge will attempt to indicate to the
+# remote broker that it is a bridge not an ordinary client. If successful, this
+# means that loop detection will be more effective and that retained messages
+# will be propagated correctly. Not all brokers support this feature so it may
+# be necessary to set try_private to false if your bridge does not connect
+# properly.
+#try_private true
+
+# -----------------------------------------------------------------
+# Certificate based SSL/TLS support
+# -----------------------------------------------------------------
+# Either bridge_cafile or bridge_capath must be defined to enable TLS support
+# for this bridge.
+# bridge_cafile defines the path to a file containing the
+# Certificate Authority certificates that have signed the remote broker
+# certificate.
+# bridge_capath defines a directory that will be searched for files containing
+# the CA certificates. For bridge_capath to work correctly, the certificate
+# files must have ".crt" as the file ending and you must run "openssl rehash
+# <path to capath>" each time you add/remove a certificate.
+#bridge_cafile
+#bridge_capath
+
+
+# If the remote broker has more than one protocol available on its port, e.g.
+# MQTT and WebSockets, then use bridge_alpn to configure which protocol is
+# requested. Note that WebSockets support for bridges is not yet available.
+#bridge_alpn
+
+# When using certificate based encryption, bridge_insecure disables
+# verification of the server hostname in the server certificate. This can be
+# useful when testing initial server configurations, but makes it possible for
+# a malicious third party to impersonate your server through DNS spoofing, for
+# example. Use this option in testing only. If you need to resort to using this
+# option in a production environment, your setup is at fault and there is no
+# point using encryption.
+#bridge_insecure false
+
+# Path to the PEM encoded client certificate, if required by the remote broker.
+#bridge_certfile
+
+# Path to the PEM encoded client private key, if required by the remote broker.
+#bridge_keyfile
+
+# -----------------------------------------------------------------
+# PSK based SSL/TLS support
+# -----------------------------------------------------------------
+# Pre-shared-key encryption provides an alternative to certificate based
+# encryption. A bridge can be configured to use PSK with the bridge_identity
+# and bridge_psk options. These are the client PSK identity, and pre-shared-key
+# in hexadecimal format with no "0x". Only one of certificate and PSK based
+# encryption can be used on one
+# bridge at once.
+#bridge_identity
+#bridge_psk
+
+
+# =================================================================
+# External config files
+# =================================================================
+
+# External configuration files may be included by using the
+# include_dir option. This defines a directory that will be searched
+# for config files. All files that end in '.conf' will be loaded as
+# a configuration file. It is best to have this as the last option
+# in the main file. This option will only be processed from the main
+# configuration file. The directory specified must not contain the
+# main configuration file.
+# Files within include_dir will be loaded sorted in case-sensitive
+# alphabetical order, with capital letters ordered first. If this option is
+# given multiple times, all of the files from the first instance will be
+# processed before the next instance. See the man page for examples.
+#include_dir
diff --git a/examples/basyx.nodered/node-red-contrib-aas-connect/get-aas-property.html b/examples/basyx.nodered/node-red-contrib-aas-connect/get-aas-property.html
new file mode 100644
index 0000000..540724e
--- /dev/null
+++ b/examples/basyx.nodered/node-red-contrib-aas-connect/get-aas-property.html
@@ -0,0 +1,50 @@
+<script type="text/javascript">
+ RED.nodes.registerType('get-aas-property', {
+ category: 'network',
+ defaults: {
+ name: { value: '' },
+ property: { value: 'temperature', required: true },
+ period: { value: 1, required: true }
+ },
+ inputs: 1,
+ outputs: 1,
+ color: '#C3D6F2',
+ align: 'left',
+ label: function() {
+ return this.name || "Get AAS property";
+ },
+ palettelabel: function() {
+ return this.name || "Get AAS property";
+ },
+ icon: 'logo-BaSys4.png',
+ })
+</script>
+
+<script type="text/html" data-template-name="get-aas-property">
+ <div class="form-row">
+ <label for="node-input-name"><i class="fa fa-tag"></i> Node name</label>
+ <input type="text" id="node-input-name" placeholder="Name">
+ </div>
+ <div class="form-row">
+ <label for="node-input-property"><i class="fa fa-rss"></i> Property</label>
+ <input type="text" id="node-input-property" placeholder="Property">
+ </div>
+ <div class="form-row">
+ <label for="node-input-period">
+ <i class="fa fa-clock-o"></i> Interval <br/><span style="font-size:0.8em">(in seconds)</span>
+ </label>
+ <input type="text" id="node-input-period" placeholder="Interval">
+ </div>
+ <!-- <div class="form-tips"><b>Tip:</b> This is here to help.</div> -->
+</script>
+
+<script type="text/html" data-help-name="get-aas-property">
+ <p>This node monitors (periodically retrives) the value of an AAS property</p>
+ <h3>Outputs</h3>
+ <dl class="message-properties">
+ <dt>payload
+ <span class="property-type">object</span>
+ </dt>
+ <dd> the payload of the message containing the property value (in the 'value' key) and the timestamp (in the 'tstamp' key). </dd>
+ </dl>
+ </script>
\ No newline at end of file
diff --git a/examples/basyx.nodered/node-red-contrib-aas-connect/get-aas-property.js b/examples/basyx.nodered/node-red-contrib-aas-connect/get-aas-property.js
new file mode 100644
index 0000000..09fdd0e
--- /dev/null
+++ b/examples/basyx.nodered/node-red-contrib-aas-connect/get-aas-property.js
@@ -0,0 +1,60 @@
+module.exports = function(RED) {
+
+ const request = require('request');
+
+ function GetAASProperty(config) {
+ let property = config.property || 'temp';
+ let endpoint = `http://aas-wrapper:6500/streamsheets/${property}`;
+ let period = Number(config.period) || 1;
+ let msperiod = period * 1000;
+
+ RED.nodes.createNode(this, config);
+
+ let node = this;
+ let interval;
+ node.on('input', function(msg, send, done) {
+ interval = setInterval(() => {
+ request(endpoint, { json: true }, (err, res, body) => {
+ if (err) {
+ node.error(err);
+ if (done) done(err);
+ return;
+ }
+
+ if (!body.success) {
+ node.error(body.messages);
+ if (done) done(body.messages);
+ return;
+ }
+
+ // let mostRecentTimestamp = body.timestamp.pop();
+ // let mostRecentValue = body.content.pop();
+
+ let data = {
+ tstamp: body.timestamp,
+ data: body.content,
+ }
+
+ msg.payload = data;
+
+ // For maximum backwards compatibility, check that send exists.
+ // If this node is installed in Node-RED 0.x, it will need to
+ // fallback to using `node.send`
+ send = send || function() { node.send.apply(node, msg) }
+ send(msg);
+
+ if (done) done();
+ });
+ }, msperiod);
+
+ });
+
+ node.on('close', function(done) {
+ clearInterval(interval);
+ if (done) done();
+ });
+
+ }
+
+ RED.nodes.registerType('get-aas-property', GetAASProperty);
+}
\ No newline at end of file
diff --git a/examples/basyx.nodered/node-red-contrib-aas-connect/icons/logo-BaSys4.png b/examples/basyx.nodered/node-red-contrib-aas-connect/icons/logo-BaSys4.png
new file mode 100644
index 0000000..56d0dac
--- /dev/null
+++ b/examples/basyx.nodered/node-red-contrib-aas-connect/icons/logo-BaSys4.png
Binary files differ
diff --git a/examples/basyx.nodered/node-red-contrib-aas-connect/icons/machine.png b/examples/basyx.nodered/node-red-contrib-aas-connect/icons/machine.png
new file mode 100644
index 0000000..56db813
--- /dev/null
+++ b/examples/basyx.nodered/node-red-contrib-aas-connect/icons/machine.png
Binary files differ
diff --git a/examples/basyx.nodered/node-red-contrib-aas-connect/package.json b/examples/basyx.nodered/node-red-contrib-aas-connect/package.json
new file mode 100644
index 0000000..882bb64
--- /dev/null
+++ b/examples/basyx.nodered/node-red-contrib-aas-connect/package.json
@@ -0,0 +1,20 @@
+{
+ "name": "node-red-contrib-aas-connect",
+ "version": "1.0.0",
+ "description": "",
+ "main": "get-aas-property.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "node-red": {
+ "nodes": {
+ "get-aas-property": "get-aas-property.js",
+ "set-aas-property": "set-aas-property.js"
+ }
+ },
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "request": "^2.88.2"
+ }
+}
diff --git a/examples/basyx.nodered/node-red-contrib-aas-connect/set-aas-property.html b/examples/basyx.nodered/node-red-contrib-aas-connect/set-aas-property.html
new file mode 100644
index 0000000..db9b93a
--- /dev/null
+++ b/examples/basyx.nodered/node-red-contrib-aas-connect/set-aas-property.html
@@ -0,0 +1,36 @@
+<script type="text/javascript">
+ RED.nodes.registerType('set-aas-property', {
+ category: 'network',
+ defaults: {
+ name: { value: '' },
+ property: { value: 'temp', required: true },
+ },
+ inputs: 1,
+ outputs: 0,
+ color: '#C3D6F2',
+ align: 'right',
+ label: function() {
+ return this.name || "Set AAS property";
+ },
+ palettelabel: function() {
+ return this.name || "Set AAS property";
+ },
+ icon: 'logo-BaSys4.png',
+ })
+</script>
+
+<script type="text/html" data-template-name="set-aas-property">
+ <div class="form-row">
+ <label for="node-input-name"><i class="fa fa-tag"></i> Node name</label>
+ <input type="text" id="node-input-name" placeholder="Name">
+ </div>
+ <div class="form-row">
+ <label for="node-input-property"><i class="fa fa-rss"></i> Property</label>
+ <input type="text" id="node-input-property" placeholder="Property">
+ </div>
+ <!-- <div class="form-tips"><b>Tip:</b> This is here to help.</div> -->
+</script>
+
+<script type="text/html" data-help-name="set-aas-property">
+ <p>This node sets the value of an AAS property</p>
+ </script>
\ No newline at end of file
diff --git a/examples/basyx.nodered/node-red-contrib-aas-connect/set-aas-property.js b/examples/basyx.nodered/node-red-contrib-aas-connect/set-aas-property.js
new file mode 100644
index 0000000..d8af768
--- /dev/null
+++ b/examples/basyx.nodered/node-red-contrib-aas-connect/set-aas-property.js
@@ -0,0 +1,40 @@
+module.exports = function(RED) {
+
+ const request = require('request');
+
+ function SetAASProperty(config) {
+ let property = config.property || 'temp';
+ let endpoint = `http://aas-wrapper:6500/streamsheets/${property}`;
+
+ RED.nodes.createNode(this, config);
+
+ let node = this;
+ node.on('input', function(msg, send, done) {
+ let newValue = msg.payload;
+
+ request({
+ uri: endpoint,
+ method: 'POST',
+ json: true,
+ body: { value: newValue }
+ }, (err, res, body) => {
+ if (err) {
+ node.error(err);
+ if (done) done(err);
+ return;
+ }
+
+ if (!body.success) {
+ node.error(body.error);
+ if (done) done(body.error);
+ return;
+ }
+
+ if (done) done();
+ });
+ });
+ }
+
+ RED.nodes.registerType('set-aas-property', SetAASProperty);
+
+}
\ No newline at end of file
diff --git a/examples/basyx.nodered/node-red/.config.json b/examples/basyx.nodered/node-red/.config.json
new file mode 100644
index 0000000..c8d13d4
--- /dev/null
+++ b/examples/basyx.nodered/node-red/.config.json
@@ -0,0 +1,456 @@
+{
+ "nodes": {
+ "node-red": {
+ "name": "node-red",
+ "version": "1.1.2",
+ "local": false,
+ "nodes": {
+ "inject": {
+ "name": "inject",
+ "types": [
+ "inject"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/common/20-inject.js"
+ },
+ "debug": {
+ "name": "debug",
+ "types": [
+ "debug"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/common/21-debug.js"
+ },
+ "complete": {
+ "name": "complete",
+ "types": [
+ "complete"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/common/24-complete.js"
+ },
+ "catch": {
+ "name": "catch",
+ "types": [
+ "catch"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/common/25-catch.js"
+ },
+ "status": {
+ "name": "status",
+ "types": [
+ "status"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/common/25-status.js"
+ },
+ "link": {
+ "name": "link",
+ "types": [
+ "link in",
+ "link out"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/common/60-link.js"
+ },
+ "comment": {
+ "name": "comment",
+ "types": [
+ "comment"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/common/90-comment.js"
+ },
+ "unknown": {
+ "name": "unknown",
+ "types": [
+ "unknown"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/common/98-unknown.js"
+ },
+ "function": {
+ "name": "function",
+ "types": [
+ "function"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/function/10-function.js"
+ },
+ "switch": {
+ "name": "switch",
+ "types": [
+ "switch"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/function/10-switch.js"
+ },
+ "change": {
+ "name": "change",
+ "types": [
+ "change"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/function/15-change.js"
+ },
+ "range": {
+ "name": "range",
+ "types": [
+ "range"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/function/16-range.js"
+ },
+ "template": {
+ "name": "template",
+ "types": [
+ "template"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/function/80-template.js"
+ },
+ "delay": {
+ "name": "delay",
+ "types": [
+ "delay"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/function/89-delay.js"
+ },
+ "trigger": {
+ "name": "trigger",
+ "types": [
+ "trigger"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/function/89-trigger.js"
+ },
+ "exec": {
+ "name": "exec",
+ "types": [
+ "exec"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/function/90-exec.js"
+ },
+ "tls": {
+ "name": "tls",
+ "types": [
+ "tls-config"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/network/05-tls.js"
+ },
+ "httpproxy": {
+ "name": "httpproxy",
+ "types": [
+ "http proxy"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/network/06-httpproxy.js"
+ },
+ "mqtt": {
+ "name": "mqtt",
+ "types": [
+ "mqtt in",
+ "mqtt out",
+ "mqtt-broker"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/network/10-mqtt.js"
+ },
+ "httpin": {
+ "name": "httpin",
+ "types": [
+ "http in",
+ "http response"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/network/21-httpin.js"
+ },
+ "httprequest": {
+ "name": "httprequest",
+ "types": [
+ "http request"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/network/21-httprequest.js"
+ },
+ "websocket": {
+ "name": "websocket",
+ "types": [
+ "websocket in",
+ "websocket out",
+ "websocket-listener",
+ "websocket-client"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/network/22-websocket.js"
+ },
+ "tcpin": {
+ "name": "tcpin",
+ "types": [
+ "tcp in",
+ "tcp out",
+ "tcp request"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/network/31-tcpin.js"
+ },
+ "udp": {
+ "name": "udp",
+ "types": [
+ "udp in",
+ "udp out"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/network/32-udp.js"
+ },
+ "CSV": {
+ "name": "CSV",
+ "types": [
+ "csv"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/parsers/70-CSV.js"
+ },
+ "HTML": {
+ "name": "HTML",
+ "types": [
+ "html"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/parsers/70-HTML.js"
+ },
+ "JSON": {
+ "name": "JSON",
+ "types": [
+ "json"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/parsers/70-JSON.js"
+ },
+ "XML": {
+ "name": "XML",
+ "types": [
+ "xml"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/parsers/70-XML.js"
+ },
+ "YAML": {
+ "name": "YAML",
+ "types": [
+ "yaml"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/parsers/70-YAML.js"
+ },
+ "split": {
+ "name": "split",
+ "types": [
+ "split",
+ "join"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/sequence/17-split.js"
+ },
+ "sort": {
+ "name": "sort",
+ "types": [
+ "sort"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/sequence/18-sort.js"
+ },
+ "batch": {
+ "name": "batch",
+ "types": [
+ "batch"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/sequence/19-batch.js"
+ },
+ "file": {
+ "name": "file",
+ "types": [
+ "file",
+ "file in"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/storage/10-file.js"
+ },
+ "watch": {
+ "name": "watch",
+ "types": [
+ "watch"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red",
+ "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/storage/23-watch.js"
+ }
+ }
+ },
+ "node-red-contrib-aas-connect": {
+ "name": "node-red-contrib-aas-connect",
+ "version": "1.0.0",
+ "local": false,
+ "nodes": {
+ "get-aas-property": {
+ "name": "get-aas-property",
+ "types": [
+ "get-aas-property"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red-contrib-aas-connect",
+ "file": "/usr/src/node-red/node_modules/node-red-contrib-aas-connect/get-aas-property.js"
+ },
+ "set-aas-property": {
+ "name": "set-aas-property",
+ "types": [
+ "set-aas-property"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red-contrib-aas-connect",
+ "file": "/usr/src/node-red/node_modules/node-red-contrib-aas-connect/set-aas-property.js"
+ }
+ }
+ },
+ "node-red-contrib-graphs": {
+ "name": "node-red-contrib-graphs",
+ "version": "0.3.5",
+ "local": false,
+ "nodes": {
+ "datasource": {
+ "name": "datasource",
+ "types": [
+ "iot-datasource"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red-contrib-graphs",
+ "file": "/usr/src/node-red/node_modules/node-red-contrib-graphs/datasource.js"
+ }
+ }
+ },
+ "node-red-node-rbe": {
+ "name": "node-red-node-rbe",
+ "version": "0.2.9",
+ "local": false,
+ "nodes": {
+ "rbe": {
+ "name": "rbe",
+ "types": [
+ "rbe"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red-node-rbe",
+ "file": "/usr/src/node-red/node_modules/node-red-node-rbe/rbe.js"
+ }
+ }
+ },
+ "node-red-node-tail": {
+ "name": "node-red-node-tail",
+ "version": "0.1.1",
+ "local": false,
+ "nodes": {
+ "tail": {
+ "name": "tail",
+ "types": [
+ "tail"
+ ],
+ "enabled": true,
+ "local": false,
+ "module": "node-red-node-tail",
+ "file": "/usr/src/node-red/node_modules/node-red-node-tail/28-tail.js"
+ }
+ }
+ }
+ },
+ "_credentialSecret": "c028885f2cb96099498adca00919db2df73313d916d037a5a1c8eb931b43c03e",
+ "users": {
+ "_": {
+ "editor": {
+ "view": {
+ "view-show-grid": true,
+ "view-snap-grid": true,
+ "view-grid-size": 20,
+ "view-node-status": true,
+ "view-node-show-label": true,
+ "view-show-tips": false
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/examples/basyx.nodered/node-red/.dash/config_default.json b/examples/basyx.nodered/node-red/.dash/config_default.json
new file mode 100644
index 0000000..711d715
--- /dev/null
+++ b/examples/basyx.nodered/node-red/.dash/config_default.json
@@ -0,0 +1,3 @@
+{
+ "dashboards": []
+}
\ No newline at end of file
diff --git a/examples/basyx.nodered/node-red/flows.json b/examples/basyx.nodered/node-red/flows.json
new file mode 100644
index 0000000..b4063b1
--- /dev/null
+++ b/examples/basyx.nodered/node-red/flows.json
@@ -0,0 +1 @@
+[{"id":"ac89e902.a48598","type":"tab","label":"AAS Temperature","disabled":false,"info":""},{"id":"91383a96.5b2e48","type":"tab","label":"Test","disabled":false,"info":""},{"id":"1b4daff8.52358","type":"mqtt-broker","z":"","name":"Mosquitto","broker":"http://mosquitto","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"2289cf21.0a21b","type":"inject","z":"ac89e902.a48598","name":"Start","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":110,"y":120,"wires":[["c3659321.46995"]]},{"id":"c3659321.46995","type":"get-aas-property","z":"ac89e902.a48598","name":"Get Temperature","property":"temp","period":1,"x":270,"y":120,"wires":[["a56bd8e1.1777c8","2c13d59c.208cea","8c41e115.ac913"]]},{"id":"4e72f0db.c2a7a","type":"inject","z":"91383a96.5b2e48","name":"Data","props":[{"p":"values","v":"[22.344,23.434,24.342,21.098]","vt":"json"},{"p":"timestamp","v":"[121323,2112231,321331,321321]","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":140,"y":100,"wires":[["a53d7930.6109f8","4a734a5f.b22314","ab2d648a.1767f8"]]},{"id":"a53d7930.6109f8","type":"debug","z":"91383a96.5b2e48","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":250,"y":240,"wires":[]},{"id":"4a734a5f.b22314","type":"function","z":"91383a96.5b2e48","name":"Calculate Average","func":"msg.avg = msg.values.reduce((a,b) => a + b, 0) / msg.values.length;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":450,"y":120,"wires":[["6b28c27b.5547bc"]]},{"id":"6b28c27b.5547bc","type":"debug","z":"91383a96.5b2e48","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":710,"y":120,"wires":[]},{"id":"ab2d648a.1767f8","type":"function","z":"91383a96.5b2e48","name":"Calculate Fahrenheit","func":"msg.fahrenheit = msg.values.map(v => v * 1.8 + 32);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":460,"y":180,"wires":[["5e614070.a223f"]]},{"id":"5e614070.a223f","type":"debug","z":"91383a96.5b2e48","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":710,"y":180,"wires":[]},{"id":"e733d05.63a9c3","type":"iot-datasource","z":"ac89e902.a48598","name":"Temperature Datasource","tstampField":"tstamp","dataField":"data","disableDiscover":false,"x":730,"y":240,"wires":[[]]},{"id":"8e627da8.65b74","type":"mqtt out","z":"ac89e902.a48598","name":"MQTT Avg Temp Publisher","topic":"temperature/average","qos":"","retain":"","broker":"1b4daff8.52358","x":740,"y":120,"wires":[]},{"id":"7aa9e937.6575c8","type":"mqtt in","z":"ac89e902.a48598","name":"MQTT Avg Temp Consumer","topic":"temperature/average","qos":"2","datatype":"json","broker":"1b4daff8.52358","x":160,"y":360,"wires":[["f96c72b.3be659"]]},{"id":"f96c72b.3be659","type":"debug","z":"ac89e902.a48598","name":"Msg","active":true,"tosidebar":true,"console":true,"tostatus":true,"complete":"payload.average","targetType":"msg","statusVal":"payload.average","statusType":"auto","x":390,"y":360,"wires":[]},{"id":"a56bd8e1.1777c8","type":"function","z":"ac89e902.a48598","name":"Calculate Average","func":"const payload = msg.payload;\nlet average = payload.data.reduce((a,b) => a + b, 0) / payload.data.length;\npayload.average = average;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":490,"y":120,"wires":[["8e627da8.65b74"]]},{"id":"2c13d59c.208cea","type":"function","z":"ac89e902.a48598","name":"Calculate Fahrenheit","func":"const payload = msg.payload;\nlet fahrenheit = payload.data.map(v => v * 1.8 + 32);\npayload.fahrenheit = fahrenheit;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":500,"y":180,"wires":[["a3733cf8.97468"]]},{"id":"a3733cf8.97468","type":"mqtt out","z":"ac89e902.a48598","name":"MQTT Fahrenheit Temp Publisher","topic":"temperature/fahrenheit","qos":"","retain":"","broker":"1b4daff8.52358","x":760,"y":180,"wires":[]},{"id":"8c41e115.ac913","type":"function","z":"ac89e902.a48598","name":"Get most recent","func":"msg.payload.tstamp = new Date(msg.payload.tstamp.pop()).getTime();\nmsg.payload.data = msg.payload.data.pop();\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":480,"y":240,"wires":[["e733d05.63a9c3"]]}]
\ No newline at end of file
diff --git a/examples/basyx.nodered/node-red/flows_cred.json b/examples/basyx.nodered/node-red/flows_cred.json
new file mode 100644
index 0000000..a4c98fe
--- /dev/null
+++ b/examples/basyx.nodered/node-red/flows_cred.json
@@ -0,0 +1 @@
+{"$":"c868da21da8ba53a0c91801df18843d0H2SPE/Z3kkH48hmjwFw92jPiFRST"}
\ No newline at end of file
diff --git a/examples/basyx.nodered/node-red/package.json b/examples/basyx.nodered/node-red/package.json
new file mode 100644
index 0000000..b788fd4
--- /dev/null
+++ b/examples/basyx.nodered/node-red/package.json
@@ -0,0 +1,6 @@
+{
+ "name": "node-red-project",
+ "description": "A Node-RED Project",
+ "version": "0.0.1",
+ "private": true
+}
\ No newline at end of file
diff --git a/examples/basyx.nodered/node-red/settings.js b/examples/basyx.nodered/node-red/settings.js
new file mode 100644
index 0000000..f3c93f5
--- /dev/null
+++ b/examples/basyx.nodered/node-red/settings.js
@@ -0,0 +1,299 @@
+/**
+ * Copyright JS Foundation and other contributors, http://js.foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ **/
+
+module.exports = {
+ // the tcp port that the Node-RED web server is listening on
+ uiPort: process.env.PORT || 1880,
+
+ // By default, the Node-RED UI accepts connections on all IPv4 interfaces.
+ // To listen on all IPv6 addresses, set uiHost to "::",
+ // The following property can be used to listen on a specific interface. For
+ // example, the following would only allow connections from the local machine.
+ //uiHost: "127.0.0.1",
+
+ // Retry time in milliseconds for MQTT connections
+ mqttReconnectTime: 15000,
+
+ // Retry time in milliseconds for Serial port connections
+ serialReconnectTime: 15000,
+
+ // Retry time in milliseconds for TCP socket connections
+ //socketReconnectTime: 10000,
+
+ // Timeout in milliseconds for TCP server socket connections
+ // defaults to no timeout
+ //socketTimeout: 120000,
+
+ // Maximum number of messages to wait in queue while attempting to connect to TCP socket
+ // defaults to 1000
+ //tcpMsgQueueSize: 2000,
+
+ // Timeout in milliseconds for HTTP request connections
+ // defaults to 120 seconds
+ //httpRequestTimeout: 120000,
+
+ // The maximum length, in characters, of any message sent to the debug sidebar tab
+ debugMaxLength: 1000,
+
+ // The maximum number of messages nodes will buffer internally as part of their
+ // operation. This applies across a range of nodes that operate on message sequences.
+ // defaults to no limit. A value of 0 also means no limit is applied.
+ //nodeMessageBufferMaxLength: 0,
+
+ // To disable the option for using local files for storing keys and certificates in the TLS configuration
+ // node, set this to true
+ //tlsConfigDisableLocalFiles: true,
+
+ // Colourise the console output of the debug node
+ //debugUseColors: true,
+
+ // The file containing the flows. If not set, it defaults to flows_<hostname>.json
+ //flowFile: 'flows.json',
+
+ // To enabled pretty-printing of the flow within the flow file, set the following
+ // property to true:
+ //flowFilePretty: true,
+
+ // By default, credentials are encrypted in storage using a generated key. To
+ // specify your own secret, set the following property.
+ // If you want to disable encryption of credentials, set this property to false.
+ // Note: once you set this property, do not change it - doing so will prevent
+ // node-red from being able to decrypt your existing credentials and they will be
+ // lost.
+ //credentialSecret: "a-secret-key",
+
+ // By default, all user data is stored in a directory called `.node-red` under
+ // the user's home directory. To use a different location, the following
+ // property can be used
+ //userDir: '/home/nol/.node-red/',
+
+ // Node-RED scans the `nodes` directory in the userDir to find local node files.
+ // The following property can be used to specify an additional directory to scan.
+ //nodesDir: '/home/nol/.node-red/nodes',
+
+ // By default, the Node-RED UI is available at http://localhost:1880/
+ // The following property can be used to specify a different root path.
+ // If set to false, this is disabled.
+ //httpAdminRoot: '/admin',
+
+ // Some nodes, such as HTTP In, can be used to listen for incoming http requests.
+ // By default, these are served relative to '/'. The following property
+ // can be used to specifiy a different root path. If set to false, this is
+ // disabled.
+ //httpNodeRoot: '/red-nodes',
+
+ // The following property can be used in place of 'httpAdminRoot' and 'httpNodeRoot',
+ // to apply the same root to both parts.
+ //httpRoot: '/red',
+
+ // When httpAdminRoot is used to move the UI to a different root path, the
+ // following property can be used to identify a directory of static content
+ // that should be served at http://localhost:1880/.
+ //httpStatic: '/home/nol/node-red-static/',
+
+ // The maximum size of HTTP request that will be accepted by the runtime api.
+ // Default: 5mb
+ //apiMaxLength: '5mb',
+
+ // If you installed the optional node-red-dashboard you can set it's path
+ // relative to httpRoot
+ //ui: { path: "ui" },
+
+ // Securing Node-RED
+ // -----------------
+ // To password protect the Node-RED editor and admin API, the following
+ // property can be used. See http://nodered.org/docs/security.html for details.
+ //adminAuth: {
+ // type: "credentials",
+ // users: [{
+ // username: "admin",
+ // password: "$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN.",
+ // permissions: "*"
+ // }]
+ //},
+
+ // To password protect the node-defined HTTP endpoints (httpNodeRoot), or
+ // the static content (httpStatic), the following properties can be used.
+ // The pass field is a bcrypt hash of the password.
+ // See http://nodered.org/docs/security.html#generating-the-password-hash
+ //httpNodeAuth: {user:"user",pass:"$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN."},
+ //httpStaticAuth: {user:"user",pass:"$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN."},
+
+ // The following property can be used to enable HTTPS
+ // See http://nodejs.org/api/https.html#https_https_createserver_options_requestlistener
+ // for details on its contents.
+ // This property can be either an object, containing both a (private) key and a (public) certificate,
+ // or a function that returns such an object:
+ //// https object:
+ //https: {
+ // key: require("fs").readFileSync('privkey.pem'),
+ // cert: require("fs").readFileSync('cert.pem')
+ //},
+ ////https function:
+ // https: function() {
+ // // This function should return the options object, or a Promise
+ // // that resolves to the options object
+ // return {
+ // key: require("fs").readFileSync('privkey.pem'),
+ // cert: require("fs").readFileSync('cert.pem')
+ // }
+ // },
+
+ // The following property can be used to refresh the https settings at a
+ // regular time interval in hours.
+ // This requires:
+ // - the `https` setting to be a function that can be called to get
+ // the refreshed settings.
+ // - Node.js 11 or later.
+ //httpsRefreshInterval : 12,
+
+ // The following property can be used to cause insecure HTTP connections to
+ // be redirected to HTTPS.
+ //requireHttps: true,
+
+ // The following property can be used to disable the editor. The admin API
+ // is not affected by this option. To disable both the editor and the admin
+ // API, use either the httpRoot or httpAdminRoot properties
+ //disableEditor: false,
+
+ // The following property can be used to configure cross-origin resource sharing
+ // in the HTTP nodes.
+ // See https://github.com/troygoode/node-cors#configuration-options for
+ // details on its contents. The following is a basic permissive set of options:
+ //httpNodeCors: {
+ // origin: "*",
+ // methods: "GET,PUT,POST,DELETE"
+ //},
+
+ // If you need to set an http proxy please set an environment variable
+ // called http_proxy (or HTTP_PROXY) outside of Node-RED in the operating system.
+ // For example - http_proxy=http://myproxy.com:8080
+ // (Setting it here will have no effect)
+ // You may also specify no_proxy (or NO_PROXY) to supply a comma separated
+ // list of domains to not proxy, eg - no_proxy=.acme.co,.acme.co.uk
+
+ // The following property can be used to add a custom middleware function
+ // in front of all http in nodes. This allows custom authentication to be
+ // applied to all http in nodes, or any other sort of common request processing.
+ //httpNodeMiddleware: function(req,res,next) {
+ // // Handle/reject the request, or pass it on to the http in node by calling next();
+ // // Optionally skip our rawBodyParser by setting this to true;
+ // //req.skipRawBodyParser = true;
+ // next();
+ //},
+
+
+ // The following property can be used to add a custom middleware function
+ // in front of all admin http routes. For example, to set custom http
+ // headers
+ // httpAdminMiddleware: function(req,res,next) {
+ // // Set the X-Frame-Options header to limit where the editor
+ // // can be embedded
+ // //res.set('X-Frame-Options', 'sameorigin');
+ // next();
+ // },
+
+ // The following property can be used to pass custom options to the Express.js
+ // server used by Node-RED. For a full list of available options, refer
+ // to http://expressjs.com/en/api.html#app.settings.table
+ //httpServerOptions: { },
+
+ // The following property can be used to verify websocket connection attempts.
+ // This allows, for example, the HTTP request headers to be checked to ensure
+ // they include valid authentication information.
+ //webSocketNodeVerifyClient: function(info) {
+ // // 'info' has three properties:
+ // // - origin : the value in the Origin header
+ // // - req : the HTTP request
+ // // - secure : true if req.connection.authorized or req.connection.encrypted is set
+ // //
+ // // The function should return true if the connection should be accepted, false otherwise.
+ // //
+ // // Alternatively, if this function is defined to accept a second argument, callback,
+ // // it can be used to verify the client asynchronously.
+ // // The callback takes three arguments:
+ // // - result : boolean, whether to accept the connection or not
+ // // - code : if result is false, the HTTP error status to return
+ // // - reason: if result is false, the HTTP reason string to return
+ //},
+
+ // The following property can be used to seed Global Context with predefined
+ // values. This allows extra node modules to be made available with the
+ // Function node.
+ // For example,
+ // functionGlobalContext: { os:require('os') }
+ // can be accessed in a function block as:
+ // global.get("os")
+ functionGlobalContext: {
+ // os:require('os'),
+ // jfive:require("johnny-five"),
+ // j5board:require("johnny-five").Board({repl:false})
+ },
+ // `global.keys()` returns a list of all properties set in global context.
+ // This allows them to be displayed in the Context Sidebar within the editor.
+ // In some circumstances it is not desirable to expose them to the editor. The
+ // following property can be used to hide any property set in `functionGlobalContext`
+ // from being list by `global.keys()`.
+ // By default, the property is set to false to avoid accidental exposure of
+ // their values. Setting this to true will cause the keys to be listed.
+ exportGlobalContextKeys: false,
+
+
+ // Context Storage
+ // The following property can be used to enable context storage. The configuration
+ // provided here will enable file-based context that flushes to disk every 30 seconds.
+ // Refer to the documentation for further options: https://nodered.org/docs/api/context/
+ //
+ //contextStorage: {
+ // default: {
+ // module:"localfilesystem"
+ // },
+ //},
+
+ // The following property can be used to order the categories in the editor
+ // palette. If a node's category is not in the list, the category will get
+ // added to the end of the palette.
+ // If not set, the following default order is used:
+ //paletteCategories: ['subflows', 'common', 'function', 'network', 'sequence', 'parser', 'storage'],
+
+ // Configure the logging output
+ logging: {
+ // Only console logging is currently supported
+ console: {
+ // Level of logging to be recorded. Options are:
+ // fatal - only those errors which make the application unusable should be recorded
+ // error - record errors which are deemed fatal for a particular request + fatal errors
+ // warn - record problems which are non fatal + errors + fatal errors
+ // info - record information about the general running of the application + warn + error + fatal errors
+ // debug - record information which is more verbose than info + info + warn + error + fatal errors
+ // trace - record very detailed logging + debug + info + warn + error + fatal errors
+ // off - turn off all logging (doesn't affect metrics or audit)
+ level: "info",
+ // Whether or not to include metric events in the log output
+ metrics: false,
+ // Whether or not to include audit events in the log output
+ audit: false
+ }
+ },
+
+ // Customising the editor
+ editorTheme: {
+ projects: {
+ // To enable the Projects feature, set this value to true
+ enabled: false
+ }
+ }
+}
diff --git a/examples/basyx.nodered/package.json b/examples/basyx.nodered/package.json
new file mode 100644
index 0000000..03f658f
--- /dev/null
+++ b/examples/basyx.nodered/package.json
@@ -0,0 +1,35 @@
+{
+ "name": "node-red-docker",
+ "version": "1.1.2",
+ "description": "Low-code programming for event-driven applications",
+ "homepage": "http://nodered.org",
+ "license": "Apache-2.0",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/node-red/node-red-docker.git"
+ },
+ "main": "node_modules/node-red/red/red.js",
+ "scripts": {
+ "start": "node $NODE_OPTIONS node_modules/node-red/red.js $FLOWS",
+ "debug": "node --inspect=0.0.0.0:9229 $NODE_OPTIONS node_modules/node-red/red.js $FLOWS",
+ "debug_brk": "node --inspect=0.0.0.0:9229 --inspect-brk $NODE_OPTIONS node_modules/node-red/red.js $FLOWS"
+ },
+ "contributors": [
+ {
+ "name": "Dave Conway-Jones"
+ },
+ {
+ "name": "Nick O'Leary"
+ },
+ {
+ "name": "James Thomas"
+ },
+ { "name": "Raymond Mouthaan" } ],
+ "dependencies": {
+ "node-red": "1.1.2",
+ "node-red-contrib-graphs": "0.3.5"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+}
\ No newline at end of file
diff --git a/examples/basyx.nodered/settings.js b/examples/basyx.nodered/settings.js
new file mode 100644
index 0000000..f3c93f5
--- /dev/null
+++ b/examples/basyx.nodered/settings.js
@@ -0,0 +1,299 @@
+/**
+ * Copyright JS Foundation and other contributors, http://js.foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ **/
+
+module.exports = {
+ // the tcp port that the Node-RED web server is listening on
+ uiPort: process.env.PORT || 1880,
+
+ // By default, the Node-RED UI accepts connections on all IPv4 interfaces.
+ // To listen on all IPv6 addresses, set uiHost to "::",
+ // The following property can be used to listen on a specific interface. For
+ // example, the following would only allow connections from the local machine.
+ //uiHost: "127.0.0.1",
+
+ // Retry time in milliseconds for MQTT connections
+ mqttReconnectTime: 15000,
+
+ // Retry time in milliseconds for Serial port connections
+ serialReconnectTime: 15000,
+
+ // Retry time in milliseconds for TCP socket connections
+ //socketReconnectTime: 10000,
+
+ // Timeout in milliseconds for TCP server socket connections
+ // defaults to no timeout
+ //socketTimeout: 120000,
+
+ // Maximum number of messages to wait in queue while attempting to connect to TCP socket
+ // defaults to 1000
+ //tcpMsgQueueSize: 2000,
+
+ // Timeout in milliseconds for HTTP request connections
+ // defaults to 120 seconds
+ //httpRequestTimeout: 120000,
+
+ // The maximum length, in characters, of any message sent to the debug sidebar tab
+ debugMaxLength: 1000,
+
+ // The maximum number of messages nodes will buffer internally as part of their
+ // operation. This applies across a range of nodes that operate on message sequences.
+ // defaults to no limit. A value of 0 also means no limit is applied.
+ //nodeMessageBufferMaxLength: 0,
+
+ // To disable the option for using local files for storing keys and certificates in the TLS configuration
+ // node, set this to true
+ //tlsConfigDisableLocalFiles: true,
+
+ // Colourise the console output of the debug node
+ //debugUseColors: true,
+
+ // The file containing the flows. If not set, it defaults to flows_<hostname>.json
+ //flowFile: 'flows.json',
+
+ // To enabled pretty-printing of the flow within the flow file, set the following
+ // property to true:
+ //flowFilePretty: true,
+
+ // By default, credentials are encrypted in storage using a generated key. To
+ // specify your own secret, set the following property.
+ // If you want to disable encryption of credentials, set this property to false.
+ // Note: once you set this property, do not change it - doing so will prevent
+ // node-red from being able to decrypt your existing credentials and they will be
+ // lost.
+ //credentialSecret: "a-secret-key",
+
+ // By default, all user data is stored in a directory called `.node-red` under
+ // the user's home directory. To use a different location, the following
+ // property can be used
+ //userDir: '/home/nol/.node-red/',
+
+ // Node-RED scans the `nodes` directory in the userDir to find local node files.
+ // The following property can be used to specify an additional directory to scan.
+ //nodesDir: '/home/nol/.node-red/nodes',
+
+ // By default, the Node-RED UI is available at http://localhost:1880/
+ // The following property can be used to specify a different root path.
+ // If set to false, this is disabled.
+ //httpAdminRoot: '/admin',
+
+ // Some nodes, such as HTTP In, can be used to listen for incoming http requests.
+ // By default, these are served relative to '/'. The following property
+ // can be used to specifiy a different root path. If set to false, this is
+ // disabled.
+ //httpNodeRoot: '/red-nodes',
+
+ // The following property can be used in place of 'httpAdminRoot' and 'httpNodeRoot',
+ // to apply the same root to both parts.
+ //httpRoot: '/red',
+
+ // When httpAdminRoot is used to move the UI to a different root path, the
+ // following property can be used to identify a directory of static content
+ // that should be served at http://localhost:1880/.
+ //httpStatic: '/home/nol/node-red-static/',
+
+ // The maximum size of HTTP request that will be accepted by the runtime api.
+ // Default: 5mb
+ //apiMaxLength: '5mb',
+
+ // If you installed the optional node-red-dashboard you can set it's path
+ // relative to httpRoot
+ //ui: { path: "ui" },
+
+ // Securing Node-RED
+ // -----------------
+ // To password protect the Node-RED editor and admin API, the following
+ // property can be used. See http://nodered.org/docs/security.html for details.
+ //adminAuth: {
+ // type: "credentials",
+ // users: [{
+ // username: "admin",
+ // password: "$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN.",
+ // permissions: "*"
+ // }]
+ //},
+
+ // To password protect the node-defined HTTP endpoints (httpNodeRoot), or
+ // the static content (httpStatic), the following properties can be used.
+ // The pass field is a bcrypt hash of the password.
+ // See http://nodered.org/docs/security.html#generating-the-password-hash
+ //httpNodeAuth: {user:"user",pass:"$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN."},
+ //httpStaticAuth: {user:"user",pass:"$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN."},
+
+ // The following property can be used to enable HTTPS
+ // See http://nodejs.org/api/https.html#https_https_createserver_options_requestlistener
+ // for details on its contents.
+ // This property can be either an object, containing both a (private) key and a (public) certificate,
+ // or a function that returns such an object:
+ //// https object:
+ //https: {
+ // key: require("fs").readFileSync('privkey.pem'),
+ // cert: require("fs").readFileSync('cert.pem')
+ //},
+ ////https function:
+ // https: function() {
+ // // This function should return the options object, or a Promise
+ // // that resolves to the options object
+ // return {
+ // key: require("fs").readFileSync('privkey.pem'),
+ // cert: require("fs").readFileSync('cert.pem')
+ // }
+ // },
+
+ // The following property can be used to refresh the https settings at a
+ // regular time interval in hours.
+ // This requires:
+ // - the `https` setting to be a function that can be called to get
+ // the refreshed settings.
+ // - Node.js 11 or later.
+ //httpsRefreshInterval : 12,
+
+ // The following property can be used to cause insecure HTTP connections to
+ // be redirected to HTTPS.
+ //requireHttps: true,
+
+ // The following property can be used to disable the editor. The admin API
+ // is not affected by this option. To disable both the editor and the admin
+ // API, use either the httpRoot or httpAdminRoot properties
+ //disableEditor: false,
+
+ // The following property can be used to configure cross-origin resource sharing
+ // in the HTTP nodes.
+ // See https://github.com/troygoode/node-cors#configuration-options for
+ // details on its contents. The following is a basic permissive set of options:
+ //httpNodeCors: {
+ // origin: "*",
+ // methods: "GET,PUT,POST,DELETE"
+ //},
+
+ // If you need to set an http proxy please set an environment variable
+ // called http_proxy (or HTTP_PROXY) outside of Node-RED in the operating system.
+ // For example - http_proxy=http://myproxy.com:8080
+ // (Setting it here will have no effect)
+ // You may also specify no_proxy (or NO_PROXY) to supply a comma separated
+ // list of domains to not proxy, eg - no_proxy=.acme.co,.acme.co.uk
+
+ // The following property can be used to add a custom middleware function
+ // in front of all http in nodes. This allows custom authentication to be
+ // applied to all http in nodes, or any other sort of common request processing.
+ //httpNodeMiddleware: function(req,res,next) {
+ // // Handle/reject the request, or pass it on to the http in node by calling next();
+ // // Optionally skip our rawBodyParser by setting this to true;
+ // //req.skipRawBodyParser = true;
+ // next();
+ //},
+
+
+ // The following property can be used to add a custom middleware function
+ // in front of all admin http routes. For example, to set custom http
+ // headers
+ // httpAdminMiddleware: function(req,res,next) {
+ // // Set the X-Frame-Options header to limit where the editor
+ // // can be embedded
+ // //res.set('X-Frame-Options', 'sameorigin');
+ // next();
+ // },
+
+ // The following property can be used to pass custom options to the Express.js
+ // server used by Node-RED. For a full list of available options, refer
+ // to http://expressjs.com/en/api.html#app.settings.table
+ //httpServerOptions: { },
+
+ // The following property can be used to verify websocket connection attempts.
+ // This allows, for example, the HTTP request headers to be checked to ensure
+ // they include valid authentication information.
+ //webSocketNodeVerifyClient: function(info) {
+ // // 'info' has three properties:
+ // // - origin : the value in the Origin header
+ // // - req : the HTTP request
+ // // - secure : true if req.connection.authorized or req.connection.encrypted is set
+ // //
+ // // The function should return true if the connection should be accepted, false otherwise.
+ // //
+ // // Alternatively, if this function is defined to accept a second argument, callback,
+ // // it can be used to verify the client asynchronously.
+ // // The callback takes three arguments:
+ // // - result : boolean, whether to accept the connection or not
+ // // - code : if result is false, the HTTP error status to return
+ // // - reason: if result is false, the HTTP reason string to return
+ //},
+
+ // The following property can be used to seed Global Context with predefined
+ // values. This allows extra node modules to be made available with the
+ // Function node.
+ // For example,
+ // functionGlobalContext: { os:require('os') }
+ // can be accessed in a function block as:
+ // global.get("os")
+ functionGlobalContext: {
+ // os:require('os'),
+ // jfive:require("johnny-five"),
+ // j5board:require("johnny-five").Board({repl:false})
+ },
+ // `global.keys()` returns a list of all properties set in global context.
+ // This allows them to be displayed in the Context Sidebar within the editor.
+ // In some circumstances it is not desirable to expose them to the editor. The
+ // following property can be used to hide any property set in `functionGlobalContext`
+ // from being list by `global.keys()`.
+ // By default, the property is set to false to avoid accidental exposure of
+ // their values. Setting this to true will cause the keys to be listed.
+ exportGlobalContextKeys: false,
+
+
+ // Context Storage
+ // The following property can be used to enable context storage. The configuration
+ // provided here will enable file-based context that flushes to disk every 30 seconds.
+ // Refer to the documentation for further options: https://nodered.org/docs/api/context/
+ //
+ //contextStorage: {
+ // default: {
+ // module:"localfilesystem"
+ // },
+ //},
+
+ // The following property can be used to order the categories in the editor
+ // palette. If a node's category is not in the list, the category will get
+ // added to the end of the palette.
+ // If not set, the following default order is used:
+ //paletteCategories: ['subflows', 'common', 'function', 'network', 'sequence', 'parser', 'storage'],
+
+ // Configure the logging output
+ logging: {
+ // Only console logging is currently supported
+ console: {
+ // Level of logging to be recorded. Options are:
+ // fatal - only those errors which make the application unusable should be recorded
+ // error - record errors which are deemed fatal for a particular request + fatal errors
+ // warn - record problems which are non fatal + errors + fatal errors
+ // info - record information about the general running of the application + warn + error + fatal errors
+ // debug - record information which is more verbose than info + info + warn + error + fatal errors
+ // trace - record very detailed logging + debug + info + warn + error + fatal errors
+ // off - turn off all logging (doesn't affect metrics or audit)
+ level: "info",
+ // Whether or not to include metric events in the log output
+ metrics: false,
+ // Whether or not to include audit events in the log output
+ audit: false
+ }
+ },
+
+ // Customising the editor
+ editorTheme: {
+ projects: {
+ // To enable the Projects feature, set this value to true
+ enabled: false
+ }
+ }
+}
diff --git a/examples/basyx.nodered/start.bat b/examples/basyx.nodered/start.bat
new file mode 100644
index 0000000..83ed0d0
--- /dev/null
+++ b/examples/basyx.nodered/start.bat
@@ -0,0 +1 @@
+docker-compose up
diff --git a/examples/basyx.nodered/start.sh b/examples/basyx.nodered/start.sh
new file mode 100644
index 0000000..d935e43
--- /dev/null
+++ b/examples/basyx.nodered/start.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+docker-compose up
\ No newline at end of file
diff --git a/examples/basyx.nodered/stop.bat b/examples/basyx.nodered/stop.bat
new file mode 100644
index 0000000..58694d0
--- /dev/null
+++ b/examples/basyx.nodered/stop.bat
@@ -0,0 +1 @@
+docker-compose down
\ No newline at end of file
diff --git a/examples/basyx.nodered/stop.sh b/examples/basyx.nodered/stop.sh
new file mode 100644
index 0000000..f5139e2
--- /dev/null
+++ b/examples/basyx.nodered/stop.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+docker-compose down
\ No newline at end of file
diff --git a/examples/basyx.streamsheets/.gitignore b/examples/basyx.streamsheets/.gitignore
new file mode 100644
index 0000000..5e2ad3c
--- /dev/null
+++ b/examples/basyx.streamsheets/.gitignore
@@ -0,0 +1,2 @@
+/mosquitto
+/streamsheets
\ No newline at end of file
diff --git a/examples/basyx.streamsheets/AAS Property Dashboard.json b/examples/basyx.streamsheets/AAS Property Dashboard.json
new file mode 100644
index 0000000..ecf6f0c
--- /dev/null
+++ b/examples/basyx.streamsheets/AAS Property Dashboard.json
@@ -0,0 +1,5225 @@
+{
+ "machines": [
+ {
+ "machine": {
+ "id": "S1-EB3RpyP",
+ "name": "AAS Property Dashboard",
+ "state": "stopped",
+ "metadata": {
+ "owner": "anon",
+ "lastModified": 1599658322212,
+ "lastModifiedBy": "unknown",
+ "machineservice": {
+ "id": "machines-HkgWO-Rp1v"
+ }
+ },
+ "streamsheets": [
+ {
+ "id": "Sk7ErnRTJD",
+ "name": "S1",
+ "loop": {
+ "path": "",
+ "enabled": false
+ },
+ "inbox": {
+ "max": 20,
+ "type": "MessageBox",
+ "id": "SyENH3Aakw",
+ "stream": null
+ },
+ "sheet": {
+ "cells": {
+ "G1": {
+ "value": "",
+ "type": "string",
+ "level": 0
+ },
+ "A3": {
+ "formula": "REST.REQUEST(|AASRESTTestProducer,\"http://aas-wrapper:6500/streamsheets/temp\",\"GET\",INBOX(\"dataElement\"))",
+ "value": "B14q-zULED",
+ "type": "undefined",
+ "level": 0,
+ "references": [
+ "|AASRESTTestProducer"
+ ]
+ },
+ "B3": {
+ "formula": "READ(INBOXDATA(,,\"content\"),,\"Array\")",
+ "value": "content",
+ "type": "undefined",
+ "level": 0
+ },
+ "C3": {
+ "formula": "READ(INBOXDATA(,,\"timestamp\"),,\"Array\")",
+ "value": "timestamp",
+ "type": "undefined",
+ "level": 0
+ },
+ "G3": {
+ "value": "Time",
+ "type": "string",
+ "level": 0
+ },
+ "H3": {
+ "value": "Temperature",
+ "type": "string",
+ "level": 0
+ },
+ "B4": {
+ "formula": "READ(INBOXDATA(,,B3,\"0\"),H4,\"Number\")",
+ "value": 0,
+ "type": "undefined",
+ "level": 0
+ },
+ "C4": {
+ "formula": "READ(INBOXDATA(,,C3,\"0\"),D4,\"String\")",
+ "value": 0,
+ "type": "undefined",
+ "level": 0
+ },
+ "D4": {
+ "value": "2020-09-09T13:00:40.409Z",
+ "type": "string",
+ "level": 0
+ },
+ "G4": {
+ "formula": "JSONTIME2EXCEL(D4)",
+ "value": 44083.54213436342,
+ "type": "undefined",
+ "level": 0
+ },
+ "H4": {
+ "value": 21.07154194806827,
+ "type": "number",
+ "level": 0
+ },
+ "B5": {
+ "formula": "READ(INBOXDATA(,,B3,\"1\"),H5,\"Number\")",
+ "value": 1,
+ "type": "undefined",
+ "level": 0
+ },
+ "C5": {
+ "formula": "READ(INBOXDATA(,,C3,\"1\"),D5,\"String\")",
+ "value": 1,
+ "type": "undefined",
+ "level": 0
+ },
+ "D5": {
+ "value": "2020-09-09T13:00:41.415Z",
+ "type": "string",
+ "level": 0
+ },
+ "G5": {
+ "formula": "JSONTIME2EXCEL(D5)",
+ "value": 44083.54213436342,
+ "type": "undefined",
+ "level": 0
+ },
+ "H5": {
+ "value": 28.496771926635027,
+ "type": "number",
+ "level": 0
+ },
+ "B6": {
+ "formula": "READ(INBOXDATA(,,B3,\"2\"),H6,\"Number\")",
+ "value": 2,
+ "type": "undefined",
+ "level": 0
+ },
+ "C6": {
+ "formula": "READ(INBOXDATA(,,C3,\"2\"),D6,\"String\")",
+ "value": 2,
+ "type": "undefined",
+ "level": 0
+ },
+ "D6": {
+ "value": "2020-09-09T13:00:42.422Z",
+ "type": "string",
+ "level": 0
+ },
+ "G6": {
+ "formula": "JSONTIME2EXCEL(D6)",
+ "value": 44083.54213436342,
+ "type": "undefined",
+ "level": 0
+ },
+ "H6": {
+ "value": 27.348393994685246,
+ "type": "number",
+ "level": 0
+ },
+ "B7": {
+ "formula": "READ(INBOXDATA(,,B3,\"3\"),H7,\"Number\")",
+ "value": 3,
+ "type": "undefined",
+ "level": 0
+ },
+ "C7": {
+ "formula": "READ(INBOXDATA(,,C3,\"3\"),D7,\"String\")",
+ "value": 3,
+ "type": "undefined",
+ "level": 0
+ },
+ "D7": {
+ "value": "2020-09-09T13:00:43.427Z",
+ "type": "string",
+ "level": 0
+ },
+ "G7": {
+ "formula": "JSONTIME2EXCEL(D7)",
+ "value": 44083.54213436342,
+ "type": "undefined",
+ "level": 0
+ },
+ "H7": {
+ "value": 21.369693237856616,
+ "type": "number",
+ "level": 0
+ },
+ "B8": {
+ "formula": "READ(INBOXDATA(,,B3,\"4\"),H8,\"Number\")",
+ "value": 4,
+ "type": "undefined",
+ "level": 0
+ },
+ "C8": {
+ "formula": "READ(INBOXDATA(,,C3,\"4\"),D8,\"String\")",
+ "value": 4,
+ "type": "undefined",
+ "level": 0
+ },
+ "D8": {
+ "value": "2020-09-09T13:00:44.436Z",
+ "type": "string",
+ "level": 0
+ },
+ "G8": {
+ "formula": "JSONTIME2EXCEL(D8)",
+ "value": 44083.54213436342,
+ "type": "undefined",
+ "level": 0
+ },
+ "H8": {
+ "value": 24.00643356528727,
+ "type": "number",
+ "level": 0
+ },
+ "B9": {
+ "formula": "READ(INBOXDATA(,,B3,\"5\"),H9,\"Number\")",
+ "value": 5,
+ "type": "undefined",
+ "level": 0
+ },
+ "C9": {
+ "formula": "READ(INBOXDATA(,,C3,\"5\"),D9,\"String\")",
+ "value": 5,
+ "type": "undefined",
+ "level": 0
+ },
+ "D9": {
+ "value": "2020-09-09T13:00:45.443Z",
+ "type": "string",
+ "level": 0
+ },
+ "G9": {
+ "formula": "JSONTIME2EXCEL(D9)",
+ "value": 44083.54213436342,
+ "type": "undefined",
+ "level": 0
+ },
+ "H9": {
+ "value": 29.263190638856287,
+ "type": "number",
+ "level": 0
+ },
+ "B10": {
+ "formula": "READ(INBOXDATA(,,B3,\"6\"),H10,\"Number\")",
+ "value": 6,
+ "type": "undefined",
+ "level": 0
+ },
+ "C10": {
+ "formula": "READ(INBOXDATA(,,C3,\"6\"),D10,\"String\")",
+ "value": 6,
+ "type": "undefined",
+ "level": 0
+ },
+ "D10": {
+ "value": "2020-09-09T13:00:46.449Z",
+ "type": "string",
+ "level": 0
+ },
+ "G10": {
+ "formula": "JSONTIME2EXCEL(D10)",
+ "value": 44083.54213436342,
+ "type": "undefined",
+ "level": 0
+ },
+ "H10": {
+ "value": 20.655619621525332,
+ "type": "number",
+ "level": 0
+ },
+ "B11": {
+ "formula": "READ(INBOXDATA(,,B3,\"7\"),H11,\"Number\")",
+ "value": 7,
+ "type": "undefined",
+ "level": 0
+ },
+ "C11": {
+ "formula": "READ(INBOXDATA(,,C3,\"7\"),D11,\"String\")",
+ "value": 7,
+ "type": "undefined",
+ "level": 0
+ },
+ "D11": {
+ "value": "2020-09-09T13:00:47.454Z",
+ "type": "string",
+ "level": 0
+ },
+ "G11": {
+ "formula": "JSONTIME2EXCEL(D11)",
+ "value": 44083.54213436342,
+ "type": "undefined",
+ "level": 0
+ },
+ "H11": {
+ "value": 27.183770324976013,
+ "type": "number",
+ "level": 0
+ },
+ "B12": {
+ "formula": "READ(INBOXDATA(,,B3,\"8\"),H12,\"Number\")",
+ "value": 8,
+ "type": "undefined",
+ "level": 0
+ },
+ "C12": {
+ "formula": "READ(INBOXDATA(,,C3,\"8\"),D12,\"String\")",
+ "value": 8,
+ "type": "undefined",
+ "level": 0
+ },
+ "D12": {
+ "value": "2020-09-09T13:00:48.464Z",
+ "type": "string",
+ "level": 0
+ },
+ "G12": {
+ "formula": "JSONTIME2EXCEL(D12)",
+ "value": 44083.54213436342,
+ "type": "undefined",
+ "level": 0
+ },
+ "H12": {
+ "value": 25.686867950571894,
+ "type": "number",
+ "level": 0
+ },
+ "B13": {
+ "formula": "READ(INBOXDATA(,,B3,\"9\"),H13,\"Number\")",
+ "value": 9,
+ "type": "undefined",
+ "level": 0
+ },
+ "C13": {
+ "formula": "READ(INBOXDATA(,,C3,\"9\"),D13,\"String\")",
+ "value": 9,
+ "type": "undefined",
+ "level": 0
+ },
+ "D13": {
+ "value": "2020-09-09T13:00:49.469Z",
+ "type": "string",
+ "level": 0
+ },
+ "G13": {
+ "formula": "JSONTIME2EXCEL(D13)",
+ "value": 44083.54213436342,
+ "type": "undefined",
+ "level": 0
+ },
+ "H13": {
+ "value": 20.187588152170466,
+ "type": "number",
+ "level": 0
+ },
+ "F24": {
+ "value": "",
+ "type": "string",
+ "level": 0
+ },
+ "F4": {
+ "value": 1,
+ "type": "number",
+ "level": 0
+ },
+ "F5": {
+ "value": 2,
+ "type": "number",
+ "level": 0
+ },
+ "F6": {
+ "value": 3,
+ "type": "number",
+ "level": 0
+ },
+ "F7": {
+ "value": 4,
+ "type": "number",
+ "level": 0
+ },
+ "F8": {
+ "value": 5,
+ "type": "number",
+ "level": 0
+ },
+ "F9": {
+ "value": 6,
+ "type": "number",
+ "level": 0
+ },
+ "F10": {
+ "value": 7,
+ "type": "number",
+ "level": 0
+ },
+ "F11": {
+ "value": 8,
+ "type": "number",
+ "level": 0
+ },
+ "F12": {
+ "value": 9,
+ "type": "number",
+ "level": 0
+ },
+ "F13": {
+ "value": 10,
+ "type": "number",
+ "level": 0
+ },
+ "H18": {
+ "value": "Temperature Sensor",
+ "type": "string",
+ "level": 0
+ }
+ },
+ "namedCells": {},
+ "graphCells": {
+ "70847796661": {
+ "formula": "DRAW.POLYGON(\"70847796661\",,\"Polygon1\",12289,2675,18415,3493,,\"#345678\")",
+ "type": "string",
+ "value": "#CALC"
+ },
+ "555401109981": {
+ "formula": "DRAW.CHART(\"555401109981\",,\"Chart1\",15262,7480,8149,5080,,,,,,,\"column\",S1!G4:H13)",
+ "type": "string",
+ "value": "#CALC"
+ },
+ "60201705755": {
+ "formula": "DRAW.RECTANGLE(\"60201705755\",,\"Rectangle9\",12355,2700,7091,1984,\"None\",FILLPATTERN(\"https://www.basys40.de/wp-content/uploads/2019/12/Logo_BaSys4_1024px-300x79.png\"))",
+ "type": "string",
+ "value": "#CALC"
+ },
+ "488440667154": {
+ "formula": "DRAW.RECTANGLE(\"488440667154\",,\"Rectangle10\",3967,9421,1773,10001,,\"#345678\")",
+ "type": "string",
+ "value": "#CALC"
+ },
+ "919991966926": {
+ "formula": "DRAW.RECTANGLE(\"919991966926\",,\"Rectangle11\",20623,9433,1746,10001,,\"#345678\")",
+ "type": "string",
+ "value": "#CALC"
+ },
+ "962757771226": {
+ "formula": "DRAW.RECTANGLE(\"962757771226\",,\"Rectangle12\",12302,11081,14896,1376,,\"#345678\")",
+ "type": "string",
+ "value": "#CALC"
+ },
+ "692699117567": {
+ "formula": "DRAW.BEZIER(\"692699117567\",,\"Bezier1\",17647,13394,212,1164)",
+ "type": "boolean",
+ "value": true
+ },
+ "426951475952": {
+ "formula": "DRAW.ELLIPSE(\"426951475952\",\"Bezier1\",\"Ellipse1\",106,1032,529,529,,\"#ff0000\")",
+ "type": "string",
+ "value": "#CALC"
+ }
+ },
+ "properties": {
+ "sheet": {},
+ "cols": {},
+ "rows": {},
+ "cells": {}
+ },
+ "settings": {
+ "minrow": 1,
+ "maxrow": 100,
+ "mincol": -2,
+ "maxcol": 50,
+ "protected": false
+ },
+ "drawings": {},
+ "graphItems": {}
+ },
+ "trigger": {
+ "type": "start",
+ "repeat": "endless"
+ }
+ }
+ ],
+ "settings": {
+ "locale": "en",
+ "isOPCUA": false,
+ "cycletime": 200
+ },
+ "className": "Machine",
+ "namedCells": {
+ "|AASRESTTestProducer": {
+ "value": {
+ "id": "HJZR0U1xSI",
+ "name": "AASRESTTestProducer",
+ "type": "producer",
+ "state": "connected",
+ "timestamp": 1599656146504
+ },
+ "type": "object",
+ "info": {},
+ "level": 0
+ },
+ "|MQTT_Consumer": {
+ "value": {
+ "id": "CONSUMER_MQTT",
+ "name": "MQTT_Consumer",
+ "type": "stream",
+ "state": "disconnected",
+ "timestamp": 1599656156501
+ },
+ "type": "object",
+ "info": {},
+ "level": 0
+ },
+ "|Wind_Data": {
+ "value": {
+ "id": "HkZRIJtchH",
+ "name": "Wind_Data",
+ "type": "stream",
+ "state": "disconnected",
+ "timestamp": 1599656156513
+ },
+ "type": "object",
+ "info": {},
+ "level": 0
+ },
+ "|MQTT_Producer": {
+ "value": {
+ "id": "PRODUCER_MQTT",
+ "name": "MQTT_Producer",
+ "type": "producer",
+ "state": "disconnected",
+ "timestamp": 1599656156514
+ },
+ "type": "object",
+ "info": {},
+ "level": 0
+ },
+ "|SMTP_Sender": {
+ "value": {
+ "id": "B1-zoM0x1v",
+ "name": "SMTP_Sender",
+ "type": "producer",
+ "state": "disconnected",
+ "timestamp": 1599656167573
+ },
+ "type": "object",
+ "info": {},
+ "level": 0
+ }
+ },
+ "defproperties": {
+ "attributes": {
+ "cell": {
+ "level": 0,
+ "protected": true,
+ "visible": true,
+ "key": false
+ },
+ "sheet": {
+ "defaultsectionsize": 2000,
+ "initialsection": 0
+ }
+ },
+ "formats": {
+ "styles": {
+ "brightness": 0,
+ "fillstyle": 0,
+ "fillcolor": "#FFFFFF",
+ "gradientcolor": "#CCCCCC",
+ "gradientcolorstops": "",
+ "gradientangle": 0,
+ "gradienttype": 0,
+ "gradientoffset_x": 0,
+ "gradientoffset_y": 0,
+ "linecolor": "#000000",
+ "linewidth": -1,
+ "linestyle": 1,
+ "lineshape": 0,
+ "linetransparency": 100,
+ "pattern": "",
+ "patternstyle": 0,
+ "transparency": 100,
+ "leftbordercolor": "#000000",
+ "leftborderstyle": 0,
+ "leftborderwidth": 1,
+ "topbordercolor": "#000000",
+ "topborderstyle": 0,
+ "topborderwidth": 1,
+ "rightbordercolor": "#000000",
+ "rightborderstyle": 0,
+ "rightborderwidth": 1,
+ "bottombordercolor": "#000000",
+ "bottomborderstyle": 0,
+ "bottomborderwidth": 1
+ },
+ "text": {
+ "baseline": "alphabetic",
+ "valign": 2,
+ "halign": 3,
+ "fontsize": 9,
+ "fontname": "Verdana",
+ "fontcolor": "#000000",
+ "fontstyle": 0,
+ "vposition": 3,
+ "hpostion": 3,
+ "richtext": true,
+ "lineheight": 1.2,
+ "numberformat": "General",
+ "localculture": "general"
+ }
+ }
+ }
+ },
+ "graph": {
+ "id": "SkHS206JD",
+ "graphdef": {
+ "type": "machinegraph",
+ "version": "2",
+ "uniqueid": "1",
+ "o-outbox": {
+ "split": "5000",
+ "width": "5000"
+ },
+ "a-graphitem": [
+ {
+ "id": "1000",
+ "o-attributes": {
+ "o-sheetid": {
+ "v": "Sk7ErnRTJD",
+ "t": "s"
+ }
+ },
+ "o-pin": {
+ "o-p": {
+ "o-x": {
+ "v": "16933"
+ },
+ "o-y": {
+ "v": "7814"
+ }
+ },
+ "o-lp": {
+ "o-x": {
+ "f": "WIDTH%20*%200.5",
+ "v": "16433"
+ },
+ "o-y": {
+ "f": "HEIGHT%20*%200.5",
+ "v": "7314"
+ }
+ }
+ },
+ "o-size": {
+ "o-w": {
+ "v": "32867"
+ },
+ "o-h": {
+ "v": "14628"
+ }
+ },
+ "o-inbox": {
+ "split": "5000",
+ "width": "6111"
+ },
+ "o-processsheet": {
+ "o-attributes": {
+ "o-calcondemand": {
+ "v": "true",
+ "t": "b"
+ }
+ },
+ "o-name": {
+ "v": "S1",
+ "t": "s"
+ },
+ "o-rows": {
+ "a-section": [
+ {
+ "index": "0",
+ "size": "2140",
+ "visible": "1"
+ },
+ {
+ "index": "1",
+ "size": "2458",
+ "visible": "1"
+ },
+ {
+ "index": "2",
+ "size": "632",
+ "visible": "1"
+ },
+ {
+ "index": "15",
+ "size": "1003",
+ "visible": "1"
+ },
+ {
+ "index": "16",
+ "size": "738",
+ "visible": "1"
+ },
+ {
+ "index": "17",
+ "size": "738",
+ "visible": "1"
+ },
+ {
+ "index": "18",
+ "size": "1161",
+ "visible": "1"
+ }
+ ]
+ },
+ "o-columns": {
+ "a-section": [
+ {
+ "index": "0",
+ "size": "0",
+ "visible": "0"
+ },
+ {
+ "index": "1",
+ "size": "515",
+ "visible": "1"
+ },
+ {
+ "index": "2",
+ "size": "0",
+ "visible": "0"
+ },
+ {
+ "index": "3",
+ "size": "0",
+ "visible": "0"
+ },
+ {
+ "index": "4",
+ "size": "0",
+ "visible": "0"
+ },
+ {
+ "index": "5",
+ "size": "0",
+ "visible": "0"
+ },
+ {
+ "index": "6",
+ "size": "4175",
+ "visible": "1"
+ },
+ {
+ "index": "7",
+ "size": "1086",
+ "visible": "1"
+ },
+ {
+ "index": "8",
+ "size": "1921",
+ "visible": "1"
+ },
+ {
+ "index": "9",
+ "size": "3561",
+ "visible": "1"
+ },
+ {
+ "index": "13",
+ "size": "1418",
+ "visible": "1"
+ }
+ ]
+ },
+ "o-drawings": {
+ "a-graphitem": [
+ {
+ "id": "70847796661",
+ "parentid": "1028",
+ "o-al": {
+ "n": "model.attributes",
+ "cl": "JSG.AttributeList",
+ "a-al": [
+ {
+ "n": "format",
+ "cl": "FormatAttributes",
+ "a-al": [
+ {
+ "n": "fillcolor",
+ "o-vl": {
+ "v": "%23345678",
+ "t": "s"
+ }
+ }
+ ]
+ },
+ {
+ "n": "graphitem",
+ "cl": "ItemAttributes",
+ "a-al": [
+ {
+ "n": "sheetformula",
+ "o-vl": {
+ "f": "DRAW.POLYGON(~2270847796661~22%2C%2C~22Polygon1~22%2C12289%2C2675%2C18415%2C3493%2C%2C~22%23345678~22)",
+ "v": "0"
+ }
+ },
+ {
+ "n": "sheetsource",
+ "cl": "StringAttribute",
+ "o-vl": {
+ "v": "name",
+ "t": "s"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ "o-type": {
+ "v": "rectCornerCutSame",
+ "t": "s"
+ },
+ "o-name": {
+ "v": "Polygon1",
+ "t": "s"
+ },
+ "o-pin": {
+ "o-p": {
+ "o-x": {
+ "v": "12289"
+ },
+ "o-y": {
+ "v": "2675"
+ }
+ },
+ "o-lp": {
+ "o-x": {
+ "f": "WIDTH%20*%200.5",
+ "v": "9208"
+ },
+ "o-y": {
+ "f": "HEIGHT%20*%200.5",
+ "v": "1746"
+ }
+ }
+ },
+ "o-size": {
+ "o-w": {
+ "v": "18415"
+ },
+ "o-h": {
+ "v": "3493"
+ }
+ },
+ "o-rscoordinates": {
+ "a-c": [
+ {
+ "name": "CUTTOP",
+ "xtype": "13",
+ "ytype": "-1",
+ "xMax": "0.5",
+ "o-x": {
+ "v": "0.10"
+ },
+ "o-y": {
+ "v": "0.00"
+ }
+ },
+ {
+ "name": "CUTBOTTOM",
+ "xtype": "13",
+ "ytype": "-1",
+ "xMax": "0.5",
+ "yMin": "1",
+ "yMax": "1",
+ "o-x": {
+ "v": "0.00"
+ },
+ "o-y": {
+ "v": "1.00"
+ }
+ }
+ ]
+ },
+ "o-shape": {
+ "type": "polygon",
+ "o-cs": {
+ "a-c": [
+ {
+ "o-x": {
+ "f": "MIN(WIDTH%2C%20HEIGHT)%20*%20CUTTOP",
+ "v": "0"
+ },
+ "o-y": {
+ "v": "0"
+ }
+ },
+ {
+ "o-x": {
+ "v": "0"
+ },
+ "o-y": {
+ "f": "MIN(WIDTH%2C%20HEIGHT)%20*%20CUTTOP",
+ "v": "0"
+ }
+ },
+ {
+ "o-x": {
+ "v": "0"
+ },
+ "o-y": {
+ "f": "HEIGHT%20-%20MIN(WIDTH%2C%20HEIGHT)%20*%20CUTBOTTOM",
+ "v": "0"
+ }
+ },
+ {
+ "o-x": {
+ "f": "MIN(WIDTH%2C%20HEIGHT)%20*%20CUTBOTTOM",
+ "v": "0"
+ },
+ "o-y": {
+ "f": "HEIGHT",
+ "v": "3493"
+ }
+ },
+ {
+ "o-x": {
+ "f": "WIDTH%20-%20MIN(WIDTH%2C%20HEIGHT)%20*%20CUTBOTTOM",
+ "v": "0"
+ },
+ "o-y": {
+ "f": "HEIGHT",
+ "v": "3493"
+ }
+ },
+ {
+ "o-x": {
+ "f": "WIDTH",
+ "v": "18415"
+ },
+ "o-y": {
+ "f": "HEIGHT%20-%20MIN(WIDTH%2C%20HEIGHT)%20*%20CUTBOTTOM",
+ "v": "0"
+ }
+ },
+ {
+ "o-x": {
+ "f": "WIDTH",
+ "v": "18415"
+ },
+ "o-y": {
+ "f": "MIN(WIDTH%2C%20HEIGHT)%20*%20CUTTOP",
+ "v": "0"
+ }
+ },
+ {
+ "o-x": {
+ "f": "WIDTH%20-%20MIN(WIDTH%2C%20HEIGHT)%20*%20CUTTOP",
+ "v": "0"
+ },
+ "o-y": {
+ "v": "0"
+ }
+ }
+ ]
+ }
+ },
+ "type": "node"
+ },
+ {
+ "id": "555401109981",
+ "parentid": "1028",
+ "o-al": {
+ "n": "model.attributes",
+ "cl": "JSG.AttributeList",
+ "a-al": [
+ {
+ "n": "graphitem",
+ "cl": "ItemAttributes",
+ "a-al": [
+ {
+ "n": "portmode",
+ "o-vl": {
+ "v": "0"
+ }
+ },
+ {
+ "n": "sheetformula",
+ "o-vl": {
+ "f": "DRAW.CHART(~22555401109981~22%2C%2C~22Chart1~22%2C15262%2C7480%2C8149%2C5080%2C%2C%2C%2C%2C%2C%2C~22column~22%2CS1!G4%3AH13)",
+ "v": "0"
+ }
+ },
+ {
+ "n": "sheetsource",
+ "cl": "StringAttribute",
+ "o-vl": {
+ "v": "name",
+ "t": "s"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ "o-name": {
+ "v": "Chart1",
+ "t": "s"
+ },
+ "o-pin": {
+ "o-p": {
+ "o-x": {
+ "v": "15262"
+ },
+ "o-y": {
+ "v": "7480"
+ }
+ },
+ "o-lp": {
+ "o-x": {
+ "f": "WIDTH%20*%200.5",
+ "v": "4074"
+ },
+ "o-y": {
+ "f": "HEIGHT%20*%200.5",
+ "v": "2540"
+ }
+ }
+ },
+ "o-size": {
+ "o-w": {
+ "v": "8149"
+ },
+ "o-h": {
+ "v": "5080"
+ }
+ },
+ "o-shape": {
+ "type": "rectangle"
+ },
+ "type": "chartnode",
+ "data": "{"chartType":"column","coherent":true,"hasCategoryLabels":"first","hasSeriesLabels":"first","categoryLabelData":[" 14:46:20 GM"," 14:46:21 GM"," 14:46:22 GM"," 14:46:23 GM"," 14:46:24 GM"," 14:46:25 GM"," 14:46:26 GM"," 14:46:27 GM"," 14:46:28 GM"," 14:46:29 GM"],"direction":"columns","range":"=S1!G4:H13","formatRange":"","categoryRange":"=E5:E14","stacked":false,"smooth":true,"step":false,"fill":false,"hideEmpty":"none","angle":6.283185307179586,"series":[{"categoryLabels":"=E5:E14","seriesLabelRange":"=F4","data":"=F5:F14","seriesLabel":"Temperature","fillColor":"#4a90e2","lineColor":"#4a90e2"}]}",
+ "title": "{"title":"","font":{"fontName":"Verdana","fontSize":"12","bold":false,"italic":false,"color":"#000000"}}",
+ "legend": "{"position":"top","font":{"fontName":"Verdana","fontSize":"7","bold":false,"italic":false,"color":"#000000"}}",
+ "scales": "{"xAxes":[{"id":"XAxis1","ticks":{"fontFamily":"Verdana","fontSize":"7","fontColor":"#000000","fontStyle":"normal","minRotation":0,"maxRotation":90,"reverse":false},"gridLines":{"display":false,"color":"#DDDDDD"},"stacked":false,"type":"category","position":"bottom","scaleLabel":{"labelString":"Time","display":true}}],"yAxes":[{"id":"YAxis1","ticks":{"fontFamily":"Verdana","fontSize":"7","fontColor":"#000000","fontStyle":"bold","minRotation":0,"maxRotation":90,"reverse":false,"min":20},"gridLines":{"display":true,"color":"#DDDDDD"},"stacked":false,"type":"linear","position":"left","scaleLabel":{"labelString":"Temperature (ºC)","display":true}}]}"
+ },
+ {
+ "id": "60201705755",
+ "parentid": "1028",
+ "o-al": {
+ "n": "model.attributes",
+ "cl": "JSG.AttributeList",
+ "a-al": [
+ {
+ "n": "format",
+ "cl": "FormatAttributes",
+ "a-al": [
+ {
+ "n": "fillstyle",
+ "o-vl": {
+ "v": "3"
+ }
+ },
+ {
+ "n": "linecolor",
+ "o-vl": {
+ "v": "None",
+ "t": "s"
+ }
+ },
+ {
+ "n": "linestyle",
+ "o-vl": {
+ "v": "0"
+ }
+ }
+ ]
+ },
+ {
+ "n": "graphitem",
+ "cl": "ItemAttributes",
+ "a-al": [
+ {
+ "n": "sheetformula",
+ "o-vl": {
+ "f": "DRAW.RECTANGLE(~2260201705755~22%2C%2C~22Rectangle9~22%2C12355%2C2700%2C7091%2C1984%2C~22None~22%2CFILLPATTERN(~22https%3A%2F%2Fwww.basys40.de%2Fwp-content%2Fuploads%2F2019%2F12%2FLogo_BaSys4_1024px-300x79.png~22))",
+ "v": "0"
+ }
+ },
+ {
+ "n": "sheetsource",
+ "cl": "StringAttribute",
+ "o-vl": {
+ "v": "name",
+ "t": "s"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ "o-name": {
+ "v": "Rectangle9",
+ "t": "s"
+ },
+ "o-pin": {
+ "o-p": {
+ "o-x": {
+ "v": "12355"
+ },
+ "o-y": {
+ "v": "2700"
+ }
+ },
+ "o-lp": {
+ "o-x": {
+ "f": "WIDTH%20*%200.5",
+ "v": "3545"
+ },
+ "o-y": {
+ "f": "HEIGHT%20*%200.5",
+ "v": "992"
+ }
+ }
+ },
+ "o-size": {
+ "o-w": {
+ "v": "7091"
+ },
+ "o-h": {
+ "v": "1984"
+ }
+ },
+ "o-shape": {
+ "type": "rectangle"
+ },
+ "type": "node"
+ },
+ {
+ "id": "488440667154",
+ "parentid": "1028",
+ "o-al": {
+ "n": "model.attributes",
+ "cl": "JSG.AttributeList",
+ "a-al": [
+ {
+ "n": "format",
+ "cl": "FormatAttributes",
+ "a-al": [
+ {
+ "n": "fillcolor",
+ "o-vl": {
+ "v": "%23345678",
+ "t": "s"
+ }
+ }
+ ]
+ },
+ {
+ "n": "graphitem",
+ "cl": "ItemAttributes",
+ "a-al": [
+ {
+ "n": "sheetformula",
+ "o-vl": {
+ "f": "DRAW.RECTANGLE(~22488440667154~22%2C%2C~22Rectangle10~22%2C3967%2C9421%2C1773%2C10001%2C%2C~22%23345678~22)",
+ "v": "0"
+ }
+ },
+ {
+ "n": "sheetsource",
+ "cl": "StringAttribute",
+ "o-vl": {
+ "v": "name",
+ "t": "s"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ "o-name": {
+ "v": "Rectangle10",
+ "t": "s"
+ },
+ "o-pin": {
+ "o-p": {
+ "o-x": {
+ "v": "3967"
+ },
+ "o-y": {
+ "v": "9421"
+ }
+ },
+ "o-lp": {
+ "o-x": {
+ "f": "WIDTH%20*%200.5",
+ "v": "886"
+ },
+ "o-y": {
+ "f": "HEIGHT%20*%200.5",
+ "v": "5001"
+ }
+ }
+ },
+ "o-size": {
+ "o-w": {
+ "v": "1773"
+ },
+ "o-h": {
+ "v": "10001"
+ }
+ },
+ "o-shape": {
+ "type": "rectangle"
+ },
+ "type": "node"
+ },
+ {
+ "id": "919991966926",
+ "parentid": "1028",
+ "o-al": {
+ "n": "model.attributes",
+ "cl": "JSG.AttributeList",
+ "a-al": [
+ {
+ "n": "format",
+ "cl": "FormatAttributes",
+ "a-al": [
+ {
+ "n": "fillcolor",
+ "o-vl": {
+ "v": "%23345678",
+ "t": "s"
+ }
+ }
+ ]
+ },
+ {
+ "n": "graphitem",
+ "cl": "ItemAttributes",
+ "a-al": [
+ {
+ "n": "sheetformula",
+ "o-vl": {
+ "f": "DRAW.RECTANGLE(~22919991966926~22%2C%2C~22Rectangle11~22%2C20623%2C9433%2C1746%2C10001%2C%2C~22%23345678~22)",
+ "v": "0"
+ }
+ },
+ {
+ "n": "sheetsource",
+ "cl": "StringAttribute",
+ "o-vl": {
+ "v": "name",
+ "t": "s"
+ }
+ }
+ ]
+ },
+ {
+ "n": "textformat",
+ "cl": "TextFormatAttributes",
+ "pl": "tl:TextFormatAttributes.Template",
+ "a-al": [
+ {
+ "n": "richtext",
+ "o-vl": {
+ "v": "false",
+ "t": "b"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ "o-name": {
+ "v": "Rectangle11",
+ "t": "s"
+ },
+ "o-pin": {
+ "o-p": {
+ "o-x": {
+ "v": "20623"
+ },
+ "o-y": {
+ "v": "9433"
+ }
+ },
+ "o-lp": {
+ "o-x": {
+ "f": "WIDTH%20*%200.5",
+ "v": "873"
+ },
+ "o-y": {
+ "f": "HEIGHT%20*%200.5",
+ "v": "5001"
+ }
+ }
+ },
+ "o-size": {
+ "o-w": {
+ "v": "1746"
+ },
+ "o-h": {
+ "v": "10001"
+ }
+ },
+ "o-shape": {
+ "type": "rectangle"
+ },
+ "type": "node"
+ },
+ {
+ "id": "962757771226",
+ "parentid": "1028",
+ "o-al": {
+ "n": "model.attributes",
+ "cl": "JSG.AttributeList",
+ "a-al": [
+ {
+ "n": "format",
+ "cl": "FormatAttributes",
+ "a-al": [
+ {
+ "n": "fillcolor",
+ "o-vl": {
+ "v": "%23345678",
+ "t": "s"
+ }
+ }
+ ]
+ },
+ {
+ "n": "graphitem",
+ "cl": "ItemAttributes",
+ "a-al": [
+ {
+ "n": "sheetformula",
+ "o-vl": {
+ "f": "DRAW.RECTANGLE(~22962757771226~22%2C%2C~22Rectangle12~22%2C12302%2C11081%2C14896%2C1376%2C%2C~22%23345678~22)",
+ "v": "0"
+ }
+ },
+ {
+ "n": "sheetsource",
+ "cl": "StringAttribute",
+ "o-vl": {
+ "v": "name",
+ "t": "s"
+ }
+ }
+ ]
+ },
+ {
+ "n": "textformat",
+ "cl": "TextFormatAttributes",
+ "pl": "tl:TextFormatAttributes.Template",
+ "a-al": [
+ {
+ "n": "richtext",
+ "o-vl": {
+ "v": "false",
+ "t": "b"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ "o-name": {
+ "v": "Rectangle12",
+ "t": "s"
+ },
+ "o-pin": {
+ "o-p": {
+ "o-x": {
+ "v": "12302"
+ },
+ "o-y": {
+ "v": "11081"
+ }
+ },
+ "o-lp": {
+ "o-x": {
+ "f": "WIDTH%20*%200.5",
+ "v": "7448"
+ },
+ "o-y": {
+ "f": "HEIGHT%20*%200.5",
+ "v": "688"
+ }
+ }
+ },
+ "o-size": {
+ "o-w": {
+ "v": "14896"
+ },
+ "o-h": {
+ "v": "1376"
+ }
+ },
+ "o-shape": {
+ "type": "rectangle"
+ },
+ "type": "node"
+ },
+ {
+ "id": "692699117567",
+ "parentid": "1028",
+ "o-al": {
+ "n": "model.attributes",
+ "cl": "JSG.AttributeList",
+ "a-al": [
+ {
+ "n": "graphitem",
+ "cl": "ItemAttributes",
+ "a-al": [
+ {
+ "n": "sheetformula",
+ "o-vl": {
+ "f": "DRAW.BEZIER(~22692699117567~22%2C%2C~22Bezier1~22%2C17647%2C13394%2C212%2C1164)",
+ "v": "0"
+ }
+ },
+ {
+ "n": "sheetsource",
+ "cl": "StringAttribute",
+ "o-vl": {
+ "v": "name",
+ "t": "s"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ "o-type": {
+ "v": "roundRectCornerCutSame",
+ "t": "s"
+ },
+ "o-name": {
+ "v": "Bezier1",
+ "t": "s"
+ },
+ "o-pin": {
+ "o-p": {
+ "o-x": {
+ "v": "17647"
+ },
+ "o-y": {
+ "v": "13394"
+ }
+ },
+ "o-lp": {
+ "o-x": {
+ "f": "WIDTH%20*%200.5",
+ "v": "106"
+ },
+ "o-y": {
+ "f": "HEIGHT%20*%200.5",
+ "v": "582"
+ }
+ }
+ },
+ "o-size": {
+ "o-w": {
+ "v": "212"
+ },
+ "o-h": {
+ "v": "1164"
+ }
+ },
+ "o-rscoordinates": {
+ "a-c": [
+ {
+ "name": "ROUND",
+ "xtype": "14",
+ "ytype": "-1",
+ "xMax": "0.5",
+ "o-x": {
+ "v": "0.10"
+ },
+ "o-y": {
+ "v": "0.00"
+ }
+ },
+ {
+ "name": "ROUND2",
+ "xtype": "13",
+ "ytype": "-1",
+ "xMax": "0.5",
+ "yMin": "1",
+ "yMax": "1",
+ "o-x": {
+ "v": "0.00"
+ },
+ "o-y": {
+ "v": "1.00"
+ }
+ }
+ ]
+ },
+ "o-shape": {
+ "type": "bezier",
+ "o-cs": {
+ "a-c": [
+ {
+ "o-x": {
+ "f": "MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND",
+ "v": "0"
+ },
+ "o-y": {
+ "v": "0"
+ }
+ },
+ {
+ "o-x": {
+ "f": "WIDTH%20-%20MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND",
+ "v": "0"
+ },
+ "o-y": {
+ "v": "0"
+ }
+ },
+ {
+ "o-x": {
+ "f": "WIDTH",
+ "v": "212"
+ },
+ "o-y": {
+ "f": "MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND",
+ "v": "0"
+ }
+ },
+ {
+ "o-x": {
+ "f": "WIDTH",
+ "v": "212"
+ },
+ "o-y": {
+ "f": "HEIGHT%20-%20ROUND2%20*%20MIN(WIDTH%2C%20HEIGHT)",
+ "v": "0"
+ }
+ },
+ {
+ "o-x": {
+ "f": "WIDTH%20-%20MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND2",
+ "v": "0"
+ },
+ "o-y": {
+ "f": "HEIGHT",
+ "v": "1164"
+ }
+ },
+ {
+ "o-x": {
+ "f": "MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND2",
+ "v": "0"
+ },
+ "o-y": {
+ "f": "HEIGHT",
+ "v": "1164"
+ }
+ },
+ {
+ "o-x": {
+ "v": "0"
+ },
+ "o-y": {
+ "f": "HEIGHT%20-%20MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND2",
+ "v": "0"
+ }
+ },
+ {
+ "o-x": {
+ "v": "0"
+ },
+ "o-y": {
+ "f": "MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND",
+ "v": "0"
+ }
+ }
+ ]
+ },
+ "o-cpfrom": {
+ "a-c": [
+ {
+ "o-x": {
+ "f": "MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND%20*%200.45",
+ "v": "0"
+ },
+ "o-y": {
+ "v": "0"
+ }
+ },
+ {
+ "o-x": {
+ "f": "MIN(WIDTH%2C%20HEIGHT)%20*%200.6",
+ "v": "0"
+ },
+ "o-y": {
+ "v": "0"
+ }
+ },
+ {
+ "o-x": {
+ "f": "WIDTH",
+ "v": "212"
+ },
+ "o-y": {
+ "f": "MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND%20*%200.45",
+ "v": "0"
+ }
+ },
+ {
+ "o-x": {
+ "f": "WIDTH",
+ "v": "212"
+ },
+ "o-y": {
+ "f": "MIN(WIDTH%2C%20HEIGHT)%20*%200.6",
+ "v": "0"
+ }
+ },
+ {
+ "o-x": {
+ "f": "WIDTH%20-%20MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND2%20*%200.45",
+ "v": "0"
+ },
+ "o-y": {
+ "f": "HEIGHT",
+ "v": "1164"
+ }
+ },
+ {
+ "o-x": {
+ "f": "MIN(WIDTH%2C%20HEIGHT)%20*%200.4",
+ "v": "0"
+ },
+ "o-y": {
+ "f": "HEIGHT",
+ "v": "1164"
+ }
+ },
+ {
+ "o-x": {
+ "v": "0"
+ },
+ "o-y": {
+ "f": "HEIGHT%20-%20MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND2%20*%200.45",
+ "v": "0"
+ }
+ },
+ {
+ "o-x": {
+ "v": "0"
+ },
+ "o-y": {
+ "f": "MIN(WIDTH%2C%20HEIGHT)%20*%200.4",
+ "v": "0"
+ }
+ }
+ ]
+ },
+ "o-cpto": {
+ "a-c": [
+ {
+ "o-x": {
+ "f": "MIN(WIDTH%2C%20HEIGHT)%20*%200.4",
+ "v": "0"
+ },
+ "o-y": {
+ "v": "0"
+ }
+ },
+ {
+ "o-x": {
+ "f": "WIDTH%20-%20MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND%20*%200.45",
+ "v": "0"
+ },
+ "o-y": {
+ "v": "0"
+ }
+ },
+ {
+ "o-x": {
+ "f": "WIDTH",
+ "v": "212"
+ },
+ "o-y": {
+ "f": "MIN(WIDTH%2C%20HEIGHT)%20*%200.4",
+ "v": "0"
+ }
+ },
+ {
+ "o-x": {
+ "f": "WIDTH",
+ "v": "212"
+ },
+ "o-y": {
+ "f": "HEIGHT%20-%20MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND2%20*%200.45",
+ "v": "0"
+ }
+ },
+ {
+ "o-x": {
+ "f": "MIN(WIDTH%2C%20HEIGHT)%20*%200.6",
+ "v": "0"
+ },
+ "o-y": {
+ "f": "HEIGHT",
+ "v": "1164"
+ }
+ },
+ {
+ "o-x": {
+ "f": "MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND2%20*%200.45",
+ "v": "0"
+ },
+ "o-y": {
+ "f": "HEIGHT",
+ "v": "1164"
+ }
+ },
+ {
+ "o-x": {
+ "v": "0"
+ },
+ "o-y": {
+ "f": "MIN(WIDTH%2C%20HEIGHT)%20*%200.6",
+ "v": "0"
+ }
+ },
+ {
+ "o-x": {
+ "v": "0"
+ },
+ "o-y": {
+ "f": "MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND%20*%200.45",
+ "v": "0"
+ }
+ }
+ ],
+ "pie": "false"
+ }
+ },
+ "a-graphitem": [
+ {
+ "id": "426951475952",
+ "parentid": "692699117567",
+ "o-al": {
+ "n": "model.attributes",
+ "cl": "JSG.AttributeList",
+ "a-al": [
+ {
+ "n": "format",
+ "cl": "FormatAttributes",
+ "a-al": [
+ {
+ "n": "fillcolor",
+ "o-vl": {
+ "v": "%23ff0000",
+ "t": "s"
+ }
+ }
+ ]
+ },
+ {
+ "n": "graphitem",
+ "cl": "ItemAttributes",
+ "a-al": [
+ {
+ "n": "sheetformula",
+ "o-vl": {
+ "f": "DRAW.ELLIPSE(~22426951475952~22%2C~22Bezier1~22%2C~22Ellipse1~22%2C106%2C1032%2C529%2C529%2C%2C~22%23ff0000~22)",
+ "v": "0"
+ }
+ },
+ {
+ "n": "sheetsource",
+ "cl": "StringAttribute",
+ "o-vl": {
+ "v": "name",
+ "t": "s"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ "o-name": {
+ "v": "Ellipse1",
+ "t": "s"
+ },
+ "o-pin": {
+ "o-p": {
+ "o-x": {
+ "v": "106"
+ },
+ "o-y": {
+ "v": "1032"
+ }
+ },
+ "o-lp": {
+ "o-x": {
+ "f": "WIDTH%20*%200.5",
+ "v": "265"
+ },
+ "o-y": {
+ "f": "HEIGHT%20*%200.5",
+ "v": "265"
+ }
+ }
+ },
+ "o-size": {
+ "o-w": {
+ "v": "529"
+ },
+ "o-h": {
+ "v": "529"
+ }
+ },
+ "o-shape": {
+ "type": "ellipse",
+ "o-cs": {
+ "a-c": [
+ {
+ "o-x": {
+ "f": "WIDTH%20*%200.5",
+ "v": "265"
+ },
+ "o-y": {
+ "v": "0"
+ }
+ },
+ {
+ "o-x": {
+ "f": "WIDTH",
+ "v": "529"
+ },
+ "o-y": {
+ "f": "HEIGHT%20*%200.5",
+ "v": "265"
+ }
+ },
+ {
+ "o-x": {
+ "f": "WIDTH%20*%200.5",
+ "v": "265"
+ },
+ "o-y": {
+ "f": "HEIGHT",
+ "v": "529"
+ }
+ },
+ {
+ "o-x": {
+ "v": "0"
+ },
+ "o-y": {
+ "f": "HEIGHT%20*%200.5",
+ "v": "265"
+ }
+ }
+ ]
+ },
+ "o-cpfrom": {
+ "a-c": [
+ {
+ "o-x": {
+ "f": "WIDTH%20*%200.225",
+ "v": "119"
+ },
+ "o-y": {
+ "v": "0"
+ }
+ },
+ {
+ "o-x": {
+ "f": "WIDTH",
+ "v": "529"
+ },
+ "o-y": {
+ "f": "HEIGHT%20*%200.225",
+ "v": "119"
+ }
+ },
+ {
+ "o-x": {
+ "f": "WIDTH%20*%200.775",
+ "v": "410"
+ },
+ "o-y": {
+ "f": "HEIGHT",
+ "v": "529"
+ }
+ },
+ {
+ "o-x": {
+ "v": "0"
+ },
+ "o-y": {
+ "f": "HEIGHT%20*%200.775",
+ "v": "410"
+ }
+ }
+ ]
+ },
+ "o-cpto": {
+ "a-c": [
+ {
+ "o-x": {
+ "f": "WIDTH%20*%200.775",
+ "v": "410"
+ },
+ "o-y": {
+ "v": "0"
+ }
+ },
+ {
+ "o-x": {
+ "f": "WIDTH",
+ "v": "529"
+ },
+ "o-y": {
+ "f": "HEIGHT%20*%200.775",
+ "v": "410"
+ }
+ },
+ {
+ "o-x": {
+ "f": "WIDTH%20*%200.225",
+ "v": "119"
+ },
+ "o-y": {
+ "f": "HEIGHT",
+ "v": "529"
+ }
+ },
+ {
+ "o-x": {
+ "v": "0"
+ },
+ "o-y": {
+ "f": "HEIGHT%20*%200.225",
+ "v": "119"
+ }
+ }
+ ],
+ "pie": "false"
+ }
+ },
+ "type": "node"
+ }
+ ],
+ "type": "node"
+ }
+ ]
+ },
+ "o-defaultcell": {
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23ffffff",
+ "t": "s"
+ },
+ "o-fillstyle": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ "o-data": {
+ "a-r": [
+ {
+ "n": "0",
+ "a-c": [
+ {
+ "n": "6",
+ "o-cell": {
+ "o-t": {
+ "o-numberformat": {
+ "v": "h%3Amm%3Ass%20AM%2FPM",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "time%3Ben",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "7",
+ "o-cell": {
+ "o-t": {
+ "o-numberformat": {
+ "v": "h%3Amm%3Ass",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "time%3Ben",
+ "t": "s"
+ }
+ }
+ }
+ }
+ ]
+ },
+ {
+ "n": "1",
+ "a-c": [
+ {
+ "n": "3",
+ "o-cell": {
+ "o-t": {
+ "o-fontstyle": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "7",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "8",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "9",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "10",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "11",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "12",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "13",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "14",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ }
+ ]
+ },
+ {
+ "n": "2",
+ "a-c": [
+ {
+ "n": "4",
+ "o-cell": {
+ "o-t": {
+ "o-fontstyle": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "7",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-fontsize": {
+ "v": "12"
+ },
+ "o-fontcolor": {
+ "v": "%230f4db5",
+ "t": "s"
+ }
+ },
+ "o-a": {
+ "o-leftbordercolor": {
+ "v": "%230887fb",
+ "t": "s"
+ },
+ "o-topbordercolor": {
+ "v": "%230887fb",
+ "t": "s"
+ },
+ "o-rightbordercolor": {
+ "v": "%230887fb",
+ "t": "s"
+ },
+ "o-bottombordercolor": {
+ "v": "%230887fb",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "8",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-halign": {
+ "v": "1"
+ },
+ "o-fontsize": {
+ "v": "12"
+ },
+ "o-fontcolor": {
+ "v": "%231758ab",
+ "t": "s"
+ }
+ },
+ "o-a": {
+ "o-leftbordercolor": {
+ "v": "%23f8e71c",
+ "t": "s"
+ },
+ "o-topbordercolor": {
+ "v": "%23f8e71c",
+ "t": "s"
+ },
+ "o-rightbordercolor": {
+ "v": "%23f8e71c",
+ "t": "s"
+ },
+ "o-bottombordercolor": {
+ "v": "%23f8e71c",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "9",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-halign": {
+ "v": "1"
+ },
+ "o-fontsize": {
+ "v": "12"
+ },
+ "o-fontcolor": {
+ "v": "%231758ab",
+ "t": "s"
+ }
+ },
+ "o-a": {
+ "o-leftbordercolor": {
+ "v": "%23f8e71c",
+ "t": "s"
+ },
+ "o-topbordercolor": {
+ "v": "%23f8e71c",
+ "t": "s"
+ },
+ "o-rightbordercolor": {
+ "v": "%23f8e71c",
+ "t": "s"
+ },
+ "o-bottombordercolor": {
+ "v": "%23f8e71c",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "10",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "11",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "12",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "13",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "14",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ }
+ ]
+ },
+ {
+ "n": "3",
+ "a-c": [
+ {
+ "n": "3",
+ "o-cell": {
+ "o-a": {
+ "o-key": {
+ "v": "true",
+ "t": "b"
+ }
+ }
+ }
+ },
+ {
+ "n": "5",
+ "o-cell": {
+ "o-t": {
+ "o-numberformat": {
+ "v": "0",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "number%3B0%3Bfalse",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "6",
+ "o-cell": {
+ "o-t": {
+ "o-numberformat": {
+ "v": "h%3Amm%3Ass%20AM%2FPM",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "time%3Ben",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "7",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-fontcolor": {
+ "v": "%230f4db5",
+ "t": "s"
+ },
+ "o-fontsize": {
+ "v": "10"
+ }
+ },
+ "o-a": {
+ "o-key": {
+ "v": "true",
+ "t": "b"
+ }
+ }
+ }
+ },
+ {
+ "n": "8",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-numberformat": {
+ "v": "hh%3Amm%3Ass",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "time%3Ben",
+ "t": "s"
+ },
+ "o-halign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "9",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-halign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "10",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "11",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "12",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "13",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "14",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ }
+ ]
+ },
+ {
+ "n": "4",
+ "a-c": [
+ {
+ "n": "3",
+ "o-cell": {
+ "o-a": {
+ "o-key": {
+ "v": "true",
+ "t": "b"
+ }
+ }
+ }
+ },
+ {
+ "n": "5",
+ "o-cell": {
+ "o-t": {
+ "o-numberformat": {
+ "v": "d~5C.m~5C.yyyy%20h%3Amm",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "date%3Bde",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "6",
+ "o-cell": {
+ "o-t": {
+ "o-numberformat": {
+ "v": "h%3Amm%3Ass%20AM%2FPM",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "time%3Ben",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "7",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-fontcolor": {
+ "v": "%230f4db5",
+ "t": "s"
+ },
+ "o-fontsize": {
+ "v": "10"
+ }
+ },
+ "o-a": {
+ "o-key": {
+ "v": "true",
+ "t": "b"
+ }
+ }
+ }
+ },
+ {
+ "n": "8",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-numberformat": {
+ "v": "hh%3Amm%3Ass",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "time%3Ben",
+ "t": "s"
+ },
+ "o-halign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "9",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-halign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "10",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "11",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "12",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "13",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "14",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ }
+ ]
+ },
+ {
+ "n": "5",
+ "a-c": [
+ {
+ "n": "3",
+ "o-cell": {
+ "o-a": {
+ "o-key": {
+ "v": "true",
+ "t": "b"
+ }
+ }
+ }
+ },
+ {
+ "n": "5",
+ "o-cell": {
+ "o-t": {
+ "o-numberformat": {
+ "v": "d~5C.m~5C.yyyy%20h%3Amm",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "date%3Bde",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "6",
+ "o-cell": {
+ "o-t": {
+ "o-numberformat": {
+ "v": "h%3Amm%3Ass%20AM%2FPM",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "time%3Ben",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "7",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-fontcolor": {
+ "v": "%230f4db5",
+ "t": "s"
+ },
+ "o-fontsize": {
+ "v": "10"
+ }
+ },
+ "o-a": {
+ "o-key": {
+ "v": "true",
+ "t": "b"
+ }
+ }
+ }
+ },
+ {
+ "n": "8",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-numberformat": {
+ "v": "hh%3Amm%3Ass",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "time%3Ben",
+ "t": "s"
+ },
+ "o-halign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "9",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-halign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "10",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "11",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "12",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "13",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "14",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ }
+ ]
+ },
+ {
+ "n": "6",
+ "a-c": [
+ {
+ "n": "3",
+ "o-cell": {
+ "o-a": {
+ "o-key": {
+ "v": "true",
+ "t": "b"
+ }
+ }
+ }
+ },
+ {
+ "n": "5",
+ "o-cell": {
+ "o-t": {
+ "o-numberformat": {
+ "v": "d~5C.m~5C.yyyy%20h%3Amm",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "date%3Bde",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "6",
+ "o-cell": {
+ "o-t": {
+ "o-numberformat": {
+ "v": "h%3Amm%3Ass%20AM%2FPM",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "time%3Ben",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "7",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-fontcolor": {
+ "v": "%230f4db5",
+ "t": "s"
+ },
+ "o-fontsize": {
+ "v": "10"
+ }
+ },
+ "o-a": {
+ "o-key": {
+ "v": "true",
+ "t": "b"
+ }
+ }
+ }
+ },
+ {
+ "n": "8",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-numberformat": {
+ "v": "hh%3Amm%3Ass",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "time%3Ben",
+ "t": "s"
+ },
+ "o-halign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "9",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-halign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "10",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "11",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "12",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "13",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "14",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ }
+ ]
+ },
+ {
+ "n": "7",
+ "a-c": [
+ {
+ "n": "3",
+ "o-cell": {
+ "o-a": {
+ "o-key": {
+ "v": "true",
+ "t": "b"
+ }
+ }
+ }
+ },
+ {
+ "n": "5",
+ "o-cell": {
+ "o-t": {
+ "o-numberformat": {
+ "v": "d~5C.m~5C.yyyy%20h%3Amm",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "date%3Bde",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "6",
+ "o-cell": {
+ "o-t": {
+ "o-numberformat": {
+ "v": "h%3Amm%3Ass%20AM%2FPM",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "time%3Ben",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "7",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-fontcolor": {
+ "v": "%230f4db5",
+ "t": "s"
+ },
+ "o-fontsize": {
+ "v": "10"
+ }
+ },
+ "o-a": {
+ "o-key": {
+ "v": "true",
+ "t": "b"
+ }
+ }
+ }
+ },
+ {
+ "n": "8",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-numberformat": {
+ "v": "hh%3Amm%3Ass",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "time%3Ben",
+ "t": "s"
+ },
+ "o-halign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "9",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-halign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "10",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "11",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "12",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "13",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "14",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ }
+ ]
+ },
+ {
+ "n": "8",
+ "a-c": [
+ {
+ "n": "3",
+ "o-cell": {
+ "o-a": {
+ "o-key": {
+ "v": "true",
+ "t": "b"
+ }
+ }
+ }
+ },
+ {
+ "n": "5",
+ "o-cell": {
+ "o-t": {
+ "o-numberformat": {
+ "v": "d~5C.m~5C.yyyy%20h%3Amm",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "date%3Bde",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "6",
+ "o-cell": {
+ "o-t": {
+ "o-numberformat": {
+ "v": "h%3Amm%3Ass%20AM%2FPM",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "time%3Ben",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "7",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-fontcolor": {
+ "v": "%230f4db5",
+ "t": "s"
+ },
+ "o-fontsize": {
+ "v": "10"
+ }
+ },
+ "o-a": {
+ "o-key": {
+ "v": "true",
+ "t": "b"
+ }
+ }
+ }
+ },
+ {
+ "n": "8",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-numberformat": {
+ "v": "hh%3Amm%3Ass",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "time%3Ben",
+ "t": "s"
+ },
+ "o-halign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "9",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-halign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "10",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "11",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "12",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "13",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "14",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ }
+ ]
+ },
+ {
+ "n": "9",
+ "a-c": [
+ {
+ "n": "3",
+ "o-cell": {
+ "o-a": {
+ "o-key": {
+ "v": "true",
+ "t": "b"
+ }
+ }
+ }
+ },
+ {
+ "n": "5",
+ "o-cell": {
+ "o-t": {
+ "o-numberformat": {
+ "v": "d~5C.m~5C.yyyy%20h%3Amm",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "date%3Bde",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "6",
+ "o-cell": {
+ "o-t": {
+ "o-numberformat": {
+ "v": "h%3Amm%3Ass%20AM%2FPM",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "time%3Ben",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "7",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-fontcolor": {
+ "v": "%230f4db5",
+ "t": "s"
+ },
+ "o-fontsize": {
+ "v": "10"
+ }
+ },
+ "o-a": {
+ "o-key": {
+ "v": "true",
+ "t": "b"
+ }
+ }
+ }
+ },
+ {
+ "n": "8",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-numberformat": {
+ "v": "hh%3Amm%3Ass",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "time%3Ben",
+ "t": "s"
+ },
+ "o-halign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "9",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-halign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "10",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "11",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "12",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "13",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "14",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ }
+ ]
+ },
+ {
+ "n": "10",
+ "a-c": [
+ {
+ "n": "3",
+ "o-cell": {
+ "o-a": {
+ "o-key": {
+ "v": "true",
+ "t": "b"
+ }
+ }
+ }
+ },
+ {
+ "n": "5",
+ "o-cell": {
+ "o-t": {
+ "o-numberformat": {
+ "v": "d~5C.m~5C.yyyy%20h%3Amm",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "date%3Bde",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "6",
+ "o-cell": {
+ "o-t": {
+ "o-numberformat": {
+ "v": "h%3Amm%3Ass%20AM%2FPM",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "time%3Ben",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "7",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-fontcolor": {
+ "v": "%230f4db5",
+ "t": "s"
+ },
+ "o-fontsize": {
+ "v": "10"
+ }
+ },
+ "o-a": {
+ "o-key": {
+ "v": "true",
+ "t": "b"
+ }
+ }
+ }
+ },
+ {
+ "n": "8",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-numberformat": {
+ "v": "hh%3Amm%3Ass",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "time%3Ben",
+ "t": "s"
+ },
+ "o-halign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "9",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-halign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "10",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "11",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "12",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "13",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "14",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ }
+ ]
+ },
+ {
+ "n": "11",
+ "a-c": [
+ {
+ "n": "3",
+ "o-cell": {
+ "o-a": {
+ "o-key": {
+ "v": "true",
+ "t": "b"
+ }
+ }
+ }
+ },
+ {
+ "n": "5",
+ "o-cell": {
+ "o-t": {
+ "o-numberformat": {
+ "v": "d~5C.m~5C.yyyy%20h%3Amm",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "date%3Bde",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "6",
+ "o-cell": {
+ "o-t": {
+ "o-numberformat": {
+ "v": "h%3Amm%3Ass%20AM%2FPM",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "time%3Ben",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "7",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-fontcolor": {
+ "v": "%230f4db5",
+ "t": "s"
+ },
+ "o-fontsize": {
+ "v": "10"
+ }
+ },
+ "o-a": {
+ "o-key": {
+ "v": "true",
+ "t": "b"
+ }
+ }
+ }
+ },
+ {
+ "n": "8",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-numberformat": {
+ "v": "hh%3Amm%3Ass",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "time%3Ben",
+ "t": "s"
+ },
+ "o-halign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "9",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-halign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "10",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "11",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "12",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "13",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "14",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ }
+ ]
+ },
+ {
+ "n": "12",
+ "a-c": [
+ {
+ "n": "3",
+ "o-cell": {
+ "o-a": {
+ "o-key": {
+ "v": "true",
+ "t": "b"
+ }
+ }
+ }
+ },
+ {
+ "n": "5",
+ "o-cell": {
+ "o-t": {
+ "o-numberformat": {
+ "v": "d~5C.m~5C.yyyy%20h%3Amm",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "date%3Bde",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "6",
+ "o-cell": {
+ "o-t": {
+ "o-numberformat": {
+ "v": "h%3Amm%3Ass%20AM%2FPM",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "time%3Ben",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "7",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-fontcolor": {
+ "v": "%230f4db5",
+ "t": "s"
+ },
+ "o-fontsize": {
+ "v": "10"
+ }
+ },
+ "o-a": {
+ "o-key": {
+ "v": "true",
+ "t": "b"
+ }
+ }
+ }
+ },
+ {
+ "n": "8",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-numberformat": {
+ "v": "hh%3Amm%3Ass",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "time%3Ben",
+ "t": "s"
+ },
+ "o-halign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "9",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-halign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "10",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "11",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "12",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "13",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "14",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ }
+ ]
+ },
+ {
+ "n": "13",
+ "a-c": [
+ {
+ "n": "7",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-numberformat": {
+ "v": "0.00",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "number%3B2%3Bfalse",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "8",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "9",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "10",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "11",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "12",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "13",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ },
+ {
+ "n": "14",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5fef3",
+ "t": "s"
+ }
+ }
+ }
+ }
+ ]
+ },
+ {
+ "n": "15",
+ "a-c": [
+ {
+ "n": "1",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "2",
+ "o-cell": {
+ "o-t": {
+ "o-fontstyle": {
+ "v": "1"
+ },
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "7",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ },
+ "o-fontstyle": {
+ "v": "1"
+ },
+ "o-numberformat": {
+ "v": "0.00",
+ "t": "s"
+ },
+ "o-localculture": {
+ "v": "number%3B2%3Bfalse",
+ "t": "s"
+ }
+ }
+ }
+ }
+ ]
+ },
+ {
+ "n": "16",
+ "a-c": [
+ {
+ "n": "1",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "2",
+ "o-cell": {
+ "o-t": {
+ "o-fontstyle": {
+ "v": "1"
+ },
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "7",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ },
+ "o-a": {
+ "o-key": {
+ "v": "true",
+ "t": "b"
+ }
+ }
+ }
+ },
+ {
+ "n": "8",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5b5b5",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ },
+ "o-fontstyle": {
+ "v": "1"
+ },
+ "o-fontcolor": {
+ "v": "%234a90e2",
+ "t": "s"
+ }
+ },
+ "o-a": {
+ "o-key": {
+ "v": "true",
+ "t": "b"
+ },
+ "o-leftborderwidth": {
+ "v": "8"
+ },
+ "o-topborderwidth": {
+ "v": "8"
+ }
+ }
+ }
+ },
+ {
+ "n": "9",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5b5b5",
+ "t": "s"
+ }
+ },
+ "o-a": {
+ "o-leftborderwidth": {
+ "v": "8"
+ },
+ "o-topborderwidth": {
+ "v": "8"
+ }
+ }
+ }
+ },
+ {
+ "n": "10",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5b5b5",
+ "t": "s"
+ }
+ },
+ "o-a": {
+ "o-leftborderwidth": {
+ "v": "8"
+ },
+ "o-topborderwidth": {
+ "v": "8"
+ }
+ }
+ }
+ },
+ {
+ "n": "11",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5b5b5",
+ "t": "s"
+ }
+ },
+ "o-a": {
+ "o-leftborderwidth": {
+ "v": "8"
+ },
+ "o-topborderwidth": {
+ "v": "8"
+ }
+ }
+ }
+ },
+ {
+ "n": "12",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5b5b5",
+ "t": "s"
+ }
+ },
+ "o-a": {
+ "o-leftborderwidth": {
+ "v": "8"
+ },
+ "o-topborderwidth": {
+ "v": "8"
+ }
+ }
+ }
+ },
+ {
+ "n": "13",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5b5b5",
+ "t": "s"
+ }
+ },
+ "o-a": {
+ "o-leftborderwidth": {
+ "v": "8"
+ },
+ "o-topborderwidth": {
+ "v": "8"
+ }
+ }
+ }
+ }
+ ]
+ },
+ {
+ "n": "17",
+ "a-c": [
+ {
+ "n": "1",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "2",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "6",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "7",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "8",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5b5b5",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ },
+ "o-a": {
+ "o-leftborderwidth": {
+ "v": "8"
+ },
+ "o-topborderwidth": {
+ "v": "8"
+ }
+ }
+ }
+ },
+ {
+ "n": "9",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5b5b5",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ },
+ "o-fontsize": {
+ "v": "24"
+ }
+ },
+ "o-a": {
+ "o-leftborderwidth": {
+ "v": "8"
+ },
+ "o-topborderwidth": {
+ "v": "8"
+ }
+ }
+ }
+ },
+ {
+ "n": "10",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5b5b5",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ },
+ "o-a": {
+ "o-leftborderwidth": {
+ "v": "8"
+ },
+ "o-topborderwidth": {
+ "v": "8"
+ }
+ }
+ }
+ },
+ {
+ "n": "11",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5b5b5",
+ "t": "s"
+ }
+ },
+ "o-a": {
+ "o-leftborderwidth": {
+ "v": "8"
+ },
+ "o-topborderwidth": {
+ "v": "8"
+ }
+ }
+ }
+ },
+ {
+ "n": "12",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5b5b5",
+ "t": "s"
+ }
+ },
+ "o-a": {
+ "o-leftborderwidth": {
+ "v": "8"
+ },
+ "o-topborderwidth": {
+ "v": "8"
+ }
+ }
+ }
+ },
+ {
+ "n": "13",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5b5b5",
+ "t": "s"
+ }
+ },
+ "o-a": {
+ "o-leftborderwidth": {
+ "v": "8"
+ },
+ "o-topborderwidth": {
+ "v": "8"
+ }
+ }
+ }
+ }
+ ]
+ },
+ {
+ "n": "18",
+ "a-c": [
+ {
+ "n": "2",
+ "o-cell": {
+ "o-t": {
+ "o-fontstyle": {
+ "v": "1"
+ },
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "7",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "8",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5b5b5",
+ "t": "s"
+ }
+ },
+ "o-a": {
+ "o-leftborderwidth": {
+ "v": "8"
+ },
+ "o-topborderwidth": {
+ "v": "8"
+ }
+ }
+ }
+ },
+ {
+ "n": "9",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5b5b5",
+ "t": "s"
+ }
+ },
+ "o-a": {
+ "o-leftborderwidth": {
+ "v": "8"
+ },
+ "o-topborderwidth": {
+ "v": "8"
+ }
+ }
+ }
+ },
+ {
+ "n": "10",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5b5b5",
+ "t": "s"
+ }
+ },
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ },
+ "o-a": {
+ "o-leftborderwidth": {
+ "v": "8"
+ },
+ "o-topborderwidth": {
+ "v": "8"
+ }
+ }
+ }
+ },
+ {
+ "n": "11",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5b5b5",
+ "t": "s"
+ }
+ },
+ "o-a": {
+ "o-leftborderwidth": {
+ "v": "8"
+ },
+ "o-topborderwidth": {
+ "v": "8"
+ }
+ }
+ }
+ },
+ {
+ "n": "12",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5b5b5",
+ "t": "s"
+ }
+ },
+ "o-a": {
+ "o-leftborderwidth": {
+ "v": "8"
+ },
+ "o-topborderwidth": {
+ "v": "8"
+ }
+ }
+ }
+ },
+ {
+ "n": "13",
+ "o-cell": {
+ "o-f": {
+ "o-fillcolor": {
+ "v": "%23b5b5b5",
+ "t": "s"
+ }
+ },
+ "o-a": {
+ "o-leftborderwidth": {
+ "v": "8"
+ },
+ "o-topborderwidth": {
+ "v": "8"
+ }
+ }
+ }
+ }
+ ]
+ },
+ {
+ "n": "19",
+ "a-c": [
+ {
+ "n": "1",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "2",
+ "o-cell": {
+ "o-t": {
+ "o-fontstyle": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "10",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ }
+ ]
+ },
+ {
+ "n": "20",
+ "a-c": [
+ {
+ "n": "1",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "2",
+ "o-cell": {
+ "o-t": {
+ "o-fontstyle": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "10",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ }
+ ]
+ },
+ {
+ "n": "21",
+ "a-c": [
+ {
+ "n": "1",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "2",
+ "o-cell": {
+ "o-t": {
+ "o-fontstyle": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "10",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ }
+ ]
+ },
+ {
+ "n": "22",
+ "a-c": [
+ {
+ "n": "1",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "2",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "3",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "4",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "5",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "6",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "7",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ }
+ ]
+ },
+ {
+ "n": "23",
+ "a-c": [
+ {
+ "n": "1",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "2",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "3",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "4",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "5",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "6",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "7",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ }
+ ]
+ },
+ {
+ "n": "24",
+ "a-c": [
+ {
+ "n": "1",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "2",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "3",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "4",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "5",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "6",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "7",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ }
+ ]
+ },
+ {
+ "n": "25",
+ "a-c": [
+ {
+ "n": "1",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "2",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "3",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "4",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "5",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "6",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "7",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ }
+ ]
+ },
+ {
+ "n": "26",
+ "a-c": [
+ {
+ "n": "1",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "2",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "3",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "4",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "5",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "6",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "7",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ }
+ ]
+ },
+ {
+ "n": "27",
+ "a-c": [
+ {
+ "n": "1",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "2",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "3",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "4",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "5",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "6",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ },
+ {
+ "n": "7",
+ "o-cell": {
+ "o-t": {
+ "o-valign": {
+ "v": "1"
+ }
+ }
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ ],
+ "o-images": {}
+ },
+ "machineId": "S1-EB3RpyP"
+ }
+ }
+ ],
+ "streams": [
+ {
+ "id": "HJZR0U1xSI",
+ "name": "AASRESTTestProducer",
+ "owner": null,
+ "disabled": false,
+ "className": "ProducerConfiguration",
+ "lastModified": "2020-09-09T12:55:45.437Z",
+ "lastAccessed": "2020-03-06T15:05:58.112Z",
+ "connector": {
+ "_id": "S1lML8ygr8",
+ "id": "S1lML8ygr8",
+ "className": "ConnectorConfiguration",
+ "owner": null,
+ "disabled": false,
+ "lastModified": "2020-09-09T12:34:12.984Z",
+ "lastAccessed": "2020-03-06T15:03:38.128Z",
+ "isRef": true
+ },
+ "samplePayloads": null,
+ "mimeType": "auto"
+ },
+ {
+ "id": "S1lML8ygr8",
+ "name": "AASRESTTestProvider",
+ "owner": null,
+ "disabled": false,
+ "className": "ConnectorConfiguration",
+ "lastModified": "2020-09-09T12:55:45.436Z",
+ "lastAccessed": "2020-03-06T15:03:38.128Z",
+ "provider": {
+ "_id": "@cedalo/stream-rest-client",
+ "id": "@cedalo/stream-rest-client",
+ "className": "ProviderConfiguration",
+ "owner": null,
+ "disabled": null,
+ "lastModified": null,
+ "lastAccessed": null,
+ "isRef": true
+ },
+ "baseUrl": "",
+ "userName": "",
+ "password": ""
+ }
+ ]
+}
\ No newline at end of file
diff --git a/examples/basyx.streamsheets/docker-compose.yml b/examples/basyx.streamsheets/docker-compose.yml
new file mode 100644
index 0000000..c4903f4
--- /dev/null
+++ b/examples/basyx.streamsheets/docker-compose.yml
@@ -0,0 +1,34 @@
+version: '3'
+services:
+
+ registry:
+ image: eclipsebasyx/aas-registry:1.0.1
+ container_name: dashboard-registry
+ ports:
+ - 4000:4000
+
+ dashboard-aas:
+ image: eclipsebasyx/dashboard-aas:0.1.0-SNAPSHOT
+ container_name: dashboard-aas
+ environment:
+ - BaSyxDashboardSubmodel_Min=15
+# - BaSyxDashboardSubmodel_Max=30
+ ports:
+ - 6400:6400
+
+ aas-wrapper:
+ image: eclipsebasyx/aas-wrapper:0.1.0-SNAPSHOT
+ container_name: aas-wrapper
+ ports:
+ - 6500:6500
+
+ streamsheets:
+ image: cedalo/streamsheets:1.5
+ container_name: streamsheets
+ ports:
+ - 8081:8081
+ - 8083:8083
+ - 1883:1883
+ volumes:
+ - ./mosquitto:/etc/mosquitto-default-credentials
+ - ./streamsheets:/var/lib/mongodb
\ No newline at end of file
diff --git a/examples/basyx.streamsheets/readme.txt b/examples/basyx.streamsheets/readme.txt
new file mode 100644
index 0000000..5023bde
--- /dev/null
+++ b/examples/basyx.streamsheets/readme.txt
@@ -0,0 +1,12 @@
+HowTo: First Setup
+------------------
+
+1. Start docker-compose
+- Run "docker-compose up" in the /streamsheets/ folder
+
+2. Open in Browser (admin/admin)
+- http://localhost:8081/
+
+3. Import dashboard from JSON (drag & drop possible)
+
+4. Run Streamsheet
diff --git a/examples/basyx.streamsheets/start.bat b/examples/basyx.streamsheets/start.bat
new file mode 100644
index 0000000..83ed0d0
--- /dev/null
+++ b/examples/basyx.streamsheets/start.bat
@@ -0,0 +1 @@
+docker-compose up
diff --git a/examples/basyx.streamsheets/start.sh b/examples/basyx.streamsheets/start.sh
new file mode 100644
index 0000000..d935e43
--- /dev/null
+++ b/examples/basyx.streamsheets/start.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+docker-compose up
\ No newline at end of file
diff --git a/examples/basyx.streamsheets/stop.bat b/examples/basyx.streamsheets/stop.bat
new file mode 100644
index 0000000..58694d0
--- /dev/null
+++ b/examples/basyx.streamsheets/stop.bat
@@ -0,0 +1 @@
+docker-compose down
\ No newline at end of file
diff --git a/examples/basyx.streamsheets/stop.sh b/examples/basyx.streamsheets/stop.sh
new file mode 100644
index 0000000..f5139e2
--- /dev/null
+++ b/examples/basyx.streamsheets/stop.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+docker-compose down
\ No newline at end of file
diff --git a/examples/mvnw b/examples/mvnw
new file mode 100644
index 0000000..a16b543
--- /dev/null
+++ b/examples/mvnw
@@ -0,0 +1,310 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+# JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+# M2_HOME - location of maven2's installed home dir
+# MAVEN_OPTS - parameters passed to the Java VM when running Maven
+# e.g. to debug Maven itself, use
+# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ] ; then
+
+ if [ -f /etc/mavenrc ] ; then
+ . /etc/mavenrc
+ fi
+
+ if [ -f "$HOME/.mavenrc" ] ; then
+ . "$HOME/.mavenrc"
+ fi
+
+fi
+
+# OS specific support. $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "`uname`" in
+ CYGWIN*) cygwin=true ;;
+ MINGW*) mingw=true;;
+ Darwin*) darwin=true
+ # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
+ # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
+ if [ -z "$JAVA_HOME" ]; then
+ if [ -x "/usr/libexec/java_home" ]; then
+ export JAVA_HOME="`/usr/libexec/java_home`"
+ else
+ export JAVA_HOME="/Library/Java/Home"
+ fi
+ fi
+ ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+ if [ -r /etc/gentoo-release ] ; then
+ JAVA_HOME=`java-config --jre-home`
+ fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+ ## resolve links - $0 may be a link to maven's home
+ PRG="$0"
+
+ # need this for relative symlinks
+ while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG="`dirname "$PRG"`/$link"
+ fi
+ done
+
+ saveddir=`pwd`
+
+ M2_HOME=`dirname "$PRG"`/..
+
+ # make it fully qualified
+ M2_HOME=`cd "$M2_HOME" && pwd`
+
+ cd "$saveddir"
+ # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --unix "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+fi
+
+# For Mingw, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME="`(cd "$M2_HOME"; pwd)`"
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+ javaExecutable="`which javac`"
+ if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
+ # readlink(1) is not available as standard on Solaris 10.
+ readLink=`which readlink`
+ if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
+ if $darwin ; then
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
+ else
+ javaExecutable="`readlink -f \"$javaExecutable\"`"
+ fi
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+ JAVA_HOME="$javaHome"
+ export JAVA_HOME
+ fi
+ fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+ if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ else
+ JAVACMD="`which java`"
+ fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+ echo "Error: JAVA_HOME is not defined correctly." >&2
+ echo " We cannot execute $JAVACMD" >&2
+ exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+ echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+
+ if [ -z "$1" ]
+ then
+ echo "Path not specified to find_maven_basedir"
+ return 1
+ fi
+
+ basedir="$1"
+ wdir="$1"
+ while [ "$wdir" != '/' ] ; do
+ if [ -d "$wdir"/.mvn ] ; then
+ basedir=$wdir
+ break
+ fi
+ # workaround for JBEAP-8937 (on Solaris 10/Sparc)
+ if [ -d "${wdir}" ]; then
+ wdir=`cd "$wdir/.."; pwd`
+ fi
+ # end of workaround
+ done
+ echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+ if [ -f "$1" ]; then
+ echo "$(tr -s '\n' ' ' < "$1")"
+ fi
+}
+
+BASE_DIR=`find_maven_basedir "$(pwd)"`
+if [ -z "$BASE_DIR" ]; then
+ exit 1;
+fi
+
+##########################################################################################
+# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+# This allows using the maven wrapper in projects that prohibit checking in binary data.
+##########################################################################################
+if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found .mvn/wrapper/maven-wrapper.jar"
+ fi
+else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
+ fi
+ if [ -n "$MVNW_REPOURL" ]; then
+ jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+ else
+ jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+ fi
+ while IFS="=" read key value; do
+ case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
+ esac
+ done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Downloading from: $jarUrl"
+ fi
+ wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
+ if $cygwin; then
+ wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
+ fi
+
+ if command -v wget > /dev/null; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found wget ... using wget"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ wget "$jarUrl" -O "$wrapperJarPath"
+ else
+ wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
+ fi
+ elif command -v curl > /dev/null; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found curl ... using curl"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ curl -o "$wrapperJarPath" "$jarUrl" -f
+ else
+ curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+ fi
+
+ else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Falling back to using Java to download"
+ fi
+ javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+ # For Cygwin, switch paths to Windows format before running javac
+ if $cygwin; then
+ javaClass=`cygpath --path --windows "$javaClass"`
+ fi
+ if [ -e "$javaClass" ]; then
+ if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Compiling MavenWrapperDownloader.java ..."
+ fi
+ # Compiling the Java class
+ ("$JAVA_HOME/bin/javac" "$javaClass")
+ fi
+ if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+ # Running the downloader
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Running MavenWrapperDownloader.java ..."
+ fi
+ ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
+ fi
+ fi
+ fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
+if [ "$MVNW_VERBOSE" = true ]; then
+ echo $MAVEN_PROJECTBASEDIR
+fi
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --path --windows "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+ [ -n "$MAVEN_PROJECTBASEDIR" ] &&
+ MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
+fi
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+exec "$JAVACMD" \
+ $MAVEN_OPTS \
+ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+ "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+ ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/examples/mvnw.cmd b/examples/mvnw.cmd
new file mode 100644
index 0000000..c8d4337
--- /dev/null
+++ b/examples/mvnw.cmd
@@ -0,0 +1,182 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM https://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Maven Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM set title of command window
+title %0
+@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
+if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+
+FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+ IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
+)
+
+@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
+if exist %WRAPPER_JAR% (
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Found %WRAPPER_JAR%
+ )
+) else (
+ if not "%MVNW_REPOURL%" == "" (
+ SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+ )
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Couldn't find %WRAPPER_JAR%, downloading it ...
+ echo Downloading from: %DOWNLOAD_URL%
+ )
+
+ powershell -Command "&{"^
+ "$webclient = new-object System.Net.WebClient;"^
+ "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
+ "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
+ "}"^
+ "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
+ "}"
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Finished downloading %WRAPPER_JAR%
+ )
+)
+@REM End of extension
+
+@REM Provide a "standardized" way to retrieve the CLI args that will
+@REM work with both Windows and non-Windows executions.
+set MAVEN_CMD_LINE_ARGS=%*
+
+%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
+if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%" == "on" pause
+
+if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
+
+exit /B %ERROR_CODE%
diff --git a/ontologies/MetaOntologyC4I/c4i.owl b/ontologies/MetaOntologyC4I/c4i.owl
index 7341f02..37092d7 100644
--- a/ontologies/MetaOntologyC4I/c4i.owl
+++ b/ontologies/MetaOntologyC4I/c4i.owl
@@ -1,16 +1,16 @@
<?xml version="1.0"?>
-<rdf:RDF xmlns="http://www.basys40.de/kb/c4i.owl#"
- xml:base="http://www.basys40.de/kb/c4i.owl"
+<rdf:RDF xmlns="https://www.w3id.org/basyx/c4i#"
+ xml:base="https://www.w3id.org/basyx/c4i"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
- xmlns:c4i="http://www.basys40.de/kb/c4i.owl#"
+ xmlns:c4i="https://www.w3id.org/basyx/c4i#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:foaf="http://xmlns.com/foaf/0.1/"
xmlns:dc="http://purl.org/dc/elements/1.1/">
- <owl:Ontology rdf:about="https://w3id.org/basyx/c4i">
- <owl:versionIRI rdf:resource="https://w3id.org/basyx/c4i/0.0.1"/>
+ <owl:Ontology rdf:about="https://www.w3id.org/basyx/c4i">
+ <owl:versionIRI rdf:resource="https://www.w3id.org/basyx/c4i/0.0.1"/>
<dc:contributor>
<rdf:Description>
<foaf:name>Siwara Schmitt</foaf:name>
@@ -73,19 +73,19 @@
- <!-- https://w3id.org/basyx/c4i#associatedWithCapability -->
+ <!-- https://www.w3id.org/basyx/c4i#associatedWithCapability -->
- <owl:ObjectProperty rdf:about="https://w3id.org/basyx/c4i#associatedWithCapability">
- <rdfs:range rdf:resource="https://w3id.org/basyx/c4i#Capability"/>
+ <owl:ObjectProperty rdf:about="https://www.w3id.org/basyx/c4i#associatedWithCapability">
+ <rdfs:range rdf:resource="https://www.w3id.org/basyx/c4i#Capability"/>
<rdfs:comment xml:lang="en">States the existence of a relationship between a Thing and a Capability. A relationship can be that a sub sub ... part of a Thing has some capability.</rdfs:comment>
</owl:ObjectProperty>
- <!-- https://w3id.org/basyx/c4i#hasCapability -->
+ <!-- https://www.w3id.org/basyx/c4i#hasCapability -->
- <owl:ObjectProperty rdf:about="https://w3id.org/basyx/c4i#hasCapability">
- <rdfs:subPropertyOf rdf:resource="https://w3id.org/basyx/c4i#associatedWithCapability"/>
+ <owl:ObjectProperty rdf:about="https://www.w3id.org/basyx/c4i#hasCapability">
+ <rdfs:subPropertyOf rdf:resource="https://www.w3id.org/basyx/c4i#associatedWithCapability"/>
<rdfs:comment xml:lang="en">The relation between a Thing and a Capability the Thing offers.</rdfs:comment>
</owl:ObjectProperty>
@@ -102,9 +102,9 @@
- <!-- https://w3id.org/basyx/c4i#Capability -->
+ <!-- https://www.w3id.org/basyx/c4i#Capability -->
- <owl:Class rdf:about="https://w3id.org/basyx/c4i#Capability">
+ <owl:Class rdf:about="https://www.w3id.org/basyx/c4i#Capability">
<rdfs:comment xml:lang="de">Ressourcenneutrales Potential einen Effekt, im Sinne eines Übergangs von einen Start- in einen Zielzustand, zu erzielen.</rdfs:comment>
<rdfs:comment xml:lang="en">The resource neutral potential to achieve an effect, in the sense of a transition from a start to an end state.</rdfs:comment>
<rdfs:label xml:lang="en">Capability</rdfs:label>
diff --git a/ontologies/MetaOntologyC4I/c4i2ssn.owl b/ontologies/MetaOntologyC4I/c4i2ssn.owl
index ab7423b..1f01373 100644
--- a/ontologies/MetaOntologyC4I/c4i2ssn.owl
+++ b/ontologies/MetaOntologyC4I/c4i2ssn.owl
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
-<rdf:RDF xmlns="https://w3id.org/basyx/c4i2ssn#"
- xml:base="https://w3id.org/basyx/c4i2ssn"
+<rdf:RDF xmlns="https://www.w3id.org/basyx/c4i2ssn#"
+ xml:base="https://www.w3id.org/basyx/c4i2ssn"
xmlns:schema="http://schema.org/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:terms="http://purl.org/dc/terms/"
@@ -12,9 +12,9 @@
xmlns:vann="http://purl.org/vocab/vann/"
xmlns:foaf="http://xmlns.com/foaf/0.1/"
xmlns:dc="http://purl.org/dc/elements/1.1/">
- <owl:Ontology rdf:about="https://w3id.org/basyx/c4i2ssn">
- <owl:versionIRI rdf:resource="https://w3id.org/basyx/c4i2ssn/0.0.1"/>
- <owl:imports rdf:resource="https://w3id.org/basyx/c4i"/>
+ <owl:Ontology rdf:about="https://www.w3id.org/basyx/c4i2ssn">
+ <owl:versionIRI rdf:resource="https://www.w3id.org/basyx/c4i2ssn/0.0.1"/>
+ <owl:imports rdf:resource="https://www.w3id.org/basyx/c4i"/>
<dc:contributor>
<rdf:Description>
@@ -75,28 +75,28 @@
- <!-- https://w3id.org/basyx/c4i#associatedWithCapability -->
+ <!-- https://www.w3id.org/basyx/c4i#associatedWithCapability -->
- <rdf:Description rdf:about="https://w3id.org/basyx/c4i#associatedWithCapability">
+ <rdf:Description rdf:about="https://www.w3id.org/basyx/c4i#associatedWithCapability">
<owl:propertyChainAxiom rdf:parseType="Collection">
<rdf:Description rdf:about="http://www.w3.org/ns/ssn/hasSubSystem"/>
- <rdf:Description rdf:about="https://w3id.org/basyx/c4i#hasCapability"/>
+ <rdf:Description rdf:about="https://www.w3id.org/basyx/c4i#hasCapability"/>
</owl:propertyChainAxiom>
</rdf:Description>
- <!-- https://w3id.org/basyx/c4i#hasCapability -->
+ <!-- https://www.w3id.org/basyx/c4i#hasCapability -->
- <owl:ObjectProperty rdf:about="https://w3id.org/basyx/c4i#hasCapability">
- <owl:equivalentProperty rdf:resource="https://w3id.org/basyx/c4i2ssn#hasSystemCapability"/>
+ <owl:ObjectProperty rdf:about="https://www.w3id.org/basyx/c4i#hasCapability">
+ <owl:equivalentProperty rdf:resource="https://www.w3id.org/basyx/c4i2ssn#hasSystemCapability"/>
</owl:ObjectProperty>
- <!-- https://w3id.org/basyx/c4i2ssn#hasSystemCapability -->
+ <!-- https://www.w3id.org/basyx/c4i2ssn#hasSystemCapability -->
- <owl:ObjectProperty rdf:about="https://w3id.org/basyx/c4i2ssn#hasSystemCapability"/>
+ <owl:ObjectProperty rdf:about="https://www.w3id.org/basyx/c4i2ssn#hasSystemCapability"/>
@@ -117,9 +117,9 @@
- <!-- https://w3id.org/basyx/c4i#Capability -->
+ <!-- https://www.w3id.org/basyx/c4i#Capability -->
- <owl:Class rdf:about="https://w3id.org/basyx/c4i#Capability">
+ <owl:Class rdf:about="https://www.w3id.org/basyx/c4i#Capability">
<owl:equivalentClass rdf:resource="http://www.w3.org/ns/ssn/systems/SystemCapability"/>
</owl:Class>
diff --git a/sandbox/Java/basyx.sandbox/WebContent/META-INF/MANIFEST.MF b/sandbox/Java/basyx.sandbox/WebContent/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..59499bc
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/WebContent/META-INF/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+
diff --git a/components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/cfgprovider/samplecfg.properties b/sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/cfgprovider/samplecfg.properties
similarity index 100%
rename from components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/cfgprovider/samplecfg.properties
rename to sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/cfgprovider/samplecfg.properties
diff --git a/components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/directory/cfgdirectory/directory.properties b/sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/directory/cfgdirectory/directory.properties
similarity index 100%
rename from components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/directory/cfgdirectory/directory.properties
rename to sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/directory/cfgdirectory/directory.properties
diff --git a/components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/excelprovider/excelcfg.properties b/sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/excelprovider/excelcfg.properties
similarity index 100%
rename from components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/excelprovider/excelcfg.properties
rename to sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/excelprovider/excelcfg.properties
diff --git a/components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/excelprovider/sampledata.xlsx b/sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/excelprovider/sampledata.xlsx
similarity index 100%
rename from components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/excelprovider/sampledata.xlsx
rename to sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/excelprovider/sampledata.xlsx
Binary files differ
diff --git a/components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/rawcfgprovider/samplecfg.properties b/sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/rawcfgprovider/samplecfg.properties
similarity index 100%
rename from components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/rawcfgprovider/samplecfg.properties
rename to sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/rawcfgprovider/samplecfg.properties
diff --git a/components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/sqlprovider/sampledb.properties b/sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/sqlprovider/sampledb.properties
similarity index 100%
rename from components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/sqlprovider/sampledb.properties
rename to sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/sqlprovider/sampledb.properties
diff --git a/components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/xmlqueryprovider/database.xml b/sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/xmlqueryprovider/database.xml
similarity index 100%
rename from components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/xmlqueryprovider/database.xml
rename to sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/xmlqueryprovider/database.xml
diff --git a/components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/xmlqueryprovider/heavySensorNames.xq b/sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/xmlqueryprovider/heavySensorNames.xq
similarity index 100%
rename from components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/xmlqueryprovider/heavySensorNames.xq
rename to sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/xmlqueryprovider/heavySensorNames.xq
diff --git a/components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/xmlqueryprovider/xmlqueryprovider.properties b/sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/xmlqueryprovider/xmlqueryprovider.properties
similarity index 100%
rename from components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/xmlqueryprovider/xmlqueryprovider.properties
rename to sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/xmlqueryprovider/xmlqueryprovider.properties
diff --git a/sandbox/Java/basyx.sandbox/WebContent/WEB-INF/web.xml b/sandbox/Java/basyx.sandbox/WebContent/WEB-INF/web.xml
new file mode 100644
index 0000000..a08f173
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/WebContent/WEB-INF/web.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
+ <display-name>basys.components</display-name>
+
+
+ <welcome-file-list>
+ <welcome-file>index.html</welcome-file>
+ <welcome-file>index.htm</welcome-file>
+ <welcome-file>index.jsp</welcome-file>
+ <welcome-file>default.html</welcome-file>
+ <welcome-file>default.htm</welcome-file>
+ <welcome-file>default.jsp</welcome-file>
+ </welcome-file-list>
+</web-app>
\ No newline at end of file
diff --git a/sandbox/Java/basyx.sandbox/pom.xml b/sandbox/Java/basyx.sandbox/pom.xml
index 2783d41..4970b82 100644
--- a/sandbox/Java/basyx.sandbox/pom.xml
+++ b/sandbox/Java/basyx.sandbox/pom.xml
@@ -5,7 +5,7 @@
<groupId>org.eclipse.basyx</groupId>
<artifactId>basyx.sandbox</artifactId>
- <version>0.0.1-SNAPSHOT</version>
+ <version>0.1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>basyx.sandbox</name>
@@ -42,21 +42,21 @@
<dependency>
<groupId>org.eclipse.basyx</groupId>
<artifactId>basyx.components.lib</artifactId>
- <version>0.0.1-SNAPSHOT</version>
+ <version>0.1.0-SNAPSHOT</version>
</dependency>
<!-- Add explicit SQLRegistry dependency -->
<dependency>
<groupId>org.eclipse.basyx</groupId>
<artifactId>basyx.components.sqlregistry</artifactId>
- <version>0.0.1-SNAPSHOT</version>
+ <version>0.1.0-SNAPSHOT</version>
</dependency>
<!-- Adds additional classes of the BaSys SDK for tests -->
<dependency>
<groupId>org.eclipse.basyx</groupId>
<artifactId>basyx.sdk</artifactId>
- <version>0.0.1-SNAPSHOT</version>
+ <version>0.1.0-SNAPSHOT</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/CFGSubModelProvider.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/CFGSubModelProvider.java
new file mode 100644
index 0000000..e26dc5e
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/CFGSubModelProvider.java
@@ -0,0 +1,44 @@
+package org.eclipse.basyx.sandbox.components.cfgprovider;
+
+import java.util.Map;
+
+import org.eclipse.basyx.components.provider.BaseConfiguredProvider;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+/**
+ * Asset administration shell sub model provider that exports a properties file
+ *
+ * @author kuhn
+ *
+ */
+public class CFGSubModelProvider extends BaseConfiguredProvider {
+
+ /**
+ * Initiates a logger using the current class
+ */
+ private static final Logger logger = LoggerFactory.getLogger(CFGSubModelProvider.class);
+
+ /**
+ * Constructor
+ */
+ public CFGSubModelProvider(Map<Object, Object> cfgValues) {
+ // Call base constructor
+ super(cfgValues);
+
+ // Add properties
+ for (String key: getConfiguredProperties(cfgValues)) {
+ // Create properties
+ SubmodelElement elem = createSubmodelElement(key, cfgValues.get(key), cfgValues);
+ createValue("submodel/" + SubmodelElementProvider.ELEMENTS, elem);
+
+ // Debug output
+ logger.debug("Adding configured property: "+key.toString()+" = "+cfgValues.get(key));
+ }
+ }
+}
+
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/RawCFGSubModelProvider.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/RawCFGSubModelProvider.java
new file mode 100644
index 0000000..4d4a2c3
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/RawCFGSubModelProvider.java
@@ -0,0 +1,81 @@
+package org.eclipse.basyx.sandbox.components.cfgprovider;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.basyx.components.provider.BaseConfiguredProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Asset administration shell sub model provider that exports a properties file
+ *
+ * @author kuhn
+ *
+ */
+public class RawCFGSubModelProvider extends BaseConfiguredProvider {
+
+ /**
+ * Initiates a logger using the current class
+ */
+ private static final Logger logger = LoggerFactory.getLogger(RawCFGSubModelProvider.class);
+
+ private static final String FTYPE = "$ftype";
+
+ /**
+ * Constructor
+ */
+ @SuppressWarnings("unchecked")
+ public RawCFGSubModelProvider(Map<Object, Object> cfgValues) {
+ // Call base constructor -> creates base submodelData from cfgValues
+ super(cfgValues);
+
+ // Load properties
+ for (Object key : cfgValues.keySet()) {
+ // Do not put meta data keys into map
+ if (((String) key).endsWith(FTYPE))
+ continue;
+
+ // Get path to element
+ String[] path = splitPath((String) key);
+
+ // Create path
+ Map<String, Object> scope = new HashMap<>();
+ scope = submodelData;
+ for (int i = 0; i < path.length - 1; i++) {
+ if (!scope.containsKey(path[i]))
+ scope.put(path[i], new HashMap<String, Object>());
+ scope = (Map<String, Object>) scope.get(path[i]);
+ }
+
+ // Get and optionally convert value
+ Object value = cfgValues.get(key);
+ // - Cast value if requested by user
+ if (cfgValues.get(key + FTYPE) != null)
+ switch ((String) cfgValues.get(key + FTYPE)) {
+ case "int":
+ value = Integer.parseInt((String) value);
+ break;
+ case "boolean":
+ value = Boolean.parseBoolean((String) value);
+ break;
+ case "float":
+ value = Float.parseFloat((String) value);
+ break;
+
+ default:
+ logger.error("Unknown type:" + cfgValues.get(key + FTYPE));
+ }
+
+ logger.debug("Putting:" + key + " = " + cfgValues.get(key) + " as " + value.getClass().getName());
+
+ scope.put(path[path.length - 1], value);
+ }
+
+ // Push data to provider
+ setSubmodel(submodelData);
+
+ // Print configuration values
+ logger.debug("CFG exported");
+ }
+}
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/AbstractCFGSubModelProviderServlet.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/AbstractCFGSubModelProviderServlet.java
new file mode 100644
index 0000000..7198b6d
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/AbstractCFGSubModelProviderServlet.java
@@ -0,0 +1,113 @@
+package org.eclipse.basyx.sandbox.components.cfgprovider.servlet;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+import javax.servlet.ServletException;
+
+import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
+import org.eclipse.basyx.submodel.restapi.SubModelProvider;
+import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Abstract super class for all config file using submodel provider servlets
+ *
+ * @author schnicke
+ *
+ */
+public abstract class AbstractCFGSubModelProviderServlet extends VABHTTPInterface<VABMultiSubmodelProvider> {
+
+ /**
+ * Initiates a logger using the current class
+ */
+ private static final Logger logger = LoggerFactory.getLogger(AbstractCFGSubModelProviderServlet.class);
+
+ /**
+ * Version information to identify the version of serialized instances
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Store ID of the sub model provided by this provider
+ */
+ protected String submodelID = null;
+
+ /**
+ * Configuration properties
+ */
+ protected Properties properties = null;
+
+
+ /**
+ * Standard constructor creating a servlet containing a new
+ * VABMultiSubmodelProvider()
+ */
+ public AbstractCFGSubModelProviderServlet() {
+ super(new VABMultiSubmodelProvider());
+ }
+
+ /**
+ * Load properties from file
+ */
+ protected void loadProperties(String cfgFilePath) {
+ // Read property file
+ try {
+ // Open property file
+ InputStream input = getServletContext().getResourceAsStream(cfgFilePath);
+
+ // Instantiate property structure
+ properties = new Properties();
+ properties.load(input);
+
+ // Extract AAS properties
+ this.submodelID = properties.getProperty(getSubmodelId());
+ } catch (IOException e) {
+ // Output exception
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Initialize servlet
+ *
+ * @throws ServletException
+ */
+ @Override
+ public void init() throws ServletException {
+ // Call base implementation
+ super.init();
+
+ // Read configuration values
+ String configFilePath = getInitParameter("config");
+ // - Read property file
+ loadProperties(configFilePath);
+
+ logger.debug("1:" + submodelID);
+
+ // Create sub model provider
+ SubModelProvider submodelProvider = createProvider(properties);
+ // - Add sub model provider
+ this.getModelProvider().addSubmodel(submodelID, submodelProvider);
+
+ logger.debug("CFG file loaded");
+ }
+
+ /**
+ * Retrieves the submodel id
+ *
+ * @return
+ */
+ protected abstract String getSubmodelId();
+
+ /**
+ * Creates the appropriate provider based on the passed properties
+ *
+ * @param properties
+ * @return
+ */
+ protected abstract SubModelProvider createProvider(Properties properties);
+
+}
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/CFGSubModelProviderServlet.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/CFGSubModelProviderServlet.java
new file mode 100644
index 0000000..be1b334
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/CFGSubModelProviderServlet.java
@@ -0,0 +1,32 @@
+package org.eclipse.basyx.sandbox.components.cfgprovider.servlet;
+
+import java.util.Properties;
+
+import org.eclipse.basyx.components.provider.BaseConfiguredProvider;
+import org.eclipse.basyx.sandbox.components.cfgprovider.CFGSubModelProvider;
+import org.eclipse.basyx.submodel.restapi.SubModelProvider;
+
+/**
+ * Servlet interface for configuration file sub model provider
+ *
+ * @author kuhn
+ *
+ */
+public class CFGSubModelProviderServlet extends AbstractCFGSubModelProviderServlet {
+
+ /**
+ * Version information to identify the version of serialized instances
+ */
+ private static final long serialVersionUID = -7525848804623194574L;
+
+
+ @Override
+ protected String getSubmodelId() {
+ return BaseConfiguredProvider.buildBasyxCfgName(BaseConfiguredProvider.SUBMODELID);
+ }
+
+ @Override
+ protected SubModelProvider createProvider(Properties properties) {
+ return new CFGSubModelProvider(properties);
+ }
+}
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/RawCFGSubModelProviderServlet.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/RawCFGSubModelProviderServlet.java
new file mode 100644
index 0000000..0087b4c
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/RawCFGSubModelProviderServlet.java
@@ -0,0 +1,33 @@
+package org.eclipse.basyx.sandbox.components.cfgprovider.servlet;
+
+import java.util.Properties;
+
+import org.eclipse.basyx.sandbox.components.cfgprovider.RawCFGSubModelProvider;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.restapi.SubModelProvider;
+
+/**
+ * Servlet interface for configuration file sub model provider
+ *
+ * @author kuhn
+ *
+ */
+public class RawCFGSubModelProviderServlet extends AbstractCFGSubModelProviderServlet {
+
+ /**
+ * Version information to identify the version of serialized instances
+ */
+ private static final long serialVersionUID = -8132051635222485719L;
+
+
+ @Override
+ protected String getSubmodelId() {
+ return Referable.IDSHORT;
+ }
+
+
+ @Override
+ protected SubModelProvider createProvider(Properties properties) {
+ return new RawCFGSubModelProvider(properties);
+ }
+}
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/AASDirectoryEntry.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/AASDirectoryEntry.java
new file mode 100644
index 0000000..34fdbdb
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/AASDirectoryEntry.java
@@ -0,0 +1,375 @@
+package org.eclipse.basyx.sandbox.components.registry;
+
+import java.util.Collection;
+import java.util.HashSet;
+
+import org.eclipse.basyx.sandbox.components.registry.exception.AASDirectoryFormatException;
+
+
+
+/**
+ * Asset Administration Shell or sub model directory entry
+ *
+ * IDs usually are formed as URIs: urn:<legalBody>:<SubUnit>:<Submodel>:<version>:<revision>:<elementID>#<instance>
+ *
+ * @author kuhn
+ *
+ */
+public class AASDirectoryEntry {
+
+
+ /**
+ * Indicate undefined AAS content type
+ */
+ public static final int AAS_CONTENTTYPE_UNDEFINED = -1;
+
+
+ /**
+ * Indicate local AAS content type. The serialized AAS is stored in the content property of this class.
+ */
+ public static final int AAS_CONTENTTYPE_LOCAL = 1;
+
+
+ /**
+ * Indicate remote AAS content type. The content property of this class contains a URL that points to the directory service.
+ */
+ public static final int AAS_CONTENTTYPE_REMOTE = 2;
+
+
+ /**
+ * Indicate proxy AAS content type. The content property of this class contains an ID (specified as URI) that points to the
+ * AAS entry that all requests should be forwarded to.
+ */
+ public static final int AAS_CONTENTTYPE_PROXY = 3;
+
+
+
+
+
+ /**
+ * Store the AAS ID
+ */
+ protected String id = null;
+
+
+ /**
+ * Store the AAS content
+ */
+ protected String content = null;
+
+
+ /**
+ * Store the AAS content type (local, remote, or proxy)
+ *
+ * Local AAS content means that the AAS is serialized in the content property. Remote indicates
+ * that the content property contains a URL that points to the AAS. Proxy indicates that the
+ * content contains another AAS ID, to which requests will be forwarded.
+ */
+ protected int contentType = -1;
+
+
+ /**
+ * Store the tags for this AAS
+ */
+ protected HashSet<String> tags = new HashSet<>();
+
+
+
+
+
+ /**
+ * Constructor
+ */
+ public AASDirectoryEntry(String aasId, String aasContent, String aasContentType, String aasTags) {
+ // Store AAS parameter
+ id = aasId;
+ content = aasContent;
+
+
+ // Try to process AAS content type
+ try {
+ // Store AAS content type
+ switch(aasContentType.toLowerCase()) {
+ case "local": contentType = AAS_CONTENTTYPE_LOCAL; break;
+ case "remote": contentType = AAS_CONTENTTYPE_REMOTE; break;
+ case "proxy": contentType = AAS_CONTENTTYPE_PROXY; break;
+
+ default: throw new AASDirectoryFormatException("Unknown content type: "+aasContentType);
+ }
+ } catch (NullPointerException e) {
+ // Assume local AAS for undefined AAS types
+ contentType = AAS_CONTENTTYPE_LOCAL;
+ }
+
+
+ // Try to Store AAS tags
+ try {
+ String[] splitTags = aasTags.split(",");
+ // - Only add non-empty tags
+ for (String tag: splitTags) if (tag.trim().length() > 0) tags.add(tag.trim());
+ } catch (NullPointerException e) {
+ // Accept AAS without tags
+ }
+ }
+
+
+ /**
+ * Check if ID is a valid URI. A valid URI starts with "urn:" prefix and defines at least a legal body.
+ */
+ public boolean isValidID() {
+ return (id.startsWith("urn"));
+ }
+
+
+ /**
+ * Check if ID contains a legal entity
+ */
+ public boolean hasLegalEntity() {
+ // Split ID by ':' token
+ String[] idParts = id.split(":");
+
+ // Check if subunit is defined
+ if (idParts.length < 2) return false;
+
+ // Check if any information is contained in subunit field
+ return (idParts[1].trim().length() > 0);
+ }
+
+
+ /**
+ * Return the legal entity of this AAS
+ */
+ public String getLegalEntity() {
+ // Split ID by ':' token
+ String[] idParts = id.split(":");
+
+ // Return legal Entity part
+ return idParts[1];
+ }
+
+
+ /**
+ * Check if AAS legal entity is of type (ends with given suffix, e.g. ".fraunhofer.de")
+ */
+ public boolean isLegalEntityOf(String suffix) {
+ return getLegalEntity().endsWith(suffix);
+ }
+
+
+ /**
+ * Check if ID contains a subunit
+ */
+ public boolean hasSubUnit() {
+ // Split ID by ':' token
+ String[] idParts = id.split(":");
+
+ // Check if subunit is defined
+ if (idParts.length < 3) return false;
+
+ // Check if any information is contained in subunit field
+ return (idParts[2].trim().length() > 0);
+ }
+
+
+ /**
+ * Get the subunit of the ID field
+ */
+ public String getSubUnit() {
+ // Split ID by ':' token
+ String[] idParts = id.split(":");
+
+ // Check if subunit is defined
+ if (idParts.length < 3) return null;
+
+ // Check if any information is contained in subunit field
+ return idParts[2].trim();
+ }
+
+
+ /**
+ * Check if ID contains a sub model
+ */
+ public boolean hasSubModel() {
+ // Split ID by ':' token
+ String[] idParts = id.split(":");
+
+ // Check if subunit is defined
+ if (idParts.length < 4) return false;
+
+ // Check if any information is contained in subunit field
+ return (idParts[3].trim().length() > 0);
+ }
+
+
+ /**
+ * Get the sub model of the ID field
+ */
+ public String getSubModel() {
+ // Split ID by ':' token
+ String[] idParts = id.split(":");
+
+ // Check if subunit is defined
+ if (idParts.length < 4) return null;
+
+ // Check if any information is contained in subunit field
+ return idParts[3].trim();
+ }
+
+
+ /**
+ * Check if ID contains a version
+ */
+ public boolean hasVersion() {
+ // Split ID by ':' token
+ String[] idParts = id.split(":");
+
+ // Check if subunit is defined
+ if (idParts.length < 5) return false;
+
+ // Check if any information is contained in subunit field
+ return (idParts[4].trim().length() > 0);
+ }
+
+
+ /**
+ * Get AAS version
+ */
+ public String getVersion() {
+ // Split ID by ':' token
+ String[] idParts = id.split(":");
+
+ // Check if subunit is defined
+ if (idParts.length < 5) return null;
+
+ // Check if any information is contained in subunit field
+ return idParts[4].trim();
+ }
+
+
+ /**
+ * Check if ID contains a revision
+ */
+ public boolean hasRevision() {
+ // Split ID by ':' token
+ String[] idParts = id.split(":");
+
+ // Check if subunit is defined
+ if (idParts.length < 6) return false;
+
+ // Check if any information is contained in subunit field
+ return (idParts[5].trim().length() > 0);
+ }
+
+
+ /**
+ * Get AAS revision
+ */
+ public String getRevision() {
+ // Split ID by ':' token
+ String[] idParts = id.split(":");
+
+ // Check if subunit is defined
+ if (idParts.length < 6) return null;
+
+ // Check if any information is contained in subunit field
+ return idParts[5].trim();
+ }
+
+
+ /**
+ * Check if ID contains an element ID
+ */
+ public boolean hasElementID() {
+ // Split ID by ':' token
+ String[] idParts = id.split(":");
+
+ // Check if subunit is defined
+ if (idParts.length < 7) return false;
+
+ // Remove element instance if an instance is defined
+ if (idParts[6].indexOf('#') > -1) idParts[6]=idParts[6].substring(0, idParts[6].indexOf('#'));
+ // Check if any information is contained in subunit field
+ return (idParts[6].trim().length() > 0);
+ }
+
+
+ /**
+ * Get element ID
+ */
+ public String getElementID() {
+ // Split ID by ':' token
+ String[] idParts = id.split(":");
+
+ // Check if subunit is defined
+ if (idParts.length < 7) return null;
+
+ // Remove element instance if an instance is defined
+ if (idParts[6].indexOf('#') > -1) idParts[6]=idParts[6].substring(0, idParts[6].indexOf('#'));
+ // Check if any information is contained in subunit field
+ return idParts[6].trim();
+ }
+
+
+ /**
+ * Check if ID contains an instance
+ */
+ public boolean hasElementInstance() {
+ // Split ID by ':' token
+ String[] idParts = id.split(":");
+
+ // Check if subunit is defined
+ if (idParts.length < 7) return false;
+
+ // Remove element instance if an instance is defined
+ if (idParts[6].indexOf('#') > -1) idParts[6]=idParts[6].substring(idParts[6].indexOf('#'));
+ // Check if any information is contained in subunit field
+ return (idParts[6].trim().length() > 0);
+ }
+
+
+ /**
+ * Get instance ID
+ */
+ public String getElementInstance() {
+ // Catch all exceptions
+ try {
+ // Split ID by ':' token
+ String[] idParts = id.split(":");
+
+ // Check if subunit is defined
+ if (idParts.length < 7) return null;
+
+ // Remove element instance if an instance is defined
+ if (idParts[6].indexOf('#') > -1) idParts[6]=idParts[6].substring(idParts[6].indexOf('#')+1);
+
+ // Check if any information is contained in subunit field
+ return idParts[6].trim();
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+
+ /**
+ * Get AAS content
+ */
+ public String getAASContent() {
+ return content;
+ }
+
+
+ /**
+ * Get AAS content type
+ */
+ public int getAASContentType() {
+ return contentType;
+ }
+
+
+ /**
+ * Get AAS tags
+ */
+ public Collection<String> getAASTags() {
+ return tags;
+ }
+}
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/StaticCFGDirectoryServlet.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/StaticCFGDirectoryServlet.java
new file mode 100644
index 0000000..db4f329
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/StaticCFGDirectoryServlet.java
@@ -0,0 +1,453 @@
+package org.eclipse.basyx.sandbox.components.registry;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URLDecoder;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.basyx.sandbox.components.registry.exception.AASDirectoryProviderException;
+import org.eclipse.basyx.vab.protocol.http.server.BasysHTTPServlet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+
+/**
+ * Static configuration file based directory provider
+ *
+ * This directory provider provides a static directory. It therefore only supports get() operations.
+ * Modification of the directory via PUT/POST/PATCH/DELETE operations is not supported.
+ *
+ * @author kuhn
+ *
+ */
+public class StaticCFGDirectoryServlet extends BasysHTTPServlet {
+
+ /**
+ * Initiates a logger using the current class
+ */
+ private static final Logger logger = LoggerFactory.getLogger(StaticCFGDirectoryServlet.class);
+
+
+ /**
+ * Version information to identify the version of serialized instances
+ */
+ private static final long serialVersionUID = 1L;
+
+
+
+ /**
+ * Configuration properties (raw input from file)
+ */
+ protected Properties properties = null;
+
+
+ /**
+ * Asset administration shells by ID
+ */
+ protected Map<String, AASDirectoryEntry> aasByID = new HashMap<>();
+
+
+ /**
+ * Asset administration shells by tag
+ */
+ protected Map<String, Collection<AASDirectoryEntry>> aasByTag = new HashMap<>();
+
+
+ /**
+ * Uplink server
+ */
+ protected String uplink = null;
+
+
+ /**
+ * Downlink servers
+ */
+ protected Map<String, String> downlinks = new HashMap<>();
+
+
+
+
+
+ /**
+ * Constructor
+ */
+ public StaticCFGDirectoryServlet() {
+ // Invoke base constructor
+ super();
+ }
+
+ /**
+ * Adds init parameter to servlet
+ */
+ @Override
+ public String getInitParameter(String name) {
+
+ if (name.equals("config")) return "/WebContent/WEB-INF/config/directory/cfgdirectory/directory.properties";
+
+ return null;
+ }
+
+ /**
+ * Load a property
+ */
+ protected String extractProperty(Properties prop, String key) {
+ // Check if properties contain value
+ if (!prop.containsKey(key)) return null;
+
+ // Extract and remove value
+ String value = (String) prop.get(key);
+ prop.remove(key);
+
+ // Return value
+ return value;
+ }
+
+
+
+ /**
+ * Extract property keys with prefix and suffix. Prefix and suffix is removed from key.
+ */
+ protected Collection<String> getProperties(Properties prop, String prefix, String suffix) {
+ // Store result
+ HashSet<String> result = new HashSet<>();
+
+ // Iterate keys
+ for (String key: prop.stringPropertyNames()) {
+ if (key.startsWith(prefix) && key.endsWith(suffix)) result.add(key.substring(prefix.length(), key.length()-suffix.length()));
+ }
+
+ // Return result
+ return result;
+ }
+
+
+
+ /**
+ * Extract downlink servers
+ */
+ protected Map<String, String> extractDownlinks(Properties prop) {
+ // Return value
+ Map<String, String> result = new HashMap<>();
+
+ // Downlink server names
+ Collection<String> downlinkServerNames = getProperties(prop, "cfg.downlink.", ".pattern");
+
+ // Remove downlink pattern and server URL
+ for (String name: downlinkServerNames) {
+ // Get downlink pattern and server URL
+ result.put(prop.getProperty("cfg.downlink."+name+".pattern"), prop.getProperty("cfg.downlink."+name+".directory"));
+ // Remove pattern and directory properties
+ prop.remove("cfg.downlink."+name+".pattern");
+ prop.remove("cfg.downlink."+name+".directory");
+ }
+
+ // Return downlink server mappings
+ return result;
+ }
+
+
+
+ /**
+ * Extract Asset Administration Shell definitions
+ */
+ protected Map<String, AASDirectoryEntry> extractAAS(Properties prop) {
+ // Return value
+ Map<String, AASDirectoryEntry> result = new HashMap<>();
+
+ // Get AAS IDs
+ Collection<String> aasIDs = getProperties(prop, "", ".id");
+
+ // Create AAS directory entries from properties
+ for (String aasID : aasIDs) {
+ // Create AAS directory entry
+ AASDirectoryEntry entry = new AASDirectoryEntry(prop.getProperty(aasID+".id"), prop.getProperty(aasID+".aas"), prop.getProperty(aasID+".type"), prop.getProperty(aasID+".tags"));
+
+ // Add AAS directory entry
+ result.put(prop.getProperty(aasID+".id"), entry);
+ }
+
+ // Return ID to AAS mappings
+ return result;
+ }
+
+
+
+ /**
+ * Map AAS tags to AAS
+ */
+ protected Map<String, Collection<AASDirectoryEntry>> mapAASToTags(Map<String, AASDirectoryEntry> aasByID) {
+ // Return value
+ Map<String, Collection<AASDirectoryEntry>> result = new HashMap<>();
+
+ // Iterate AAS directory entries
+ for (AASDirectoryEntry dirEntry: aasByID.values()) {
+ // Process tags
+ for (String tag: dirEntry.getAASTags()) {
+ // Create tag if necessary
+ if (!result.containsKey(tag)) {result.put(tag, new HashSet<AASDirectoryEntry>());}
+
+ // Add AAS to tag
+ result.get(tag).add(dirEntry);
+ }
+ }
+
+ // Return HashTag to AAS mappings
+ return result;
+ }
+
+
+
+ /**
+ * Load properties from file
+ */
+ protected void loadProperties(String cfgFilePath) {
+ // Read property file
+ try {
+ // Open property file
+ InputStream input = getServletContext().getResourceAsStream(cfgFilePath);
+
+ // Instantiate property structure
+ properties = new Properties();
+ properties.load(input);
+
+ logger.debug("properties:"+properties);
+ logger.debug("properties (keys):"+properties.keySet());
+ logger.debug("properties (cfg.downlink.is.pattern):"+properties.get("cfg.downlink.is.pattern"));
+
+ // Process properties
+ // - Uplink server
+ uplink = extractProperty(properties, "cfg.uplink");
+ // - Downlink servers
+ downlinks = extractDownlinks(properties);
+ // - AAS by ID
+ aasByID = extractAAS(properties);
+ // - AAS by tag
+ aasByTag = mapAASToTags(aasByID);
+
+ logger.debug("Downlink:"+downlinks);
+ logger.debug("properties:"+properties);
+ logger.debug("aasbyID:"+aasByID);
+
+ } catch (IOException e) {
+ // Output exception
+ e.printStackTrace();
+ }
+ }
+
+
+
+ /**
+ * Initialize servlet
+ *
+ * @throws ServletException
+ */
+ @Override
+ public void init() throws ServletException {
+ // Call base implementation
+ super.init();
+
+ // Read configuration values
+ String configFilePath = getInitParameter("config");
+ // - Read property file
+ loadProperties(configFilePath);
+ }
+
+
+ /**
+ * Get AAS content from AASDirectoryEntry
+ */
+ protected String getAASContent(AASDirectoryEntry directoryEntry) {
+ // Process directory entry
+ switch (directoryEntry.getAASContentType()) {
+
+ // Local content type
+ case AASDirectoryEntry.AAS_CONTENTTYPE_LOCAL:
+ return directoryEntry.getAASContent();
+
+ // Remote content type
+ case AASDirectoryEntry.AAS_CONTENTTYPE_REMOTE:
+ throw new AASDirectoryProviderException("Unsupported AAS content type");
+
+ // Proxy content type - content is ID of AAS that contains the information
+ case AASDirectoryEntry.AAS_CONTENTTYPE_PROXY:
+ return getAASContentByID(directoryEntry.getAASContent());
+
+ // Unknown content type
+ default:
+ throw new AASDirectoryProviderException("Unknown AAS content type");
+ }
+ }
+
+
+
+ /**
+ * Get requested tags as collection
+ */
+ protected Collection<String> getTagsAsCollection(String tags) {
+ // Collection stores AAS tags
+ Collection<String> alltags = new HashSet<>();
+
+ // Catch null pointer exceptions
+ try {
+ // Get AAS tags
+ String[] splitTags = tags.split(",");
+
+ // Only add non-empty tags
+ for (String tag: splitTags) if (tag.trim().length() > 0) alltags.add(tag.trim());
+ } catch (NullPointerException e) {}
+
+ // Return all tags
+ return alltags;
+ }
+
+
+
+ /**
+ * Get a specific AAS content with ID
+ */
+ protected String getAASContentByID(String aasID) {
+ // Extract requested AAS ID
+ AASDirectoryEntry aas = aasByID.get(aasID);
+
+ // Null pointer check
+ if (aas == null)
+ return null;
+
+ // Return result
+ return getAASContent(aas);
+ }
+
+
+
+
+
+ /**
+ * Implement "Get" operation
+ *
+ * Process HTTP get request - get sub model property value
+ */
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ // Process request depending on the path and on parameter
+ String uri = req.getRequestURI();
+ String contextPath = req.getContextPath();
+ String path = URLDecoder.decode(uri.substring(contextPath.length()+1).substring(req.getServletPath().length()), "UTF-8"); // plus 1 for "/"
+
+ // Extract action parameter
+ Collection<String> alltags = getTagsAsCollection(req.getParameter("tags"));
+
+
+ // Setup HTML response header
+ resp.setContentType("application/json");
+ resp.setCharacterEncoding("UTF-8");
+
+
+ // Process get request
+ // - Get all (local) AAS
+ if (path.equals("api/v1/registry")) {
+ // Extract AAS directory entries
+ Collection<AASDirectoryEntry> entries = null;
+
+ // Check if tags are to be processed
+ if (alltags.isEmpty()) {
+ // Get all tags
+ entries = aasByID.values();
+ } else {
+ // HashSet that holds all elements
+ Set<AASDirectoryEntry> taggedEntries = new HashSet<>();
+
+ // Get tagged elements that have all requested tags
+ // - Get first requested tag
+ taggedEntries.addAll(aasByTag.get(alltags.iterator().next()));
+ // - Remove all directory entries that do not have all tags
+ for (String tag: alltags) taggedEntries.retainAll(aasByTag.get(tag));
+ // - Place remaining elements into entries collection
+ entries = taggedEntries;
+ }
+
+ // Build response string
+ StringBuilder response = new StringBuilder();
+ for (AASDirectoryEntry entry: entries) response.append(getAASContent(entry));
+
+ // Write result
+ sendResponse(response.toString(), resp.getWriter());
+ // End processing
+ return;
+ }
+ // Get a specific AAS
+ else if (path.startsWith("api/v1/registry/")) {
+ logger.debug("Getting:"+path);
+
+ // Get requested AAS with ID
+ String aas = getAASContentByID(path.substring(new String("api/v1/registry/").length()));
+
+ // Write result
+ sendResponse(aas, resp.getWriter());
+ // End processing
+ return;
+ } else {
+ // Send null response for unknown path
+ sendResponse(null, resp.getWriter());
+ return;
+ }
+ }
+
+
+
+ /**
+ * Implement "Put" operation
+ */
+ @Override
+ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ // Indicate an unsupported operation
+ resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, "Request not implemented for this service");
+ }
+
+
+
+ /**
+ * <pre>
+ * Handle HTTP POST operation. Creates a new Property, Operation, Event, Submodel or AAS or invokes an operation.
+ */
+ @Override
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ // Indicate an unsupported operation
+ resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, "Request not implemented for this service");
+ }
+
+
+
+ /**
+ * Handle a HTTP PATCH operation. Updates a map or collection respective to action string.
+ *
+ */
+ @Override
+ protected void doPatch(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ // Indicate an unsupported operation
+ resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, "Request not implemented for this service");
+ }
+
+
+
+ /**
+ * Implement "Delete" operation. Deletes any resource under the given path.
+ */
+ @Override
+ protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ // Indicate an unsupported operation
+ resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, "Request not implemented for this service");
+ }
+}
+
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/exception/AASDirectoryFormatException.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/exception/AASDirectoryFormatException.java
new file mode 100644
index 0000000..93e57a6
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/exception/AASDirectoryFormatException.java
@@ -0,0 +1,36 @@
+package org.eclipse.basyx.sandbox.components.registry.exception;
+
+
+
+
+/**
+ * Indicate a problem with the AAS directory format
+ *
+ * @author kuhn
+ *
+ */
+public class AASDirectoryFormatException extends RuntimeException {
+
+
+ /**
+ * Version number support for serialized instances
+ */
+ private static final long serialVersionUID = 1L;
+
+
+ /**
+ * Error message
+ */
+ protected String errorMessage = null;
+
+
+
+
+ /**
+ * Constructor
+ */
+ public AASDirectoryFormatException(String errorMsg) {
+ errorMessage = errorMsg;
+ }
+}
+
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/exception/AASDirectoryProviderException.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/exception/AASDirectoryProviderException.java
new file mode 100644
index 0000000..ade137b
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/exception/AASDirectoryProviderException.java
@@ -0,0 +1,36 @@
+package org.eclipse.basyx.sandbox.components.registry.exception;
+
+
+
+
+/**
+ * Indicate a problem with the AAS directory provider
+ *
+ * @author kuhn
+ *
+ */
+public class AASDirectoryProviderException extends RuntimeException {
+
+
+ /**
+ * Version number support for serialized instances
+ */
+ private static final long serialVersionUID = 1L;
+
+
+ /**
+ * Error message
+ */
+ protected String errorMessage = null;
+
+
+
+
+ /**
+ * Constructor
+ */
+ public AASDirectoryProviderException(String errorMsg) {
+ errorMessage = errorMsg;
+ }
+}
+
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLPreconfiguredSubModelProvider.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLPreconfiguredSubModelProvider.java
new file mode 100644
index 0000000..4360636
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLPreconfiguredSubModelProvider.java
@@ -0,0 +1,518 @@
+package org.eclipse.basyx.sandbox.components.sqlprovider;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.eclipse.basyx.components.provider.BaseConfiguredProvider;
+import org.eclipse.basyx.tools.sql.driver.SQLDriver;
+import org.eclipse.basyx.tools.sql.query.DynamicSQLQuery;
+import org.eclipse.basyx.tools.sql.query.DynamicSQLRunner;
+import org.eclipse.basyx.tools.sql.query.DynamicSQLUpdate;
+import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+
+/**
+ * Asset administration shell sub model provider that connects to SQL database
+ *
+ * @author kuhn
+ *
+ */
+public class SQLPreconfiguredSubModelProvider extends BaseConfiguredProvider {
+
+ /**
+ * Initiates a logger using the current class
+ */
+ private static final Logger logger = LoggerFactory.getLogger(SQLPreconfiguredSubModelProvider.class);
+
+ /**
+ * SQL database user name
+ */
+ protected String sqlUser = null;
+
+ /**
+ * SQL database password
+ */
+ protected String sqlPass = null;
+
+ /**
+ * SQL database path
+ */
+ protected String sqlURL = null;
+
+
+
+ /**
+ * SQL database driver
+ */
+ protected String sqlDriver = null;
+
+ /**
+ * SQL database query prefix
+ */
+ protected String sqlPrefix = null;
+
+
+
+ /**
+ * SQL property connections
+ */
+ protected Set<String> sqlPropertyConnections = new HashSet<>();
+
+
+ /**
+ * SQL operation connections
+ */
+ protected Set<String> sqlOperationConnections = new HashSet<>();
+
+
+
+ /**
+ * Run queries to access properties via 'get' operation
+ */
+ protected Map<String, DynamicSQLRunner> propertyGetQueries = new HashMap<>();
+
+
+ /**
+ * Run SQL update to access properties via 'set' operation
+ */
+ protected Map<String, DynamicSQLRunner> propertySetQueries = new HashMap<>();
+
+
+ /**
+ * Run SQL update to access properties via 'create' operation
+ */
+ protected Map<String, DynamicSQLRunner> propertyCreateQueries = new HashMap<>();
+
+
+ /**
+ * Run SQL update to access properties via 'delete' operation
+ */
+ protected Map<String, DynamicSQLRunner> propertyDeleteQueries = new HashMap<>();
+
+
+
+ /**
+ * SQL operations
+ */
+ protected Map<String, DynamicSQLRunner> operations = new HashMap<>();
+
+
+ /**
+ * SQL operations that run as update operations. Not contained operations are query operations.
+ */
+ protected Set<String> updateOperations = new HashSet<>();
+
+ /**
+ * An SQL driver instance to connect to the database
+ */
+ protected SQLDriver driver;
+
+
+ public static final String DBUSER = "dbuser";
+ public static final String DBPASS = "dbpass";
+ public static final String DBURL = "dburl";
+ public static final String DRIVER = "driver";
+ public static final String PREFIX = "prefix";
+ public static final String PROPERTIES = "properties";
+ public static final String OPERATIONS = "operations";
+
+
+ /**
+ * Constructor
+ */
+ public SQLPreconfiguredSubModelProvider(Properties cfgValues) {
+ // Call base constructor
+ super(cfgValues);
+
+ // Create sub model
+ submodelData = createSubModel(cfgValues);
+
+ // Load predefined elements from sub model
+
+ try {
+ setModelPropertyValue("", submodelData);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+
+ // Extract SQL properties
+ sqlUser = cfgValues.getProperty(buildSqlCfgName(DBUSER));
+ sqlPass = cfgValues.getProperty(buildSqlCfgName(DBPASS));
+ sqlURL = cfgValues.getProperty(buildSqlCfgName(DBURL));
+
+ // Extract SQL driver properties
+ sqlDriver = cfgValues.getProperty(buildSqlCfgName(DRIVER));
+ sqlPrefix = cfgValues.getProperty(buildSqlCfgName(PREFIX));
+
+ // Create a SQL driver instance
+ driver = new SQLDriver(sqlURL, sqlUser, sqlPass, sqlPrefix, sqlDriver);
+
+ // Load and parse SQL property and operation connections
+ sqlPropertyConnections.addAll(splitString(cfgValues.getProperty(buildSqlCfgName(PROPERTIES))));
+ sqlOperationConnections.addAll(splitString(cfgValues.getProperty(buildSqlCfgName(OPERATIONS))));
+
+
+
+ // Add properties
+ for (String propertyName: sqlPropertyConnections) createSQLProperty(propertyName, cfgValues);
+
+ /*
+ // Try to parse parameter
+ propertyGetQueries.put(propertyName, createSQLOperation(propertyName+".get", cfgValues));
+ propertySetQueries.put(propertyName, createSQLOperation(propertyName+".set", cfgValues));
+ propertyCreateQueries.put(propertyName, createSQLOperation(propertyName+".create", cfgValues));
+ propertyDeleteQueries.put(propertyName, createSQLOperation(propertyName+".delete", cfgValues));
+
+
+ Map<String, Object> mapAccessors = VABLambdaProviderHelper.createMap((Supplier<?>) () -> {
+ return propertyMap_val;
+ }, (Consumer<Map<String, Object>>) (map) -> {
+ propertyMap_val = map;
+ }, (BiConsumer<String, Object>) (key, value) -> {
+ propertyMap_val.put(key, value);
+ }, (Consumer<Object>) (o) -> {
+ propertyMap_val.remove(o);
+ });
+
+ }*/
+
+
+ // Add operations
+ //for (String operationName: sqlOperationConnections) createSQLOperation(operationName, cfgValues);
+ /*{
+ // Create operation
+ operations.put(operationName, createSQLOperation(operationName, cfgValues));
+ // Mark operation as update operation depending on operations/<operationName>_kind property value
+ try {
+ if (cfgValues.getProperty(operationName+"_kind").trim().equalsIgnoreCase("update")) {
+ updateOperations.add(operationName);
+ }
+ } catch (Exception e) {}
+ }*/
+ }
+
+
+
+ /**
+ * Create an SQL property
+ */
+ protected void createSQLProperty(String name, Properties cfgValues) {
+ // Create Map with lambdas that hold SQL operations
+ Map<String, Object> value = new HashMap<>();
+
+ // Get operation
+ {
+ // Get parameter
+ String queryString = cfgValues.getProperty(name+".get");
+ String resultFilterOp = cfgValues.getProperty(name+".get.result");
+
+ // Trim query string and resultFilterOp (remove '"' at beginning and end)
+ queryString = queryString.substring(1, queryString.length()-1);
+ try {resultFilterOp = resultFilterOp.substring(1, resultFilterOp.length()-1);} catch (NullPointerException | StringIndexOutOfBoundsException e) {}
+
+ // Create dynamic SQL query
+ value.put(VABLambdaHandler.VALUE_GET_SUFFIX, new DynamicSQLQuery(driver, queryString, resultFilterOp));
+ }
+
+ // Set operation
+ {
+ // Get parameter
+ String updateString = cfgValues.getProperty(name+".set");
+
+ // Trim query string and resultFilterOp (remove '"' at beginning and end)
+ updateString = updateString.substring(1, updateString.length()-1);
+
+ // Create dynamic SQL query
+ value.put(VABLambdaHandler.VALUE_SET_SUFFIX, new DynamicSQLUpdate(driver, updateString));
+ }
+
+ // Delete operation
+ {
+ // Get parameter
+ String updateString = cfgValues.getProperty(name+".delete");
+
+ // Trim query string and resultFilterOp (remove '"' at beginning and end)
+ updateString = updateString.substring(1, updateString.length()-1);
+
+ // Create dynamic SQL query
+ value.put(VABLambdaHandler.VALUE_REMOVEKEY_SUFFIX, new DynamicSQLUpdate(driver, updateString));
+ value.put(VABLambdaHandler.VALUE_REMOVEOBJ_SUFFIX, new DynamicSQLUpdate(driver, updateString));
+ }
+
+ // Create operation
+ {
+ // Get parameter
+ String updateString = cfgValues.getProperty(name+".create");
+
+ // Trim query string and resultFilterOp (remove '"' at beginning and end)
+ updateString = updateString.substring(1, updateString.length()-1);
+
+ // Create dynamic SQL query
+ value.put(VABLambdaHandler.VALUE_INSERT_SUFFIX, new DynamicSQLUpdate(driver, updateString));
+ }
+
+
+ logger.debug("Putting SQL:"+name);
+ // Add property as map of lambdas
+ submodelData.getProperties().put(name, createSubmodelElement(name, value, cfgValues));
+ }
+
+
+ /**
+ * Create a dynamic SQL operation
+ */
+ protected DynamicSQLRunner createSQLOperation(String propertyName, Properties cfgValues) {/*
+ // Check parameter presence
+ if (!cfgValues.containsKey(propertyName)) return null;
+
+ // Get parameter count and parameter count
+ int parameterCount = Integer.parseInt(cfgValues.getProperty(propertyName+".parameter"));
+ String queryString = cfgValues.getProperty(propertyName);
+ String resultFilterOp = cfgValues.getProperty(propertyName+".result");
+
+ // Trim query string and resultFilterOp (remove '"' at beginning and end)
+ queryString = queryString.substring(1, queryString.length()-1);
+ try {resultFilterOp = resultFilterOp.substring(1, resultFilterOp.length()-1);} catch (NullPointerException | StringIndexOutOfBoundsException e) {}
+
+ // Create dynamic SQL query
+ DynamicSQLRunner sqlQuery = new DynamicSQLRunner(sqlURL, sqlUser, sqlPass, sqlPrefix, sqlDriver, parameterCount, queryString, resultFilterOp);
+
+ // Return created query
+ return sqlQuery;*/
+
+ return null;
+ }
+
+
+ /**
+ * Split a whitespace delimited string
+ */
+ @Override
+ protected Collection<String> splitString(String input) {
+ // Return value
+ HashSet<String> result = new HashSet<>();
+
+ // Split string into segments
+ for (String inputStr: input.split(" ")) result.add(inputStr.trim());
+
+ // Return result
+ return result;
+ }
+
+
+ /**
+ * Create a key list for an SQL statement
+ *//*
+ protected String sqlCreateKeys(Collection<String> keys) {
+ // Return value builder
+ StringBuilder result = new StringBuilder();
+
+ // Process keys
+ // - Flag that handles the first key
+ boolean isFirst = true;
+ // - Process keys
+ for (String key: keys) {if (!isFirst) result.append(","); else isFirst=false; result.append(key);}
+
+ // Return string
+ return result.toString();
+ }*/
+
+
+ /**
+ * Extract a list of values from a map
+ *//*
+ protected String sqlCreateValues(Collection<Object> values) {
+ // Return value builder
+ StringBuilder result = new StringBuilder();
+
+ // Process keys
+ // - Flag that handles the first key
+ boolean isFirst = true;
+ // - Process keys
+ for (Object key: values) {if (!isFirst) result.append(","); else isFirst=false; result.append("'"+key+"'");}
+
+ // Return string
+ return result.toString();
+ }*/
+
+
+
+ /**
+ * Create (insert) a value into the SQL table
+ *//*
+ @Override @SuppressWarnings("unchecked")
+ public void createValue(String propertyName, Object arg1) throws Exception {
+ // Set query
+ DynamicSQLRunner query = propertyCreateQueries.get(propertyName);
+
+ // Null pointer check
+ if (query == null) return;
+
+ // Create parameter array
+ Object[] parameter = new Object[2];
+ parameter[0] = sqlCreateKeys(((Map<String, Object>) arg1).keySet());
+ parameter[1] = sqlCreateValues(((Map<String, Object>) arg1).values());
+
+ // Execute query and return result
+ query.runUpdate(parameter);
+ }*/
+
+
+
+ /**
+ * Delete a value from the SQL table
+ *//*
+ @Override
+ public void deleteValue(String arg0) throws Exception {
+ // This is not implemented
+ }*/
+
+
+
+ /**
+ * Delete a value from the SQL table
+ *//*
+ @Override @SuppressWarnings("unchecked")
+ public void deleteValue(String propertyName, Object arg1) throws Exception {
+ // Set query
+ DynamicSQLRunner query = propertyDeleteQueries.get(propertyName);
+
+ // Null pointer check
+ if (query == null) return;
+
+ // Cast argument to collection
+ Collection<Object> parameterList = (Collection<Object>) arg1;
+
+ // Create parameter array
+ Object[] parameter = new Object[parameterList.size()];
+ // - Copy parameter
+ int counter = 0; for (Object par: parameterList) parameter[counter++] = par;
+
+ // Execute query and return result
+ query.runUpdate(parameter);
+ }*/
+
+
+/*
+ @Override
+ public Map<String, IElementReference> getContainedElements(String arg0) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+
+ @Override
+ public String getElementScope(String arg0) {
+ logger.debug("GetScope:"+arg0);
+ // TODO Auto-generated method stub
+ return null;
+ }
+*/
+
+
+ /**
+ * Query the SQL database
+ *//*
+ @Override
+ public Object getModelPropertyValue(String propertyName) {
+ // Get query
+ DynamicSQLRunner query = propertyGetQueries.get(propertyName);
+
+ // Null pointer check
+ if (query == null) return null;
+
+ // Execute query and return result
+ return query.runQuery();
+ }*/
+
+
+
+ /**
+ * Invoke operation with given parameter list
+ *//*
+ @Override
+ public Object invokeOperation(String propertyName, Object[] parameter) throws Exception {
+ // Set query
+ DynamicSQLRunner query = operations.get(propertyName);
+
+ // Null pointer check
+ if (query == null) return null;
+
+ // Execute query and return result
+ if (updateOperations.contains(propertyName)) {
+ query.runUpdate(parameter);
+ return null;
+ } else {
+ return query.runQuery(parameter);
+ }
+ }*/
+
+
+
+ /**
+ * Invoke set operation with given parameter
+ *//*
+ @Override @SuppressWarnings("unchecked")
+ public void setModelPropertyValue(String propertyName, Object arg1) throws Exception {
+ // Set query
+ DynamicSQLRunner query = propertySetQueries.get(propertyName);
+
+ // Null pointer check
+ if (query == null) return;
+
+ logger.debug("LENC:"+arg1);
+
+ // Create parameter array
+ Object[] parameter = null;
+ // - Process collections
+ if (arg1 instanceof Collection) {
+ // Cast to collection
+ Collection<Object> parameterList = (Collection<Object>) arg1;
+
+ // Create parameter array and copy parameter
+ parameter = new Object[parameterList.size()];
+ int counter = 0; for (Object par: parameterList) parameter[counter++] = par;
+ } else {
+ // Create parameter array and copy parameter
+ parameter = new Object[1];
+ parameter[0] = arg1;
+ }
+
+
+ // Execute query and return result
+ query.runUpdate(parameter);
+ }*/
+
+
+
+ /**
+ * Invoke set operation with given parameter list
+ *//*
+ @Override
+ public void setModelPropertyValue(String propertyName, Object... parameter) throws Exception {
+ // Set query
+ DynamicSQLRunner query = propertySetQueries.get(propertyName);
+
+ // Null pointer check
+ if (query == null) return;
+
+ logger.debug("LEN:"+parameter.length);
+ logger.debug("LEN-0:"+parameter[0]);
+
+ // Execute query and return result
+ query.runUpdate(parameter);
+ }*/
+
+ public static String buildSqlCfgName(String valueName) {
+ return BaseConfiguredProvider.buildCfgName("basyx.sql", valueName);
+ }
+}
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLProviderTestOLD.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLProviderTestOLD.java
new file mode 100644
index 0000000..c2a5344
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLProviderTestOLD.java
@@ -0,0 +1,186 @@
+package org.eclipse.basyx.sandbox.components.sqlprovider;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.LinkedList;
+
+import org.eclipse.basyx.tools.sql.driver.ISQLDriver;
+import org.eclipse.basyx.tools.sql.driver.SQLDriver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SQLProviderTestOLD {
+
+ /**
+ * Initiates a logger using the current class
+ */
+ private static final Logger logger = LoggerFactory.getLogger(SQLProviderTestOLD.class);
+
+
+ /**
+ * Define a parameter tuple (name/type)
+ *
+ * @author kuhn
+ *
+ */
+ static class Parameter {
+ String name;
+ String type;
+
+
+ /**
+ * Constructor
+ *
+ * @param name Parameter name
+ * @param type Parameter type
+ */
+ Parameter(String name, String type) {
+ this.name = name;
+ this.type = type;
+ }
+
+
+ /**
+ * Return parameter name
+ *
+ * @return parameter name
+ */
+ public String getName() {
+ return name;
+ }
+
+
+ /**
+ * Return parameter type
+ *
+ * @return parameter type
+ */
+ public String getType() {
+ return type;
+ }
+ }
+
+
+
+
+ /**
+ * Get operation name of operation definition
+ *
+ * @param opDef The operation definition string
+ * @return Operation name
+ */
+ public static String getOperation(String opDef) {
+ // Get operation name
+ return opDef.substring(0, opDef.indexOf("("));
+ }
+
+
+
+ /**
+ * Get parameter list of an operation definition
+ *
+ * A parameter list contains of a name and of a type for each parameter+
+ *
+ * @param opDef The operation definition string
+ * @return Collection of Parameter definitions
+ */
+ public static Collection<Parameter> getParameter(String opDef) {
+ // Return type
+ LinkedList<Parameter> result = new LinkedList<>();
+
+ // Extract parameter sequence
+ String callParameterStr = opDef.substring(opDef.indexOf("(")+1, opDef.length()-1);
+ String[] callParameterList = callParameterStr.split(",");
+
+ // Iterate all parameter. If no parameter is given, the loop will execute once with an empty String (length = 0)
+ for (String parameterDef: callParameterList) {
+ // Only process strings with a length > 0
+ if (parameterDef.length() == 0) continue;
+
+ // Add parameter
+ result.add(new Parameter(parameterDef.substring(0, parameterDef.indexOf(":")).trim(), parameterDef.substring(parameterDef.indexOf(":")+1).trim().toLowerCase()));
+ }
+
+ // Return result
+ return result;
+ }
+
+
+
+ /**
+ * Create a SQL string from an input SQL string with place holders in format $x with x being an integer number.
+ *
+ * @param baseString SQL string with place holders
+ * @param parameter Parameter values that place holders are substituted for
+ *
+ * @return SQL string with parameter instead of place holders
+ */
+ public static String getSQLString(String baseString, Collection<String> parameter) {
+ // Resulting SQL String
+ String result = baseString;
+
+ // Replace place holders with parameter
+ // - Counter variable
+ int counter = 1;
+ // - Replace all place holders
+ for (String par: parameter) {
+ result = result.replace("$"+counter, par);
+ counter++;
+ }
+
+ // Return SQL string with resolved parameter
+ return result;
+ }
+
+
+
+ public static void main(String[] args) throws SQLException {
+ logger.debug("Test");
+
+ ISQLDriver sqlDriver = new SQLDriver("localhost:5432/basyx-sample-vibrations", "postgres", "admin", "jdbc:postgresql://", "org.postgresql.Driver");
+
+
+
+ Collection<String> sqlQuery1Params = new LinkedList<>();
+ sqlQuery1Params.add(Integer.valueOf(1).toString());
+ String sqlQuery1String = getSQLString("SELECT * FROM vibrations.sensors WHERE vibrations.sensors.sensorid='$1'", sqlQuery1Params);
+
+ ResultSet result1 = sqlDriver.sqlQuery(sqlQuery1String);
+
+ logger.debug(""+result1);
+ logger.debug(""+result1.next());
+ logger.debug("ID : "+result1.getString("sensorid"));
+ logger.debug("NAME : "+result1.getString("sensorname"));
+ logger.debug(""+result1.next());
+
+
+
+ Collection<String> sqlQuery2Params = new LinkedList<>();
+ sqlQuery2Params.add("vibrations.sensors.sensorid");
+ sqlQuery2Params.add(Integer.valueOf(1).toString());
+ String sqlQuery2String = getSQLString("SELECT * FROM vibrations.sensors WHERE $1='$2'", sqlQuery2Params);
+
+ ResultSet result2 = sqlDriver.sqlQuery(sqlQuery2String);
+
+ logger.debug(""+result2);
+ logger.debug(""+result2.next());
+ logger.debug("ID : "+result2.getString("sensorid"));
+ logger.debug("NAME : "+result2.getString("sensorname"));
+ logger.debug(""+result2.next());
+
+
+
+ String call1 = "MapString()";
+
+ logger.debug("- "+getOperation(call1));
+ logger.debug("- "+getParameter(call1));
+
+
+ String call2 = "MapArray(sensorid:int, sensorname:String)";
+
+ logger.debug("- "+getOperation(call2));
+ logger.debug("- "+getParameter(call2));
+
+ }
+}
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLSubModelProvider.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLSubModelProvider.java
new file mode 100644
index 0000000..38914d3
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLSubModelProvider.java
@@ -0,0 +1,512 @@
+package org.eclipse.basyx.sandbox.components.sqlprovider;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.eclipse.basyx.components.provider.BaseConfiguredProvider;
+import org.eclipse.basyx.tools.sql.driver.SQLDriver;
+import org.eclipse.basyx.tools.sql.query.DynamicSQLQuery;
+import org.eclipse.basyx.tools.sql.query.DynamicSQLRunner;
+import org.eclipse.basyx.tools.sql.query.DynamicSQLUpdate;
+import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+
+/**
+ * Asset administration shell sub model provider that connects to SQL database
+ *
+ * @author kuhn
+ *
+ */
+public class SQLSubModelProvider extends BaseConfiguredProvider {
+
+ /**
+ * Initiates a logger using the current class
+ */
+ private static final Logger logger = LoggerFactory.getLogger(SQLSubModelProvider.class);
+
+ /**
+ * SQL database user name
+ */
+ protected String sqlUser = null;
+
+ /**
+ * SQL database password
+ */
+ protected String sqlPass = null;
+
+ /**
+ * SQL database path
+ */
+ protected String sqlURL = null;
+
+
+
+ /**
+ * SQL database driver
+ */
+ protected String sqlDriver = null;
+
+ /**
+ * SQL database query prefix
+ */
+ protected String sqlPrefix = null;
+
+ /**
+ * An SQL driver instance to connect to the database
+ */
+ protected SQLDriver driver;
+
+
+ /**
+ * SQL property connections
+ */
+ protected Set<String> sqlPropertyConnections = new HashSet<>();
+
+
+ /**
+ * SQL operation connections
+ */
+ protected Set<String> sqlOperationConnections = new HashSet<>();
+
+
+
+ /**
+ * Run queries to access properties via 'get' operation
+ */
+ protected Map<String, DynamicSQLRunner> propertyGetQueries = new HashMap<>();
+
+
+ /**
+ * Run SQL update to access properties via 'set' operation
+ */
+ protected Map<String, DynamicSQLRunner> propertySetQueries = new HashMap<>();
+
+
+ /**
+ * Run SQL update to access properties via 'create' operation
+ */
+ protected Map<String, DynamicSQLRunner> propertyCreateQueries = new HashMap<>();
+
+
+ /**
+ * Run SQL update to access properties via 'delete' operation
+ */
+ protected Map<String, DynamicSQLRunner> propertyDeleteQueries = new HashMap<>();
+
+
+
+ /**
+ * SQL operations
+ */
+ protected Map<String, DynamicSQLRunner> operations = new HashMap<>();
+
+
+ /**
+ * SQL operations that run as update operations. Not contained operations are query operations.
+ */
+ protected Set<String> updateOperations = new HashSet<>();
+
+
+
+
+ /**
+ * Constructor
+ */
+ public SQLSubModelProvider(Properties cfgValues) {
+ // Call base constructor
+ super(cfgValues);
+
+ // Create sub model
+ submodelData = createSubModel(cfgValues);
+
+ // Load predefined elements from sub model
+ try {
+ setModelPropertyValue("", submodelData);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+
+ // Extract SQL properties
+ sqlUser = cfgValues.getProperty(
+ SQLPreconfiguredSubModelProvider.buildSqlCfgName(SQLPreconfiguredSubModelProvider.DBUSER));
+ sqlPass = cfgValues.getProperty(
+ SQLPreconfiguredSubModelProvider.buildSqlCfgName(SQLPreconfiguredSubModelProvider.DBPASS));
+ sqlURL = cfgValues.getProperty(
+ SQLPreconfiguredSubModelProvider.buildSqlCfgName(SQLPreconfiguredSubModelProvider.DBURL));
+
+ // Extract SQL driver properties
+ sqlDriver = cfgValues.getProperty(
+ SQLPreconfiguredSubModelProvider.buildSqlCfgName(SQLPreconfiguredSubModelProvider.DRIVER));
+ sqlPrefix = cfgValues.getProperty(
+ SQLPreconfiguredSubModelProvider.buildSqlCfgName(SQLPreconfiguredSubModelProvider.PREFIX));
+
+ // Create a SQL driver instance
+ driver = new SQLDriver(sqlURL, sqlUser, sqlPass, sqlPrefix, sqlDriver);
+
+ // Load and parse SQL property and operation connections
+ sqlPropertyConnections.addAll(splitString(cfgValues.getProperty(
+ SQLPreconfiguredSubModelProvider.buildSqlCfgName(SQLPreconfiguredSubModelProvider.PROPERTIES))));
+ sqlOperationConnections.addAll(splitString(cfgValues.getProperty(
+ SQLPreconfiguredSubModelProvider.buildSqlCfgName(SQLPreconfiguredSubModelProvider.OPERATIONS))));
+
+
+
+ // Add properties
+ for (String propertyName: sqlPropertyConnections) createSQLProperty(propertyName, cfgValues);
+
+ /*
+ // Try to parse parameter
+ propertyGetQueries.put(propertyName, createSQLOperation(propertyName+".get", cfgValues));
+ propertySetQueries.put(propertyName, createSQLOperation(propertyName+".set", cfgValues));
+ propertyCreateQueries.put(propertyName, createSQLOperation(propertyName+".create", cfgValues));
+ propertyDeleteQueries.put(propertyName, createSQLOperation(propertyName+".delete", cfgValues));
+
+
+ Map<String, Object> mapAccessors = VABLambdaProviderHelper.createMap((Supplier<?>) () -> {
+ return propertyMap_val;
+ }, (Consumer<Map<String, Object>>) (map) -> {
+ propertyMap_val = map;
+ }, (BiConsumer<String, Object>) (key, value) -> {
+ propertyMap_val.put(key, value);
+ }, (Consumer<Object>) (o) -> {
+ propertyMap_val.remove(o);
+ });
+
+ }*/
+
+
+ // Add operations
+ //for (String operationName: sqlOperationConnections) createSQLOperation(operationName, cfgValues);
+ /*{
+ // Create operation
+ operations.put(operationName, createSQLOperation(operationName, cfgValues));
+ // Mark operation as update operation depending on operations/<operationName>_kind property value
+ try {
+ if (cfgValues.getProperty(operationName+"_kind").trim().equalsIgnoreCase("update")) {
+ updateOperations.add(operationName);
+ }
+ } catch (Exception e) {}
+ }*/
+ }
+
+
+
+ /**
+ * Create an SQL property
+ */
+ protected void createSQLProperty(String name, Properties cfgValues) {
+ // Create Map with lambdas that hold SQL operations
+ Map<String, Object> value = new HashMap<>();
+
+ // Get operation
+ {
+ // Get parameter
+ String queryString = cfgValues.getProperty(name+".get");
+ String resultFilterOp = cfgValues.getProperty(name+".get.result");
+
+ // Trim query string and resultFilterOp (remove '"' at beginning and end)
+ queryString = queryString.substring(1, queryString.length()-1);
+ try {resultFilterOp = resultFilterOp.substring(1, resultFilterOp.length()-1);} catch (NullPointerException | StringIndexOutOfBoundsException e) {}
+
+ // Create dynamic SQL query
+ value.put(VABLambdaHandler.VALUE_GET_SUFFIX, new DynamicSQLQuery(driver, queryString, resultFilterOp));
+ }
+
+ // Set operation
+ {
+ // Get parameter
+ String updateString = cfgValues.getProperty(name+".set");
+
+ // Trim query string and resultFilterOp (remove '"' at beginning and end)
+ updateString = updateString.substring(1, updateString.length()-1);
+
+ // Create dynamic SQL query
+ value.put(VABLambdaHandler.VALUE_SET_SUFFIX, new DynamicSQLUpdate(driver, updateString));
+ }
+
+ // Delete operation
+ {
+ // Get parameter
+ String updateString = cfgValues.getProperty(name+".delete");
+
+ // Trim query string and resultFilterOp (remove '"' at beginning and end)
+ updateString = updateString.substring(1, updateString.length()-1);
+
+ // Create dynamic SQL query
+ value.put(VABLambdaHandler.VALUE_REMOVEKEY_SUFFIX, new DynamicSQLUpdate(driver, updateString));
+ value.put(VABLambdaHandler.VALUE_REMOVEOBJ_SUFFIX, new DynamicSQLUpdate(driver, updateString));
+ }
+
+ // Create operation
+ {
+ // Get parameter
+ String updateString = cfgValues.getProperty(name+".create");
+
+ // Trim query string and resultFilterOp (remove '"' at beginning and end)
+ updateString = updateString.substring(1, updateString.length()-1);
+
+ // Create dynamic SQL query
+ value.put(VABLambdaHandler.VALUE_INSERT_SUFFIX, new DynamicSQLUpdate(driver, updateString));
+ }
+
+
+ logger.debug("Putting SQL:"+name);
+ // Add property as map of lambdas
+ submodelData.getProperties().put(name, createSubmodelElement(name, value, cfgValues));
+ }
+
+
+ /**
+ * Create a dynamic SQL operation
+ */
+ protected DynamicSQLRunner createSQLOperation(String propertyName, Properties cfgValues) {/*
+ // Check parameter presence
+ if (!cfgValues.containsKey(propertyName)) return null;
+
+ // Get parameter count and parameter count
+ int parameterCount = Integer.parseInt(cfgValues.getProperty(propertyName+".parameter"));
+ String queryString = cfgValues.getProperty(propertyName);
+ String resultFilterOp = cfgValues.getProperty(propertyName+".result");
+
+ // Trim query string and resultFilterOp (remove '"' at beginning and end)
+ queryString = queryString.substring(1, queryString.length()-1);
+ try {resultFilterOp = resultFilterOp.substring(1, resultFilterOp.length()-1);} catch (NullPointerException | StringIndexOutOfBoundsException e) {}
+
+ // Create dynamic SQL query
+ DynamicSQLRunner sqlQuery = new DynamicSQLRunner(sqlURL, sqlUser, sqlPass, sqlPrefix, sqlDriver, parameterCount, queryString, resultFilterOp);
+
+ // Return created query
+ return sqlQuery;*/
+
+ return null;
+ }
+
+
+ /**
+ * Split a whitespace delimited string
+ */
+ @Override
+ protected Collection<String> splitString(String input) {
+ // Return value
+ HashSet<String> result = new HashSet<>();
+
+ // Split string into segments
+ for (String inputStr: input.split(" ")) result.add(inputStr.trim());
+
+ // Return result
+ return result;
+ }
+
+
+ /**
+ * Create a key list for an SQL statement
+ *//*
+ protected String sqlCreateKeys(Collection<String> keys) {
+ // Return value builder
+ StringBuilder result = new StringBuilder();
+
+ // Process keys
+ // - Flag that handles the first key
+ boolean isFirst = true;
+ // - Process keys
+ for (String key: keys) {if (!isFirst) result.append(","); else isFirst=false; result.append(key);}
+
+ // Return string
+ return result.toString();
+ }*/
+
+
+ /**
+ * Extract a list of values from a map
+ *//*
+ protected String sqlCreateValues(Collection<Object> values) {
+ // Return value builder
+ StringBuilder result = new StringBuilder();
+
+ // Process keys
+ // - Flag that handles the first key
+ boolean isFirst = true;
+ // - Process keys
+ for (Object key: values) {if (!isFirst) result.append(","); else isFirst=false; result.append("'"+key+"'");}
+
+ // Return string
+ return result.toString();
+ }*/
+
+
+
+ /**
+ * Create (insert) a value into the SQL table
+ *//*
+ @Override @SuppressWarnings("unchecked")
+ public void createValue(String propertyName, Object arg1) throws Exception {
+ // Set query
+ DynamicSQLRunner query = propertyCreateQueries.get(propertyName);
+
+ // Null pointer check
+ if (query == null) return;
+
+ // Create parameter array
+ Object[] parameter = new Object[2];
+ parameter[0] = sqlCreateKeys(((Map<String, Object>) arg1).keySet());
+ parameter[1] = sqlCreateValues(((Map<String, Object>) arg1).values());
+
+ // Execute query and return result
+ query.runUpdate(parameter);
+ }*/
+
+
+
+ /**
+ * Delete a value from the SQL table
+ *//*
+ @Override
+ public void deleteValue(String arg0) throws Exception {
+ // This is not implemented
+ }*/
+
+
+
+ /**
+ * Delete a value from the SQL table
+ *//*
+ @Override @SuppressWarnings("unchecked")
+ public void deleteValue(String propertyName, Object arg1) throws Exception {
+ // Set query
+ DynamicSQLRunner query = propertyDeleteQueries.get(propertyName);
+
+ // Null pointer check
+ if (query == null) return;
+
+ // Cast argument to collection
+ Collection<Object> parameterList = (Collection<Object>) arg1;
+
+ // Create parameter array
+ Object[] parameter = new Object[parameterList.size()];
+ // - Copy parameter
+ int counter = 0; for (Object par: parameterList) parameter[counter++] = par;
+
+ // Execute query and return result
+ query.runUpdate(parameter);
+ }*/
+
+
+/*
+ @Override
+ public Map<String, IElementReference> getContainedElements(String arg0) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+
+ @Override
+ public String getElementScope(String arg0) {
+ logger.debug("GetScope:"+arg0);
+ // TODO Auto-generated method stub
+ return null;
+ }
+*/
+
+
+ /**
+ * Query the SQL database
+ *//*
+ @Override
+ public Object getModelPropertyValue(String propertyName) {
+ // Get query
+ DynamicSQLRunner query = propertyGetQueries.get(propertyName);
+
+ // Null pointer check
+ if (query == null) return null;
+
+ // Execute query and return result
+ return query.runQuery();
+ }*/
+
+
+
+ /**
+ * Invoke operation with given parameter list
+ *//*
+ @Override
+ public Object invokeOperation(String propertyName, Object[] parameter) throws Exception {
+ // Set query
+ DynamicSQLRunner query = operations.get(propertyName);
+
+ // Null pointer check
+ if (query == null) return null;
+
+ // Execute query and return result
+ if (updateOperations.contains(propertyName)) {
+ query.runUpdate(parameter);
+ return null;
+ } else {
+ return query.runQuery(parameter);
+ }
+ }*/
+
+
+
+ /**
+ * Invoke set operation with given parameter
+ *//*
+ @Override @SuppressWarnings("unchecked")
+ public void setModelPropertyValue(String propertyName, Object arg1) throws Exception {
+ // Set query
+ DynamicSQLRunner query = propertySetQueries.get(propertyName);
+
+ // Null pointer check
+ if (query == null) return;
+
+ logger.debug("LENC:"+arg1);
+
+ // Create parameter array
+ Object[] parameter = null;
+ // - Process collections
+ if (arg1 instanceof Collection) {
+ // Cast to collection
+ Collection<Object> parameterList = (Collection<Object>) arg1;
+
+ // Create parameter array and copy parameter
+ parameter = new Object[parameterList.size()];
+ int counter = 0; for (Object par: parameterList) parameter[counter++] = par;
+ } else {
+ // Create parameter array and copy parameter
+ parameter = new Object[1];
+ parameter[0] = arg1;
+ }
+
+
+ // Execute query and return result
+ query.runUpdate(parameter);
+ }*/
+
+
+
+ /**
+ * Invoke set operation with given parameter list
+ *//*
+ @Override
+ public void setModelPropertyValue(String propertyName, Object... parameter) throws Exception {
+ // Set query
+ DynamicSQLRunner query = propertySetQueries.get(propertyName);
+
+ // Null pointer check
+ if (query == null) return;
+
+ logger.debug("LEN:"+parameter.length);
+ logger.debug("LEN-0:"+parameter[0]);
+
+ // Execute query and return result
+ query.runUpdate(parameter);
+ }*/
+}
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/servlet/SQLSubModelProviderServlet.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/servlet/SQLSubModelProviderServlet.java
new file mode 100644
index 0000000..7ee2fab
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/servlet/SQLSubModelProviderServlet.java
@@ -0,0 +1,79 @@
+package org.eclipse.basyx.sandbox.components.sqlprovider.servlet;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+import javax.servlet.ServletException;
+
+import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
+import org.eclipse.basyx.components.provider.BaseConfiguredProvider;
+import org.eclipse.basyx.sandbox.components.sqlprovider.SQLPreconfiguredSubModelProvider;
+import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
+
+/**
+ * Servlet interface for SQL sub model provider
+ *
+ * @author kuhn
+ *
+ */
+public class SQLSubModelProviderServlet extends VABHTTPInterface<VABMultiSubmodelProvider> {
+
+ /**
+ * Version information to identify the version of serialized instances
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Sub model ID
+ */
+ protected String submodelID = null;
+
+ /**
+ * Configuration properties
+ */
+ protected Properties cfgProperties = null;
+
+ /**
+ * Constructor
+ */
+ public SQLSubModelProviderServlet() {
+ // Invoke base constructor
+ super(new VABMultiSubmodelProvider());
+ }
+
+ /**
+ * Initialize servlet
+ *
+ * @throws ServletException
+ */
+ public void init() throws ServletException {
+ // Call base implementation
+ super.init();
+
+ // Read configuration values
+ String configFilePath = (String) getInitParameter("config");
+
+ // Read property file
+ try {
+ // Open property file
+ InputStream input = getServletContext().getResourceAsStream(configFilePath);
+
+ // Instantiate property structure
+ cfgProperties = new Properties();
+ cfgProperties.load(input);
+
+ // Extract sub model provider properties
+ this.submodelID = cfgProperties.getProperty(BaseConfiguredProvider.buildBasyxCfgName(BaseConfiguredProvider.SUBMODELID));
+
+ } catch (IOException e) {
+ // Output exception
+ e.printStackTrace();
+ }
+
+ // Instantiate and add sub model provider
+ SQLPreconfiguredSubModelProvider sqlSMProvider = new SQLPreconfiguredSubModelProvider(cfgProperties);
+ // - Add sub model provider
+ this.getModelProvider().addSubmodel(submodelID, sqlSMProvider);
+ }
+}
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/xmlxqueryprovider/OperationNotImplementedException.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/xmlxqueryprovider/OperationNotImplementedException.java
index 8cae16a..1ee8d3b 100644
--- a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/xmlxqueryprovider/OperationNotImplementedException.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/xmlxqueryprovider/OperationNotImplementedException.java
@@ -1,6 +1,6 @@
package org.eclipse.basyx.sandbox.components.xmlxqueryprovider;
-
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
/**
* Exception that indicates that a requested operation is not implemented
@@ -8,9 +8,13 @@
* @author kuhn
*
*/
-public class OperationNotImplementedException extends RuntimeException {
+public class OperationNotImplementedException extends ProviderException {
+ public OperationNotImplementedException() {
+ super("Operation not implemented");
+ }
+
/**
* Version of serialized instances
*/
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/xmlxqueryprovider/XMLXQuerySubModelProvider.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/xmlxqueryprovider/XMLXQuerySubModelProvider.java
index 37be45b..1b6e539 100644
--- a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/xmlxqueryprovider/XMLXQuerySubModelProvider.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/xmlxqueryprovider/XMLXQuerySubModelProvider.java
@@ -261,7 +261,7 @@
* Create (insert) a value into the SQL table
*/
@Override
- public void createValue(String propertyName, Object arg1) throws Exception {
+ public void createValue(String propertyName, Object arg1) {
// Indicate exception
throw new OperationNotImplementedException();
}
@@ -272,7 +272,7 @@
* Delete a value from the SQL table
*/
@Override
- public void deleteValue(String arg0) throws Exception {
+ public void deleteValue(String arg0) {
// Indicate exception
throw new OperationNotImplementedException();
}
@@ -283,7 +283,7 @@
* Delete a value from the SQL table
*/
@Override
- public void deleteValue(String propertyName, Object arg1) throws Exception {
+ public void deleteValue(String propertyName, Object arg1) {
// Indicate exception
throw new OperationNotImplementedException();
}
@@ -313,7 +313,7 @@
* Invoke operation with given parameter list
*/
@Override
- public Object invokeOperation(String propertyName, Object... parameter) throws Exception {
+ public Object invokeOperation(String propertyName, Object... parameter) {
// Indicate exception
throw new OperationNotImplementedException();
}
@@ -324,7 +324,7 @@
* Invoke set operation with given parameter
*/
@Override
- public void setModelPropertyValue(String propertyName, Object arg1) throws Exception {
+ public void setModelPropertyValue(String propertyName, Object arg1) {
// Indicate exception
throw new OperationNotImplementedException();
}
@@ -334,7 +334,7 @@
/**
* Invoke set operation with given parameter list
*/
- public void setModelPropertyValue(String propertyName, Object... parameter) throws Exception {
+ public void setModelPropertyValue(String propertyName, Object... parameter) {
// Indicate exception
throw new OperationNotImplementedException();
}
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/models/manufacturing/process/product/ProductQualitySubmodel.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/models/manufacturing/process/product/ProductQualitySubmodel.java
index 3631953..ae787c6 100644
--- a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/models/manufacturing/process/product/ProductQualitySubmodel.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/models/manufacturing/process/product/ProductQualitySubmodel.java
@@ -36,7 +36,7 @@
this.setIdShort(id);
// Add quality data property
- getDataElements().put("qualityData", new Property(qualityData));
+ getProperties().put("qualityData", new Property(qualityData));
// Add access operations for quality data
// - Add a quality data entry
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/code/BaSyxCreateProvideUseExampleAASSubmodel.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/code/BaSyxCreateProvideUseExampleAASSubmodel.java
new file mode 100644
index 0000000..9ca9e9d
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/code/BaSyxCreateProvideUseExampleAASSubmodel.java
@@ -0,0 +1,66 @@
+package org.eclipse.basyx.examples.snippets.undoc.aas.code;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Map;
+
+import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.restapi.SubModelProvider;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
+import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
+import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnector;
+import org.eclipse.basyx.vab.protocol.basyx.server.BaSyxTCPServer;
+import org.junit.Test;
+
+/**
+ * Illustrate manual creation and providing of AAS sub model
+ *
+ * @author kuhn
+ *
+ */
+public class BaSyxCreateProvideUseExampleAASSubmodel {
+
+
+ /**
+ * Create, export, and access an example AAS sub model
+ */
+ @SuppressWarnings("unchecked")
+ @Test
+ public void createExportAndAccessSubModel() throws Exception {
+
+ // Create sub model and add properties
+ SubModel statusSM = new SubModel();
+ // - Property status: indicate device status
+ Property statusProp = new Property("offline");
+ statusProp.setIdShort("status");
+ statusSM.addSubModelElement(statusProp);
+ // - Property statistics: export invocation statistics for every service
+ // - invocations: indicate total service invocations. Properties are not persisted in this example,
+ // therefore we start counting always at 0.
+ Property invocationsProp = new Property(0);
+ invocationsProp.setIdShort("invocations");
+ statusSM.addSubModelElement(invocationsProp);
+
+
+ // Provide sub model via BaSyx server
+ BaSyxTCPServer<SubModelProvider> server = new BaSyxTCPServer<>(new SubModelProvider(statusSM), 9998);
+ // - Start local BaSyx/TCP server
+ server.start();
+
+
+ // Access BaSyx TCP server
+ // - Create BaSyx connector to connect with the sub model
+ BaSyxConnector basyxConnector = new BaSyxConnector("localhost", 9998);
+ // - Create connection to device manager
+ JSONConnector toDeviceManager = new JSONConnector(basyxConnector);
+ // - Access sub model property, check value
+ Map<String, Object> property = (Map<String, Object>) toDeviceManager
+ .getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/status");
+ assertEquals("offline", property.get("value"));
+
+
+ // Stop local BaSyx/TCP server
+ server.stop();
+ }
+}
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnection.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnection.java
new file mode 100644
index 0000000..10a4bb7
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnection.java
@@ -0,0 +1,142 @@
+package org.eclipse.basyx.examples.snippets.undoc.aas.connection.servlet;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.Map;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.components.servlet.submodel.SubmodelServlet;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_Empty;
+import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
+import org.eclipse.basyx.examples.support.directory.ExampleAASRegistry;
+import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
+import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+/**
+ * Export sub model through a servlet and connect to that servlet
+ *
+ * @author kuhn
+ *
+ */
+public class AASServletConnection {
+
+
+ /**
+ * Example sub model. This example sub model is created with the BaSyx SDK factory and defines the AAS meta model properties
+ */
+ static class SampleSubModelFactory extends SubModel {
+ /**
+ * Constructor - create sub model property
+ */
+ @SuppressWarnings("unchecked")
+ public SampleSubModelFactory() {
+ // Set sub model ID
+ setIdShort("sm-001");
+
+ // Add example properties
+ // - Add simple property
+ Property prop1 = new Property(234);
+ prop1.setIdShort("prop1");
+ addSubModelElement(prop1);
+
+ Property prop11 = new Property(123);
+ prop11.setIdShort("prop11");
+ // - Add container property that holds other properties
+ SubmodelElementCollection container = new SubmodelElementCollection();
+ container.setIdShort("prop2");
+ container.addSubModelElement(prop11);
+ // - Add container to property map
+ addSubModelElement(container);
+
+ // Add another property manually to sub model container "properties"
+ Property prop3 = new Property(17);
+ prop3.setIdShort("prop3");
+ {
+ ((Map<String, Object>) this.get("submodelElements")).put("prop3", prop3);
+ }
+ }
+ }
+
+ /**
+ * Create manager using the directory stub an the HTTPConnectorProvider
+ */
+ ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(
+ // Add example specific mappings
+ new ExampleAASRegistry()
+ .addAASMapping("aas-001", "") // No AAS is provided in this example
+ .addSubmodelMapping("aas-001", "sm-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/submodel"),
+ // We connect via HTTP
+ new HTTPConnectorProvider());
+
+
+
+ /**
+ * VAB connection manager backend
+ */
+ protected VABConnectionManager connManager = new VABConnectionManager(
+ // Add example specific mappings
+ new ExamplesPreconfiguredDirectory()
+ // - VAB needs to know the relative path of the sub model that is defined by AAS meta model
+ .addMapping("sm-001VAB", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/submodel"),
+ // We connect via HTTP
+ new HTTPConnectorProvider());
+
+
+
+ /**
+ * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
+ * components on the IP address of the host. Therefore, all components use the same IP address.
+ */
+ @ClassRule
+ public static BaSyxDeployment context = new BaSyxDeployment(
+ // Servlets for example snippet
+ new BaSyxExamplesContext_Empty().
+ // Deploy example specific servlets to Tomcat server in this context
+ addServletMapping("/Testsuite/components/BaSys/1.0/SampleModel/*", new SubmodelServlet(new SampleSubModelFactory())));
+
+
+ /**
+ * Connect to sub model, query, and set property values
+ */
+ @Test @SuppressWarnings("unchecked")
+ public void accessSubModel() throws Exception {
+ // Create and connect SDK connector
+ ISubModel subModel = manager.retrieveSubModel(new ModelUrn("aas-001"), new ModelUrn("sm-001"));
+ // - Retrieve sub model values and compare to expected values
+ assertTrue(subModel.getIdShort().equals("sm-001"));
+ assertTrue(subModel.getProperties().get("prop1").getIdShort().equals("prop1"));
+ assertTrue((int) subModel.getProperties().get("prop1").getValue() == 234);
+ assertTrue((int) subModel.getProperties().get("prop3").getValue() == 17);
+ assertTrue(subModel.getSubmodelElements().get("prop2").getIdShort().equals("prop2"));
+ assertTrue((int) ((ISubmodelElementCollection) subModel.getSubmodelElements().get("prop2")).getProperties().get("prop11").getValue() == 123);
+
+ // Connect to sub model using lower-level VAB interface
+ VABElementProxy connSubModel1 = this.connManager.connectToVABElement("sm-001VAB");
+ // - Read property values and compare with expected values
+ assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1")).get("value") == 234);
+ assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop3")).get("value") == 17);
+ assertTrue(((Map<String, Object>) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1")).get("idShort").equals("prop1"));
+ assertTrue(((Map<String, Object>) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop2")).get("idShort").equals("prop2"));
+ assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue("submodelElements/prop2/prop11")).get("value") == 123);
+ // - Change property value using VAB primitive
+ connSubModel1.setModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1/value", 456);
+ // - Read value back using VAB primitive
+ assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1")).get("value") == 456);
+
+ // Read changed value back using SDK connector
+ assertTrue((int) subModel.getProperties().get("prop1").getValue() == 456);
+ }
+}
+
+
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnectionFull.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnectionFull.java
new file mode 100644
index 0000000..707398b
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnectionFull.java
@@ -0,0 +1,150 @@
+package org.eclipse.basyx.examples.snippets.undoc.aas.connection.servlet;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.Map;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.components.servlet.submodel.SubmodelServlet;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_Empty;
+import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
+import org.eclipse.basyx.examples.support.directory.ExampleAASRegistry;
+import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
+import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+
+/**
+ * Export sub model through a servlet and connect to that servlet
+ *
+ * @author kuhn
+ *
+ */
+public class AASServletConnectionFull {
+
+
+ /**
+ * Example sub model. This example sub model is created with the BaSyx SDK factory and defines the AAS meta model properties
+ */
+ static class SampleSubModelFactory extends SubModel {
+
+ /**
+ * Constructor - create sub model property
+ */
+ @SuppressWarnings("unchecked")
+ public SampleSubModelFactory() {
+ // Set sub model ID
+ setIdShort("sm-001");
+
+ // Add example properties
+ // - Add simple property
+ Property prop1 = new Property(234);
+ prop1.setIdShort("prop1");
+ addSubModelElement(prop1);
+
+ Property prop11 = new Property(123);
+ prop11.setIdShort("prop11");
+ // - Add container property that holds other properties
+ SubmodelElementCollection container = new SubmodelElementCollection();
+ container.setIdShort("prop2");
+ container.addSubModelElement(prop11);
+ // - Add container to property map
+ addSubModelElement(container);
+
+ // Add another property manually to sub model container "properties"
+ Property prop3 = new Property(17);
+ prop3.setIdShort("prop3");
+ {
+ ((Map<String, Object>) this.get("submodelElements")).put("prop3", prop3);
+ }
+ }
+ }
+
+ /**
+ * VAB connection manager backend
+ */
+ protected VABConnectionManager connManager = new VABConnectionManager(
+ // Add example specific mappings
+ new ExamplesPreconfiguredDirectory()
+ // - VAB needs to know the relative path of the sub model that is defined by AAS
+ // meta model
+ .addMapping("sm-001VAB", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/submodel")
+ // - VAB needs to know the relative path of the sub model that is defined by AAS
+ // meta model
+ .addMapping("sm-001MVAB", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModelManual/submodel"),
+ // We connect via HTTP
+ new HTTPConnectorProvider());
+
+
+
+ /**
+ * VAB connection manager backend
+ */
+ protected ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(
+ // Add example specific mappings
+ new ExampleAASRegistry()
+ .addAASMapping("aas-001", "") // no AAS is provided in this example
+ .addSubmodelMapping("aas-001", "sm-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/submodel"),
+ // We connect via HTTP
+ new HTTPConnectorProvider());
+
+
+
+ /**
+ * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
+ * components on the IP address of the host. Therefore, all components use the same IP address.
+ */
+ @ClassRule
+ public static BaSyxDeployment context = new BaSyxDeployment(
+ // Servlets for example snippet
+ new BaSyxExamplesContext_Empty().
+ // Deploy example specific servlets to Tomcat server in this context
+ addServletMapping("/Testsuite/components/BaSys/1.0/SampleModel/*", new SubmodelServlet(new SampleSubModelFactory())));
+
+
+ /**
+ * Connect to sub model, query, and set property values
+ */
+ @Test @SuppressWarnings("unchecked")
+ public void accessSubModel() throws Exception {
+ // Create and connect SDK connector
+ ISubModel subModel = manager.retrieveSubModel(new ModelUrn("aas-001"), new ModelUrn("sm-001"));
+ // - Retrieve sub model values and compare to expected values
+ assertTrue(subModel.getIdShort().equals("sm-001"));
+ assertTrue(subModel.getProperties().get("prop1").getIdShort().equals("prop1"));
+ assertTrue((int) subModel.getProperties().get("prop1").getValue() == 234);
+ assertTrue((int) subModel.getProperties().get("prop3").getValue() == 17);
+ assertTrue(subModel.getSubmodelElements().get("prop2").getIdShort().equals("prop2"));
+ assertTrue((int) ((ISubmodelElementCollection) subModel.getSubmodelElements().get("prop2")).getProperties().get("prop11").getValue() == 123);
+
+
+ // Connect to sub model using lower-level VAB interface
+ VABElementProxy connSubModel1 = this.connManager.connectToVABElement("sm-001VAB");
+ // - Read property values and compare with expected values
+ assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1")).get("value") == 234);
+ assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop3")).get("value") == 17);
+ assertTrue(((Map<String, Object>) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1")).get("idShort").equals("prop1"));
+ assertTrue(((Map<String, Object>) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop2")).get("idShort").equals("prop2"));
+ assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue("submodelElements/prop2/prop11")).get("value") == 123);
+ // - Change property value using VAB primitive
+ connSubModel1.setModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1/value", 456);
+ // - Read value back using VAB primitive
+ assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1")).get("value") == 456);
+
+ // Read changed value back using SDK connector
+ assertTrue((int) subModel.getProperties().get("prop1").getValue() == 456);
+ }
+}
+
+
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletConnectorConnection.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletConnectorConnection.java
new file mode 100644
index 0000000..59152d1
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletConnectorConnection.java
@@ -0,0 +1,133 @@
+package org.eclipse.basyx.examples.snippets.undoc.aas.connection.servlet;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Map;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.components.servlet.submodel.SubmodelServlet;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_Empty;
+import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
+import org.eclipse.basyx.examples.support.directory.ExampleAASRegistry;
+import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
+import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+
+/**
+ * Export sub model through a servlet and connect to that servlet
+ *
+ * @author kuhn
+ *
+ */
+public class AASSubModelServletConnectorConnection {
+
+
+ /**
+ * Example sub model. This example sub model is created with the BaSyx SDK factory and defines the AAS meta model properties
+ */
+ static class SampleSubModel extends SubModel {
+ /**
+ * Constructor - create sub model property
+ */
+ @SuppressWarnings("unchecked")
+ public SampleSubModel() {
+ // Set sub model ID
+ setIdShort("sm-001");
+
+ // Add example properties
+ // - Add simple property
+ Property prop1 = new Property(234);
+ prop1.setIdShort("prop1");
+ addSubModelElement(prop1);
+
+ Property prop11 = new Property(123);
+ prop11.setIdShort("prop11");
+ // - Add container property that holds other properties
+ SubmodelElementCollection container = new SubmodelElementCollection();
+ container.setIdShort("prop2");
+ container.addSubModelElement(prop11);
+ // - Add container to property map
+ addSubModelElement(container);
+
+ // Add another property manually to sub model container "properties"
+ Property prop3 = new Property(17);
+ prop3.setIdShort("prop3");
+ {
+ ((Map<String, Object>) this.get("submodelElements")).put("prop3", prop3);
+ }
+ }
+ }
+
+ /**
+ * Create manager using the directory stub an the HTTPConnectorProvider
+ */
+ ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(
+ // Add example specific mappings
+ new ExampleAASRegistry()
+ // - SDK connectors encapsulate relative path to sub model (/aas/submodels/sm-001)
+ .addAASMapping("aas-001", "") // No AAS is provided in this example
+ .addSubmodelMapping("aas-001", "sm-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/submodel"),
+ // We connect via HTTP
+ new HTTPConnectorProvider());
+
+ /**
+ * VAB connection manager backend
+ */
+ protected VABConnectionManager connManager = new VABConnectionManager(
+ // Add example specific mappings
+ new ExamplesPreconfiguredDirectory()
+ // - VAB needs to know the relative path of the sub model that is defined by AAS meta model
+ .addMapping("sm-001VAB", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/aas/submodels/sm-001/submodel"),
+ // We connect via HTTP
+ new HTTPConnectorProvider());
+
+
+
+ /**
+ * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
+ * components on the IP address of the host. Therefore, all components use the same IP address.
+ */
+ @ClassRule
+ public static BaSyxDeployment context = new BaSyxDeployment(
+ // Servlets for example snippet
+ new BaSyxExamplesContext_Empty().
+ // Deploy example specific servlets to Tomcat server in this context
+ addServletMapping("/Testsuite/components/BaSys/1.0/SampleModel/*", new SubmodelServlet(new SampleSubModel()))
+ );
+
+
+ /**
+ * Application code: Connect to sub model, query, and set property values
+ */
+ @Test
+ public void accessSubModel() throws Exception {
+
+ // Create and connect SDK connector
+ ISubModel subModel = manager.retrieveSubModel(new ModelUrn("aas-001"), new ModelUrn("sm-001"));
+
+ // - Retrieve sub model values and compare to expected values
+ assertTrue(subModel.getIdShort().equals("sm-001"));
+ assertTrue(subModel.getProperties().get("prop1").getIdShort().equals("prop1"));
+ assertTrue((int) subModel.getProperties().get("prop1").getValue() == 234);
+ assertTrue((int) subModel.getProperties().get("prop3").getValue() == 17);
+
+ ISubmodelElementCollection prop2 = (ISubmodelElementCollection) subModel.getSubmodelElements().get("prop2");
+ assertEquals("prop2", prop2.getIdShort());
+ Map<String, IProperty> properties = prop2.getProperties();
+ assertEquals(123, properties.get("prop11").getValue());
+ }
+}
+
+
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletVABConnection.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletVABConnection.java
new file mode 100644
index 0000000..6e4e498
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletVABConnection.java
@@ -0,0 +1,118 @@
+package org.eclipse.basyx.examples.snippets.undoc.aas.connection.servlet;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.Map;
+
+import org.eclipse.basyx.components.servlet.submodel.SubmodelServlet;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_Empty;
+import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
+import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
+import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+
+/**
+ * Export sub model through a servlet and connect to that servlet
+ *
+ * @author kuhn
+ *
+ */
+public class AASSubModelServletVABConnection {
+
+
+ /**
+ * Example sub model. This example sub model is created with the BaSyx SDK factory and defines the AAS meta model properties
+ */
+ static class SampleSubModel extends SubModel {
+ /**
+ * Constructor - create sub model property
+ */
+ @SuppressWarnings("unchecked")
+ public SampleSubModel() {
+ // Set sub model ID
+ setIdShort("sm-001");
+
+ // Add example properties
+ // - Add simple property
+ Property prop1 = new Property(234);
+ prop1.setIdShort("prop1");
+ addSubModelElement(prop1);
+
+ Property prop11 = new Property(123);
+ prop11.setIdShort("prop11");
+ // - Add container property that holds other properties
+ SubmodelElementCollection container = new SubmodelElementCollection();
+ container.setIdShort("prop2");
+ container.addSubModelElement(prop11);
+ // - Add container to property map
+ addSubModelElement(container);
+
+ // Add another property manually to sub model container "properties"
+ Property prop3 = new Property(17);
+ prop3.setIdShort("prop3");
+ {
+ ((Map<String, Object>) this.get("submodelElements")).put("prop3", prop3);
+ }
+ }
+ }
+
+
+
+ /**
+ * VAB connection manager backend
+ */
+ protected VABConnectionManager connManager = new VABConnectionManager(
+ // Add example specific mappings
+ new ExamplesPreconfiguredDirectory()
+ // Entries map directly at the SubmodelServlet
+ .addMapping("aas-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/submodel")
+ .addMapping("sm-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/submodel")
+ .addMapping("sm-001VAB", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/submodel"),
+ // We connect via HTTP
+ new HTTPConnectorProvider());
+
+
+
+ /**
+ * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
+ * components on the IP address of the host. Therefore, all components use the same IP address.
+ */
+ @ClassRule
+ public static BaSyxDeployment context = new BaSyxDeployment(
+ // Servlets for example snippet
+ new BaSyxExamplesContext_Empty().
+ // Deploy example specific servlets to Tomcat server in this context
+ addServletMapping("/Testsuite/components/BaSys/1.0/SampleModel/*", new SubmodelServlet(new SampleSubModel()))
+ );
+
+
+ /**
+ * Connect to sub model, query, and set property values
+ */
+ @Test @SuppressWarnings("unchecked")
+ public void accessSubModel() throws Exception {
+ // Connect to sub model using lower-level VAB interface
+ VABElementProxy connSubModel1 = this.connManager.connectToVABElement("sm-001VAB");
+ // - Read property values and compare with expected values
+ assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1")).get("value") == 234);
+ assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop3")).get("value") == 17);
+ assertTrue(((Map<String, Object>) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1")).get("idShort").equals("prop1"));
+ assertTrue(((Map<String, Object>) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop2")).get("idShort").equals("prop2"));
+ assertTrue((Integer) connSubModel1.getModelPropertyValue("submodelElements/prop2/prop11/value") == 123);
+ // - Change property value using VAB primitive
+ connSubModel1.setModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1/value", 456);
+ // - Read value back using VAB primitive
+ assertTrue((Integer) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1/value") == 456);
+ }
+}
+
+
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASDynamicOperationSnippet.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASDynamicOperationSnippet.java
new file mode 100644
index 0000000..bd0243c
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASDynamicOperationSnippet.java
@@ -0,0 +1,106 @@
+package org.eclipse.basyx.examples.snippets.undoc.aas.dynamic;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
+import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
+import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
+import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProviderHelper;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+
+/**
+ * Illustrate the dynamic deployment of AAS operations
+ *
+ * @author kuhn
+ *
+ */
+public class RunAASDynamicOperationSnippet {
+
+
+ /**
+ * VAB connection manager backend
+ */
+ protected VABConnectionManager connManager = new VABConnectionManager(
+ new ExamplesPreconfiguredDirectory()
+ // Add example specific mappings
+ .addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
+ new HTTPConnectorProvider());
+
+
+ /**
+ * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
+ * components on the IP address of the host. Therefore, all components use the same IP address.
+ */
+ @ClassRule
+ public static BaSyxDeployment context = new BaSyxDeployment(
+ // Simulated servlets
+ // - BaSys topology with one AAS Server and one SQL directory
+ new BaSyxExamplesContext().
+ // Deploy example specific servlets to Tomcat server in this context
+ addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
+ );
+
+
+
+
+ /**
+ * Test basic queries
+ */
+ @Test
+ public void snippet() throws Exception {
+
+ // Server connections
+ // - Connect to device (VAB object)
+ VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
+
+
+ // Create properties on AAS
+
+ // - Add example properties
+ SubModel submodel = new SubModel();
+ submodel.setIdShort("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
+ Property prop1 = new Property(7);
+ prop1.setIdShort("prop1");
+ submodel.addSubModelElement(prop1);
+
+ Property prop2 = new Property("myStr");
+ prop2.setIdShort("prop2");
+ submodel.addSubModelElement(prop2);
+ // - Transfer sub model to server
+ connSubModel1.setModelPropertyValue("/", submodel);
+
+
+ // Read property values
+ String prop2Val = (String) connSubModel1.getModelPropertyValue("submodelElements/prop2/value");
+ // - Check property values
+ assertTrue(prop2Val.equals("myStr"));
+
+
+ // Create dynamic get/set operation as lambda expression
+ Map<String, Object> dynamicPropertyVal = VABLambdaProviderHelper.createSimple((Supplier<Object> & Serializable) () -> {
+ return "dynamicExampleValue";
+ }, null);
+ // - Update property properties/dynamicExample with dynamic get/set operation
+ connSubModel1.setModelPropertyValue("submodelElements/prop2/value", dynamicPropertyVal);
+
+
+ // Read dynamicExample property
+ prop2Val = (String) connSubModel1.getModelPropertyValue("submodelElements/prop2/value");
+ // - Check property values
+ assertTrue(prop2Val.equals("dynamicExampleValue"));
+ }
+}
+
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASManualHTTPOperationsSnippet.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASManualHTTPOperationsSnippet.java
new file mode 100644
index 0000000..3be7c43
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASManualHTTPOperationsSnippet.java
@@ -0,0 +1,99 @@
+package org.eclipse.basyx.examples.snippets.undoc.aas.dynamic;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Map;
+
+import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
+import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
+import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
+import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.tools.webserviceclient.WebServiceJSONClient;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+
+/**
+ * Illustrate the use of AAS operations using HTTP REST calls
+ *
+ * @author kuhn
+ *
+ */
+public class RunAASManualHTTPOperationsSnippet {
+
+
+ /**
+ * VAB connection manager backend
+ */
+ protected VABConnectionManager connManager = new VABConnectionManager(
+ new ExamplesPreconfiguredDirectory()
+ // Add example specific mappings
+ .addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
+ new HTTPConnectorProvider());
+
+
+ /**
+ * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
+ * components on the IP address of the host. Therefore, all components use the same IP address.
+ */
+ @ClassRule
+ public static BaSyxDeployment context = new BaSyxDeployment(
+ // Simulated servlets
+ // - BaSys topology with one AAS Server and one SQL directory
+ new BaSyxExamplesContext().
+ // Deploy example specific servlets to Tomcat server in this context
+ addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
+ );
+
+
+
+
+ /**
+ * Test basic queries
+ */
+ @Test @SuppressWarnings("unchecked")
+ public void snippet() throws Exception {
+
+ // Server connections
+ // - Connect to device (VAB object)
+ VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
+
+ int prop1Val = 7;
+ String prop1IdShort = "prop1";
+ String prop2Val = "myStr";
+ // Add example properties
+ SubModel submodel = new SubModel();
+ submodel.setIdShort("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
+ Property prop1 = new Property(prop1Val);
+ prop1.setIdShort(prop1IdShort);
+ submodel.addSubModelElement(prop1);
+
+ Property prop2 = new Property(prop2Val);
+ prop2.setIdShort("prop2");
+ submodel.addSubModelElement(prop2);
+
+ // Transfer sub model to server
+ connSubModel1.setModelPropertyValue("/", submodel);
+
+ // Web service client accesses AAS using HTTP REST calls
+ WebServiceJSONClient jsonClient = new WebServiceJSONClient();
+
+ // Read property values
+ // - Use WebServiceJSONClient class. Returned property contains meta data. The actual property is stored in property "entity", property value is in entity property "value"
+ int retrievedProp1Val = (int) ((Map<String, Object>) jsonClient.get("http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/submodelElements/prop1")).get("value");
+ String retrievedProp1Id = (String) ((Map<String, Object>) jsonClient.get("http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/submodelElements/prop1")).get("idShort");
+ String retrievedProp2Val = (String) ((Map<String, Object>) jsonClient.get("http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/submodelElements/prop2")).get("value");
+
+ // Check results
+ assertEquals(prop1Val, retrievedProp1Val);
+ assertEquals(prop1IdShort, retrievedProp1Id);
+ assertEquals(prop2Val, retrievedProp2Val);
+ }
+}
+
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASPropertiesCRUDAccessSnippet.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASPropertiesCRUDAccessSnippet.java
new file mode 100644
index 0000000..8f7d879
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASPropertiesCRUDAccessSnippet.java
@@ -0,0 +1,114 @@
+package org.eclipse.basyx.examples.snippets.undoc.aas.dynamic;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
+import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
+import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
+import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+
+/**
+ * Illustrate the use of AAS operations
+ *
+ * @author kuhn
+ *
+ */
+public class RunAASPropertiesCRUDAccessSnippet {
+
+
+ /**
+ * VAB connection manager backend
+ */
+ protected VABConnectionManager connManager = new VABConnectionManager(
+ new ExamplesPreconfiguredDirectory()
+ // Add example specific mappings
+ .addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
+ new HTTPConnectorProvider());
+
+
+ /**
+ * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
+ * components on the IP address of the host. Therefore, all components use the same IP address.
+ */
+ @ClassRule
+ public static BaSyxDeployment context = new BaSyxDeployment(
+ // Simulated servlets
+ // - BaSys topology with one AAS Server and one SQL directory
+ new BaSyxExamplesContext().
+ // Deploy example specific servlets to Tomcat server in this context
+ addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
+ );
+
+
+
+
+ /**
+ * Test basic queries
+ */
+ @Test
+ public void snippet() throws Exception {
+
+ // Server connections
+ // - Connect to device (VAB object)
+ VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
+
+
+ // Create properties on AAS
+ // - Add example properties
+ SubModel submodel = new SubModel();
+ submodel.setIdShort("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
+ Property prop1 = new Property(7);
+ prop1.setIdShort("prop1");
+ submodel.addSubModelElement(prop1);
+
+ Property prop2 = new Property("myStr");
+ prop2.setIdShort("prop2");
+ submodel.addSubModelElement(prop2);
+ // - Transfer sub model to server
+ connSubModel1.setModelPropertyValue("/", submodel);
+
+ // Read property values
+ int prop1Val = (int) connSubModel1.getModelPropertyValue("submodelElements/prop1/value");
+ String prop2Val = (String) connSubModel1.getModelPropertyValue("submodelElements/prop2/value");
+ // - Check property values
+ assertTrue(prop1Val == 7);
+ assertTrue(prop2Val.equals("myStr"));
+
+ // Update property values
+ connSubModel1.setModelPropertyValue("submodelElements/prop1/value", 8);
+ connSubModel1.setModelPropertyValue("submodelElements/prop2/value", "stillMine");
+
+ // Read property values again
+ prop1Val = (int) connSubModel1.getModelPropertyValue("submodelElements/prop1/value");
+ prop2Val = (String) connSubModel1.getModelPropertyValue("submodelElements/prop2/value");
+ // - Check property values
+ assertTrue(prop1Val == 8);
+ assertTrue(prop2Val.equals("stillMine"));
+
+ // Delete property values
+ connSubModel1.deleteValue("submodelElements/prop1");
+ connSubModel1.deleteValue("submodelElements/prop2");
+
+ // Read property values again
+ try {
+ connSubModel1.getModelPropertyValue("submodelElements/prop1");
+ fail();
+ } catch (ResourceNotFoundException e) {}
+ try {
+ connSubModel1.getModelPropertyValue("submodelElements/prop2");
+ fail();
+ } catch (ResourceNotFoundException e) {}
+ }
+}
+
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASTailoredSupplierSnippet.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASTailoredSupplierSnippet.java
new file mode 100644
index 0000000..d08cd3b
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASTailoredSupplierSnippet.java
@@ -0,0 +1,141 @@
+package org.eclipse.basyx.examples.snippets.undoc.aas.dynamic;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
+import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
+import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
+import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProviderHelper;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+
+/**
+ * Example for a tailored BaSyx supplier
+ *
+ * - BaSyx will serialize this class (and all contained references) and transmit it to the AAS server
+ *
+ * @author kuhn
+ *
+ */
+class TailoredBaSyxSupplier implements Supplier<Object>, Serializable {
+
+ /**
+ * Version number of serialized instances
+ */
+ private static final long serialVersionUID = 1L;
+
+
+ /**
+ * Return value
+ */
+ @Override
+ public Object get() {
+ // Delegate call to tailored BaSyx supplier base class
+ return getInternal();
+ }
+
+
+ /**
+ * Example function of tailored BaSyx supplier base class
+ */
+ protected String getInternal() {
+ return "BaSyxSupplier!";
+ }
+}
+
+
+
+
+/**
+ * Illustrate the dynamic deployment of AAS operations with a tailored consumer
+ *
+ * @author kuhn
+ *
+ */
+public class RunAASTailoredSupplierSnippet {
+
+
+ /**
+ * VAB connection manager backend
+ */
+ protected VABConnectionManager connManager = new VABConnectionManager(
+ new ExamplesPreconfiguredDirectory()
+ // Add example specific mappings
+ .addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
+ new HTTPConnectorProvider());
+
+
+ /**
+ * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
+ * components on the IP address of the host. Therefore, all components use the same IP address.
+ */
+ @ClassRule
+ public static BaSyxDeployment context = new BaSyxDeployment(
+ // Simulated servlets
+ // - BaSys topology with one AAS Server and one SQL directory
+ new BaSyxExamplesContext().
+ // Deploy example specific servlets to Tomcat server in this context
+ addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
+ );
+
+
+
+ /**
+ * Test basic queries
+ */
+ @Test
+ public void snippet() throws Exception {
+
+ // Server connections
+ // - Connect to device (VAB object)
+ VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
+
+
+ // Create properties on AAS
+
+ // - Add example properties
+ SubModel submodel = new SubModel();
+ submodel.setIdShort("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
+ Property prop1 = new Property(7);
+ prop1.setIdShort("prop1");
+ submodel.addSubModelElement(prop1);
+
+ Property prop2 = new Property("myStr");
+ prop2.setIdShort("prop2");
+ submodel.addSubModelElement(prop2);
+
+ // - Transfer sub model to server
+ connSubModel1.setModelPropertyValue("/", submodel);
+
+
+ // Read property values
+ String prop2Val = (String) connSubModel1.getModelPropertyValue("submodelElements/prop2/value");
+ // - Check property values
+ assertTrue(prop2Val.equals("myStr"));
+
+
+ // Create dynamic get/set operation as lambda expression
+ Map<String, Object> dynamicPropertyVal = VABLambdaProviderHelper.createSimple(new TailoredBaSyxSupplier(), null);
+ // - Update property properties/dynamicExample with dynamic get/set operation
+ connSubModel1.setModelPropertyValue("submodelElements/prop2/value", dynamicPropertyVal);
+
+ // Read dynamicExample property
+ prop2Val = (String) connSubModel1.getModelPropertyValue("submodelElements/prop2/value");
+
+ // - Check value
+ assertTrue(prop2Val.equals("BaSyxSupplier!"));
+ }
+}
+
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASManualHTTPOperationsSnippet.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASManualHTTPOperationsSnippet.java
new file mode 100644
index 0000000..b643870
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASManualHTTPOperationsSnippet.java
@@ -0,0 +1,81 @@
+package org.eclipse.basyx.examples.snippets.undoc.vab.connection;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.HashMap;
+
+import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
+import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
+import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
+import org.eclipse.basyx.tools.webserviceclient.WebServiceJSONClient;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+
+
+
+/**
+ * Illustrate the use of AAS operations using HTTP REST calls
+ *
+ * @author kuhn
+ *
+ */
+public class RunAASManualHTTPOperationsSnippet {
+
+
+ /**
+ * VAB connection manager backend
+ */
+ protected VABConnectionManager connManager = new VABConnectionManager(
+ new ExamplesPreconfiguredDirectory()
+ // Add example specific mappings
+ .addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
+ new HTTPConnectorProvider());
+
+
+ /**
+ * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
+ * components on the IP address of the host. Therefore, all components use the same IP address.
+ */
+ @ClassRule
+ public static BaSyxDeployment context = new BaSyxDeployment(
+ // Simulated servlets
+ // - BaSys topology with one AAS Server and one SQL directory
+ new BaSyxExamplesContext().
+ // Deploy example specific servlets to Tomcat server in this context
+ addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
+ );
+
+
+
+
+ /**
+ * Test basic queries
+ */
+ public void snippet() throws Exception {
+
+ // Server connections
+ // - Connect to device (VAB object)
+ VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
+
+ int prop1Val = 7;
+ String prop2Val = "myStr";
+ // Create properties on AAS using connection
+ connSubModel1.createValue("properties", new HashMap<String, Object>());
+ connSubModel1.createValue("properties/prop1", prop1Val);
+ connSubModel1.createValue("properties/prop2", prop2Val);
+
+
+ // Web service client accesses AAS using HTTP REST calls
+ WebServiceJSONClient jsonClient = new WebServiceJSONClient();
+
+
+ // Read property values
+ // - Use WebServiceJSONClient class. Returned property contains meta data. The actual value is stored in property "entity"
+ assertEquals(prop1Val, jsonClient.get("http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/properties/prop1"));
+ assertEquals(prop2Val, jsonClient.get("http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/properties/prop2"));
+ }
+}
+
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASPropertiesSnippet.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASPropertiesSnippet.java
new file mode 100644
index 0000000..730cfd5
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASPropertiesSnippet.java
@@ -0,0 +1,99 @@
+package org.eclipse.basyx.examples.snippets.undoc.vab.connection;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.HashMap;
+
+import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
+import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
+import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+
+/**
+ * Illustrate the use of AAS operations
+ *
+ * @author kuhn
+ *
+ */
+public class RunAASPropertiesSnippet {
+
+
+ /**
+ * VAB connection manager backend
+ */
+ protected VABConnectionManager connManager = new VABConnectionManager(
+ new ExamplesPreconfiguredDirectory()
+ // Add example specific mappings
+ .addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
+ new HTTPConnectorProvider());
+
+
+ /**
+ * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
+ * components on the IP address of the host. Therefore, all components use the same IP address.
+ */
+ @ClassRule
+ public static BaSyxDeployment context = new BaSyxDeployment(
+ // Simulated servlets
+ // - BaSys topology with one AAS Server and one SQL directory
+ new BaSyxExamplesContext().
+ // Deploy example specific servlets to Tomcat server in this context
+ addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
+ );
+
+
+
+
+ /**
+ * Test basic queries
+ */
+ @Test
+ public void snippet() throws Exception {
+
+ // Server connections
+ // - Connect to device (VAB object)
+ VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
+
+
+ // Create properties on AAS
+ connSubModel1.createValue("properties", new HashMap<String, Object>());
+ connSubModel1.createValue("properties/prop1", 7);
+ connSubModel1.createValue("properties/prop2", "myStr");
+
+ // Read property values
+ assertTrue((int) connSubModel1.getModelPropertyValue("properties/prop1") == 7);
+ assertTrue(connSubModel1.getModelPropertyValue("properties/prop2").equals("myStr"));
+
+ // Update property values
+ connSubModel1.setModelPropertyValue("properties/prop1", 8);
+ connSubModel1.setModelPropertyValue("properties/prop2", "stillMine");
+
+ // Read property values again
+ assertTrue((int) connSubModel1.getModelPropertyValue("properties/prop1") == 8);
+ assertTrue(connSubModel1.getModelPropertyValue("properties/prop2").equals("stillMine"));
+
+ // Delete property values
+ connSubModel1.deleteValue("properties/prop1");
+ connSubModel1.deleteValue("properties/prop2");
+
+ // Read property values again
+ try {
+ connSubModel1.getModelPropertyValue("properties/prop1");
+ fail();
+ } catch (ResourceNotFoundException e) {}
+ try {
+ connSubModel1.getModelPropertyValue("properties/prop2");
+ fail();
+ } catch (ResourceNotFoundException e) {}
+ }
+}
+
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProvider.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProvider.java
new file mode 100644
index 0000000..ffa29dc
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProvider.java
@@ -0,0 +1,68 @@
+package org.eclipse.basyx.sandbox.regression.components.cfgprovider;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Map;
+
+import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
+import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+/**
+ * Test queries to CFG file provider
+ *
+ * @author kuhn
+ *
+ */
+public class TestCFGProvider {
+
+
+ /**
+ * VAB connection manager backend
+ */
+ protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(), new HTTPConnectorProvider());
+
+
+ /**
+ * Makes sure Tomcat Server is started with basyx.components regression test case
+ */
+ @ClassRule
+ public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
+
+
+ /**
+ * Test basic queries
+ */
+ @SuppressWarnings("unchecked")
+ @Test
+ public void test() throws Exception {
+ // Connect to sub model "CfgFileTestAAS"
+ VABElementProxy connSubModel = this.connManager.connectToVABElement("CfgFileTestAAS");
+
+
+ // Get property value
+ Map<String, Object> value1 = (Map<String, Object>) connSubModel
+ .getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty1/value");
+
+ assertEquals("exampleStringValue", value1.get(Property.VALUE));
+
+
+ // Get property value
+ Map<String, Object> value2 = (Map<String, Object>) connSubModel
+ .getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty2/value");
+ assertEquals("12", value2.get(Property.VALUE));
+
+ // Get property value
+ Map<String, Object> value3 = (Map<String, Object>) connSubModel
+ .getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty3/value");
+ assertEquals("45.8", value3.get(Property.VALUE));
+ }
+}
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProviderPropertyMetaData.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProviderPropertyMetaData.java
new file mode 100644
index 0000000..22f824e
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProviderPropertyMetaData.java
@@ -0,0 +1,75 @@
+package org.eclipse.basyx.sandbox.regression.components.cfgprovider;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
+import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+/**
+ * Test queries to CFG file provider
+ *
+ * @author kuhn
+ *
+ */
+public class TestCFGProviderPropertyMetaData {
+
+ /**
+ * VAB connection manager backend
+ */
+ protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(),
+ new HTTPConnectorProvider());
+
+ /**
+ * Makes sure Tomcat Server is started
+ */
+ @ClassRule
+ public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
+
+ /**
+ * Test basic queries
+ */
+ @SuppressWarnings("unchecked")
+ @Test
+ public void test() throws Exception {
+
+ // Connect to sub model "CfgFileTestAAS"
+ VABElementProxy connSubModel = this.connManager.connectToVABElement("CfgFileTestAAS");
+
+ // Get property value
+ Map<String, Object> value1 = (Map<String, Object>) connSubModel
+ .getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty1");
+ assertEquals("exampleStringValue", value1.get(Property.VALUE));
+ // - Check property meta data (description)
+ Map<String, Object> value1a = (Map<String, Object>) connSubModel
+ .getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty1");
+ LangStrings description = LangStrings.createAsFacade((Collection<Map<String, Object>>) value1a.get("description"));
+ assertEquals("Configuration property description", description.get(""));
+
+ // Get property value
+ Map<String, Object> value2 = (Map<String, Object>) connSubModel
+ .getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty2");
+ assertEquals("12", value2.get(Property.VALUE));
+ // - Check property meta data (description)
+ Map<String, Object> value2a = (Map<String, Object>) connSubModel
+ .getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty2");
+ description = LangStrings.createAsFacade((Collection<Map<String, Object>>) value2a.get("description"));
+ assertEquals("Configuration property description on multiple lines", description.get(""));
+
+ // Get property value
+ Map<String, Object> value3 = (Map<String, Object>) connSubModel
+ .getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty3");
+ assertEquals("45.8", value3.get(Property.VALUE));
+ }
+}
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProviderSubmodelMetaData.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProviderSubmodelMetaData.java
new file mode 100644
index 0000000..a3dfb92
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProviderSubmodelMetaData.java
@@ -0,0 +1,68 @@
+package org.eclipse.basyx.sandbox.regression.components.cfgprovider;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
+import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.AdministrativeInformation;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+
+/**
+ * Test queries to CFG file provider
+ *
+ * @author kuhn
+ *
+ */
+public class TestCFGProviderSubmodelMetaData {
+
+
+ /**
+ * VAB connection manager backend
+ */
+ protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(), new HTTPConnectorProvider());
+
+ /**
+ * Makes sure Tomcat Server is started
+ */
+ @ClassRule
+ public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
+
+ /**
+ * Test basic queries
+ */
+ @SuppressWarnings("unchecked")
+ @Test
+ public void test() throws Exception {
+
+ // Connect to sub model "CfgFileTestAAS"
+ VABElementProxy connSubModel = this.connManager.connectToVABElement("CfgFileTestAAS");
+
+
+ // Get property value
+ Map<String, Object> sampleCFG = (Map<String, Object>) connSubModel
+ .getModelPropertyValue("/aas/submodels/sampleCFG");
+
+ LangStrings description = LangStrings.createAsFacade((Collection<Map<String, Object>>) sampleCFG.get("description"));
+ assertEquals("BaSys regression test file for CFG file provider", description.get(""));
+
+ // Get property value
+ assertEquals("1.0",
+ AdministrativeInformation.createAsFacade((Map<String, Object>) sampleCFG.get(Identifiable.ADMINISTRATION))
+ .getVersion());
+
+ // Get complete sub model
+ Object value3 = connSubModel.getModelPropertyValue("/aas/submodels/sampleCFG");
+ }
+}
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestAASDirectoryEntry.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestAASDirectoryEntry.java
new file mode 100644
index 0000000..7ad49ce
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestAASDirectoryEntry.java
@@ -0,0 +1,217 @@
+package org.eclipse.basyx.sandbox.regression.components.directory.file;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.basyx.sandbox.components.registry.AASDirectoryEntry;
+import org.junit.Test;
+
+
+
+/**
+ * Test the AAS Directory entry class
+ *
+ * @author kuhn
+ *
+ */
+public class TestAASDirectoryEntry {
+
+
+
+ /**
+ * Execute test case that tests parsing of id constructor parameter
+ */
+ @Test
+ public void testConstuctorParameterID() {
+ // Test object with minimal ID
+ AASDirectoryEntry aasEntry1 = new AASDirectoryEntry("urn:FHG", "<serializedAAS>", "local", "");
+ // - Validate object
+ assertTrue(aasEntry1.isValidID());
+ assertTrue(aasEntry1.getLegalEntity().equals("FHG"));
+ assertTrue(aasEntry1.isLegalEntityOf("FHG"));
+ assertFalse(aasEntry1.hasSubUnit());
+ assertFalse(aasEntry1.hasSubModel());
+ assertFalse(aasEntry1.hasVersion());
+ assertFalse(aasEntry1.hasRevision());
+
+
+ // Test object with empty ID, SubUnit and sub model
+ AASDirectoryEntry aasEntry2 = new AASDirectoryEntry("urn:::::", "<serializedAAS>", "local", "");
+ // - Validate object
+ assertTrue(aasEntry2.isValidID());
+ assertFalse(aasEntry2.hasLegalEntity());
+ assertFalse(aasEntry2.hasSubUnit());
+ assertFalse(aasEntry2.hasSubModel());
+ assertFalse(aasEntry2.hasVersion());
+ assertFalse(aasEntry2.hasRevision());
+
+
+ // Test object with almost empty ID and SubUnit
+ AASDirectoryEntry aasEntry3 = new AASDirectoryEntry("urn: : : : : ", "<serializedAAS>", "local", "");
+ // - Validate object
+ assertTrue(aasEntry3.isValidID());
+ assertFalse(aasEntry3.hasLegalEntity());
+ assertFalse(aasEntry3.hasSubUnit());
+ assertFalse(aasEntry3.hasSubModel());
+ assertFalse(aasEntry3.hasVersion());
+ assertFalse(aasEntry3.hasRevision());
+
+
+ // Test object with ID, SubUnit, version and revision
+ AASDirectoryEntry aasEntry4 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1", "<serializedAAS>", "local", "");
+ // - Validate object
+ assertTrue(aasEntry4.isValidID());
+ assertTrue(aasEntry4.getLegalEntity().equals("FHG"));
+ assertTrue(aasEntry4.isLegalEntityOf("FHG"));
+ assertTrue(aasEntry4.hasSubUnit());
+ assertTrue(aasEntry4.getSubUnit().equals("iese"));
+ assertTrue(aasEntry4.hasSubModel());
+ assertTrue(aasEntry4.getSubModel().equals("aas"));
+ assertTrue(aasEntry4.hasVersion());
+ assertTrue(aasEntry4.getVersion().equals("0.97"));
+ assertTrue(aasEntry4.hasRevision());
+ assertTrue(aasEntry4.getRevision().equals("1"));
+ assertFalse(aasEntry4.hasElementID());
+
+
+ // Test object with ID, SubUnit, version and revision
+ AASDirectoryEntry aasEntry5 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:entity", "<serializedAAS>", "local", "");
+ // - Validate object
+ assertTrue(aasEntry5.isValidID());
+ assertTrue(aasEntry5.getLegalEntity().equals("FHG"));
+ assertTrue(aasEntry5.isLegalEntityOf("FHG"));
+ assertTrue(aasEntry5.hasSubUnit());
+ assertTrue(aasEntry5.getSubUnit().equals("iese"));
+ assertTrue(aasEntry5.hasSubModel());
+ assertTrue(aasEntry5.getSubModel().equals("aas"));
+ assertTrue(aasEntry5.hasVersion());
+ assertTrue(aasEntry5.getVersion().equals("0.97"));
+ assertTrue(aasEntry5.hasRevision());
+ assertTrue(aasEntry5.getRevision().equals("1"));
+ assertTrue(aasEntry5.hasElementID());
+ assertTrue(aasEntry5.getElementID().equals("entity"));
+
+
+ // Test object with ID, SubUnit, version and revision
+ AASDirectoryEntry aasEntry6 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:entity#001", "<serializedAAS>", "local", "");
+ // - Validate object
+ assertTrue(aasEntry6.isValidID());
+ assertTrue(aasEntry6.getLegalEntity().equals("FHG"));
+ assertTrue(aasEntry6.isLegalEntityOf("FHG"));
+ assertTrue(aasEntry6.hasSubUnit());
+ assertTrue(aasEntry6.getSubUnit().equals("iese"));
+ assertTrue(aasEntry6.hasSubModel());
+ assertTrue(aasEntry6.getSubModel().equals("aas"));
+ assertTrue(aasEntry6.hasVersion());
+ assertTrue(aasEntry6.getVersion().equals("0.97"));
+ assertTrue(aasEntry6.hasRevision());
+ assertTrue(aasEntry6.getRevision().equals("1"));
+ assertTrue(aasEntry6.hasElementID());
+ assertTrue(aasEntry6.getElementID().equals("entity"));
+ assertTrue(aasEntry6.hasElementInstance());
+ assertTrue(aasEntry6.getElementInstance().equals("001"));
+
+
+ // Test object with ID, SubUnit, version and revision
+ AASDirectoryEntry aasEntry7 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "local", "");
+ // - Validate object
+ assertTrue(aasEntry7.isValidID());
+ assertTrue(aasEntry7.getLegalEntity().equals("FHG"));
+ assertTrue(aasEntry7.isLegalEntityOf("FHG"));
+ assertTrue(aasEntry7.hasSubUnit());
+ assertTrue(aasEntry7.getSubUnit().equals("iese"));
+ assertTrue(aasEntry7.hasSubModel());
+ assertTrue(aasEntry7.getSubModel().equals("aas"));
+ assertTrue(aasEntry7.hasVersion());
+ assertTrue(aasEntry7.getVersion().equals("0.97"));
+ assertTrue(aasEntry7.hasRevision());
+ assertTrue(aasEntry7.getRevision().equals("1"));
+ assertFalse(aasEntry7.hasElementID());
+ assertTrue(aasEntry7.hasElementInstance());
+ assertTrue(aasEntry7.getElementInstance().equals("001"));
+ }
+
+
+
+ /**
+ * Execute test case that tests parsing of content and content type constructor parameter
+ */
+ @Test
+ public void testConstuctorParameterContentAndContentType() {
+ // Test object with local content and without tags
+ AASDirectoryEntry aasEntry1 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "local", "");
+ // - Validate object
+ assertTrue(aasEntry1.getAASContent().equals("<serializedAAS>"));
+ assertTrue(aasEntry1.getAASContentType() == AASDirectoryEntry.AAS_CONTENTTYPE_LOCAL);
+ assertTrue(aasEntry1.getAASTags().isEmpty());
+
+
+ // Test object with remote content and without tags
+ AASDirectoryEntry aasEntry2 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "remote", "");
+ // - Validate object
+ assertTrue(aasEntry2.getAASContent().equals("<serializedAAS>"));
+ assertTrue(aasEntry2.getAASContentType() == AASDirectoryEntry.AAS_CONTENTTYPE_REMOTE);
+ assertTrue(aasEntry2.getAASTags().isEmpty());
+
+
+ // Test object with remote content and without tags
+ AASDirectoryEntry aasEntry3 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "ReMote", "");
+ // - Validate object
+ assertTrue(aasEntry3.getAASContent().equals("<serializedAAS>"));
+ assertTrue(aasEntry3.getAASContentType() == AASDirectoryEntry.AAS_CONTENTTYPE_REMOTE);
+ assertTrue(aasEntry3.getAASTags().isEmpty());
+
+
+ // Test object with proxy content and without tags
+ AASDirectoryEntry aasEntry4 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "PROXY", "");
+ // - Validate object
+ assertTrue(aasEntry4.getAASContent().equals("<serializedAAS>"));
+ assertTrue(aasEntry4.getAASContentType() == AASDirectoryEntry.AAS_CONTENTTYPE_PROXY);
+ assertTrue(aasEntry4.getAASTags().isEmpty());
+ }
+
+
+
+ /**
+ * Execute test case that tests parsing of tags constructor parameter
+ */
+ @Test
+ public void testConstuctorParameterTags() {
+ // Test object without tags
+ AASDirectoryEntry aasEntry1 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "local", "");
+ // - Validate object
+ assertTrue(aasEntry1.getAASTags().isEmpty());
+
+
+ // Test object with one tag
+ AASDirectoryEntry aasEntry2 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "local", "tag1");
+ // - Validate object
+ assertTrue(aasEntry2.getAASTags().size() == 1);
+ assertTrue(aasEntry2.getAASTags().toArray(new String[1])[0].equals("tag1"));
+
+
+ // Test object with one tag
+ AASDirectoryEntry aasEntry3 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "local", "tag1,tag2");
+ // - Validate object
+ assertTrue(aasEntry3.getAASTags().size() == 2);
+ assertTrue(aasEntry3.getAASTags().toArray(new String[2])[0].equals("tag1"));
+ assertTrue(aasEntry3.getAASTags().toArray(new String[2])[1].equals("tag2"));
+ }
+
+
+
+ /**
+ * Execute test case that tests invalid directory entries
+ */
+ @Test
+ public void testInvalidConstuctorParameter() {
+ // Test object with minimal ID
+ AASDirectoryEntry aasEntry1 = new AASDirectoryEntry("FHG", "<serializedAAS>", "local", "");
+ // - Validate object
+ assertFalse(aasEntry1.isValidID());
+ assertFalse(aasEntry1.hasLegalEntity());
+ assertFalse(aasEntry1.hasSubUnit());
+ assertFalse(aasEntry1.hasSubModel());
+ }
+}
+
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestStaticDirectoryFileProvider.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestStaticDirectoryFileProvider.java
new file mode 100644
index 0000000..0395d56
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestStaticDirectoryFileProvider.java
@@ -0,0 +1,142 @@
+package org.eclipse.basyx.sandbox.regression.components.directory.file;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+
+import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
+import org.eclipse.basyx.tools.webserviceclient.WebServiceRawClient;
+import org.eclipse.basyx.vab.coder.json.metaprotocol.MetaprotocolHandler;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+
+
+/**
+ * Test queries to CFG file directory provider
+ *
+ * @author kuhn
+ *
+ */
+public class TestStaticDirectoryFileProvider {
+
+ /**
+ * Makes sure Tomcat Server is started
+ */
+ @ClassRule
+ public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
+ private MetaprotocolHandler handler = new MetaprotocolHandler();
+
+ /**
+ * Execute test case that test working calls
+ */
+ @Test
+ public void testWorkingCalls() {
+ // Invoke BaSyx service calls via web services
+ WebServiceRawClient client = new WebServiceRawClient();
+
+ // Directory web service URL
+ String wsURL = "http://localhost:8080/basys.components/Testsuite/Directory/CFGFile";
+
+
+ // First test - get all locally registered AAS
+ {
+ // Get all locally registered AAS
+ String result = getResult(client.get(wsURL + "/api/v1/registry"));
+
+ // Check if all AAS are contained in result
+ assertTrue(result.contains("{content.aas1}"));
+ assertTrue(result.contains("{content.aas2}"));
+ assertTrue(result.contains("{content.aas3}"));
+ assertTrue(result.contains("{content.aas4}"));
+ }
+
+
+ // Get a specific AAS (1)
+ try {
+ // Get a known AAS by its ID
+ String result = getResult(client.get(wsURL + "/api/v1/registry/urn:de.FHG:es.iese:aas:0.98:5:lab/" + URLEncoder.encode("microscope#A-19", "UTF-8")));
+
+ // Check if all AAS are contained in result
+ assertTrue(result.equals("{content.aas1}"));
+ } catch (Exception e) {
+ fail("Get specific AAS test case did throw exception:"+e);
+ }
+
+
+ // Get a specific AAS (2)
+ try {
+ // Get a known AAS by its ID
+ String result = getResult(client.get(wsURL + "/api/v1/registry/urn:de.FHG:es.iese:aas:0.98:5:lab/" + URLEncoder.encode("microscope#A-18", "UTF-8")));
+
+ // Check if all AAS are contained in result
+ assertTrue(result.equals("{content.aas2}"));
+ } catch (Exception e) {
+ fail("Get specific AAS test case did throw exception:"+e);
+ }
+
+
+ // Get a specific AAS (3)
+ try {
+ // Get a known AAS by its ID
+ String result = getResult(client.get(wsURL + "/api/v1/registry/urn:de.FHG:es.iese:aas:0.98:5:lab/" + URLEncoder.encode("microscope#A-17", "UTF-8")));
+
+ // Check if all AAS are contained in result
+ assertTrue(result.equals("{content.aas3}"));
+ } catch (Exception e) {
+ fail("Get specific AAS test case did throw exception:"+e);
+ }
+
+
+ // Get a specific AAS (4)
+ try {
+ // Get a known AAS by its ID
+ String result = getResult(client.get(wsURL + "/api/v1/registry/urn:de.FHG:es.iese:aas:0.98:5:lab/" + URLEncoder.encode("microscope#A-16", "UTF-8")));
+
+ // Check if all AAS are contained in result
+ assertTrue(result.equals("{content.aas4}"));
+ } catch (Exception e) {
+ fail("Get specific AAS test case did throw exception:"+e);
+ }
+ }
+
+
+
+ /**
+ * Execute test case that test non-working calls
+ *
+ * @throws UnsupportedEncodingException
+ */
+ @Test
+ public void testNonWorkingCalls() throws UnsupportedEncodingException {
+ // Invoke service call via web services
+ WebServiceRawClient client = new WebServiceRawClient();
+
+ // Directory web service URL
+ String wsURL = "http://localhost:8080/basys.components/Testsuite/Directory/CFGFile";
+
+
+ // Get unknown AAS ID
+ // Get a known AAS by its ID
+ String result = getResult(client.get(
+ wsURL + "/api/v1/registry/urn:de.FHG:es.iese:aas:0.98:5:lab/" + URLEncoder.encode("unknown", "UTF-8")));
+
+ // Check if the getting a non existing URL returns a null
+ assertEquals(null, result);
+ }
+
+ private String getResult(String res) {
+ try {
+ return (String) handler.deserialize(res);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
+
+
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestStaticDirectoryFileProviderExceptions.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestStaticDirectoryFileProviderExceptions.java
new file mode 100644
index 0000000..369c60d
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestStaticDirectoryFileProviderExceptions.java
@@ -0,0 +1,91 @@
+package org.eclipse.basyx.sandbox.regression.components.directory.file;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+
+import javax.ws.rs.ServerErrorException;
+
+import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
+import org.eclipse.basyx.tools.webserviceclient.WebServiceJSONClient;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+
+/**
+ * Test queries to CFG file provider
+ *
+ * @author kuhn
+ *
+ */
+public class TestStaticDirectoryFileProviderExceptions {
+
+ /**
+ * Makes sure Tomcat Server is started
+ */
+ @ClassRule
+ public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
+
+ /**
+ * Execute test case that tests not implemented calls
+ *
+ * @throws UnsupportedEncodingException
+ */
+ @Test
+ public void testUnsupportedCalls() throws UnsupportedEncodingException {
+ // Invoke BaSyx service calls via web services
+ WebServiceJSONClient client = new WebServiceJSONClient();
+
+ // Directory web service URL
+ String wsURL = "http://localhost:8080/basys.components/Testsuite/Directory/CFGFile";
+
+
+
+ // Register a new AAS (using POST)
+ try {
+ // Get a known AAS by its ID
+ client.post(wsURL + "/api/v1/registry", "Some content");
+
+ // Exception was not thrown
+ fail("Expected exception indicating that feature is not implemented was not thrown");
+ } catch (ServerErrorException e) {
+ // Check return code for expected return value (501)
+ assertEquals(501, e.getResponse().getStatus());
+
+ }
+
+
+
+ // Renew a specific AAS registration (using PUT)
+ try {
+ // Get a known AAS by its ID
+ client.put(wsURL + "/api/v1/registry/urn:de.FHG:es.iese:aas:0.98:5:lab/" + URLEncoder.encode("microscope#A-19", "UTF-8"), "Some updated content");
+
+ // Exception was not thrown
+ fail("Expected exception indicating that feature is not implemented was not thrown");
+ } catch (ServerErrorException e) {
+ // Check return code for expected return value (501)
+ assertEquals(501, e.getResponse().getStatus());
+ }
+
+
+ // Delete a specific AAS registration (using PUT)
+ try {
+ // Get a known AAS by its ID
+ client.delete(wsURL+"/api/v1/registry/urn:de.FHG:es.iese:aas:0.98:5:lab/"+URLEncoder.encode("microscope#A-19","UTF-8"));
+
+ // Exception was not thrown
+ fail("Expected exception indicating that feature is not implemented was not thrown");
+ } catch (ServerErrorException e) {
+ // Check return code for expected return value (501)
+ assertEquals(501, e.getResponse().getStatus());
+ }
+
+ }
+}
+
+
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderAAS.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderAAS.java
new file mode 100644
index 0000000..c113a3f
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderAAS.java
@@ -0,0 +1,71 @@
+package org.eclipse.basyx.sandbox.regression.components.rawcfgprovider;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
+import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
+import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+
+/**
+ * Test queries to CFG file provider
+ *
+ * @author kuhn
+ *
+ */
+public class TestRawCFGProviderAAS {
+
+
+ /**
+ * VAB connection manager backend
+ */
+ protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(), new HTTPConnectorProvider());
+
+ /**
+ * Makes sure Tomcat Server is started
+ */
+ @ClassRule
+ public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
+
+ /**
+ * Test basic queries
+ */
+ @SuppressWarnings({ "unchecked" })
+ @Test
+ public void test() throws Exception {
+
+ // Connect to sub model "CfgFileTestAAS"
+ VABElementProxy connSubModel = this.connManager.connectToVABElement("AASProvider");
+
+
+ // Create map with complex type
+ AssetAdministrationShell aas = new AssetAdministrationShell();
+ aas.setIdShort("testAAS");
+
+ // Create AAS structure on server
+ connSubModel.createValue("/aas", aas);
+
+
+ // Read complex property completely
+ Map<String, Object> aasReadBack = (Map<String, Object>) connSubModel.getModelPropertyValue("/aas");
+
+ assertEquals(aas.getIdShort(), AssetAdministrationShell.createAsFacade(aasReadBack).getIdShort());
+
+ // Read AAS SubModel
+ Map<String, Object> smReadBack = (Map<String, Object>) connSubModel
+ .getModelPropertyValue("/aas/submodels/rawSampleCFG");
+
+ assertEquals("rawSampleCFG", SubModel.createAsFacade(smReadBack).getIdShort());
+
+ }
+}
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderAASNewModel.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderAASNewModel.java
new file mode 100644
index 0000000..784ed50
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderAASNewModel.java
@@ -0,0 +1,62 @@
+package org.eclipse.basyx.sandbox.regression.components.rawcfgprovider;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Map;
+
+import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
+import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+
+/**
+ * Test queries to CFG file provider
+ *
+ * @author kuhn
+ *
+ */
+public class TestRawCFGProviderAASNewModel {
+
+
+ /**
+ * VAB connection manager backend
+ */
+ protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(), new HTTPConnectorProvider());
+
+ /**
+ * Makes sure Tomcat Server is started
+ */
+ @ClassRule
+ public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
+
+ /**
+ * Test basic queries
+ */
+ @SuppressWarnings({ "unchecked", "unused" })
+ @Test
+ public void test() throws Exception {
+
+ // Connect to sub model "CfgFileTestAAS"
+ VABElementProxy connSubModel = this.connManager.connectToVABElement("RawCfgFileTestAAS");
+
+
+ // Create map with complex type
+ Property prop = new Property ();
+ prop.setIdShort("prop");
+ // Create AAS structure on server
+ connSubModel.createValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES, prop);
+
+
+ // Read complex property completely
+ Map<String, Object> aasReadBack = (Map<String, Object>) connSubModel.getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/prop");
+ assertEquals(prop.getIdShort(), Property.createAsFacade(prop).getIdShort());
+ }
+}
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderSimpleValues.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderSimpleValues.java
new file mode 100644
index 0000000..4863157
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderSimpleValues.java
@@ -0,0 +1,88 @@
+package org.eclipse.basyx.sandbox.regression.components.rawcfgprovider;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Map;
+
+import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
+import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.AdministrativeInformation;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+/**
+ * Test queries to CFG file provider
+ *
+ * @author kuhn
+ *
+ */
+public class TestRawCFGProviderSimpleValues {
+
+ /**
+ * VAB connection manager backend
+ */
+ protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(),
+ new HTTPConnectorProvider());
+
+ /**
+ * Makes sure Tomcat Server is started
+ */
+ @ClassRule
+ public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
+
+ /**
+ * Test basic queries
+ */
+ @SuppressWarnings("unchecked")
+ @Test
+ public void test() throws Exception {
+
+ // Connect to sub model "CfgFileTestAAS"
+ VABElementProxy connSubModel = this.connManager.connectToVABElement("RawCfgFileTestAAS");
+
+ // Check sub model meta data
+ Map<String, Object> submodel = (Map<String, Object>) connSubModel
+ .getModelPropertyValue("/aas/submodels/rawSampleCFG");
+ assertEquals("1.0",
+ AdministrativeInformation.createAsFacade((Map<String, Object>) submodel.get(Identifiable.ADMINISTRATION))
+ .getVersion());
+
+ // Get property value
+ Map<String, Object> value1 = (Map<String, Object>) connSubModel
+ .getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty1/value");
+ assertEquals("exampleStringValueRaw", value1.get(Property.VALUE));
+ Map<String, Object> cfgProperty1 = (Map<String, Object>) connSubModel
+ .getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty1");
+ assertEquals("Configuration property description", cfgProperty1.get("description"));
+
+ // Get property value
+ Map<String, Object> value2 = (Map<String, Object>) connSubModel
+ .getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty2/value");
+ assertEquals(12, value2.get(Property.VALUE));
+ // - Check property meta data (description)
+ Map<String, Object> cfgProperty2 = (Map<String, Object>) connSubModel
+ .getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty2");
+ assertEquals("Configuration property description on multiple lines", cfgProperty2.get("description"));
+
+ // Get property value
+ Map<String, Object> value3 = (Map<String, Object>) connSubModel
+ .getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty3/value");
+ assertEquals("45.8", value3.get(Property.VALUE));
+
+ // Get property value
+ Map<String, Object> value4 = (Map<String, Object>) connSubModel
+ .getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty4/value");
+ assertEquals("44.8", value4.get(Property.VALUE));
+ Map<String, Object> cfgProperty4 = (Map<String, Object>) connSubModel
+ .getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty4");
+ assertEquals("Another configuration property description", cfgProperty4.get("description"));
+ assertEquals("8", cfgProperty4.get("newMetaData"));
+ }
+}
diff --git a/sdks/c++/basys.sdk.cc/.gitignore b/sdks/c++/basys.sdk.cc/.gitignore
index 24c9089..b0357a0 100644
--- a/sdks/c++/basys.sdk.cc/.gitignore
+++ b/sdks/c++/basys.sdk.cc/.gitignore
@@ -4,5 +4,6 @@
.cproject
bin/
compile_commands.json
-.clangd
-run-msbuild.bat
\ No newline at end of file
+run-msbuild.bat
+.clangd/
+*.swp
diff --git a/sdks/c++/basys.sdk.cc/CMakeLists.txt b/sdks/c++/basys.sdk.cc/CMakeLists.txt
index c79f618..ec9b6d6 100644
--- a/sdks/c++/basys.sdk.cc/CMakeLists.txt
+++ b/sdks/c++/basys.sdk.cc/CMakeLists.txt
@@ -13,6 +13,9 @@
include(enable_testbed)
include(GNUInstallDirs)
+# Check if standalone build or being included as submodule
+get_directory_property(BASYX_IS_SUBMODULE PARENT_DIRECTORY)
+
set (BASYX_PACKAGE_VERSION_MAJOR "0")
set (BASYX_PACKAGE_VERSION_MINOR "1")
set (BASYX_PACKAGE_VERSION_PATCH "0")
@@ -34,24 +37,43 @@
message(STATUS "CMAKE_BINARY_DIR: ${CMAKE_BINARY_DIR}")
message(STATUS "" )
+if(NOT BASYX_IS_SUBMODULE)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
+endif()
### BaSyx directories ###
-set(BASYX_SOURCE_DIR "${CMAKE_SOURCE_DIR}/src")
-set(BASYX_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/include")
-set(BASYX_TEST_DIR "${CMAKE_SOURCE_DIR}/regression")
-set(BASYX_LIBRARY_DIR "${CMAKE_SOURCE_DIR}/lib")
+set(BASYX_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src")
+set(BASYX_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include")
+set(BASYX_TEST_DIR "${CMAKE_CURRENT_SOURCE_DIR}/regression")
+set(BASYX_LIBRARY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/lib")
+
+## Set project defaults
+if(BASYX_IS_SUBMODULE)
+ message(STATUS "BaSyx included as submodule.")
+ set(BASYX_BUILD_TESTS_DEFAULT OFF)
+ set(BASYX_UTILITY_PROJECTS_DEFAULT OFF)
+ set(BASYX_INSTALL_SDK_DEFAULT OFF)
+ set(BUILD_SHARED_LIBS_DEFAULT OFF)
+ set(BASYX_VERBOSE_CMAKE_OUTPUT OFF)
+else()
+ set(BASYX_BUILD_TESTS_DEFAULT ON)
+ set(BASYX_UTILITY_PROJECTS_DEFAULT ON)
+ set(BASYX_INSTALL_SDK_DEFAULT ON)
+ set(BUILD_SHARED_LIBS_DEFAULT OFF)
+endif()
### Build options ###
-set(BASYX_BUILD_TESTS ON CACHE BOOL "Build unit tests")
+set(BASYX_BUILD_TESTS ${BASYX_BUILD_TESTS_DEFAULT} CACHE BOOL "Build unit tests")
set(BASYX_BUILD_API ON CACHE BOOL "Build BaSyx API")
-set(BASYX_UTILITY_PROJECTS ON CACHE BOOL "Create utility targets")
+set(BASYX_UTILITY_PROJECTS ${BASYX_UTILITY_PROJECTS_DEFAULT} CACHE BOOL "Create utility targets")
set(BASYX_DEBUG_PRINT_FRAMES OFF CACHE BOOL "Print BaSyx frames")
-set(BASYX_INSTALL_SDK ON CACHE BOOL "Create install instructions for BaSyx SDK")
+set(BASYX_INSTALL_SDK ${BASYX_INSTALL_SDK_DEFAULT} CACHE BOOL "Create install instructions for BaSyx SDK")
+option(BASYX_VERBOSE_CMAKE_OUTPUT "Show detailed CMake output" ON)
-set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build Shared (.so / .dll) instead of static libraries")
+
+set(BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS_DEFAULT} CACHE BOOL "Build Shared (.so / .dll) instead of static libraries")
option(BASYX_USE_SYSTEM_LIBFMT "Wether to build external, yet included library libfmt" OFF)
option(BASYX_USE_SYSTEM_ASIO "Use system supplied ASIO library." OFF)
@@ -64,8 +86,12 @@
add_compile_definitions(BASYX_MAJOR_REV=${BASYX_PACKAGE_VERSION_MAJOR})
add_compile_definitions(BASYX_MINOR_REV=${BASYX_PACKAGE_VERSION_MINOR})
add_compile_definitions(BASYX_PATCH_REV=${BASYX_PACKAGE_VERSION_PATCH})
-add_compile_definitions(WIN32_LEAN_AND_MEAN)
-##add_compile_definitions(__USE_MINGW_ANSI_STDIO=0)
+
+### Load system specific config ###
+if(WIN32)
+ include(config.windows)
+endif()
+
###############################################
### Library Settings ###
@@ -106,7 +132,7 @@
###############################################
### Source Directory ###
###############################################
-include_directories("${BASYX_INCLUDE_DIR}")
+#include_directories("${BASYX_INCLUDE_DIR}")
add_subdirectory(src/abstraction)
add_subdirectory(src/logging)
@@ -115,7 +141,7 @@
add_subdirectory(src/vab)
add_subdirectory(src/server)
add_subdirectory(src/submodel)
-add_subdirectory(src/aas)
+add_subdirectory(src/controlcomponent)
###############################################
### Test Directory ###
@@ -147,7 +173,7 @@
# Let the projects using our server infrastucure find asio (interally /
# externally provided)
-install(FILES ${CMAKE_CURRENT_BINARY_DIR}/cmake/Findasio.cmake
+install(FILES ${CMAKE_SOURCE_DIR}/cmake/Findasio.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/BaSyxAsio
)
@@ -188,4 +214,4 @@
BaSyx, please use distribution provided libraries if possible!")
endif()
-endif() # ${BASYX_INSTALL_SDK}
\ No newline at end of file
+endif() # ${BASYX_INSTALL_SDK}
diff --git a/sdks/c++/basys.sdk.cc/cmake/config.windows.cmake b/sdks/c++/basys.sdk.cc/cmake/config.windows.cmake
new file mode 100644
index 0000000..9c599cc
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/cmake/config.windows.cmake
@@ -0,0 +1,3 @@
+add_compile_definitions(WIN32_LEAN_AND_MEAN)
+add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
+add_compile_options(/wd4250)
diff --git a/sdks/c++/basys.sdk.cc/cmake/diagnostics_print.cmake b/sdks/c++/basys.sdk.cc/cmake/diagnostics_print.cmake
index e5e807e..a07ec14 100644
--- a/sdks/c++/basys.sdk.cc/cmake/diagnostics_print.cmake
+++ b/sdks/c++/basys.sdk.cc/cmake/diagnostics_print.cmake
@@ -6,9 +6,7 @@
### about the specified target
###
-function( diagnostics_print target_name )
- build_source_group(${target_name})
-
+function( diagnostics_print target_name )
message(STATUS "${target_name} settings:")
message(STATUS "==============\n")
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/manager/IAssetAdministrationShellManager.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/manager/IAssetAdministrationShellManager.h
deleted file mode 100644
index 7ce4948..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/manager/IAssetAdministrationShellManager.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * IAssetAdministrationShellManager.h
- *
- * Author: wendel
- */
-
-#ifndef IASSETADMINISTRATIONSHELLMANAGER_H_
-#define IASSETADMINISTRATIONSHELLMANAGER_H_
-
-#include <string>
-#include "aas/api/metamodel/IAssetAdministrationShell.h"
-#include "aas/map/modelurn/ModelUrn.h"
-#include "submodel/api/ISubModel.h"
-
-namespace basyx {
-namespace aas {
-namespace api {
-namespace manager {
-
-class IAssetAdministrationShellManager
-{
-public:
- ~IAssetAdministrationShellManager() = default;
- virtual std::shared_ptr<IAssetAdministrationShell> retrieveAAS(ModelUrn aasUrn) = 0;
- virtual basyx::specificCollection_t<IAssetAdministrationShell> retrieveAASAll() = 0;
- virtual void createAAS(std::shared_ptr<IAssetAdministrationShell> aas, ModelUrn urn) = 0;
- virtual void deleteAAS(std::string id) = 0;
- virtual std::shared_ptr<submodel::ISubModel> retrieveSubModel(ModelUrn aasUrn, std::string subModelId) = 0;
- virtual void createSubModel(ModelUrn aasUrn, std::shared_ptr<submodel::ISubModel> submodel) = 0;
-};
-
-}
-}
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/metamodel/IAssetAdministrationShell.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/metamodel/IAssetAdministrationShell.h
deleted file mode 100644
index 999f7cd..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/metamodel/IAssetAdministrationShell.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * IAssetAdministrationShell.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_IASSETADMINISTRATIONSHELL_H_
-#define AAS_IASSETADMINISTRATIONSHELL_H_
-
-#include <BaSyx/submodel/api/qualifier/IHasDataSpecification.h>
-#include <BaSyx/submodel/api/qualifier/IIdentifiable.h>
-#include <BaSyx/submodel/api/qualifier/IReferable.h>
-#include <BaSyx/aas/api/security/ISecurity.h>
-#include <BaSyx/submodel/api/reference/IReference.h>
-
-#include <memory>
-
-namespace basyx {
-namespace aas {
-
-class IAssetAdministrationShell
- : public virtual submodel::IHasDataSpecification
- , public virtual submodel::IIdentifiable
- , public virtual submodel::IReferable
-{
-public:
- struct Path
- {
- static constexpr char ModelType[] = "AssetAdministationShell";
- static constexpr char Security[] = "security";
- static constexpr char DerivedFrom[] = "derivedFrom";
- };
-public:
- virtual std::shared_ptr<ISecurity> getSecurity() const = 0;
- virtual void setSecurity(std::shared_ptr<ISecurity> security) const = 0;
-
- virtual std::shared_ptr<submodel::IReference> getDerivedFrom() const = 0;
- virtual void setDerivedFrom(std::shared_ptr<submodel::IReference> derived_from) const = 0;
-};
-
-}
-}
-
-#endif
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/parts/IAsset.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/parts/IAsset.h
deleted file mode 100644
index 982869e..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/parts/IAsset.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * IAsset.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IAsset_H_
-#define BASYX_METAMODEL_IAsset_H_
-
-
-#include <BaSyx/submodel/api/qualifier/IHasDataSpecification.h>
-#include <BaSyx/submodel/api/qualifier/IHasKind.h>
-#include <BaSyx/submodel/api/qualifier/IIdentifiable.h>
-#include <BaSyx/submodel/api/reference/IReference.h>
-
-namespace basyx {
-namespace aas {
-
-class IAsset :
- public virtual submodel::IHasDataSpecification,
- public virtual submodel::IHasKind,
- public virtual submodel::IIdentifiable
-{
-public:
- struct Path
- {
- static constexpr char AssetIdentificationModel[] = "assetIdentificationModel";
- static constexpr char ModelType[] = "Asset";
- static constexpr char BillOfMaterial[] = "billOfMaterial";
- };
-public:
- virtual ~IAsset() = default;
-
- virtual std::shared_ptr<submodel::IReference> getAssetIdentificationModel() const = 0;
- virtual std::shared_ptr<submodel::IReference> getBillOfMaterial() const = 0;
-};
-
-}
-}
-
-#endif
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/parts/IConceptDictionary.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/parts/IConceptDictionary.h
deleted file mode 100644
index 36a4ac1..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/parts/IConceptDictionary.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * IConceptDictionary.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IConceptDictionary_H_
-#define BASYX_METAMODEL_IConceptDictionary_H_
-
-
-#include <BaSyx/submodel/api/qualifier/IReferable.h>
-
-#include <string>
-#include <vector>
-
-namespace basyx {
-namespace aas {
-
-class IConceptDictionary
- : public submodel::IReferable
-{
-public:
- struct Path {
- static constexpr char ConceptDescription[] = "conceptDescription";
- static constexpr char ConceptDescriptions[] = "conceptDescriptions";
- };
-
- virtual ~IConceptDictionary() = default;
-
- virtual basyx::specificCollection_t<submodel::IReference> getConceptDescription() const = 0;
- virtual void setConceptDescription(const basyx::specificCollection_t<submodel::IReference> & references) = 0;
-};
-
-}
-}
-
-#endif
-
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/parts/IView.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/parts/IView.h
deleted file mode 100644
index bbb0c3c..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/parts/IView.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * IView.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IView_H_
-#define BASYX_METAMODEL_IView_H_
-
-
-#include <BaSyx/submodel/api/qualifier/IHasSemantics.h>
-#include <BaSyx/submodel/api/qualifier/IHasDataSpecification.h>
-#include <BaSyx/submodel/api/qualifier/IReferable.h>
-#include <BaSyx/submodel/api/reference/IReference.h>
-
-namespace basyx {
-namespace aas {
-
-class IView :
- public submodel::IHasDataSpecification,
- public submodel::IHasSemantics,
- public submodel::IReferable
-{
-public:
- struct Path
- {
- static constexpr char ContainedElement[] = "containedElement";
- static constexpr char ModelType[] = "View";
- };
-public:
- virtual ~IView() = default;
-
- virtual void setContainedElements(const basyx::specificCollection_t<submodel::IReference> & references) = 0;
- virtual basyx::specificCollection_t<submodel::IReference> getContainedElements() const = 0;
-};
-
-}
-}
-
-#endif
-
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/policypoints/IAccessControlPolicyPoints.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/policypoints/IAccessControlPolicyPoints.h
deleted file mode 100644
index cc0800c..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/policypoints/IAccessControlPolicyPoints.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * IAccessControlPolicyPoints.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IAccessControlPolicyPoints_H_
-#define BASYX_METAMODEL_IAccessControlPolicyPoints_H_
-
-
-#include "types/BaSysTypes.h"
-
-class IAccessControlPolicyPoints
-{
-public:
- virtual ~IAccessControlPolicyPoints() = default;
-
- virtual void setPolicyAdministrationPoint(const basyx::object & obj) = 0;
- virtual basyx::object getPolicyAdministrationPoint() const = 0;
-
- virtual void setPolicyDecisionPoint(const basyx::object & obj) = 0;
- virtual basyx::object getPolicyDecisionPoint() const = 0;
-
- virtual void setPolicyEnforcementPoint(const basyx::object & obj) = 0;
- virtual basyx::object getPolicyEnforcementPoint() const = 0;
-
- virtual void setPolicyInformationPoints(const basyx::object & obj) = 0;
- virtual basyx::object getPolicyInformationPoints() const = 0;
-
-};
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/security/ISecurity.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/security/ISecurity.h
deleted file mode 100644
index 3107f30..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/security/ISecurity.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * ISecurity.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_ISecurity_H_
-#define BASYX_METAMODEL_ISecurity_H_
-
-#include <BaSyx/shared/types.h>
-#include <BaSyx/shared/object.h>
-
-namespace basyx {
-namespace aas {
-
-class ISecurity
-{
-public:
- struct Path
- {
- static constexpr char AccessControlPolicyPoints[] = "accessControlPolicyPoints";
- static constexpr char TrustAnchor[] = "trustAnchor";
- };
-public:
- virtual ~ISecurity() = default;
-
- virtual basyx::object getAccessControlPolicyPoints() const = 0;
- virtual basyx::object getTrustAnchor() const = 0;
-};
-
-}
-}
-
-#endif
-
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/connected/ConnectedAssetAdministrationShell.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/connected/ConnectedAssetAdministrationShell.h
deleted file mode 100644
index 736bae6..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/connected/ConnectedAssetAdministrationShell.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * ConnectedAssetAdministrationShell.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_BACKEND_CONNECTED_CONNECTEDASSETADMINISTRATIONSHELL_H_
-#define AAS_BACKEND_CONNECTED_CONNECTEDASSETADMINISTRATIONSHELL_H_
-
-#include "aas/api/metamodel/IAssetAdministrationShell.h"
-#include "submodel/connected/ConnectedVABModelMap.h"
-#include "aas/api/manager/IAssetAdministrationShellManager.h"
-
-namespace basyx {
-namespace aas {
-namespace backend {
-
-class ConnectedAssetAdministrationShell : public api::IAssetAdministrationShell, public submodel::backend::ConnectedVABModelMap
-{
-public:
- ConnectedAssetAdministrationShell(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy, std::shared_ptr<api::manager::IAssetAdministrationShellManager> manager);
- ~ConnectedAssetAdministrationShell() = default;
-
-private:
- std::shared_ptr<api::manager::IAssetAdministrationShellManager> manager;
-
- // Inherited via IAssetAdministrationShell
- virtual basyx::specificCollection_t<submodel::IReference> getDataSpecificationReferences() const override;
- virtual std::string getIdShort() const override;
- virtual std::string getCategory() const override;
- virtual submodel::Description getDescription() const override;
- virtual std::shared_ptr<submodel::IReference> getParent() const override;
- virtual std::shared_ptr<submodel::IAdministrativeInformation> getAdministration() const override;
- virtual std::shared_ptr<submodel::IIdentifier> getIdentification() const override;
- virtual basyx::specificMap_t<submodel::ISubModel> getSubModels() const override;
- virtual void addSubModel(const descriptor::SubModelDescriptor & subModelDescriptor) override;
- virtual std::shared_ptr<security::ISecurity> getSecurity() const override;
- virtual std::shared_ptr<submodel::IReference> getDerivedFrom() const override;
- virtual std::shared_ptr<aas::IAsset> getAsset() const override;
- virtual void setSubmodels(const basyx::specificCollection_t<descriptor::SubModelDescriptor> & submodels) override;
- virtual basyx::specificCollection_t<descriptor::SubModelDescriptor> getSubModelDescriptors() const override;
- virtual basyx::specificCollection_t<IView> getViews() const override;
- virtual basyx::specificCollection_t<IConceptDictionary> getConceptDictionary() const override;
-};
-
-}
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/connected/ConnectedAssetAdministrationShellManager.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/connected/ConnectedAssetAdministrationShellManager.h
deleted file mode 100644
index 0d15cb2..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/connected/ConnectedAssetAdministrationShellManager.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * ConnectedAssetAdministrationShellManager.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_BACKEND_CONNECTED_CONNECTEDASSETADMINISTRATIONSHELLMANAGER_H_
-#define AAS_BACKEND_CONNECTED_CONNECTEDASSETADMINISTRATIONSHELLMANAGER_H_
-
-class ConnectedAssetAdministrationShellManager
-{
-public:
- ~ConnectedAssetAdministrationShellManager();
-};
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/descriptor/ModelDescriptor.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/descriptor/ModelDescriptor.h
deleted file mode 100644
index fffde9a..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/descriptor/ModelDescriptor.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * ModelDescriptor.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_IMPL_METAMODEL_HASHMAP_DESCRIPTOR_MODELDESCRIPTOR_H_
-#define AAS_IMPL_METAMODEL_HASHMAP_DESCRIPTOR_MODELDESCRIPTOR_H_
-
-#include <string>
-
-#include <BaSyx/shared/types.h>
-#include <BaSyx/shared/object.h>
-
-#include <BaSyx/submodel/api/identifier/IIdentifier.h>
-
-namespace basyx {
-namespace aas {
-
-class ModelDescriptor
-{
-public:
- ~ModelDescriptor() = default;
- ModelDescriptor(basyx::object map);
-
- /**
- * Create a new descriptor with minimal information
- */
- ModelDescriptor(std::string idShort, std::shared_ptr<submodel::IIdentifier> id, std::string httpEndpoint);
-
- /**
- * Return AAS ID
- */
- std::shared_ptr<submodel::IIdentifier> getIdentifier();
-
- /**
- * Return first AAS endpoint
- */
- std::string getFirstEndpoint();
-
- /**
- * Return all AAS endpoints
- */
- basyx::object::list_t<basyx::object::object_map_t> getEndpoints();
-
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/descriptor/SubModelDescriptor.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/descriptor/SubModelDescriptor.h
deleted file mode 100644
index 241448e..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/descriptor/SubModelDescriptor.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * SubModelDescriptor.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_IMPL_METAMODEL_HASHMAP_DESCRIPTOR_SUBMODELDESCRIPTOR_H_
-#define AAS_IMPL_METAMODEL_HASHMAP_DESCRIPTOR_SUBMODELDESCRIPTOR_H_
-
-#include "ModelDescriptor.h"
-
-#include <BaSyx/submodel/api/ISubModel.h>
-
-namespace basyx {
-namespace aas {
-namespace descriptor {
-
-class SubModelDescriptor : public ModelDescriptor
-{
-public:
- ~SubModelDescriptor() = default;
-
- SubModelDescriptor(basyx::object::object_map_t map);
-
- /**
- * Create a new aas descriptor with minimal information based on an existing
- * submodel.
- */
- SubModelDescriptor(std::shared_ptr<submodel::ISubModel> subModel, std::string httpEndpoint);
-
- /**
- * Create a new descriptor with minimal information
- */
- SubModelDescriptor(std::string idShort, std::shared_ptr<submodel::IIdentifier> identifier, std::string httpEndpoint);
-};
-
-}
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/manager/AssetAdministrationShellManager.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/manager/AssetAdministrationShellManager.h
deleted file mode 100644
index 661c2c5..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/manager/AssetAdministrationShellManager.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * AssetAdministrationShellManager.h
- *
- * Author: wendel
- */
-
-#ifndef ASSETADMINISTRATIONSHELLMANAGER_H_
-#define ASSETADMINISTRATIONSHELLMANAGER_H_
-
-class AssetAdministrationShellManager
-{
-public:
- ~AssetAdministrationShellManager() = default;
-};
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/metamodel/AssetAdministrationShell.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/metamodel/AssetAdministrationShell.h
deleted file mode 100644
index 3b2359a..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/metamodel/AssetAdministrationShell.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * AssetAdministrationShell.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_IMPL_METAMODEL_HASHMAP_ASSETADMINISTRATIONSHELL_H_
-#define AAS_IMPL_METAMODEL_HASHMAP_ASSETADMINISTRATIONSHELL_H_
-
-#include <BaSyx/aas/api/metamodel/IAssetAdministrationShell.h>
-
-#include <BaSyx/submodel/map/qualifier/HasDataSpecification.h>
-#include <BaSyx/submodel/map/qualifier/Identifiable.h>
-#include <BaSyx/submodel/map/qualifier/Referable.h>
-#include <BaSyx/submodel/map/modeltype/ModelType.h>
-
-#include <BaSyx/shared/object.h>
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace aas {
-
-class AssetAdministrationShell
- : public IAssetAdministrationShell
- , public virtual vab::ElementMap
- , public virtual submodel::HasDataSpecification
- , public virtual submodel::Identifiable
- , public virtual submodel::Referable
- , public virtual submodel::ModelType
-{
-public:
- ~AssetAdministrationShell() = default;
-
- // constructors
- AssetAdministrationShell();
- AssetAdministrationShell(basyx::object obj);
- AssetAdministrationShell(std::shared_ptr<submodel::IReference> parentAAS);
-
- // Inherited via IAssetAdministrationShell
- virtual std::shared_ptr<ISecurity> getSecurity() const override;
- virtual void setSecurity(std::shared_ptr<ISecurity> security) const override;
- virtual std::shared_ptr<submodel::IReference> getDerivedFrom() const override;
- virtual void setDerivedFrom(std::shared_ptr<submodel::IReference> derived_from) const override;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/modelurn/ModelUrn.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/modelurn/ModelUrn.h
deleted file mode 100644
index 1210e66..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/modelurn/ModelUrn.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * ModelUrn.h
- *
- * Author: wendel
- */
-
-#ifndef MODELURN_H_
-#define MODELURN_H_
-
-class ModelUrn
-{
-public:
- ~ModelUrn();
-};
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/parts/Asset.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/parts/Asset.h
deleted file mode 100644
index d5dcffd..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/parts/Asset.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Asset.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_IMPL_METAMODEL_HASHMAP_PARTS_ASSET_H_
-#define AAS_IMPL_METAMODEL_HASHMAP_PARTS_ASSET_H_
-
-#include <BaSyx/aas/api/parts/IAsset.h>
-
-#include <BaSyx/submodel/map/qualifier/HasDataSpecification.h>
-#include <BaSyx/submodel/map/qualifier/HasKind.h>
-#include <BaSyx/submodel/map/qualifier/Identifiable.h>
-#include <BaSyx/submodel/map/modeltype/ModelType.h>
-
-namespace basyx {
-namespace aas {
-
-class Asset
- : public IAsset
- , public virtual submodel::HasKind
- , public virtual submodel::HasDataSpecification
- , public virtual submodel::Identifiable
- , public virtual submodel::ModelType
-{
-public:
- ~Asset() = default;
-
- // constructors
- Asset();
-
- /**
- *
- * @param submodel A reference to a Submodel that defines the handling of
- * additional domain specific (proprietary) Identifiers for the
- * asset like e.g. serial number etc.
- */
- Asset(const std::shared_ptr<submodel::IReference> & submodel);
-
- // Inherited via IAsset
- virtual std::shared_ptr<submodel::IReference> getAssetIdentificationModel() const override;
- virtual std::shared_ptr<submodel::IReference> getBillOfMaterial() const override;
-
-
- void setAssetIdentificationModel(const std::shared_ptr<submodel::IReference>& submodel);
- void setBillOfMaterial(const std::shared_ptr<submodel::IReference>& submodel);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/parts/ConceptDictionary.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/parts/ConceptDictionary.h
deleted file mode 100644
index 82c923b..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/parts/ConceptDictionary.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * ConceptDictionary.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_IMPL_METAMODEL_HASHMAP_PARTS_CONCEPTDICTIONARY_H_
-#define AAS_IMPL_METAMODEL_HASHMAP_PARTS_CONCEPTDICTIONARY_H_
-
-#include <BaSyx/aas/api/parts/IConceptDictionary.h>
-
-#include <BaSyx/submodel/api/parts/IConceptDescription.h>
-#include <BaSyx/submodel/map/qualifier/Referable.h>
-
-namespace basyx {
-namespace aas {
-
-class ConceptDictionary
- : public virtual IConceptDictionary
- , public virtual submodel::Referable
- , public virtual basyx::vab::ElementMap
-{
-public:
- ~ConceptDictionary() = default;
-
- ConceptDictionary(basyx::object obj);
- ConceptDictionary(basyx::specificCollection_t<submodel::IReference> concept_descriptions);
-
-
- // Inherited via IConceptDictionary
- virtual basyx::specificCollection_t<submodel::IReference> getConceptDescription() const override;
- virtual void setConceptDescription(const basyx::specificCollection_t<submodel::IReference> & references) override;
-
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/parts/View.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/parts/View.h
deleted file mode 100644
index 4f2981d..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/parts/View.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * View.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_IMPL_METAMODEL_HASHMAP_PARTS_VIEW_H_
-#define AAS_IMPL_METAMODEL_HASHMAP_PARTS_VIEW_H_
-
-#include <BaSyx/aas/api/parts/IView.h>
-
-#include <BaSyx/submodel/map/modeltype/ModelType.h>
-#include <BaSyx/submodel/map/qualifier/HasDataSpecification.h>
-#include <BaSyx/submodel/map/qualifier/Referable.h>
-#include <BaSyx/submodel/map/qualifier/HasSemantics.h>
-
-namespace basyx {
-namespace aas {
-
-class View
- : public IView
- , public virtual vab::ElementMap
- , public virtual submodel::ModelType
- , public virtual submodel::HasDataSpecification
- , public virtual submodel::HasSemantics
-{
-public:
- ~View() = default;
-
- View(basyx::object obj);
- View();
- View(const basyx::specificCollection_t<submodel::IReference> & references);
-
- // Inherited via IView
- virtual void setContainedElements(const basyx::specificCollection_t<submodel::IReference> & references) override;
- virtual basyx::specificCollection_t<submodel::IReference> getContainedElements() const override;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/security/Security.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/security/Security.h
deleted file mode 100644
index 86b17b8..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/security/Security.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Security.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_IMPL_METAMODEL_HASHMAP_SECURITY_SECURITY_H_
-#define AAS_IMPL_METAMODEL_HASHMAP_SECURITY_SECURITY_H_
-
-#include <BaSyx/aas/api/security/ISecurity.h>
-
-#include <BaSyx/shared/types.h>
-
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace aas {
-
-class Security
- : public ISecurity
- , public virtual vab::ElementMap
-{
-public:
- ~Security() = default;
-
- Security(ISecurity & other);
- Security(basyx::object obj);
-
- // Inherited via ISecurity
- virtual basyx::object getAccessControlPolicyPoints() const override;
- virtual basyx::object getTrustAnchor() const override;
-
- void setAccessControlPolicyPoints(const basyx::object & obj);
- void setTrustAnchor(const basyx::object & obj);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/Net.h b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/Net.h
index 4fe62bd..f1bd828 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/Net.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/Net.h
@@ -1,3 +1,6 @@
+#ifndef BASYX_ABSTRACTION_NET_H
+#define BASYX_ABSTRACTION_NET_H
+
/*
* Net.h
*
@@ -9,3 +12,5 @@
#include <BaSyx/abstraction/net/Acceptor.h>
#include <BaSyx/abstraction/net/Buffer.h>
#include <BaSyx/abstraction/net/Socket.h>
+
+#endif /* BASYX_ABSTRACTION_NET_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/Thread.h b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/Thread.h
index 6509c16..4b2dfc3 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/Thread.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/Thread.h
@@ -1,3 +1,6 @@
+#ifndef BASYX_ABSTRACTION_THREAD_H
+#define BASYX_ABSTRACTION_THREAD_H
+
/*
* Thread.h
*
@@ -6,3 +9,5 @@
*/
#include <BaSyx/abstraction/thread/Thread.h>
+
+#endif /* BASYX_ABSTRACTION_THREAD_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/acceptor_impl.h b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/acceptor_impl.h
index 5b79cd7..58c3b00 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/acceptor_impl.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/acceptor_impl.h
@@ -1,12 +1,5 @@
-/*
- * Socket.h
- *
- * Created on: 06.11.2018
- * Author: schnicke
- */
-
-#ifndef ABSTRACTION_ACCEPTOR_IMPL_H_
-#define ABSTRACTION_ACCEPTOR_IMPL_H_
+#ifndef BASYX_ABSTRACTION_IMPL_ACCEPTOR_IMPL_H
+#define BASYX_ABSTRACTION_IMPL_ACCEPTOR_IMPL_H
#include <cstdlib>
@@ -18,34 +11,34 @@
#include <BaSyx/log/log.h>
namespace basyx {
- namespace net {
- namespace impl {
+namespace net {
+namespace impl {
- // Forward declarations
- class socket_impl;
+// Forward declarations
+class socket_impl;
- class acceptor_impl
- {
- public:
- acceptor_impl()
- : log{ "AcceptorImpl" } {};
- ~acceptor_impl();
- public:
- int listen(const std::string & port);
+class acceptor_impl {
+public:
+ acceptor_impl()
+ : log { "AcceptorImpl" } {};
+ ~acceptor_impl();
- std::unique_ptr<socket_impl> accept();
- int shutdown(enum SocketShutdownDir how);
- int close();
+public:
+ int listen(const std::string& port);
- int getErrorCode();
- private:
- native_socket_type socketDesc = 0;
- basyx::log log;
- };
+ std::unique_ptr<socket_impl> accept();
+ int shutdown(enum SocketShutdownDir how);
+ int close();
+ int getErrorCode();
- }
- }
+private:
+ native_socket_type socketDesc = 0;
+ basyx::log log;
+};
+
+}
+}
}
-#endif /* ABSTRACTION_ACCEPTOR_IMPL_H_ */
+#endif /* BASYX_ABSTRACTION_IMPL_ACCEPTOR_IMPL_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/socket_impl.h b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/socket_impl.h
index 4cba639..30ae729 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/socket_impl.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/socket_impl.h
@@ -1,12 +1,5 @@
-/*
- * Socket.h
- *
- * Created on: 06.11.2018
- * Author: schnicke
- */
-
-#ifndef ABSTRACTION_SOCKET_IMPL_H_
-#define ABSTRACTION_SOCKET_IMPL_H_
+#ifndef BASYX_ABSTRACTION_IMPL_SOCKET_IMPL_H
+#define BASYX_ABSTRACTION_IMPL_SOCKET_IMPL_H
#include <BaSyx/abstraction/impl/system_net_types.h>
@@ -17,32 +10,33 @@
namespace basyx {
namespace net {
- namespace impl {
+namespace impl {
- class socket_impl
- {
- private:
- native_socket_type SocketDesc;
- basyx::log log;
- public:
- socket_impl();
-
- explicit socket_impl(native_socket_type socket);
-
- ~socket_impl();
+class socket_impl
+{
+private:
+ native_socket_type SocketDesc;
+ basyx::log log;
+public:
+ socket_impl();
+
+ explicit socket_impl(native_socket_type socket);
+
+ ~socket_impl();
- public:
- int connect(std::string const&, std::string const&);
- int read(void*, size_t);
- int recv(void*, size_t, int);
- int write(void*, size_t);
+public:
+ int connect(std::string const&, std::string const&);
+ int read(void*, size_t);
+ int recv(void*, size_t, int);
+ int write(void*, size_t);
- int shutdown(enum SocketShutdownDir how);
- int close();
+ int shutdown(enum SocketShutdownDir how);
+ int close();
- int getErrorCode();
- };
- }
+ int getErrorCode();
+};
+
}
}
-#endif /* ABSTRACTION_SOCKET_IMPL_H_ */
+}
+#endif /* BASYX_ABSTRACTION_IMPL_SOCKET_IMPL_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/system_net_types.h b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/system_net_types.h
index 5af9050..fa0d7c3 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/system_net_types.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/system_net_types.h
@@ -1,5 +1,5 @@
-#ifndef ABSTRACTION_SYSTEM_NET_TYPES_H
-#define ABSTRACTION_SYSTEM_NET_TYPES_H
+#ifndef BASYX_ABSTRACTION_IMPL_SYSTEM_NET_TYPES_H
+#define BASYX_ABSTRACTION_IMPL_SYSTEM_NET_TYPES_H
#ifdef _WIN32
#if _WIN32_WINNT <= 0x501
@@ -31,4 +31,4 @@
};
#endif
-#endif
+#endif /* BASYX_ABSTRACTION_IMPL_SYSTEM_NET_TYPES_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/thread_impl.h b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/thread_impl.h
index 2d2567f..00724f9 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/thread_impl.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/thread_impl.h
@@ -1,5 +1,5 @@
-#ifndef ABSTRACTION_IMPL_THREAD_H
-#define ABSTRACTION_IMPL_THREAD_H
+#ifndef BASYX_ABSTRACTION_IMPL_THREAD_IMPL_H
+#define BASYX_ABSTRACTION_IMPL_THREAD_IMPL_H
#ifdef _WIN32
#include <BaSyx/abstraction/impl/windows/thread/thread_impl.h>
@@ -7,4 +7,4 @@
#include <BaSyx/abstraction/impl/unix/thread/thread_impl.h>
#endif
-#endif
+#endif /* BASYX_ABSTRACTION_IMPL_THREAD_IMPL_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/thread_launcher.h b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/thread_launcher.h
index 633d393..8732f21 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/thread_launcher.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/thread_launcher.h
@@ -5,8 +5,8 @@
* Author: psota
*/
-#ifndef UTIL_THREADIMPL_H
-#define UTIL_THREADIMPL_H
+#ifndef BASYX_ABSTRACTION_IMPL_THREAD_LAUNCHER_H
+#define BASYX_ABSTRACTION_IMPL_THREAD_LAUNCHER_H
#define USE_STD_ATOMIC
//#define USE_STD_INVOKE
@@ -30,83 +30,86 @@
#endif
namespace basyx {
- namespace detail
- {
- template<class Func, typename... Args>
- class Thread_Launcher
- {
- private:
+namespace detail {
+
+template <class Func, typename... Args>
+class Thread_Launcher {
+private:
#ifdef USE_STD_ATOMIC
- std::atomic_flag not_started_lock = ATOMIC_FLAG_INIT;
+ std::atomic_flag not_started_lock = ATOMIC_FLAG_INIT;
#else
- bool started = false;
+ bool started = false;
#endif
- private:
- struct target
- {
- util::decay_t<Func> f;
- std::tuple<util::decay_t<Args>...> args;
+private:
+ struct target {
+ util::decay_t<Func> f;
+ std::tuple<util::decay_t<Args>...> args;
- template<class OtherFunc, typename... OtherArgs>
- target(OtherFunc && f, OtherArgs && ... args)
- : f{ std::forward<OtherFunc>(f) }
- , args{ std::make_tuple<OtherArgs...>(std::forward<OtherArgs>(args)...) }
- {
- }
+ template <class OtherFunc, typename... OtherArgs>
+ target(OtherFunc&& f, OtherArgs&&... args)
+ : f { std::forward<OtherFunc>(f) }
+ , args { std::make_tuple<OtherArgs...>(std::forward<OtherArgs>(args)...) }
+ {
+ }
- inline void dispatch() {
- callFunc(typename util::meta::generator_sequence<sizeof...(Args)>::type());
- }
+ inline void dispatch()
+ {
+ callFunc(typename util::meta::generator_sequence<sizeof...(Args)>::type());
+ }
- template<int... tail>
- inline void callFunc(util::meta::sequence<tail...>) {
+ template <int... tail>
+ inline void callFunc(util::meta::sequence<tail...>)
+ {
#ifdef USE_STD_INVOKE
- std::invoke(std::forward<util::decay_t<Func>>(f), std::get<tail>(args)...);
+ std::invoke(std::forward<util::decay_t<Func>>(f), std::get<tail>(args)...);
#else
- util::invoke(std::forward<util::decay_t<Func>>(f), std::get<tail>(args)...);
+ util::invoke(std::forward<util::decay_t<Func>>(f), std::get<tail>(args)...);
#endif
- }
- };
+ }
+ };
- std::unique_ptr<target> targetPtr;
- private:
- static unsigned BASYX_THREAD_CALL_CONVENTION launch_internal(void * this_ptr)
- {
- auto _this = static_cast<Thread_Launcher<Func, Args...>*>(this_ptr);
- auto _target = std::forward<std::unique_ptr<target>>(_this->targetPtr);
+ std::unique_ptr<target> targetPtr;
+
+private:
+ static unsigned BASYX_THREAD_CALL_CONVENTION launch_internal(void* this_ptr)
+ {
+ auto _this = static_cast<Thread_Launcher<Func, Args...>*>(this_ptr);
+ auto _target = std::forward<std::unique_ptr<target>>(_this->targetPtr);
#ifdef USE_STD_ATOMIC
- _this->not_started_lock.clear(std::memory_order_release);
+ _this->not_started_lock.clear(std::memory_order_release);
#else
- _this->started = true;
+ _this->started = true;
#endif
- _target->dispatch();
- return 0;
- };
- public:
- explicit Thread_Launcher(Func && f, Args && ... args)
- : targetPtr{ util::make_unique<target>(std::forward<Func>(f), std::forward<Args>(args)...) }
- {
+ _target->dispatch();
+ return 0;
+ };
+
+public:
+ explicit Thread_Launcher(Func&& f, Args&&... args)
+ : targetPtr { util::make_unique<target>(std::forward<Func>(f), std::forward<Args>(args)...) }
+ {
#ifdef USE_STD_ATOMIC
- not_started_lock.test_and_set(std::memory_order_acquire);
+ not_started_lock.test_and_set(std::memory_order_acquire);
#endif
- }
+ }
- template<typename T, typename D, template<typename, typename> class thrd_impl >
- inline void Launch(thrd_impl<T,D> & thrd)
- {
- thrd = util::make_unique<T>(Thread_Launcher<Func, Args...>::launch_internal, this);
- thrd->run();
+ template <typename T, typename D, template <typename, typename> class thrd_impl>
+ inline void Launch(thrd_impl<T, D>& thrd)
+ {
+ thrd = util::make_unique<T>(Thread_Launcher<Func, Args...>::launch_internal, this);
+ thrd->run();
- // spinlock until thread is started
+ // spinlock until thread is started
#ifdef USE_STD_ATOMIC
- while (this->not_started_lock.test_and_set(std::memory_order_acquire))
+ while (this->not_started_lock.test_and_set(std::memory_order_acquire))
#else
- while (!started)
+ while (!started)
#endif
- ; // spin
- };
- };
- }
+ /* spin */ ; // do nothing
+ };
};
-#endif
+}
+}
+
+#endif /* BASYX_ABSTRACTION_IMPL_THREAD_LAUNCHER_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/unix/thread/thread_impl.h b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/unix/thread/thread_impl.h
index c8b5700..4d02a96 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/unix/thread/thread_impl.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/unix/thread/thread_impl.h
@@ -5,8 +5,8 @@
* Author: cgries
*/
-#ifndef ABSTRACTION_UNIX_THREAD_BASYXTHREAD_H_
-#define ABSTRACTION_UNIX_THREAD_BASYXTHREAD_H_
+#ifndef BASYX_ABSTRACTION_IMPL_UNIX_THREAD_THREAD_IMPL_H
+#define BASYX_ABSTRACTION_IMPL_UNIX_THREAD_THREAD_IMPL_H
#include <pthread.h>
@@ -15,25 +15,25 @@
namespace basyx {
namespace detail {
- class thread_impl
- {
- public:
- thread_impl(unsigned int (*)(void*), void*);
- ~thread_impl();
+class thread_impl {
+public:
+ thread_impl(unsigned int (*)(void*), void*);
+ ~thread_impl();
- int run();
- int join();
- int detach();
+ int run();
+ int join();
+ int detach();
- private:
- pthread_t threadDesc;
- unsigned int (*threadFn)(void*);
- void* threadArg;
+private:
+ pthread_t threadDesc;
+ unsigned int (*threadFn)(void*);
+ void* threadArg;
- public:
- static int getCurrentThreadId();
- };
+public:
+ static int getCurrentThreadId();
+};
+
}
}
-#endif /* ABSTRACTION_UNIX_THREAD_BASYXTHREAD_H_ */
+#endif /* BASYX_ABSTRACTION_IMPL_UNIX_THREAD_THREAD_IMPL_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/windows/thread/thread_impl.h b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/windows/thread/thread_impl.h
index 07975d7..0b42015 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/windows/thread/thread_impl.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/windows/thread/thread_impl.h
@@ -5,36 +5,36 @@
* Author: cgries
*/
-#ifndef ABSTRACTION_UNIX_THREAD_BASYXTHREAD_H_
-#define ABSTRACTION_UNIX_THREAD_BASYXTHREAD_H_
+#ifndef BASYX_ABSTRACTION_IMPL_WINDOWS_THREAD_THREAD_IMPL_H
+#define BASYX_ABSTRACTION_IMPL_WINDOWS_THREAD_THREAD_IMPL_H
#include <process.h>
#include <windows.h>
namespace basyx {
- namespace detail {
+namespace detail {
- class thread_impl {
+class thread_impl
+{
+public:
+ thread_impl(unsigned int(__stdcall*)(void*), void*);
+ ~thread_impl();
- public:
- thread_impl(unsigned int (__stdcall *)(void*), void*);
- ~thread_impl();
+ int run();
+ int join();
+ int detach();
- int run();
- int join();
- int detach();
+private:
+ HANDLE threadDesc;
+ unsigned int threadID;
+ unsigned int(__stdcall* threadFn)(void*);
+ void* threadArg;
- private:
- HANDLE threadDesc;
- unsigned int threadID;
- unsigned int (__stdcall *threadFn) (void*);
- void* threadArg;
- public:
- static int getCurrentThreadId();
- };
- }
+public:
+ static int getCurrentThreadId();
+};
+
+}
}
-
-
-#endif /* ABSTRACTION_UNIX_THREAD_BASYXTHREAD_H_ */
+#endif /* BASYX_ABSTRACTION_IMPL_WINDOWS_THREAD_THREAD_IMPL_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/net/Acceptor.h b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/net/Acceptor.h
index aec07aa..83815e5 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/net/Acceptor.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/net/Acceptor.h
@@ -5,52 +5,53 @@
* Author: psota
*/
-#ifndef ABSTRACTION_NET_ACCEPTOR_H_
-#define ABSTRACTION_NET_ACCEPTOR_H_
+#ifndef BASYX_ABSTRACTION_NET_ACCEPTOR_H
+#define BASYX_ABSTRACTION_NET_ACCEPTOR_H
-#include <memory>
#include <BaSyx/log/log.h>
+#include <memory>
#include <BaSyx/abstraction/net/Socket.h>
namespace basyx {
- namespace net {
-
- // Forward declarations
- namespace impl {
- class acceptor_impl;
- }
+namespace net {
- namespace tcp {
-
- class Acceptor
- {
- private:
- std::unique_ptr<basyx::net::impl::acceptor_impl> acceptor;
- basyx::log log;
- Acceptor & _move_acceptor(Acceptor && other);
- public:
- explicit Acceptor(int port);
- explicit Acceptor(const std::string & port);
-
- // Delete copy-assignment and constructor, there should only ever be one Acceptor object representing a single acceptor
- Acceptor(const Acceptor & other) = delete;
- Acceptor& operator=(const Acceptor & other) = delete;
-
- // Allow move-operations
- Acceptor & operator=(Acceptor && other);
- Acceptor(Acceptor && other);
-
- ~Acceptor();
- public:
- void close();
-
- // Blockingly wait for connection
- Socket accept();
- };
- }
- }
+// Forward declarations
+namespace impl {
+ class acceptor_impl;
}
+namespace tcp {
-#endif
+ class Acceptor {
+ private:
+ std::unique_ptr<basyx::net::impl::acceptor_impl> acceptor;
+ basyx::log log;
+ Acceptor& _move_acceptor(Acceptor&& other);
+
+ public:
+ explicit Acceptor(int port);
+ explicit Acceptor(const std::string& port);
+
+ // Delete copy-assignment and constructor, there should only ever be one Acceptor object representing a single acceptor
+ Acceptor(const Acceptor& other) = delete;
+ Acceptor& operator=(const Acceptor& other) = delete;
+
+ // Allow move-operations
+ Acceptor& operator=(Acceptor&& other);
+ Acceptor(Acceptor&& other);
+
+ ~Acceptor();
+
+ public:
+ void close();
+
+ // Blockingly wait for connection
+ Socket accept();
+ };
+}
+
+}
+}
+
+#endif /* BASYX_ABSTRACTION_NET_ACCEPTOR_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/net/Buffer.h b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/net/Buffer.h
index 4d1da9b..46ac5ea 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/net/Buffer.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/net/Buffer.h
@@ -1,71 +1,71 @@
/*
- * Socket.h
- *
- * Created on: 05.02.2018
- * Author: psota
- */
+* Socket.h
+*
+* Created on: 05.02.2018
+* Author: psota
+*/
-#ifndef ABSTRACTION_NET_BUFFER_H_
-#define ABSTRACTION_NET_BUFFER_H_
+#ifndef BASYX_ABSTRACTION_NET_BUFFER_H
+#define BASYX_ABSTRACTION_NET_BUFFER_H
-#include <string>
#include <cstddef>
+#include <string>
namespace basyx {
- namespace net {
+namespace net {
- class Buffer
- {
- private:
- void * _data;
- std::size_t _size;
- public:
- // Creates a non-owning representation of a block of memory
- Buffer(void*data, std::size_t size)
- : _size(size), _data(data)
- {};
- ~Buffer() = default;
+class Buffer {
+private:
+ void* _data;
+ std::size_t _size;
- // Since this is just using an observing pointer and doesn't own any memory, it is cheap to copy/move
- // Copy operations
- Buffer(Buffer & other) = default;
- Buffer & operator=(Buffer & other) = default;
+public:
+ // Creates a non-owning representation of a block of memory
+ Buffer(void* data, std::size_t size)
+ : _size(size)
+ , _data(data) {};
+ ~Buffer() = default;
- // Move operations
- Buffer(Buffer && other) = default;
- Buffer & operator=(Buffer && other) = default;
- public:
- inline void * data() const { return _data; };
- inline std::size_t size() const { return _size; };
- };
+ // Since this is just using an observing pointer and doesn't own any memory, it is cheap to copy/move
+ // Copy operations
+ Buffer(Buffer& other) = default;
+ Buffer& operator=(Buffer& other) = default;
- template<typename T>
- Buffer make_buffer(T & t)
- {
- return Buffer{ &t, sizeof(T) };
- };
+ // Move operations
+ Buffer(Buffer&& other) = default;
+ Buffer& operator=(Buffer&& other) = default;
- template<class CharT, class Traits, class Allocator>
- const Buffer make_buffer(std::basic_string<CharT, Traits, Allocator> & string)
- {
- return Buffer{ (void*)string.data(), string.size() * sizeof(CharT) };
- };
+public:
+ inline void* data() const { return _data; };
+ inline std::size_t size() const { return _size; };
+};
- template<typename T, std::size_t N>
- Buffer make_buffer(const T(&data)[N])
- {
- return Buffer{ data, N * sizeof(T) };
- }
+template <typename T>
+Buffer make_buffer(T& t)
+{
+ return Buffer { &t, sizeof(T) };
+};
- template<typename T>
- Buffer make_buffer(T * data, std::size_t size)
- {
- return Buffer{ reinterpret_cast<void*>(data), size };
- }
+template <class CharT, class Traits, class Allocator>
+const Buffer make_buffer(std::basic_string<CharT, Traits, Allocator>& string)
+{
+ return Buffer { (void*)string.data(), string.size() * sizeof(CharT) };
+};
- }
+template <typename T, std::size_t N>
+Buffer make_buffer(const T (&data)[N])
+{
+ return Buffer { data, N * sizeof(T) };
+}
+
+template <typename T>
+Buffer make_buffer(T* data, std::size_t size)
+{
+ return Buffer { reinterpret_cast<void*>(data), size };
+}
}
+}
-#endif
\ No newline at end of file
+#endif /* BASYX_ABSTRACTION_NET_BUFFER_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/net/Socket.h b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/net/Socket.h
index 70826f8..00b6ac9 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/net/Socket.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/net/Socket.h
@@ -1,12 +1,12 @@
/*
- * Socket.h
- *
- * Created on: 05.02.2018
- * Author: psota
- */
+* Socket.h
+*
+* Created on: 05.02.2018
+* Author: psota
+*/
-#ifndef ABSTRACTION_NET_SOCKET_H_
-#define ABSTRACTION_NET_SOCKET_H_
+#ifndef BASYX_ABSTRACTION_NET_SOCKET_H
+#define BASYX_ABSTRACTION_NET_SOCKET_H
#include <BaSyx/abstraction/impl/socket_impl.h>
@@ -17,121 +17,112 @@
#include <string>
namespace basyx {
- namespace net {
- namespace tcp {
+namespace net {
+namespace tcp {
- template<typename socket_impl>
- class basic_socket
- {
- private:
- basyx::log log;
- std::unique_ptr<socket_impl> socket;
+template <typename socket_impl>
+class basic_socket {
+private:
+ basyx::log log;
+ std::unique_ptr<socket_impl> socket;
- basic_socket<socket_impl> & _move_socket(basic_socket<socket_impl> && other)
- {
- // close current socket and assign new one
- if (this->socket != nullptr)
- this->socket->close();
+ basic_socket<socket_impl>& _move_socket(basic_socket<socket_impl>&& other)
+ {
+ // close current socket and assign new one
+ if (this->socket != nullptr)
+ this->socket->close();
- this->socket = std::move(other.socket);
- // other no longer represents a socket connection
- other.socket.reset(nullptr);
- return *this;
- }
- public:
- basic_socket()
- : socket{ nullptr }
- , log{ "Socket" }
- {
- };
+ this->socket = std::move(other.socket);
+ // other no longer represents a socket connection
+ other.socket.reset(nullptr);
+ return *this;
+ }
- basic_socket(std::unique_ptr<socket_impl> socket)
- : socket{ std::forward<std::unique_ptr<socket_impl>>(socket) }
- , log{"Socket"}
- {
- };
+public:
+ basic_socket()
+ : socket { nullptr }
+ , log { "Socket" } {};
- ~basic_socket()
- {
- };
+ basic_socket(std::unique_ptr<socket_impl> socket)
+ : socket { std::forward<std::unique_ptr<socket_impl>>(socket) }
+ , log { "Socket" } {};
- // Delete copy-assignment and constructor, there should only ever be one Socket object representing a single connection
- basic_socket<socket_impl> & operator=(basic_socket<socket_impl> & other) = delete;
- basic_socket(basic_socket<socket_impl> & other) = delete;
+ ~basic_socket() {};
- // Allow move-operations
- basic_socket<socket_impl> & operator=(basic_socket<socket_impl> && other) { return _move_socket(std::forward<basic_socket<socket_impl>>(other)); };
- basic_socket(basic_socket<socket_impl> && other) { _move_socket(std::forward<basic_socket<socket_impl>>(other)); };
+ // Delete copy-assignment and constructor, there should only ever be one Socket object representing a single connection
+ basic_socket<socket_impl>& operator=(basic_socket<socket_impl>& other) = delete;
+ basic_socket(basic_socket<socket_impl>& other) = delete;
- template<typename Buffer>
- std::size_t Send(Buffer && buffer)
- {
- if (socket == nullptr)
- return 0;
+ // Allow move-operations
+ basic_socket<socket_impl>& operator=(basic_socket<socket_impl>&& other) { return _move_socket(std::forward<basic_socket<socket_impl>>(other)); };
+ basic_socket(basic_socket<socket_impl>&& other) { _move_socket(std::forward<basic_socket<socket_impl>>(other)); };
- return socket->write(buffer.data(), buffer.size());
- }
+ template <typename Buffer>
+ std::size_t Send(Buffer&& buffer)
+ {
+ if (socket == nullptr)
+ return 0;
- template<typename MutableBuffer>
- std::size_t Receive(MutableBuffer && buffer)
- {
- if (socket == nullptr)
- return 0;
+ return socket->write(buffer.data(), buffer.size());
+ }
- return socket->recv(buffer.data(), buffer.size(), 0);
- }
+ template <typename MutableBuffer>
+ std::size_t Receive(MutableBuffer&& buffer)
+ {
+ if (socket == nullptr)
+ return 0;
- static basic_socket<socket_impl> Connect(const std::string & address, int port)
- {
- return basic_socket<socket_impl>::Connect(address, std::to_string(port));
- }
+ return socket->recv(buffer.data(), buffer.size(), 0);
+ }
- static basic_socket<socket_impl> Connect(const std::string & address, const std::string & port)
- {
- //ToDo: Error handling
- auto sock_impl = util::make_unique<socket_impl>();
- auto result = sock_impl->connect(address, port);
+ static basic_socket<socket_impl> Connect(const std::string& address, int port)
+ {
+ return basic_socket<socket_impl>::Connect(address, std::to_string(port));
+ }
- if (result != 0)
- return basic_socket<socket_impl>{};
+ static basic_socket<socket_impl> Connect(const std::string& address, const std::string& port)
+ {
+ //ToDo: Error handling
+ auto sock_impl = util::make_unique<socket_impl>();
+ auto result = sock_impl->connect(address, port);
- return basic_socket<socket_impl>{std::forward<std::unique_ptr<socket_impl>>(sock_impl)};
- }
+ if (result != 0)
+ return basic_socket<socket_impl> {};
- int GetErrorCode()
- {
- if (this->socket == nullptr)
- return -1;
+ return basic_socket<socket_impl> { std::forward<std::unique_ptr<socket_impl>>(sock_impl) };
+ }
- return this->socket->getErrorCode();
- }
+ int GetErrorCode()
+ {
+ if (this->socket == nullptr)
+ return -1;
- void Close()
- {
- if (this->socket != nullptr)
- {
- log.trace("Closing socket...");
+ return this->socket->getErrorCode();
+ }
- //this->socket->shutdown(SHUTDOWN_RDWR);
- this->socket->close();
- this->socket.reset();
- }
- }
+ void Close()
+ {
+ if (this->socket != nullptr) {
+ log.trace("Closing socket...");
- bool Healthy()
- {
- if (this->socket == nullptr)
- return false;
+ //this->socket->shutdown(SHUTDOWN_RDWR);
+ this->socket->close();
+ this->socket.reset();
+ }
+ }
- return true;
- }
- };
+ bool Healthy()
+ {
+ if (this->socket == nullptr)
+ return false;
+ return true;
+ }
+};
-
- using Socket = basic_socket<basyx::net::impl::socket_impl>;
- };
- }
+using Socket = basic_socket<basyx::net::impl::socket_impl>;
+};
+}
}
-#endif
+#endif /* BASYX_ABSTRACTION_NET_SOCKET_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/thread/Thread.h b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/thread/Thread.h
index 07ec9d5..f1d1a08 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/thread/Thread.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/thread/Thread.h
@@ -5,76 +5,77 @@
* Author: psota
*/
-#ifndef UTIL_THREAD_H
-#define UTIL_THREAD_H
+#ifndef BASYX_ABSTRACTION_THREAD_THREAD_H
+#define BASYX_ABSTRACTION_THREAD_THREAD_H
#include <memory>
-#include <BaSyx/abstraction/impl/thread_launcher.h>
#include <BaSyx/abstraction/impl/thread_impl.h>
+#include <BaSyx/abstraction/impl/thread_launcher.h>
namespace basyx {
- class thread
- {
- private:
- std::unique_ptr<detail::thread_impl> thread_impl;
- public:
- // Creates empty Thread object
- thread() noexcept : thread_impl{ nullptr } {};
+class thread {
+private:
+ std::unique_ptr<detail::thread_impl> thread_impl;
- // Creates a Thread object with function f and parameters args and starts a new thread of execution
- template<class Func, typename... Args>
- explicit thread(Func && f, Args && ... args)
- : thread_impl{ nullptr }
- {
- detail::Thread_Launcher<Func, Args...> launcher{ std::forward<Func>(f), std::forward<Args>(args)... };
- launcher.Launch(thread_impl);
- }
+public:
+ // Creates empty Thread object
+ thread() noexcept
+ : thread_impl { nullptr } {};
- // Delete copy constructor, no two Thread objects should ever represent the same thread of exectuion
- thread(const thread & Other) = delete;
+ // Creates a Thread object with function f and parameters args and starts a new thread of execution
+ template <class Func, typename... Args>
+ explicit thread(Func&& f, Args&&... args)
+ : thread_impl { nullptr }
+ {
+ detail::Thread_Launcher<Func, Args...> launcher { std::forward<Func>(f), std::forward<Args>(args)... };
+ launcher.Launch(thread_impl);
+ }
- // Move constructor
- thread(thread && other) noexcept
- {
- this->thread_impl = std::forward<std::unique_ptr<detail::thread_impl>>(other.thread_impl);
- other.thread_impl.reset();
- };
+ // Delete copy constructor, no two Thread objects should ever represent the same thread of exectuion
+ thread(const thread& Other) = delete;
- // Move-assignment operator
- thread & operator=(thread && other) noexcept
- {
- if (this->thread_impl != nullptr)
- std::terminate();
+ // Move constructor
+ thread(thread&& other) noexcept
+ {
+ this->thread_impl = std::forward<std::unique_ptr<detail::thread_impl>>(other.thread_impl);
+ other.thread_impl.reset();
+ };
- this->thread_impl = std::forward<std::unique_ptr<detail::thread_impl>>(other.thread_impl);
+ // Move-assignment operator
+ thread& operator=(thread&& other) noexcept
+ {
+ if (this->thread_impl != nullptr)
+ std::terminate();
- return *this;
- };
+ this->thread_impl = std::forward<std::unique_ptr<detail::thread_impl>>(other.thread_impl);
- inline void join()
- {
- this->thread_impl->join();
- };
+ return *this;
+ };
- inline void detach()
- {
- this->thread_impl->detach();
- this->thread_impl.reset();
- };
+ inline void join()
+ {
+ this->thread_impl->join();
+ };
- inline bool joinable()
- {
- return false;
- };
- //Static utility functions
- public:
- static int currentThreadId()
- {
- return detail::thread_impl::getCurrentThreadId();
- };
- };
+ inline void detach()
+ {
+ this->thread_impl->detach();
+ this->thread_impl.reset();
+ };
+
+ inline bool joinable()
+ {
+ return false;
+ };
+ //Static utility functions
+public:
+ static int currentThreadId()
+ {
+ return detail::thread_impl::getCurrentThreadId();
+ };
+};
}
-#endif
+#endif /* BASYX_ABSTRACTION_THREAD_THREAD_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/ControlComponentConstants.h b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/ControlComponentConstants.h
new file mode 100644
index 0000000..8df4194
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/ControlComponentConstants.h
@@ -0,0 +1,57 @@
+#ifndef BASYX_SUBMODEL_ENUM_ControlComponentConstants_H
+#define BASYX_SUBMODEL_ENUM_ControlComponentConstants_H
+
+#include <string>
+
+namespace basyx {
+namespace controlcomponent {
+
+enum class ControlComponentConstants {
+ status,
+ orderList,
+ LOCAL,
+ operations,
+ service,
+ clear,
+ stop,
+ abort,
+ unsuspend,
+ suspend,
+ unhold,
+ hold,
+ reset,
+ start,
+ simulation,
+ manual,
+ Auto,
+ semiauto,
+ priority,
+ occupy,
+ free,
+ bstate,
+ cmd,
+ localOverwriteFree,
+ localOverwrite,
+ prevError,
+ errorState,
+ workState,
+ opMode,
+ exState,
+ exMode,
+ lastOccupier,
+ occupier,
+ occupationState,
+};
+
+class ControlComponentConstants_
+{
+public:
+ static ControlComponentConstants from_string(const std::string & name);
+ static const char * to_string(ControlComponentConstants value);
+};
+
+
+}
+}
+
+#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/ExecutionMode.h b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/ExecutionMode.h
new file mode 100644
index 0000000..a035ef8
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/ExecutionMode.h
@@ -0,0 +1,20 @@
+#ifndef BASYX_CONTROLCOMPONENT_ENUM_EXECUTIONMODE_H
+#define BASYX_CONTROLCOMPONENT_ENUM_EXECUTIONMODE_H
+
+#include <string>
+
+namespace basyx {
+namespace controlcomponent {
+
+enum class ExecutionMode {
+ Auto = 1,
+ Semiauto = 2,
+ Manual = 3,
+ Reserved = 4,
+ Simulation = 5
+};
+
+}
+}
+
+#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/ExecutionOrder.h b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/ExecutionOrder.h
new file mode 100644
index 0000000..80cadb4
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/ExecutionOrder.h
@@ -0,0 +1,33 @@
+#ifndef BASYX_CONTROLCOMPONENT_ENUM_EXECUTIONORDER_H
+#define BASYX_CONTROLCOMPONENT_ENUM_EXECUTIONORDER_H
+
+#include <string>
+
+namespace basyx {
+namespace controlcomponent {
+
+enum class ExecutionOrder {
+ start,
+ complete,
+ reset,
+ hold,
+ unhold,
+ suspend,
+ unsuspend,
+ clear,
+ stop,
+ abort,
+};
+
+class ExecutionOrder_
+{
+public:
+ static ExecutionOrder from_string(const std::string & name);
+ static const char * to_string(ExecutionOrder value);
+};
+
+
+}
+}
+
+#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/ExecutionState.h b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/ExecutionState.h
new file mode 100644
index 0000000..f5ef17f
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/ExecutionState.h
@@ -0,0 +1,40 @@
+#ifndef BASYX_CONTROLCOMPONENT_ENUM_EXECUTIONSTATE_H
+#define BASYX_CONTROLCOMPONENT_ENUM_EXECUTIONSTATE_H
+
+#include <string>
+
+namespace basyx {
+namespace controlcomponent {
+
+enum class ExecutionState {
+ idle,
+ starting,
+ execute,
+ completing,
+ complete,
+ resetting,
+ holding,
+ held,
+ unholding,
+ suspending,
+ suspended,
+ unsuspending,
+ stopping,
+ stopped,
+ aborting,
+ aborted,
+ clearing,
+};
+
+class ExecutionState_
+{
+public:
+ static ExecutionState from_string(const std::string & name);
+ static const char * to_string(ExecutionState value);
+};
+
+
+}
+}
+
+#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/OccupationState.h b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/OccupationState.h
new file mode 100644
index 0000000..e1db83a
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/OccupationState.h
@@ -0,0 +1,17 @@
+#ifndef BASYX_CONTROLCOMPONENT_ENUM_OCCUPATIONSTATE_H
+#define BASYX_CONTROLCOMPONENT_ENUM_OCCUPATIONSTATE_H
+
+namespace basyx {
+namespace controlcomponent {
+
+enum class OccupationState {
+ free = 0,
+ occupied = 1,
+ priority = 2,
+ local = 3
+};
+
+}
+}
+
+#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/interfaces/IControlComponent.h b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/interfaces/IControlComponent.h
new file mode 100644
index 0000000..c05e95a
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/interfaces/IControlComponent.h
@@ -0,0 +1,184 @@
+#ifndef BASYX_CONTROLCOMPONENT_ICONTROLCOMPONENT_H
+#define BASYX_CONTROLCOMPONENT_ICONTROLCOMPONENT_H
+
+#include <string>
+#include <vector>
+
+#include <BaSyx/shared/object.h>
+
+#include <BaSyx/controlcomponent/interfaces/IControlComponentChangeListener.h>
+
+#include <BaSyx/controlcomponent/enumerations/OccupationState.h>
+#include <BaSyx/controlcomponent/enumerations/ExecutionMode.h>
+#include <BaSyx/controlcomponent/enumerations/ExecutionState.h>
+
+/**
+ * BaSys 4.0 control component interface. This is a VAB object that cannot be serialized.
+ */
+namespace basyx {
+namespace controlcomponent {
+
+class IControlComponent
+{
+public:
+
+ /**
+ * Add ControlComponentChangeListener
+ */
+ virtual void addControlComponentChangeListener(const std::shared_ptr<IControlComponentChangeListener> listener) = 0;
+
+ /**
+ * Remove ControlComponentChangeListener
+ */
+ virtual void removeControlComponentChangeListener(const std::shared_ptr<IControlComponentChangeListener> listener) = 0;
+
+ /**
+ * Get "operations" map
+ */
+ virtual const basyx::object getServiceOperationMap() = 0;
+
+ /**
+ * Finish current execution state (execute 'SC' order). This only works in transition states
+ */
+ virtual void finishState() = 0;
+
+ /**
+ * Get order list
+ */
+ virtual const std::vector<std::string> & getOrderList() = 0;
+
+ /**
+ * Add order to order list
+ */
+ virtual void addOrder(const std::string &newOrder) = 0;
+
+ /**
+ * Clear order list
+ */
+ virtual void clearOrder() = 0;
+
+ /**
+ * Get occupation state
+ */
+ virtual OccupationState getOccupationState() = 0;
+
+ /**
+ * Set occupation state
+ */
+ virtual void setOccupationState(const OccupationState &occSt) = 0;
+
+ /**
+ * Get occupier ID
+ */
+ virtual std::string getOccupierID() = 0;
+
+ /**
+ * Set occupier ID
+ */
+ virtual void setOccupierID(const std::string &occId) = 0;
+
+ /**
+ * Get last occupier ID
+ */
+ virtual std::string getLastOccupierID() = 0;
+
+ /**
+ * Set last occupier ID
+ */
+ virtual void setLastOccupierID(const std::string &occId) = 0;
+
+ /**
+ * Get execution mode
+ */
+ virtual ExecutionMode getExecutionMode() = 0;
+
+ /**
+ * Set execution mode
+ */
+ virtual void setExecutionMode(const ExecutionMode &exMode) = 0;
+
+ /**
+ * Get execution state
+ */
+ virtual ExecutionState getExecutionState() = 0;
+
+ /**
+ * Set execution state
+ */
+ virtual void setExecutionState(const ExecutionState &newSt) = 0;
+
+ /**
+ * Get operation mode
+ */
+ virtual std::string getOperationMode() = 0;
+
+ /**
+ * Set operation mode
+ */
+ virtual void setOperationMode(const std::string &opMode) = 0;
+
+ /**
+ * Get work state
+ */
+ virtual std::string getWorkState() = 0;
+
+ /**
+ * Set work state
+ */
+ virtual void setWorkState(const std::string &workState) = 0;
+
+ /**
+ * Get error state
+ */
+ virtual std::string getErrorState() = 0;
+
+ /**
+ * Set error state
+ */
+ virtual void setErrorState(const std::string &errorState) = 0;
+
+ /**
+ * Get last error state
+ */
+ virtual std::string getLastErrorState() = 0;
+
+ /**
+ * Set last error state
+ */
+ virtual void setLastErrorState(const std::string &lastErrorState) = 0;
+
+ /**
+ * Get last command
+ */
+ virtual std::string getCommand() = 0;
+
+ /**
+ * Set command
+ */
+ virtual void setCommand(const std::string &cmd) = 0;
+
+ /**
+ * Get local overwrite variable
+ */
+ virtual std::string getLocalOverwrite() = 0;
+
+ /**
+ * Set local overwrite variable
+ */
+ virtual void setLocalOverwrite(const std::string &cmd) = 0;
+
+ /**
+ * Get local overwrite free variable
+ */
+ virtual std::string getLocalOverwriteFree() = 0;
+
+ /**
+ * Set local overwrite free variable
+ */
+ virtual void setLocalOverwriteFree(const std::string &cmd) = 0;
+};
+
+}
+}
+
+#endif /* BASYX_CONTROLCOMPOMPONENT_ICONTROLCOMPONENT_H */
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/interfaces/IControlComponentChangeListener.h b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/interfaces/IControlComponentChangeListener.h
new file mode 100644
index 0000000..98729e5
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/interfaces/IControlComponentChangeListener.h
@@ -0,0 +1,90 @@
+#ifndef BASYX_CONTROLCOMPONENT_ICONTROLCOMPONENTCHANGELISTENER_H
+#define BASYX_CONTROLCOMPONENT_ICONTROLCOMPONENTCHANGELISTENER_H
+
+#include <BaSyx/shared/object.h>
+#include <BaSyx/controlcomponent/enumerations/OccupationState.h>
+#include <BaSyx/controlcomponent/enumerations/ExecutionState.h>
+#include <BaSyx/controlcomponent/enumerations/ExecutionMode.h>
+
+namespace basyx {
+namespace controlcomponent {
+
+/**
+ * Receive change events from control components.
+ */
+class IControlComponentChangeListener
+{
+public:
+ virtual ~IControlComponentChangeListener() = 0;
+
+ /**
+ * Indicate change of a variable
+ */
+ virtual void onVariableChange(const std::string & varName, object newValue) = 0;
+
+
+ /**
+ * Indicate new occupier
+ */
+ virtual void onNewOccupier(const std::string & occupierId) = 0;
+
+
+ /**
+ * Indicate new occupation state
+ */
+ virtual void onNewOccupationState(OccupationState state) = 0;
+
+
+ /**
+ * Indicate a change of last occupier.
+ */
+ virtual void onLastOccupier(const std::string & lastOccupierId) = 0;
+
+
+ /**
+ * Indicate an execution mode change
+ */
+ virtual void onChangedExecutionMode(ExecutionMode newExecutionMode) = 0;
+
+
+ /**
+ * Indicate an execution state change
+ */
+ virtual void onChangedExecutionState(ExecutionState newExecutionState) = 0;
+
+
+ /**
+ * Indicate an operation mode change
+ */
+ virtual void onChangedOperationMode(const std::string & newOperationMode) = 0;
+
+
+ /**
+ * Indicate an work state change
+ */
+ virtual void onChangedWorkState(const std::string & newWorkState) = 0;
+
+
+ /**
+ * Indicate an error state change
+ */
+ virtual void onChangedErrorState(const std::string & newWorkState) = 0;
+
+
+ /**
+ * Indicate an previous error state change.
+ */
+ virtual void onChangedPrevError(const std::string & newWorkState) = 0;
+
+ /**
+ * Generates a unique ID to identify ControlComponentChangeListener
+ */
+ virtual int getUniqueID() = 0;
+};
+
+inline IControlComponentChangeListener::~IControlComponentChangeListener() = default;
+
+}
+}
+
+#endif //BASYX_API_V2_SDK_ICONTROLCOMPONENTCHANGELISTENER_H
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/map/ControlComponent.h b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/map/ControlComponent.h
new file mode 100644
index 0000000..4a6879b
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/map/ControlComponent.h
@@ -0,0 +1,111 @@
+#ifndef BASYX_CONTROLCOMPONENT_MAP_CONTROLCOMPONENT_H
+#define BASYX_CONTROLCOMPONENT_MAP_CONTROLCOMPONENT_H
+
+#include <BaSyx/controlcomponent/interfaces/IControlComponent.h>
+
+#include <BaSyx/vab/ElementMap.h>
+#include <BaSyx/controlcomponent/enumerations/ControlComponentConstants.h>
+#include <BaSyx/controlcomponent/enumerations/ExecutionOrder.h>
+
+namespace basyx {
+namespace controlcomponent {
+namespace map {
+
+class ControlComponent : public IControlComponent, public vab::ElementMap
+{
+private:
+ std::map<int, std::shared_ptr<IControlComponentChangeListener>> componentChangeListeners;
+ std::string savedOccupierId;
+ basyx::object status_map, operations;
+
+public:
+ ControlComponent();
+
+ virtual void addControlComponentChangeListener(const std::shared_ptr<IControlComponentChangeListener> listener) override;
+
+ virtual void removeControlComponentChangeListener(const std::shared_ptr<IControlComponentChangeListener> listener) override;
+
+ const basyx::object getServiceOperationMap();
+
+ void put(const std::string &key, basyx::object value);
+
+ virtual void finishState() override;
+
+ virtual const std::vector<std::string> & getOrderList() override;
+
+ virtual void addOrder(const std::string &newOrder) override;
+
+ virtual void clearOrder() override;
+
+ virtual OccupationState getOccupationState() override;
+
+ virtual void setOccupationState(const OccupationState &occState) override;
+
+ virtual std::string getOccupierID() override;
+
+ virtual void setOccupierID(const std::string &occId) override;
+
+ virtual std::string getLastOccupierID() override;
+
+ virtual void setLastOccupierID(const std::string &occId) override;
+
+ virtual ExecutionMode getExecutionMode() override;
+
+ virtual void setExecutionMode(const ExecutionMode &exMode) override;
+
+ virtual ExecutionState getExecutionState() override;
+
+ virtual void setExecutionState(const ExecutionState &newSt) override;
+
+ virtual std::string getOperationMode() override;
+
+ virtual void setOperationMode(const std::string &opMode) override;
+
+ virtual std::string getWorkState() override;
+
+ virtual void setWorkState(const std::string &workState) override;
+
+ virtual std::string getErrorState() override;
+
+ virtual void setErrorState(const std::string &errorState) override;
+
+ virtual std::string getLastErrorState() override;
+
+ virtual void setLastErrorState(const std::string &lastErrorState) override;
+
+ virtual std::string getCommand() override;
+
+ virtual void setCommand(const std::string &cmd) override;
+
+ virtual std::string getLocalOverwrite() override;
+
+ virtual void setLocalOverwrite(const std::string &cmd) override;
+
+ virtual std::string getLocalOverwriteFree() override;
+
+ virtual void setLocalOverwriteFree(const std::string &cmd) override;
+
+private:
+ void changeExecutionState(const ExecutionOrder &);
+
+ void invokeLocalOverwrite();
+
+ void clearLocalOverwrite();
+
+ void freeControlComponent(const std::string &);
+
+ void occupyControlComponent(const std::string &occupier);
+
+ void priorityOccupation(const std::string &occupier);
+
+ object init_service_operations();
+
+ template<typename T> void insert_status(const basyx::controlcomponent::ControlComponentConstants &, T status);
+
+ template<typename T> T get_status(const basyx::controlcomponent::ControlComponentConstants &);
+};
+
+}
+}
+}
+#endif //BASYX_CONTROLCOMPONENT_CONTROLCOMPONENT_H
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/simple/ControlComponent.h b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/simple/ControlComponent.h
new file mode 100644
index 0000000..5614968
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/simple/ControlComponent.h
@@ -0,0 +1,92 @@
+#ifndef BASYX_CONTROLCOMPONENT_SIMPLE_CONTROLCOMPONENT_H
+#define BASYX_CONTROLCOMPONENT_SIMPLE_CONTROLCOMPONENT_H
+
+#include <BaSyx/controlcomponent/interfaces/IControlComponent.h>
+
+#include <BaSyx/controlcomponent/enumerations/ControlComponentConstants.h>
+#include <BaSyx/controlcomponent/enumerations/ExecutionOrder.h>
+
+namespace basyx {
+namespace controlcomponent {
+namespace simple {
+
+class ControlComponent : public IControlComponent
+{
+private:
+ std::map<int, std::shared_ptr<IControlComponentChangeListener>> componentChangeListeners;
+ std::string savedOccupierId;
+ std::string occupier, lastOccupier, opMode, workState, errorState, prevError, cmd, localOverwrite, localOverwriteFree;
+ ExecutionState exState;
+ OccupationState occupationState;
+ ExecutionMode exMode;
+
+ std::string operations;
+ basyx::object service_operations;
+ std::vector<std::string> orderList;
+
+public:
+ ControlComponent();
+
+ virtual void addControlComponentChangeListener(const std::shared_ptr<IControlComponentChangeListener> listener) override;
+ virtual void removeControlComponentChangeListener(const std::shared_ptr<IControlComponentChangeListener> listener) override;
+
+ const basyx::object getServiceOperationMap();
+
+ virtual void finishState() override;
+ virtual const std::vector<std::string> & getOrderList() override;
+
+ virtual void addOrder(const std::string &newOrder) override;
+ virtual void clearOrder() override;
+
+ virtual OccupationState getOccupationState() override;
+ virtual void setOccupationState(const OccupationState &occState) override;
+
+ virtual std::string getOccupierID() override;
+ virtual void setOccupierID(const std::string &occId) override;
+
+ virtual std::string getLastOccupierID() override;
+ virtual void setLastOccupierID(const std::string &occId) override;
+
+ virtual ExecutionMode getExecutionMode() override;
+ virtual void setExecutionMode(const ExecutionMode &exMode) override;
+
+ virtual ExecutionState getExecutionState() override;
+ virtual void setExecutionState(const ExecutionState &newSt) override;
+
+ virtual std::string getOperationMode() override;
+ virtual void setOperationMode(const std::string &opMode) override;
+
+ virtual std::string getWorkState() override;
+ virtual void setWorkState(const std::string &workState) override;
+
+ virtual std::string getErrorState() override;
+ virtual void setErrorState(const std::string &errorState) override;
+
+ virtual std::string getLastErrorState() override;
+ virtual void setLastErrorState(const std::string &lastErrorState) override;
+
+ virtual std::string getCommand() override;
+ virtual void setCommand(const std::string &cmd) override;
+
+ virtual std::string getLocalOverwrite() override;
+ virtual void setLocalOverwrite(const std::string &cmd) override;
+
+ virtual std::string getLocalOverwriteFree() override;
+ virtual void setLocalOverwriteFree(const std::string &cmd) override;
+
+private:
+ void changeExecutionState(const ExecutionOrder &);
+ void invokeLocalOverwrite();
+ void clearLocalOverwrite();
+ void freeControlComponent(const std::string &);
+ void occupyControlComponent(const std::string &occupier);
+ void priorityOccupation(const std::string &occupier);
+ void init_service_operations();
+
+ template<typename T> void notify_change_listeners_on_variable_change(const basyx::controlcomponent::ControlComponentConstants &status_key, T status);
+};
+
+}
+}
+}
+#endif //BASYX_CONTROLCOMPONENT_CONTROLCOMPONENT_H
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/log/log.h b/sdks/c++/basys.sdk.cc/include/BaSyx/log/log.h
index cb24202..627b459 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/log/log.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/log/log.h
@@ -1,115 +1,118 @@
-#ifndef LOGGING_LOG_H_
-#define LOGGING_LOG_H_
+#ifndef BASYX_LOG_LOG_H
+#define BASYX_LOG_LOG_H
#include <iostream>
#include <fmt/format.h>
namespace basyx {
- class log {
- public:
- enum class Level
- {
- Debug = 0,
- Trace = 1,
- Info = 2,
- Warn = 3,
- Error = 4,
- Critical = 5
- };
- public:
- explicit log(const std::string& sourceName)
- : sourceName{ sourceName }
- {
- }
- explicit log()
- : sourceName{ "" } {};
+class log {
+public:
+ enum class Level {
+ Debug = 0,
+ Trace = 1,
+ Info = 2,
+ Warn = 3,
+ Error = 4,
+ Critical = 5
+ };
- private:
- const char * printLevel(Level level);
- private:
- static Level logLevel;
- public:
- static void setLogLevel(Level level)
- {
- logLevel = level;
- };
- private:
- std::string sourceName;
+public:
+ explicit log(const std::string& sourceName)
+ : sourceName { sourceName }
+ {
+ }
- std::string timestamp();
+ explicit log()
+ : sourceName { "" } {};
- template<typename... Args>
- std::string buildMessage(const std::string & format, Level level, Args && ... args)
- {
- auto message = fmt::format("[{}] [{}] [{}] {}", timestamp(), printLevel(level), sourceName, format);
- return fmt::format(message, std::forward<Args>(args)...);
- };
+private:
+ const char* printLevel(Level level);
- //template<typename T>
- //inline T && normalize(T && t)
- //{
- // return std::forward<T>(t);
- //}
+private:
+ static Level logLevel;
- //inline const char * normalize(const std::string & s)
- //{
- // return s.c_str();
- //}
+public:
+ static void setLogLevel(Level level)
+ {
+ logLevel = level;
+ };
+private:
+ std::string sourceName;
- template<typename... Args>
- inline void log_message(Level level, const std::string & msg, Args && ... args)
- {
- if (level >= logLevel)
- std::cout << buildMessage(msg, level, std::forward<Args>(args)...) << std::endl;
- };
+ std::string timestamp();
- public:
- template <typename... Args>
- inline void trace(const std::string& msg, Args&&... args)
- {
- log_message(Level::Trace, msg, std::forward<Args>(args)...);
- }
+ template <typename... Args>
+ std::string buildMessage(const std::string& format, Level level, Args&&... args)
+ {
+ auto message = fmt::format("[{}] [{}] [{}] {}", timestamp(), printLevel(level), sourceName, format);
+ return fmt::format(message, std::forward<Args>(args)...);
+ };
- template <typename... Args>
- inline void debug(const std::string& msg, Args&&... args)
- {
- log_message(Level::Debug, msg, std::forward<Args>(args)...);
- }
+ //template<typename T>
+ //inline T && normalize(T && t)
+ //{
+ // return std::forward<T>(t);
+ //}
- template <typename... Args>
- inline void info(const std::string& msg, Args&&... args)
- {
- log_message(Level::Info, msg, std::forward<Args>(args)...);
- }
+ //inline const char * normalize(const std::string & s)
+ //{
+ // return s.c_str();
+ //}
- template <typename... Args>
- inline void warn(const std::string& msg, Args&&... args)
- {
- log_message(Level::Warn, msg, std::forward<Args>(args)...);
- }
+ template <typename... Args>
+ inline void log_message(Level level, const std::string& msg, Args&&... args)
+ {
+ if (level >= logLevel)
+ std::cout << buildMessage(msg, level, std::forward<Args>(args)...) << std::endl;
+ };
- template <typename... Args>
- inline void error(const std::string& msg, Args&&... args)
- {
- log_message(Level::Error, msg, std::forward<Args>(args)...);
- }
+public:
+ template <typename... Args>
+ inline void trace(const std::string& msg, Args&&... args)
+ {
+ log_message(Level::Trace, msg, std::forward<Args>(args)...);
+ }
- template <typename... Args>
- inline void crit(const std::string& msg, Args&&... args)
- {
- log_message(Level::Critical, msg, std::forward<Args>(args)...);
- }
+ template <typename... Args>
+ inline void debug(const std::string& msg, Args&&... args)
+ {
+ log_message(Level::Debug, msg, std::forward<Args>(args)...);
+ }
- // static logging functions
- public:
- inline static log topic(const std::string & topic)
- {
- return log(topic);
- };
- };
+ template <typename... Args>
+ inline void info(const std::string& msg, Args&&... args)
+ {
+ log_message(Level::Info, msg, std::forward<Args>(args)...);
+ }
+
+ template <typename... Args>
+ inline void warn(const std::string& msg, Args&&... args)
+ {
+ log_message(Level::Warn, msg, std::forward<Args>(args)...);
+ }
+
+ template <typename... Args>
+ inline void error(const std::string& msg, Args&&... args)
+ {
+ log_message(Level::Error, msg, std::forward<Args>(args)...);
+ }
+
+ template <typename... Args>
+ inline void crit(const std::string& msg, Args&&... args)
+ {
+ log_message(Level::Critical, msg, std::forward<Args>(args)...);
+ }
+
+ // static logging functions
+public:
+ inline static log topic(const std::string& topic)
+ {
+ return log(topic);
+ };
+};
};
-#endif
+#endif /* BASYX_LOG_LOG_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/server/BaSyxNativeProvider.h b/sdks/c++/basys.sdk.cc/include/BaSyx/server/BaSyxNativeProvider.h
index 6f74321..057a92f 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/server/BaSyxNativeProvider.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/server/BaSyxNativeProvider.h
@@ -1,12 +1,12 @@
/*
- * BaSyxNativeProvider.h
- *
- * Created on: 14.08.2018
- * Author: schnicke
- */
+* BaSyxNativeProvider.h
+*
+* Created on: 14.08.2018
+* Author: schnicke
+*/
-#ifndef VAB_VAB_PROVIDER_NATIVE_BASYXNATIVEPROVIDER_H
-#define VAB_VAB_PROVIDER_NATIVE_BASYXNATIVEPROVIDER_H
+#ifndef BASYX_SERVER_BASYXNATIVEPROVIDER_H
+#define BASYX_SERVER_BASYXNATIVEPROVIDER_H
#include <BaSyx/shared/types.h>
@@ -21,135 +21,128 @@
#include <asio.hpp>
-
/**
- * Provies access based on the basyx native protocol
- */
+* Provies access based on the basyx native protocol
+*/
namespace basyx {
namespace vab {
namespace provider {
namespace native {
- class NativeProvider {
- private:
- // Connection socket
- asio::ip::tcp::socket & clientSocket;
+class NativeProvider {
+private:
+ // Connection socket
+ asio::ip::tcp::socket& clientSocket;
- // Frame processor
- frame::BaSyxNativeFrameProcessor * frameProcessor;
+ // Frame processor
+ frame::BaSyxNativeFrameProcessor* frameProcessor;
- // Buffers
- static constexpr std::size_t default_buffer_size = 4096;
- std::array<char, default_buffer_size> recv_buffer;
- std::array<char, default_buffer_size> send_buffer;
+ // Buffers
+ static constexpr std::size_t default_buffer_size = 8192;
+ std::array<char, default_buffer_size> recv_buffer;
+ std::array<char, default_buffer_size> send_buffer;
- bool closed;
- basyx::log log;
- public:
- NativeProvider(asio::ip::tcp::socket & clientSocket,
- frame::BaSyxNativeFrameProcessor* frameProcessor)
- : clientSocket(clientSocket)
- , frameProcessor(frameProcessor)
- , closed(false)
- , log{ "NativeProvider" }
- {
- }
+ bool closed;
+ basyx::log log;
- ~NativeProvider()
- {
- // Connection no longer needed, close it
- try
- {
- if (this->clientSocket.is_open())
- this->clientSocket.close();
- }
- catch (std::exception & e)
- {
- log.warn("Exception in closing socket");
- };
- }
+public:
+ NativeProvider(asio::ip::tcp::socket& clientSocket,
+ frame::BaSyxNativeFrameProcessor* frameProcessor)
+ : clientSocket(clientSocket)
+ , frameProcessor(frameProcessor)
+ , closed(false)
+ , log { "NativeProvider" }
+ {
+ }
- // Has to be called repeatedly
- void update()
- {
- log.trace("Updating...");
- if (!closed)
- {
- asio::error_code ec;
- log.trace("Waiting for incoming message");
- auto input_frame = recvFrame(ec);
+ ~NativeProvider()
+ {
+ // Connection no longer needed, close it
+ try {
+ if (this->clientSocket.is_open())
+ this->clientSocket.close();
+ } catch (std::exception& e) {
+ log.warn("Exception in closing socket: {}", e.what());
+ };
+ }
- if(ec) {
- log.info("Connection closed");
- closed = true;
- }
- else {
- log.trace("Received frame.");
- log.info("Received: {}", input_frame.getFirstValue());
+ // Has to be called repeatedly
+ void update()
+ {
+ log.trace("Updating...");
+ if (!closed) {
+ asio::error_code ec;
+ log.trace("Waiting for incoming message");
+ auto input_frame = recvFrame(ec);
- auto output_frame = frameProcessor->processInputFrame(input_frame);
+ if (ec) {
+ log.info("Connection closed");
+ closed = true;
+ } else {
+ log.trace("Received frame.");
+ log.info("Received: {}", input_frame.getFirstValue());
- log.info("Sending reply.");
+ auto output_frame = frameProcessor->processInputFrame(input_frame);
- auto bytes_sent = sendFrame(output_frame);
- if (bytes_sent < 0) {
- log.error("Sending failed: {}", "ERROR");
- closed = true;
- }
- }
- }
- }
+ log.info("Sending reply.");
- bool isClosed()
- {
- return closed;
- }
+ auto bytes_sent = sendFrame(output_frame);
+ if (bytes_sent < 0) {
+ log.error("Sending failed: {}", "ERROR");
+ closed = true;
+ }
+ }
+ }
+ }
- std::size_t sendData(char* data, std::size_t size)
- {
- log.debug("Sending {} bytes.", size);
- std::size_t bytes_sent = this->clientSocket.send(asio::buffer(data, size));
- log.debug("Sent {} bytes.", bytes_sent);
- return bytes_sent;
- };
+ bool isClosed()
+ {
+ return closed;
+ }
+ std::size_t sendData(char* data, std::size_t size)
+ {
+ log.debug("Sending {} bytes.", size);
+ std::size_t bytes_sent = this->clientSocket.send(asio::buffer(data, size));
+ log.debug("Sent {} bytes.", bytes_sent);
+ return bytes_sent;
+ };
- std::size_t receiveData(char* data, asio::error_code & ec)
- {
- std::size_t bytes_read = this->clientSocket.receive(asio::buffer(recv_buffer.data(), recv_buffer.size()), 0, ec);
- log.debug("Received {} bytes.", bytes_read);
- return bytes_read;
- };
+ std::size_t receiveData(char* data, asio::error_code& ec)
+ {
+ std::size_t bytes_read = this->clientSocket.receive(asio::buffer(recv_buffer.data(), recv_buffer.size()), 0, ec);
+ log.debug("Received {} bytes.", bytes_read);
+ return bytes_read;
+ };
- std::size_t sendFrame(const connector::native::Frame & frame)
- {
- connector::native::Frame::write_to_buffer(
- basyx::net::make_buffer(
- send_buffer.data() + BASYX_FRAMESIZE_SIZE, default_buffer_size - BASYX_FRAMESIZE_SIZE),
- frame);
+ std::size_t sendFrame(const connector::native::Frame& frame)
+ {
+ connector::native::Frame::write_to_buffer(
+ basyx::net::make_buffer(
+ send_buffer.data() + BASYX_FRAMESIZE_SIZE, default_buffer_size - BASYX_FRAMESIZE_SIZE),
+ frame);
- auto size_field = reinterpret_cast<uint32_t*>(&send_buffer[0]);
- *size_field = frame.size();
+ auto size_field = reinterpret_cast<uint32_t*>(&send_buffer[0]);
+ *size_field = static_cast<uint32_t>(frame.size());
- return sendData(send_buffer.data(), frame.size() + BASYX_FRAMESIZE_SIZE);
- };
+ return sendData(send_buffer.data(), frame.size() + BASYX_FRAMESIZE_SIZE);
+ };
- connector::native::Frame recvFrame(asio::error_code & ec)
- {
- this->receiveData(recv_buffer.data(), ec);
- auto size = *reinterpret_cast<uint32_t*>(recv_buffer.data());
- auto frame = connector::native::Frame::read_from_buffer(
- basyx::net::make_buffer(this->recv_buffer.data() + BASYX_FRAMESIZE_SIZE, size - BASYX_FRAMESIZE_SIZE)
- );
+ connector::native::Frame recvFrame(asio::error_code& ec)
+ {
+ this->receiveData(recv_buffer.data(), ec);
+ auto size = *reinterpret_cast<uint32_t*>(recv_buffer.data());
+ auto frame = connector::native::Frame::read_from_buffer(
+ basyx::net::make_buffer(this->recv_buffer.data() + BASYX_FRAMESIZE_SIZE, size - BASYX_FRAMESIZE_SIZE));
- return frame;
- };
- };
+ return frame;
+ };
+};
};
};
};
};
-#endif /* VAB_VAB_PROVIDER_NATIVE_BASYXNATIVEPROVIDER_H */
+#endif /* BASYX_SERVER_BASYXNATIVEPROVIDER_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/server/TCPSelectServer.h b/sdks/c++/basys.sdk.cc/include/BaSyx/server/TCPSelectServer.h
index 5ef3c75..6dfef78 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/server/TCPSelectServer.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/server/TCPSelectServer.h
@@ -4,8 +4,8 @@
* Author: wendel
*/
-#ifndef BASYX_SERVER_BASYXTCPSELECTSERVER_H_
-#define BASYX_SERVER_BASYXTCPSELECTSERVER_H_
+#ifndef BASYX_SERVER_TCPSELECTSERVER_H
+#define BASYX_SERVER_TCPSELECTSERVER_H
#include <BaSyx/vab/core/IModelProvider.h>
#include <BaSyx/vab/provider/native/frame/BaSyxNativeFrameProcessor.h>
@@ -115,4 +115,4 @@
}
}
-#endif
+#endif /* BASYX_SERVER_TCPSELECTSERVER_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/server/TCPServer.h b/sdks/c++/basys.sdk.cc/include/BaSyx/server/TCPServer.h
index 98e0f22..0e50193 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/server/TCPServer.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/server/TCPServer.h
@@ -1,5 +1,5 @@
-#ifndef VAB_VAB_PROVIDER_NATIVE_BASYXTCPSERVER_2_H
-#define VAB_VAB_PROVIDER_NATIVE_BASYXTCPSERVER_2_H
+#ifndef BASYX_SERVER_TCPSERVER_H
+#define BASYX_SERVER_TCPSERVER_H
#include <atomic>
#include <iostream>
@@ -15,174 +15,163 @@
namespace basyx {
namespace server {
- template <typename Backend>
- class TCPServer {
- public:
- using socket_ptr_t = std::unique_ptr<asio::ip::tcp::socket>;
- private:
- Backend * backend;
+template <typename Backend>
+class TCPServer {
+public:
+ using socket_ptr_t = std::unique_ptr<asio::ip::tcp::socket>;
- asio::io_context io_context;
- asio::ip::tcp::acceptor acceptor;
+private:
+ Backend* backend;
- std::vector<std::thread> threads;
- std::vector<socket_ptr_t> sockets;
+ asio::io_context io_context;
+ asio::ip::tcp::acceptor acceptor;
- bool closed;
- std::atomic_bool running;
+ std::vector<std::thread> threads;
+ std::vector<socket_ptr_t> sockets;
- basyx::log log;
+ bool closed;
+ std::atomic_bool running;
- public:
- TCPServer(Backend * backend, int port)
- : backend{ backend }
- , running{ true }
- , io_context{ 0 }
- , acceptor{ io_context, asio::ip::tcp::endpoint(asio::ip::tcp::v4(), port) }
- , log{ "TCPServer" }
- {
- // ToDo: Check health of acceptor
- log.info("Starting server on port {}", port);
-// acceptor.listen();
- start_accept();
- }
+ basyx::log log;
- void run()
- {
- this->io_context.run();
- };
+public:
+ TCPServer(Backend* backend, int port)
+ : backend { backend }
+ , running { false }
+ , io_context { 1 }
+ , acceptor { io_context, asio::ip::tcp::endpoint(asio::ip::tcp::v4(), port) }
+ , log { "TCPServer" }
+ {
+ // ToDo: Check health of acceptor
+ log.info("Starting server on port {}", port);
+ acceptor.listen();
+ }
- void stop()
- {
- this->io_context.stop();
- };
+ void run()
+ {
+ start_accept();
+ this->running.store(true);
+ this->io_context.run();
+ };
- void start_accept()
- {
- asio::error_code ec;
- auto client_socket = util::make_unique<asio::ip::tcp::socket>(io_context);
- //this->acceptor.accept(*client_socket.get(), ec);
+ void stop()
+ {
+ this->io_context.stop();
+ };
- //auto error = WSAGetLastError();
+ void start_accept()
+ {
+ asio::error_code ec;
+ auto client_socket = util::make_unique<asio::ip::tcp::socket>(io_context);
- //if (!client_socket->is_open()) {
- // log.warn("Incoming connection failed");
- // return;
- //}
- sockets.emplace_back(std::move(client_socket));
+ sockets.emplace_back(std::move(client_socket));
- acceptor.async_accept(*sockets.back(),
- std::bind(&TCPServer::handle_accept, this,
- std::placeholders::_1));
- };
+ acceptor.async_accept(*sockets.back(),
+ std::bind(&TCPServer::handle_accept, this,
+ std::placeholders::_1));
+ };
- void handle_accept(
- const asio::error_code& error)
- {
- if (!error)
- {
- log.info("Incoming new connection");
+ void handle_accept(
+ const asio::error_code& error)
+ {
+ if (!error) {
+ log.info("Incoming new connection");
- std::thread handlerThread{ &TCPServer<Backend>::processConnection, this, std::ref(*sockets.back()) };
- threads.emplace_back(std::move(handlerThread));
- }
- else
- {
- sockets.pop_back();
- }
+ std::thread handlerThread { &TCPServer<Backend>::processConnection, this, std::ref(*sockets.back()) };
+ threads.emplace_back(std::move(handlerThread));
+ } else {
+ sockets.pop_back();
+ }
- start_accept();
- };
+ start_accept();
+ };
- void Close()
- {
- log.trace("Closing...");
+ void Close()
+ {
+ log.trace("Closing...");
- if (!isRunning())
- return;
+ if (!isRunning())
+ return;
- running.store(false);
- this->stop();
+ running.store(false);
+ this->stop();
- //// Close the acceptor socket
- //log.trace("Closing Acceptor...");
- //acceptor.close();
+ //// Close the acceptor socket
+ //log.trace("Closing Acceptor...");
+ //acceptor.close();
- // Close all accepted connections
- // This will bring all open connection threads to a finish
- log.trace("Closing open connections...");
- for (auto& socket : sockets)
- {
- try {
- if (socket->is_open())
- socket->close();
- }
- catch (std::exception & e)
- {
- log.warn("Socket closed unexpectedly.");
- }
- };
+ // Close all accepted connections
+ // This will bring all open connection threads to a finish
+ log.trace("Closing open connections...");
+ for (auto& socket : sockets) {
+ try {
+ if (socket->is_open())
+ socket->close();
+ } catch (std::exception& e) {
+ log.warn("Socket closed unexpectedly: {}", e.what());
+ }
+ };
- // Wait for all threads to finish
- for (auto& thread : threads)
- thread.join();
+ // Wait for all threads to finish
+ for (auto& thread : threads)
+ thread.join();
- // ToDo: Check for errors during cleanup
- }
+ // ToDo: Check for errors during cleanup
+ }
- ~TCPServer()
- {
- this->Close();
- }
+ ~TCPServer()
+ {
+ this->Close();
+ }
- /**
- * Has to be called periodically
- */
- void update()
- {
- if (isRunning()) {
- log.info("Accepting new connections.");
+ /**
+ * Has to be called periodically
+ */
+ void update()
+ {
+ if (isRunning()) {
+ log.info("Accepting new connections.");
- auto ClientSocket = util::make_unique<asio::ip::tcp::socket>(io_context);
- this->acceptor.accept(*ClientSocket.get());
+ auto ClientSocket = util::make_unique<asio::ip::tcp::socket>(io_context);
+ this->acceptor.accept(*ClientSocket.get());
- //auto error = WSAGetLastError();
+ //auto error = WSAGetLastError();
- if (!ClientSocket->is_open()) {
- log.warn("Incoming connection failed");
- return;
- }
+ if (!ClientSocket->is_open()) {
+ log.warn("Incoming connection failed");
+ return;
+ }
- log.info("Incoming new connection");
- sockets.emplace_back(std::move(ClientSocket));
+ log.info("Incoming new connection");
+ sockets.emplace_back(std::move(ClientSocket));
- std::thread handlerThread{ &TCPServer<Backend>::processConnection, this, std::ref(*sockets.back()) };
- threads.emplace_back(std::move(handlerThread));
- }
- }
+ std::thread handlerThread { &TCPServer<Backend>::processConnection, this, std::ref(*sockets.back()) };
+ threads.emplace_back(std::move(handlerThread));
+ }
+ }
- bool isRunning()
- {
- return running.load();
- }
+ bool isRunning()
+ {
+ return running.load();
+ }
- private:
- /**
- * Handles a BaSyxNativeProvider
- */
- void processConnection(asio::ip::tcp::socket & socket)
- {
- log.trace("Processing new connection");
+private:
+ /**
+* Handles a BaSyxNativeProvider
+*/
+ void processConnection(asio::ip::tcp::socket& socket)
+ {
+ log.trace("Processing new connection");
- vab::provider::native::frame::BaSyxNativeFrameProcessor processor{ this->backend };
- vab::provider::native::NativeProvider provider{ socket, &processor };
+ vab::provider::native::frame::BaSyxNativeFrameProcessor processor { this->backend };
+ vab::provider::native::NativeProvider provider { socket, &processor };
- while (!provider.isClosed()) {
- provider.update();
- }
- }
- };
+ while (!provider.isClosed()) {
+ provider.update();
+ }
+ }
+};
};
};
-#endif /* VAB_VAB_PROVIDER_NATIVE_BASYXTCPSERVER_2_H */
\ No newline at end of file
+#endif /* BASYX_SERVER_TCPSERVER_H */
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/anyTypeChecker.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/anyTypeChecker.h
index f663d82..f940a6f 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/anyTypeChecker.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/anyTypeChecker.h
@@ -4,52 +4,49 @@
* Author: wendel
*/
-#ifndef UTIL_ANYTYPECHECKER_H_
-#define UTIL_ANYTYPECHECKER_H_
+#ifndef BASYX_SHARED_ANYTYPECHECKER_H
+#define BASYX_SHARED_ANYTYPECHECKER_H
-#include <BaSyx/shared/types.h>
#include <BaSyx/shared/object.h>
+#include <BaSyx/shared/types.h>
#include <string>
namespace basyx {
-namespace PropertyTypeInfo
+namespace PropertyTypeInfo {
+ static constexpr char STRING[] = "string";
+ static constexpr char INT[] = "int";
+ static constexpr char COLLECTION[] = "collection";
+ static constexpr char MAP[] = "map";
+ static constexpr char BOOL[] = "boolean";
+ static constexpr char DOUBLE[] = "double";
+ static constexpr char FLOAT[] = "long";
+ static constexpr char PROPNULL[] = "null";
+ static constexpr char NONETYPE[] = "Type not specified";
+}
+
+static std::string getPropertyTypeInfo(const basyx::object& object)
{
- static constexpr char STRING[] = "string";
- static constexpr char INT[] = "int";
- static constexpr char COLLECTION[] = "collection";
- static constexpr char MAP[] = "map";
- static constexpr char BOOL[] = "boolean";
- static constexpr char DOUBLE[] = "double";
- static constexpr char FLOAT[] = "long";
- static constexpr char PROPNULL[] = "null";
- static constexpr char NONETYPE[] = "Type not specified";
-}
-
-
-static std::string getPropertyTypeInfo(const basyx::object & object)
-{
- if ( object.InstanceOf<std::string>() )
- return PropertyTypeInfo::STRING;
- if ( object.InstanceOf<int>() )
- return PropertyTypeInfo::INT;
- if ( object.InstanceOf<basyx::object::object_list_t>() )
- return PropertyTypeInfo::COLLECTION;
- if ( object.InstanceOf<basyx::object::object_map_t>() )
- return PropertyTypeInfo::MAP;
- if ( object.InstanceOf<bool>() )
- return PropertyTypeInfo::BOOL;
- if ( object.InstanceOf<double>() )
- return PropertyTypeInfo::DOUBLE;
- if ( object.InstanceOf<float>() )
- return PropertyTypeInfo::FLOAT;
- if ( object.InstanceOf<std::nullptr_t>() )
- return PropertyTypeInfo::PROPNULL;
- return PropertyTypeInfo::NONETYPE;
+ if (object.InstanceOf<std::string>())
+ return PropertyTypeInfo::STRING;
+ if (object.InstanceOf<int>())
+ return PropertyTypeInfo::INT;
+ if (object.InstanceOf<basyx::object::object_list_t>())
+ return PropertyTypeInfo::COLLECTION;
+ if (object.InstanceOf<basyx::object::object_map_t>())
+ return PropertyTypeInfo::MAP;
+ if (object.InstanceOf<bool>())
+ return PropertyTypeInfo::BOOL;
+ if (object.InstanceOf<double>())
+ return PropertyTypeInfo::DOUBLE;
+ if (object.InstanceOf<float>())
+ return PropertyTypeInfo::FLOAT;
+ if (object.InstanceOf<std::nullptr_t>())
+ return PropertyTypeInfo::PROPNULL;
+ return PropertyTypeInfo::NONETYPE;
}
}
-
-#endif // !UTIL_ANYTYPECHECKER_H_
+#endif /* BASYX_SHARED_ANYTYPECHECKER_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/enums.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/enums.h
index 6f92379..1289a75 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/enums.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/enums.h
@@ -1,24 +1,19 @@
-#ifndef BASYX_ENUMS_H
-#define BASYX_ENUMS_H
+#ifndef BASYX_SHARED_ENUMS_H
+#define BASYX_SHARED_ENUMS_H
-namespace basyx
-{
+namespace basyx {
-enum class EntityType : char
-{
- CoManagedEntity = 0,
- SelfManagedEntity = 1,
+enum class EntityType : char {
+ CoManagedEntity = 0,
+ SelfManagedEntity = 1,
};
-enum class Category : char
-{
- Constant = 0,
- Parameter = 1,
- Variable = 2,
+enum class Category : char {
+ Constant = 0,
+ Parameter = 1,
+ Variable = 2,
};
};
-
-
-#endif
\ No newline at end of file
+#endif /* BASYX_SHARED_ENUMS_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object.h
index 5a715ff..36f7fbf 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object.h
@@ -1,3 +1,6 @@
+#ifndef BASYX_SHARED_OBJECT_H
+#define BASYX_SHARED_OBJECT_H
+
#include <BaSyx/shared/object/object_header.h>
#include <BaSyx/shared/object/impl/object_cast_impl.h>
#include <BaSyx/shared/object/impl/object_meta_impl.h>
@@ -5,3 +8,5 @@
#include <BaSyx/shared/object/impl/object_access_impl.h>
#include <BaSyx/shared/object/obj_holder.h>
#include <BaSyx/shared/object/obj_ref_holder.h>
+
+#endif /* BASYX_SHARED_OBJECT_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/bad_object_cast.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/bad_object_cast.h
index 4a6af5a..15d1981 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/bad_object_cast.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/bad_object_cast.h
@@ -5,35 +5,35 @@
* Author: psota
*/
-#ifndef BASYX_object_BAD_object_CAST_H
-#define BASYX_object_BAD_object_CAST_H
+#ifndef BASYX_SHARED_OBJECT_BAD_OBJECT_CAST_H
+#define BASYX_SHARED_OBJECT_BAD_OBJECT_CAST_H
#include <exception>
#include <memory>
#include <string>
namespace basyx {
- // Exception: bad_object_cast
- // Thrown whenever a bad cast on a basyx::object object is tried
- class bad_object_cast : public std::bad_cast {
- private:
- std::string msg;
+// Exception: bad_object_cast
+// Thrown whenever a bad cast on a basyx::object object is tried
+class bad_object_cast : public std::bad_cast {
+private:
+ std::string msg;
- public:
- bad_object_cast(const std::type_info& base_type, const std::type_info& casted_type)
- : msg { "basyx::bad_object_cast: " }
- {
- msg.append("Base type: <").append(base_type.name()).append(">");
- msg.append(", casted type: <").append(casted_type.name()).append(">");
- };
-
- public:
- virtual const char* what() const noexcept override
- {
- return msg.c_str();
- }
+public:
+ bad_object_cast(const std::type_info& base_type, const std::type_info& casted_type)
+ : msg { "basyx::bad_object_cast: " }
+ {
+ msg.append("Base type: <").append(base_type.name()).append(">");
+ msg.append(", casted type: <").append(casted_type.name()).append(">");
};
+public:
+ virtual const char* what() const noexcept override
+ {
+ return msg.c_str();
+ }
+};
+
};
-#endif /* BASYX_object_BAD_object_CAST_H */
+#endif /* BASYX_SHARED_OBJECT_BAD_OBJECT_CAST_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_access_impl.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_access_impl.h
index c21fb3d..e750d69 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_access_impl.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_access_impl.h
@@ -1,107 +1,110 @@
-#ifndef SHARED_BASYX_OBJECT_IMPL_OBJECT_ACCESS_IMPL_H
-#define SHARED_BASYX_OBJECT_IMPL_OBJECT_ACCESS_IMPL_H
+#ifndef BASYX_SHARED_OBJECT_IMPL_OBJECT_ACCESS_IMPL_H
+#define BASYX_SHARED_OBJECT_IMPL_OBJECT_ACCESS_IMPL_H
template<typename T>
bool basyx::object::insert(const T & t)
{
- if (!this->content)
- return false;
+ if (!this->content)
+ return false;
- // Check if contained object is list or set
- switch (content->object_type())
- {
- case basyx::type::objectType::List:
- if (this->InstanceOf<object::list_t<T>>())
- {
- auto & vec = this->Get<object::list_t<T>&>();
- vec.push_back(t);
- return true;
- }
- else if (this->InstanceOf<object::object_list_t>())
- {
- auto & vec = this->Get<object::object_list_t&>();
- vec.emplace_back(t);
- return true;
- }
- break;
- };
- return false;
+ // Check if contained object is list or set
+ switch (content->object_type())
+ {
+ case basyx::type::objectType::List:
+ if (this->InstanceOf<object::list_t<T>>())
+ {
+ auto & vec = this->Get<object::list_t<T>&>();
+ vec.push_back(t);
+ return true;
+ }
+ else if (this->InstanceOf<object::object_list_t>())
+ {
+ auto & vec = this->Get<object::object_list_t&>();
+ vec.emplace_back(t);
+ return true;
+ }
+ break;
+ default:
+ break;
+ };
+ return false;
};
template<typename T>
bool basyx::object::insertKey(const std::string & key, const T & t, bool override)
{
- if (!this->content)
- return false;
+ if (!this->content)
+ return false;
- // Check if contained object is hashmap
- if (content->object_type() == basyx::type::objectType::Map)
- {
- // Check contained type
- if (this->InstanceOf<object::object_map_t>())
- {
- auto & map = this->Get<object::object_map_t&>();
+ // Check if contained object is hashmap
+ if (content->object_type() == basyx::type::objectType::Map)
+ {
+ // Check contained type
+ if (this->InstanceOf<object::object_map_t>())
+ {
+ auto & map = this->Get<object::object_map_t&>();
- // Check if key already exists
- if (map.find(key) != map.end())
- {
- // if override, set new value, else return false
- if (override) {
- map[key] = t;
- return true;
- };
+ // Check if key already exists
+ if (map.find(key) != map.end())
+ {
+ // if override, set new value, else return false
+ if (override) {
+ map[key] = t;
+ return true;
+ };
- return false;
- }
- else // key doesn't exist, just insert object
- {
- map.emplace(key, t);
- return true;
- }
- }
- };
+ return false;
+ }
+ else // key doesn't exist, just insert object
+ {
+ map.emplace(key, t);
+ return true;
+ }
+ }
+ };
- return false;
+ return false;
};
template<typename T>
bool basyx::object::remove(const T & t)
{
- if (!this->content)
- return false;
+ if (!this->content)
+ return false;
- // Check if contained object is list or set
- switch (content->object_type())
- {
- case basyx::type::objectType::List:
- auto & list = this->Get<object::list_t<T>&>();
- list.erase(std::remove(list.begin(), list.end(), t), list.end());
- return true;
- break;
- };
- return false;
+ // Check if contained object is list or set
+ switch (content->object_type())
+ {
+ case basyx::type::objectType::List:
+ {
+ auto & list = this->Get<object::list_t<T>&>();
+ list.erase(std::remove(list.begin(), list.end(), t), list.end());
+ return true;
+ };
+ default:
+ break;
+ };
+ return false;
}
inline bool basyx::object::remove(basyx::object & obj)
{
- auto valueType = obj.GetValueType();
- switch(valueType)
- {
- case basyx::type::valueType::Bool:
- return this->remove(obj.Get<const bool>());
- break;
- case basyx::type::valueType::Int:
- return this->remove(obj.Get<const int>());
- break;
- case basyx::type::valueType::String:
- return this->remove(obj.Get<const std::string>());
- break;
- case basyx::type::valueType::Float:
- return this->remove(obj.Get<const double>());
- break;
- };
+ auto valueType = obj.GetValueType();
+ switch(valueType)
+ {
+ case basyx::type::valueType::Bool:
+ return this->remove(obj.Get<const bool>());
+ case basyx::type::valueType::Int:
+ return this->remove(obj.Get<const int>());
+ case basyx::type::valueType::String:
+ return this->remove(obj.Get<const std::string>());
+ case basyx::type::valueType::Float:
+ return this->remove(obj.Get<const double>());
+ default:
+ break;
+ };
- return false;
+ return false;
};
-#endif /* SHARED_BASYX_OBJECT_IMPL_OBJECT_ACCESS_IMPL_H */
+#endif /* BASYX_SHARED_OBJECT_IMPL_OBJECT_ACCESS_IMPL_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_cast_impl.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_cast_impl.h
index d169a34..76b9453 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_cast_impl.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_cast_impl.h
@@ -1,5 +1,5 @@
-#ifndef SHARED_BASYX_OBJECT_IMPL_OBJECT_CAST_IMPL_H
-#define SHARED_BASYX_OBJECT_IMPL_OBJECT_CAST_IMPL_H
+#ifndef BASYX_SHARED_OBJECT_IMPL_OBJECT_CAST_IMPL_H
+#define BASYX_SHARED_OBJECT_IMPL_OBJECT_CAST_IMPL_H
#include <BaSyx/shared/object/object_header.h>
#include <BaSyx/shared/object/obj_holder.h>
@@ -66,4 +66,4 @@
return object_cast<T>(const_cast<object*>(operand));
}
-#endif /* SHARED_BASYX_OBJECT_IMPL_OBJECT_CAST_IMPL_H */
+#endif /* BASYX_SHARED_OBJECT_IMPL_OBJECT_CAST_IMPL_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_factories_impl.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_factories_impl.h
index 4279fef..3c38594 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_factories_impl.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_factories_impl.h
@@ -1,5 +1,5 @@
-#ifndef SHARED_BASYX_OBJECT_IMPL_OBJECT_FACTORIES_IMPL_H
-#define SHARED_BASYX_OBJECT_IMPL_OBJECT_FACTORIES_IMPL_H
+#ifndef BASYX_SHARED_OBJECT_IMPL_OBJECT_FACTORIES_IMPL_H
+#define BASYX_SHARED_OBJECT_IMPL_OBJECT_FACTORIES_IMPL_H
#include <BaSyx/util/printer.h>
#include <BaSyx/util/util.h>
@@ -53,4 +53,4 @@
return basyx::detail::functionWrapper::wrap_func(util::make_function(std::forward<Args>(args)...));
};
-#endif /* SHARED_BASYX_OBJECT_IMPL_OBJECT_FACTORIES_IMPL_H */
+#endif /* BASYX_SHARED_OBJECT_IMPL_OBJECT_FACTORIES_IMPL_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_meta_impl.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_meta_impl.h
index 50b7cec..6abe59e 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_meta_impl.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_meta_impl.h
@@ -1,5 +1,5 @@
-#ifndef SHARED_BASYX_OBJECT_IMPL_OBJECT_META_IMPL_H
-#define SHARED_BASYX_OBJECT_IMPL_OBJECT_META_IMPL_H
+#ifndef BASYX_SHARED_OBJECT_IMPL_OBJECT_META_IMPL_H
+#define BASYX_SHARED_OBJECT_IMPL_OBJECT_META_IMPL_H
template <typename T>
bool basyx::object::operator!=(const T& rhs) const
@@ -17,4 +17,4 @@
}
-#endif /* SHARED_BASYX_OBJECT_IMPL_OBJECT_META_IMPL_H */
+#endif /* BASYX_SHARED_OBJECT_IMPL_OBJECT_META_IMPL_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_error.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_error.h
index 34114c7..304bc1c 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_error.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_error.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_ENUM_ERROR_H
-#define BASYX_ENUM_ERROR_H
+#ifndef BASYX_SHARED_OBJECT_OBJ_ERROR_H
+#define BASYX_SHARED_OBJECT_OBJ_ERROR_H
#include <string>
@@ -26,4 +26,4 @@
}
}
-#endif
+#endif /* BASYX_SHARED_OBJECT_OBJ_ERROR_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_error_holder.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_error_holder.h
index 9619fb7..c4e58dd 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_error_holder.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_error_holder.h
@@ -5,8 +5,8 @@
* Author: psota
*/
-#ifndef BASYX_object_error_HOLDER_H
-#define BASYX_object_error_HOLDER_H
+#ifndef BASYX_SHARED_OBJECT_OBJ_ERROR_HOLDER_H
+#define BASYX_SHARED_OBJECT_OBJ_ERROR_HOLDER_H
#include <memory>
#include <string>
@@ -76,4 +76,4 @@
}
}
-#endif /* BASYX_object_error_HOLDER_H */
+#endif /* BASYX_SHARED_OBJECT_OBJ_ERROR_HOLDER_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_function.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_function.h
index 9902e82..d86035c 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_function.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_function.h
@@ -1,5 +1,5 @@
-#ifndef OBJ_FUNCTION_H
-#define OBJ_FUNCTION_H
+#ifndef BASYX_SHARED_OBJECT_OBJ_FUNCTION_H
+#define BASYX_SHARED_OBJECT_OBJ_FUNCTION_H
#include <functional>
@@ -34,6 +34,18 @@
return func(&obj);
};
+ // Wrap void function with no arguments
+ static functionWrapper wrap_func(std::function<void(void)> f)
+ {
+ functionWrapper fw;
+ fw.func = [f](basyx::object*)
+ {
+ f();
+ return basyx::object::make_null();
+ };
+ return fw;
+ };
+
// Wrap function with no arguments
template<typename RetType>
static functionWrapper wrap_func(std::function<RetType(void)> f)
@@ -109,4 +121,4 @@
}
-#endif /* OBJ_FUNCTION_H */
+#endif /* BASYX_SHARED_OBJECT_OBJ_FUNCTION_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_holder.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_holder.h
index d39d6a6..17b137f 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_holder.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_holder.h
@@ -5,8 +5,8 @@
* Author: psota
*/
-#ifndef BASYX_object_HOLDER_H
-#define BASYX_object_HOLDER_H
+#ifndef BASYX_SHARED_OBJECT_OBJ_HOLDER_H
+#define BASYX_SHARED_OBJECT_OBJ_HOLDER_H
#include <memory>
#include <string>
@@ -83,4 +83,4 @@
}
}
-#endif /* BASYX_object_HOLDER_H */
+#endif /* BASYX_SHARED_OBJECT_OBJ_HOLDER_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_placeholder.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_placeholder.h
index d1bff64..c157c66 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_placeholder.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_placeholder.h
@@ -5,8 +5,8 @@
* Author: psota
*/
-#ifndef BASYX_object_PLACEHOLDER_H
-#define BASYX_object_PLACEHOLDER_H
+#ifndef BASYX_SHARED_OBJECT_OBJ_PLACEHOLDER_H
+#define BASYX_SHARED_OBJECT_OBJ_PLACEHOLDER_H
#include <BaSyx/shared/object/object_type.h>
@@ -43,4 +43,4 @@
}
};
-#endif /* BASYX_object_PLACEHOLDER_H */
+#endif /* BASYX_SHARED_OBJECT_OBJ_PLACEHOLDER_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_ref_holder.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_ref_holder.h
index 7619afb..59dbbdb 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_ref_holder.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_ref_holder.h
@@ -5,8 +5,8 @@
* Author: psota
*/
-#ifndef BASYX_object_ref_HOLDER_H
-#define BASYX_object_ref_HOLDER_H
+#ifndef BASYX_SHARED_OBJECT_OBJ_REF_HOLDER_H
+#define BASYX_SHARED_OBJECT_OBJ_REF_HOLDER_H
#include <memory>
#include <string>
@@ -81,4 +81,4 @@
}
}
-#endif /* BASYX_object_HOLDER_H */
+#endif /* BASYX_SHARED_OBJECT_OBJ_REF_HOLDER_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/object_header.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/object_header.h
index 806c110..6264f9b 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/object_header.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/object_header.h
@@ -5,8 +5,8 @@
* Author: psota
*/
-#ifndef BASYX_object_object_header_H
-#define BASYX_object_object_header_H
+#ifndef BASYX_SHARED_OBJECT_OBJECT_HEADER_H
+#define BASYX_SHARED_OBJECT_OBJECT_HEADER_H
#include <cstddef>
#include <memory>
@@ -223,4 +223,4 @@
};
};
-#endif /* BASYX_object_object_H */
+#endif /* BASYX_SHARED_OBJECT_OBJECT_HEADER_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/object_type.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/object_type.h
index 8a3f762..a935b0d 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/object_type.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/object_type.h
@@ -1,12 +1,28 @@
-#ifndef BASYX_object_object_TYPE_H
-#define BASYX_object_object_TYPE_H
+#ifndef BASYX_SHARED_OBJECT_OBJECT_TYPE_H
+#define BASYX_SHARED_OBJECT_OBJECT_TYPE_H
#include <string>
#include <vector>
#include <unordered_set>
#include <unordered_map>
+template<typename T>
+struct dataTypeMapper
+{
+};
+
+template<>
+struct dataTypeMapper<float>
+{
+ static constexpr char datatype_string[] = "xsd:float";
+};
+
+template<>
+struct dataTypeMapper<int>
+{
+ static constexpr char datatype_string[] = "xsd:integer";
+};
namespace basyx {
@@ -162,4 +178,4 @@
template<> inline std::string to_string<basyx::type::valueType::Object>() { return "Object"; };
}
-#endif
\ No newline at end of file
+#endif /* BASYX_SHARED_OBJECT_OBJECT_TYPE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json.h
index f9eacd3..f3de345 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json.h
@@ -1,6 +1,6 @@
-#ifndef _JSON_H
-#define _JSON_H
+#ifndef BASYX_SHARED_SERIALIZATION_JSON_H
+#define BASYX_SHARED_SERIALIZATION_JSON_H
#include <BaSyx/shared/serialization/json/json.h>
-#endif /* _JSON_H */
+#endif /* BASYX_SHARED_SERIALIZATION_JSON_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/json.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/json.h
index 336a14a..6afab09 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/json.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/json.h
@@ -5,8 +5,8 @@
* Author: psota
*/
-#ifndef BASYX_SERIALIZATION_JSON_JSON_H
-#define BASYX_SERIALIZATION_JSON_JSON_H
+#ifndef BASYX_SHARED_SERIALIZATION_JSON_JSON_H
+#define BASYX_SHARED_SERIALIZATION_JSON_JSON_H
#include <nlohmann/json.hpp>
@@ -49,4 +49,4 @@
};
};
-#endif /* BASYX_SERIALIZATION_JSON_JSON_H */
+#endif /* BASYX_SHARED_SERIALIZATION_JSON_JSON_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/json_deserializer.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/json_deserializer.h
index 52688eb..8a46858 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/json_deserializer.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/json_deserializer.h
@@ -5,8 +5,8 @@
* Author: psota
*/
-#ifndef BASYX_JSON_DESERIALIZER_H
-#define BASYX_JSON_DESERIALIZER_H
+#ifndef BASYX_SHARED_SERIALIZATION_JSON_JSON_DESERIALIZER_H
+#define BASYX_SHARED_SERIALIZATION_JSON_JSON_DESERIALIZER_H
#include <nlohmann/json.hpp>
@@ -111,6 +111,8 @@
return deserialize_helper::list_t<double>(json_array);
case basyx::type::valueType::Object:
return deserialize_helper::object_list(json_array);
+ default:
+ break;
};
}
@@ -159,4 +161,4 @@
};
};
-#endif
+#endif /* BASYX_SHARED_SERIALIZATION_JSON_JSON_DESERIALIZER_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/json_serializer.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/json_serializer.h
index 8917501..610ce09 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/json_serializer.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/json_serializer.h
@@ -5,8 +5,8 @@
* Author: psota
*/
-#ifndef BASYX_SERIALIZATION_JSON_JSON_SERIALIZER_H
-#define BASYX_SERIALIZATION_JSON_JSON_SERIALIZER_H
+#ifndef BASYX_SHARED_SERIALIZATION_JSON_JSON_SERIALIZER_H
+#define BASYX_SHARED_SERIALIZATION_JSON_JSON_SERIALIZER_H
#include <nlohmann/json.hpp>
@@ -63,4 +63,4 @@
};
};
-#endif /* BASYX_SERIALIZATION_JSON_JSON_SERIALIZER_H */
+#endif /* BASYX_SHARED_SERIALIZATION_JSON_JSON_SERIALIZER_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/typeid.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/typeid.h
index d2276f4..1b83a4f 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/typeid.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/typeid.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_JSON_TYPEID_H
-#define BASYX_JSON_TYPEID_H
+#ifndef BASYX_SHARED_SERIALIZATION_JSON_TYPEID_H
+#define BASYX_SHARED_SERIALIZATION_JSON_TYPEID_H
#include <string>
@@ -54,4 +54,4 @@
template <typename T>
constexpr char basyx::serialization::basysType<T>::string[];
-#endif /* BASYX_JSON_TYPEID_H */
+#endif /* BASYX_SHARED_SERIALIZATION_JSON_TYPEID_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/types.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/types.h
index d9a106c..8adda9b 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/types.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/types.h
@@ -4,8 +4,8 @@
* Define type IDs
* ************************************************************************************************/
-#ifndef BASYX_TYPES_H
-#define BASYX_TYPES_H
+#ifndef BASYX_SHARED_TYPES_H
+#define BASYX_SHARED_TYPES_H
#include <set>
#include <unordered_map>
@@ -51,4 +51,4 @@
#define BASYX_FRAMESIZE_SIZE 4
#define BASYX_STRINGSIZE_SIZE 4
-#endif /* BASYX_TYPES_H */
+#endif /* BASYX_SHARED_TYPES_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/IElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/IElement.h
deleted file mode 100644
index 09c4b67..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/IElement.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * IElement.h
- *
- * Created on: 29.04.2018
- * Author: kuhn, wendel
- */
-
-#ifndef API_IELEMENT_H_
-#define API_IELEMENT_H_
-
-#include <string>
-
-/* *********************************************************************************
- * IElement class - Base class for reflexive BaSys elements
- * *********************************************************************************/
-class IElement {
-public:
- virtual ~IElement() = default;
-
- virtual void setId(const std::string & id) = 0;
- virtual std::string getId() const = 0;
-};
-
-
-#endif /* API_IELEMENT_H_ */
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/ISubModel.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/ISubModel.h
deleted file mode 100644
index 0a51f2d..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/ISubModel.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * ISubModel.h
- *
- * Author: kuhn, wendel
- */
-
-#ifndef API_ISUBMODEL_H_
-#define API_ISUBMODEL_H_
-
-
- /* *********************************************************************************
- * Includes
- * *********************************************************************************/
-
- // StdC++ includes
-#include <map>
-#include <string>
-
-// BaSyx includes
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-#include <BaSyx/submodel/api/qualifier/IHasSemantics.h>
-#include <BaSyx/submodel/api/qualifier/IIdentifiable.h>
-#include <BaSyx/submodel/api/qualifier/IHasDataSpecification.h>
-#include <BaSyx/submodel/api/qualifier/IHasKind.h>
-#include <BaSyx/submodel/api/submodelelement/operation/IOperation.h>
-#include <BaSyx/submodel/map/IVABElementContainer.h>
-#include <BaSyx/shared/types.h>
-
-
-namespace basyx {
-namespace submodel {
-
-
-/* *********************************************************************************
- * Sub model interface class
- * *********************************************************************************/
-class ISubModel :
- public virtual IHasSemantics,
- public virtual IIdentifiable,
- public virtual IQualifiable,
- public virtual IHasDataSpecification,
- public virtual IHasKind,
- public map::IVABElementContainer
-{
-public:
- struct Path {
- static constexpr char Submodelelement[] = "submodelElement";
- static constexpr char DataElements[] = "dataElements";
- static constexpr char Operations[] = "operations";
- static constexpr char ModelType[] = "Submodel";
- };
-public:
- virtual ~ISubModel() = default;
-
- virtual basyx::specificMap_t<ISubmodelElement> getSubmodelElements() const = 0;
- virtual basyx::specificMap_t<IDataElement> getDataElements() const = 0;
- virtual basyx::specificMap_t<IOperation> getOperations() const = 0;
-};
-
-}
-}
-
-
-#endif /* API_ISUBMODEL_H_ */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/IDataSpecification.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/IDataSpecification.h
deleted file mode 100644
index e4eafd1..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/IDataSpecification.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * IDataSpecification.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IDATASPECIFICATION_H_
-#define BASYX_METAMODEL_IDATASPECIFICATION_H_
-
-#include <BaSyx/submodel/api/dataspecification/IDataSpecificationContent.h>
-
-#include <BaSyx/submodel/api/qualifier/IIdentifiable.h>
-#include <BaSyx/submodel/api/qualifier/IReferable.h>
-
-#include <string>
-
-namespace basyx {
-namespace submodel {
-
-class IDataSpecification
- : public virtual submodel::IIdentifiable
- , public virtual submodel::IReferable
-{
-public:
- struct Path
- {
- static constexpr char Content[] = "content";
- };
-public:
- virtual ~IDataSpecification() = default;
-
- virtual std::shared_ptr<IDataSpecificationContent> getContent() const = 0;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/IDataSpecificationContent.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/IDataSpecificationContent.h
deleted file mode 100644
index 4b95359..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/IDataSpecificationContent.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * IDataSpecification.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IDATASPECIFICATION_CONTENT_H_
-#define BASYX_METAMODEL_IDATASPECIFICATION_CONTENT_H_
-
-#include <BaSyx/submodel/api/qualifier/IIdentifiable.h>
-#include <BaSyx/submodel/api/qualifier/IReferable.h>
-
-namespace basyx {
-namespace submodel {
-
-class IDataSpecificationContent
-{
-public:
- virtual ~IDataSpecificationContent() = default;
-};
-
-}
-}
-
-#endif
-
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/IDataSpecificationIEC61360.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/IDataSpecificationIEC61360.h
deleted file mode 100644
index 370b2c0..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/IDataSpecificationIEC61360.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * IDataSpecification.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IDATASPECIFICATION_I_DATASPECIFICATIONIEC61630_H_
-#define BASYX_METAMODEL_IDATASPECIFICATION_I_DATASPECIFICATIONIEC61630_H_
-
-#include <BaSyx/submodel/api/dataspecification/IDataSpecificationContent.h>
-#include <BaSyx/submodel/api/dataspecification/datatypes/DataTypeIEC61360.h>
-#include <BaSyx/submodel/api/dataspecification/datatypes/LevelType.h>
-
-#include <BaSyx/submodel/api/reference/IReference.h>
-
-#include <BaSyx/submodel/api/submodelelement/langstring/ILangStringSet.h>
-
-#include <BaSyx/shared/object.h>
-
-#include <string>
-
-namespace basyx {
-namespace submodel {
-
-class IDataSpecificationIEC61360
- : public virtual IDataSpecificationContent
-{
-public:
-struct Path
-{
- static constexpr char PreferredName[] = "preferredName";
- static constexpr char ShortName[] = "shortName";
- static constexpr char Unit[] = "unit";
- static constexpr char UnitId[] = "unitId";
- static constexpr char SourceOfDefinition[] = "sourceOfDefinition";
- static constexpr char Symbol[] = "symbol";
- static constexpr char DataType[] = "dataType";
- static constexpr char Definition[] = "definition";
- static constexpr char ValueFormat[] = "valueFormat";
- static constexpr char ValueList[] = "valueList";
- static constexpr char ValueId[] = "valueId";
- static constexpr char LevelType[] = "levelType";
-};
-
-public:
- virtual ~IDataSpecificationIEC61360() = default;
-
- virtual std::shared_ptr<ILangStringSet> PreferredName() = 0;
- virtual std::shared_ptr<ILangStringSet> ShortName() = 0;
- virtual std::shared_ptr<ILangStringSet> Definition() = 0;
-
- virtual std::string getUnit() const = 0;
- virtual std::shared_ptr<IReference> getUnitId() const = 0;
- virtual std::string getSourceOfDefinition() const = 0;
- virtual DataTypeIEC61360 getDataType() const = 0;
- virtual std::string getValueFormat() const = 0;
- virtual basyx::object getValueList() const = 0;
- virtual std::shared_ptr<submodel::IReference> getValueId() const = 0;
- virtual LevelType getLevelType() const = 0;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/datatypes/DataTypeIEC61360.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/datatypes/DataTypeIEC61360.h
deleted file mode 100644
index b9b3b0b..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/datatypes/DataTypeIEC61360.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * DataTypeIEC61360.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_AAS_DATASPECIFICATION_DATATYPEIEC61360_H_
-#define BASYX_AAS_DATASPECIFICATION_DATATYPEIEC61360_H_
-
-#include <string>
-#include <unordered_map>
-
-#include <BaSyx/util/util.h>
-
-namespace basyx {
-namespace submodel {
-
- enum class DataTypeIEC61360 : char
- {
- Date,
- String,
- String_Translatable,
- Real_Measure,
- Real_Count,
- Real_Currency,
- Boolean,
- Url,
- Rational,
- Rational_Measure,
- Time,
- Timestamp
- };
-}
-}
-
-namespace util {
- const std::string & to_string(basyx::submodel::DataTypeIEC61360 type);
-
- template<>
- basyx::submodel::DataTypeIEC61360 from_string<basyx::submodel::DataTypeIEC61360>(const std::string & str);
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/datatypes/LevelType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/datatypes/LevelType.h
deleted file mode 100644
index 5853940..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/datatypes/LevelType.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * LevelType.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_AAS_DATASPECIFICATION_LEVELTYPE_H_
-#define BASYX_AAS_DATASPECIFICATION_LEVELTYPE_H_
-
-#include <unordered_map>
-#include <string>
-
-#include <BaSyx/util/util.h>
-
-namespace basyx {
-namespace submodel {
-
- enum class LevelType : char
- {
- Min,
- Max,
- Nom,
- Typ
- };
-}
-}
-
-namespace util {
-
- const std::string & to_string(basyx::submodel::LevelType levelType);
-
- template<>
- basyx::submodel::LevelType from_string<basyx::submodel::LevelType>(const std::string & str);
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/identifier/IIdentifier.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/identifier/IIdentifier.h
deleted file mode 100644
index 3f3683a..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/identifier/IIdentifier.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * IIdentifier.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IIDENTIFIER_H_
-#define BASYX_METAMODEL_IIDENTIFIER_H_
-
-#include <string>
-
-namespace basyx {
-namespace submodel {
-
-class IIdentifier
-{
-public:
- struct Path {
- static constexpr char IdentifierPath[] = "identifierPath";
- static constexpr char IdType[] = "idType";
- static constexpr char Id[] = "id";
- };
-public:
- virtual ~IIdentifier() = default;
-
- /**
- * Get value of 'idType' property
- */
- virtual std::string getIdType() const = 0;
-
- /**
- * Get value of 'id' property
- */
- virtual std::string getId() const = 0;
-};
-
-}
-}
-
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/parts/IConceptDescription.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/parts/IConceptDescription.h
deleted file mode 100644
index ff585ba..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/parts/IConceptDescription.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * IConceptDescription.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IConceptDescription_H_
-#define BASYX_METAMODEL_IConceptDescription_H_
-
-#include "BaSyx/submodel/api/qualifier/IHasDataSpecification.h"
-#include "BaSyx/submodel/api/qualifier/IIdentifiable.h"
-
-#include <string>
-#include <vector>
-
-namespace basyx {
-namespace submodel {
-
-class IConceptDescription :
- public virtual submodel::IHasDataSpecification,
- public virtual submodel::IIdentifiable
-{
-public:
- struct Path
- {
- static constexpr char ModelType[] = "ConceptDescription";
- static constexpr char IsCaseOf[] = "isCaseOf";
- };
-
-public:
- virtual ~IConceptDescription() = default;
-
- virtual basyx::specificCollection_t<submodel::IReference> getIsCaseOf() const = 0;
- virtual void setIsCaseOf(const basyx::specificCollection_t<submodel::IReference> & ref) = 0;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IAdministrativeInformation.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IAdministrativeInformation.h
deleted file mode 100644
index d1af173..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IAdministrativeInformation.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * IAdministrativeInformation.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IAdministrativeInformation_H_
-#define BASYX_METAMODEL_IAdministrativeInformation_H_
-
-
-#include <BaSyx/submodel/api/qualifier/IHasDataSpecification.h>
-
-#include <string>
-
-namespace basyx {
-namespace submodel {
-
-
-class IAdministrativeInformation :
- public virtual IHasDataSpecification
-{
-public:
-struct Path {
- static constexpr char AdministrationPath[] = "administrationPath";
- static constexpr char Version[] = "version";
- static constexpr char Revision[] = "revision";
-};
-public:
- virtual ~IAdministrativeInformation() = default;
-
- virtual std::string getVersion() const = 0;
- virtual std::string getRevision() const = 0;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IHasDataSpecification.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IHasDataSpecification.h
deleted file mode 100644
index e6288ae..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IHasDataSpecification.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * IHasDataSpecification.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IHasDataSpecification_H_
-#define BASYX_METAMODEL_IHasDataSpecification_H_
-
-
-#include <BaSyx/submodel/api/reference/IReference.h>
-#include <BaSyx/submodel/api/identifier/IIdentifier.h>
-#include <BaSyx/shared/types.h>
-
-namespace basyx {
-namespace submodel {
-
-class IHasDataSpecification
-{
-public:
- struct Path {
- static constexpr char HasDataSpecification[] = "hasDataSpecification";
- };
-public:
- virtual ~IHasDataSpecification() = default;
-
- virtual basyx::specificCollection_t<IReference> getDataSpecificationReferences() const = 0;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IHasKind.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IHasKind.h
deleted file mode 100644
index feb4d34..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IHasKind.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * IHasKind.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IHASKIND_H_
-#define BASYX_METAMODEL_IHASKIND_H_
-
-#include <string>
-
-#include <BaSyx/util/util.h>
-
-namespace basyx {
-namespace submodel {
-
-enum class Kind : char
-{
- NotSpecified = 0,
- Type = 1,
- Instance = 2,
-};
-
-class IHasKind
-{
-public:
- struct Path {
- static constexpr char Kind[] = "kind";
- };
-public:
- virtual ~IHasKind() = default;
-
- virtual Kind getHasKindReference() const = 0;
-};
-
-
-}
-}
-
-namespace util {
- const std::string & to_string(basyx::submodel::Kind kind);
-
- template<>
- basyx::submodel::Kind from_string<basyx::submodel::Kind>(const std::string & str);
-}
-
-#endif
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IHasSemantics.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IHasSemantics.h
deleted file mode 100644
index 714e8bd..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IHasSemantics.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * IHasSemantics.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IHasSemantics_H_
-#define BASYX_METAMODEL_IHasSemantics_H_
-
-#include <BaSyx/submodel/api/reference/IReference.h>
-
-
-#include <memory>
-
-
-namespace basyx {
-namespace submodel {
-
-class IHasSemantics
-{
-public:
- struct Path {
- static constexpr char SemanticId[] = "semanticId";
- };
-public:
- virtual ~IHasSemantics() = default;
-
- virtual std::shared_ptr<IReference> getSemanticId() const = 0;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IIdentifiable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IIdentifiable.h
deleted file mode 100644
index efb15a5..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IIdentifiable.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * IIdentifiable.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IIdentifiable_H_
-#define BASYX_METAMODEL_IIdentifiable_H_
-
-#include <BaSyx/submodel/api/identifier/IIdentifier.h>
-#include <BaSyx/submodel/api/qualifier/IAdministrativeInformation.h>
-#include <BaSyx/shared/types.h>
-
-#include <BaSyx/submodel/api/qualifier/IReferable.h>
-
-#include <string>
-#include <memory>
-
-namespace basyx {
-namespace submodel {
-
-class IIdentifiable
- : public virtual IReferable
-{
-public:
- struct Path
- {
- static constexpr char Administration[] = "administration";
- static constexpr char Identification[] = "identification";
- };
-public:
- virtual ~IIdentifiable() = default;
-
- virtual std::shared_ptr<IAdministrativeInformation> getAdministration() const = 0;
- virtual std::shared_ptr<IIdentifier> getIdentification() const = 0;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IReferable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IReferable.h
deleted file mode 100644
index 78c7863..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IReferable.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * IReferable.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IREFERABLE_H_
-#define BASYX_METAMODEL_IREFERABLE_H_
-
-#include <BaSyx/submodel/api/reference/IReference.h>
-#include <BaSyx/submodel/map/qualifier/Description.h>
-
-#include <string>
-#include <memory>
-
-namespace basyx {
-namespace submodel {
-
-class IReferable
-{
-public:
- struct Path {
- static constexpr char IdShort[] = "idShort";
- static constexpr char Category[] = "category";
- static constexpr char Description[] = "description";
- static constexpr char Parent[] = "parent";
- };
-public:
- virtual ~IReferable() = default;
-
- virtual std::string getIdShort() const = 0;
- virtual std::string getCategory() const = 0;
- virtual Description getDescription() const = 0;
- virtual std::shared_ptr<IReference> getParent() const = 0;
-};
-
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/qualifiable/IConstraint.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/qualifiable/IConstraint.h
deleted file mode 100644
index 0e10bef..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/qualifiable/IConstraint.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * IConstraint.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_ICONSTRAINT_H_
-#define BASYX_METAMODEL_ICONSTRAINT_H_
-
-
-namespace basyx {
-namespace submodel {
-
-class IConstraint
-{
-public:
- struct Path {
- static constexpr char ModelType[] = "Constraint";
- };
-public:
- virtual ~IConstraint() = default;
-};
-
-}
-}
-
-#endif
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/qualifiable/IFormula.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/qualifiable/IFormula.h
deleted file mode 100644
index e03723b..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/qualifiable/IFormula.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * IFormula.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IFormula_H_
-#define BASYX_METAMODEL_IFormula_H_
-
-#include <BaSyx/submodel/api/reference/IReference.h>
-#include <BaSyx/shared/types.h>
-#include <BaSyx/submodel/api/qualifier/qualifiable/IConstraint.h>
-
-#include <vector>
-
-
-namespace basyx {
-namespace submodel {
-
-class IFormula : public IConstraint
-{
-public:
- struct Path {
- static constexpr char Dependson[] = "dependsOn";
- static constexpr char Modeltype[] = "Formula";
- };
-
-public:
- virtual ~IFormula() = default;
-
- virtual basyx::specificCollection_t<IReference> getDependsOn() const = 0;
-};
-
-}
-}
-
-#endif
-
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/qualifiable/IQualifiable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/qualifiable/IQualifiable.h
deleted file mode 100644
index 5838630..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/qualifiable/IQualifiable.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * IQualifiable.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IQualifiable_H_
-#define BASYX_METAMODEL_IQualifiable_H_
-
-
-#include <BaSyx/submodel/api/qualifier/qualifiable/IConstraint.h>
-#include <BaSyx/shared/types.h>
-
-#include <vector>
-#include <memory>
-
-namespace basyx {
-namespace submodel {
-
-class IQualifiable
-{
-public:
- struct Path {
- static constexpr char Constraints[] = "constraints";
- };
-public:
- virtual ~IQualifiable() = default;
-
- virtual basyx::specificCollection_t<IConstraint> getQualifier() const = 0;
-};
-
-}
-}
-
-#endif
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/qualifiable/IQualifier.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/qualifiable/IQualifier.h
deleted file mode 100644
index 4c9201b..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/qualifiable/IQualifier.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * IQualifier.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IQualifier_H_
-#define BASYX_METAMODEL_IQualifier_H_
-
-#include <BaSyx/submodel/api/reference/IReference.h>
-#include <BaSyx/submodel/api/qualifier/IHasSemantics.h>
-#include <BaSyx/shared/types.h>
-#include <BaSyx/shared/object.h>
-#include <BaSyx/submodel/api/qualifier/qualifiable/IConstraint.h>
-
-#include <string>
-
-namespace basyx {
-namespace submodel {
-
-class IQualifier
- : public virtual IHasSemantics
- , public virtual IConstraint
-{
-public:
- struct Path {
- static constexpr char Qualifier[] = "qualifier";
- static constexpr char QualifierType[] = "qualifierType";
- static constexpr char QualifierValue[] = "qualifierValue";
- static constexpr char QualifierValueID[] = "qualifierValueId";
- static constexpr char Modeltype[] = "Qualifier";
- };
-
-public:
- virtual ~IQualifier() = default;
-
- virtual std::string getQualifierType() const = 0;
- virtual basyx::object getQualifierValue() const = 0;
- virtual std::shared_ptr<IReference> getQualifierValueId() const = 0;
-};
-
-}
-}
-
-#endif
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/reference/IKey.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/reference/IKey.h
deleted file mode 100644
index 348a6d8..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/reference/IKey.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * IKey.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IKey_H_
-#define BASYX_METAMODEL_IKey_H_
-
-
-#include <string>
-
-namespace basyx {
-namespace submodel {
-
-class IKey
-{
-public:
- struct Path
- {
- static constexpr char Type[] = "type";
- static constexpr char Local[] = "local";
- static constexpr char Value[] = "value";
- static constexpr char IdType[] = "idType";
- };
-public:
- virtual ~IKey() = 0;
-
- virtual std::string getType() const = 0;
- virtual bool isLocal() const = 0;
- virtual std::string getValue() const = 0;
- virtual std::string getidType() const = 0;
-};
-
-inline IKey::~IKey() = default;
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/reference/IReference.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/reference/IReference.h
deleted file mode 100644
index 85b4894..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/reference/IReference.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * IReference.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IReference_H_
-#define BASYX_METAMODEL_IReference_H_
-
-
-#include <BaSyx/submodel/api/reference/IKey.h>
-#include <BaSyx/shared/types.h>
-
-namespace basyx {
-namespace submodel {
-
-class IReference
-{
-public:
- struct Path {
- static constexpr char DataSpecifications[] = "dataSpecificationReferences";
- static constexpr char Parents[] = "parentReferences";
- static constexpr char SemanticIds[] = "semanticIdReferences";
- static constexpr char Qualifiers[] = "qualifierReferences";
- static constexpr char ReferencePath[] = "semanticIdentifier";
- static constexpr char Key[] = "keys";
- };
-public:
- virtual ~IReference() = default;
-
- virtual const basyx::specificCollection_t<IKey> getKeys() const = 0;
- virtual void setKeys(const basyx::specificCollection_t<IKey> & keys) = 0;
-};
-
-}
-}
-
-#endif
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/IDataElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/IDataElement.h
deleted file mode 100644
index ddc5142..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/IDataElement.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * IDataElement.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IDATAELEMENT_H_
-#define BASYX_METAMODEL_IDATAELEMENT_H_
-
-
-#include <BaSyx/submodel/api/submodelelement/ISubmodelElement.h>
-
-namespace basyx {
-namespace submodel {
-
-class IDataElement : public virtual ISubmodelElement
-{
-public:
- virtual ~IDataElement() = 0;
-};
-
-inline IDataElement::~IDataElement() = default;
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/IReferenceElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/IReferenceElement.h
deleted file mode 100644
index 6b36eca..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/IReferenceElement.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * IReferenceElement.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IREFERENCEELEMENT_H_
-#define BASYX_METAMODEL_IREFERENCEELEMENT_H_
-
-#include <BaSyx/submodel/api/reference/IReference.h>
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-
-namespace basyx {
-namespace submodel {
-
-class IReferenceElement
-{
-public:
- struct Path
- {
- static constexpr char Modeltype[] = "ReferenceElement";
- };
-
-public:
- virtual ~IReferenceElement() = default;
-
- virtual std::shared_ptr<IReference> getValue() const = 0;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/IRelationshipElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/IRelationshipElement.h
deleted file mode 100644
index d647aa0..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/IRelationshipElement.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * IRelationshipElement.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IRelationshipElement_H_
-#define BASYX_METAMODEL_IRelationshipElement_H_
-
-#include <BaSyx/submodel/api/reference/IReference.h>
-
-namespace basyx {
-namespace submodel {
-
-
-class IRelationshipElement
-{
-public:
- struct Path
- {
- static constexpr char First[] = "first";
- static constexpr char Second[] = "second";
- static constexpr char ModelType[] = "RelationshipElement";
- };
-public:
- virtual ~IRelationshipElement() = default;
-
- virtual void setFirst(const IReference & first) = 0;
- virtual std::shared_ptr<IReference> getFirst() const = 0;
-
- virtual void setSecond(const IReference & second) = 0;
- virtual std::shared_ptr<IReference> getSecond() const = 0;
-};
-
-}
-}
-
-#endif
-
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/ISubmodelElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/ISubmodelElement.h
deleted file mode 100644
index 0176a1b..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/ISubmodelElement.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * ISubmodelElement.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_ISUBMODELELEMENT_H_
-#define BASYX_METAMODEL_ISUBMODELELEMENT_H_
-
-
-#include <BaSyx/submodel/api/IElement.h>
-#include <BaSyx/submodel/api/qualifier/IHasDataSpecification.h>
-#include <BaSyx/submodel/api/qualifier/IReferable.h>
-#include <BaSyx/submodel/api/qualifier/qualifiable/IQualifiable.h>
-#include <BaSyx/submodel/api/qualifier/IHasSemantics.h>
-#include <BaSyx/submodel/api/qualifier/IHasKind.h>
-
-namespace basyx {
-namespace submodel {
-
-class ISubmodelElement :
-// public virtual IElement,
- public virtual IHasDataSpecification,
- public virtual IReferable,
- public virtual IQualifiable,
- public virtual IHasSemantics,
- public virtual IHasKind
-{
-public:
- struct Path {
- static constexpr char ModelType[] = "SubmodelElement";
- };
-public:
- virtual ~ISubmodelElement() = default;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/ISubmodelElementCollection.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/ISubmodelElementCollection.h
deleted file mode 100644
index c344679..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/ISubmodelElementCollection.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * ISubmodelElementCollection.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_ISubmodelElementCollection_H_
-#define BASYX_METAMODEL_ISubmodelElementCollection_H_
-
-
-#include <BaSyx/submodel/api/submodelelement/ISubmodelElement.h>
-#include <BaSyx/shared/types.h>
-
-namespace basyx {
-namespace submodel {
-
-
-class ISubmodelElementCollection
-{
-public:
- struct Path
- {
- static constexpr long serialVersionUID = 1L;
- static constexpr char Ordered[] = "ordered";
- static constexpr char AllowDuplicates[] = "allowDuplicates";
- static constexpr char ModelType[] = "SubmodelElementCollection";
- };
-public:
- virtual ~ISubmodelElementCollection() = default;
-
- // virtual void setValue(const basyx::specificCollection_t<ISubmodelElement> & value) = 0;
- virtual basyx::specificCollection_t<ISubmodelElement> getValue() const = 0;
-
- //virtual void setOrdered(const bool & value) = 0;
- virtual bool isOrdered() const = 0;
-
- //virtual void setAllowDuplicates(const bool & value) = 0;
- virtual bool isAllowDuplicates() const = 0;
-
- //virtual void setElements(const basyx::specificMap_t<ISubmodelElement> & value) = 0;
- virtual basyx::specificMap_t<ISubmodelElement> getElements() const = 0;
-};
-
-}
-}
-
-#endif
-
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/entity/IEntity.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/entity/IEntity.h
deleted file mode 100644
index 7362a8a..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/entity/IEntity.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * IDataElement.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IENTITY_H_
-#define BASYX_METAMODEL_IENTITY_H_
-
-#include <BaSyx/submodel/api/submodelelement/ISubmodelElement.h>
-#include <BaSyx/submodel/api/reference/IReference.h>
-
-#include <BaSyx/shared/enums.h>
-
-namespace basyx {
-namespace submodel {
-
-class IEntity : public virtual ISubmodelElement
-{
-public:
- struct Path {
- static constexpr char EntityType[] = "entityType";
- };
-public:
- virtual ~IEntity() = 0;
-
- virtual basyx::specificCollection_t<ISubmodelElement> getStatements() = 0;
-
- virtual EntityType getEntityType() const = 0;
-
- virtual std::shared_ptr<IReference> getAsset() const = 0;
-};
-
-inline IEntity::~IEntity() = default;
-
-}
-}
-
-#endif
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/langstring/ILangStringSet.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/langstring/ILangStringSet.h
deleted file mode 100644
index df8867b..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/langstring/ILangStringSet.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef _ILANGSTRINGSET_H
-#define _ILANGSTRINGSET_H
-
-#include <string>
-
-namespace basyx {
-namespace submodel {
-
-class ILangStringSet
-{
-public:
- struct Path {
- static constexpr char Language[] = "language";
- static constexpr char Text[] = "text";
- };
-public: // Constructors / dtor
- ILangStringSet() = default;
-
-
- virtual ~ILangStringSet() = 0;
-public:
-
- virtual const std::string & getLangString(const std::string & languageCode) const = 0;
- virtual void addLangString(const std::string & languageCode, const std::string & langString) = 0 ;
-};
-
-inline ILangStringSet::~ILangStringSet() = default;
-
-}
-}
-
-#endif /* _ILANGSTRINGSET_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/operation/IOperation.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/operation/IOperation.h
deleted file mode 100644
index ac3a267..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/operation/IOperation.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * IOperation.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_SUBMODELELEMENT_OPERATION_IOPERATION_
-#define AAS_SUBMODELELEMENT_OPERATION_IOPERATION_
-
-#include <BaSyx/submodel/api/IElement.h>
-#include <BaSyx/submodel/api/submodelelement/operation/IOperationVariable.h>
-
-#include <BaSyx/shared/object.h>
-#include <BaSyx/shared/types.h>
-
-#include <vector>
-
-namespace basyx {
-namespace submodel {
-
-class IOperation : public virtual ISubmodelElement
-{
-public:
- struct Path {
- static constexpr char Input[] = "in";
- static constexpr char Output[] = "out";
- static constexpr char Invokable[] = "invokable";
- static constexpr char ModelType[] = "operation";
- };
-public:
- virtual basyx::specificCollection_t<IOperationVariable> getParameterTypes() const = 0;
- virtual std::shared_ptr<IOperationVariable> getReturnType() const = 0;
- virtual basyx::object getInvocable() const = 0;
- virtual basyx::object invoke(basyx::object & parameters) const = 0;
-};
-
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/operation/IOperationVariable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/operation/IOperationVariable.h
deleted file mode 100644
index e54d540..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/operation/IOperationVariable.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * IOperationVariable.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IOperationVariable_H_
-#define BASYX_METAMODEL_IOperationVariable_H_
-
-
-#include <BaSyx/submodel/api/submodelelement/ISubmodelElement.h>
-
-#include <memory>
-
-namespace basyx {
-namespace submodel {
-
-class IOperationVariable : public virtual ISubmodelElement
-{
-public:
- struct Path {
- static constexpr char Type[] = "type";
- static constexpr char ModelType[] = "OperationVariable";
- static constexpr char Value[] = "value";
- };
-public:
- virtual ~IOperationVariable() = default;
- virtual std::shared_ptr<ISubmodelElement> getValue() const = 0;
- virtual std::string getType() const = 0;
-};
-
-}
-}
-
-#endif
-
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/ICollectionProperty.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/ICollectionProperty.h
deleted file mode 100644
index 56f2e5d..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/ICollectionProperty.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * ICollectionProperty.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_SUBMODELELEMENT_PROPERTY_ICOLLECTIONPROPERTY_
-#define AAS_SUBMODELELEMENT_PROPERTY_ICOLLECTIONPROPERTY_
-
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-#include <BaSyx/shared/types.h>
-
-
-namespace basyx {
-namespace submodel {
-namespace submodelelement {
-namespace property {
-
-class ICollectionProperty
-{
-
-public:
- virtual ~ICollectionProperty() = default;
-
- virtual void set(const basyx::object::object_list_t & collection) const = 0;
- virtual void add(const basyx::object & newValue) = 0;
- virtual void remove(basyx::object & objectRef) = 0;
- virtual basyx::object::object_list_t getElements() const = 0;
- virtual int getElementCount() const = 0;
-};
-
-}
-}
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/IContainerProperty.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/IContainerProperty.h
deleted file mode 100644
index 10f9ff2..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/IContainerProperty.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * IContainernProperty.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_SUBMODELELEMENT_PROPERTY_ICONTAINERPROPERTY_
-#define AAS_SUBMODELELEMENT_PROPERTY_ICONTAINERPROPERTY_
-
-
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-#include <BaSyx/shared/types.h>
-#include <BaSyx/aas/backend/vab/IVABElementContainer.h>
-
-
-namespace basyx {
-namespace submodel {
-namespace submodelelement {
-namespace property {
-
-class IContainerProperty : public IProperty, vab::IVABElementContainer
-{
-
-public:
- virtual ~IContainerProperty() = default;
-
-};
-
-}
-}
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/IMapProperty.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/IMapProperty.h
deleted file mode 100644
index 22b6b87..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/IMapProperty.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * IMapProperty.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_SUBMODELELEMENT_PROPERTY_IMAPPROPERTY_
-#define AAS_SUBMODELELEMENT_PROPERTY_IMAPPROPERTY_
-
-
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-#include <BaSyx/shared/types.h>
-
-
-namespace basyx {
-namespace submodel {
-namespace submodelelement {
-namespace property {
-
-class IMapProperty
-{
-
-public:
- virtual ~IMapProperty() = default;
-
- virtual basyx::object getValue(const std::string & key) const = 0;
- virtual void put(const std::string & key, const basyx::object & value) const = 0;
- virtual void set(const basyx::object::object_map_t & map) const = 0;
- virtual basyx::object::object_list_t getKeys() const = 0;
- virtual int getEntryCount() const = 0;
- virtual void remove(const std::string & key) const = 0;
-
-};
-
-}
-}
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/IProperty.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/IProperty.h
deleted file mode 100644
index 994b601..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/IProperty.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * IProperty.h
- *
- * Created on: 29.04.2018
- * Author: kuhn, wendel
- */
-#ifndef API_IPROPERTY_H_
-#define API_IPROPERTY_H_
-
-#include <BaSyx/submodel/api/submodelelement/IDataElement.h>
-
-#include <BaSyx/shared/types.h>
-
-namespace basyx {
-namespace submodel {
-
-
-/* *********************************************************************************
- * Property interface
- * *********************************************************************************/
-class IProperty : public virtual IDataElement
-{
-public:
- enum class PropertyType
- {
- Single, Collection, Map, Container
- };
-public:
- struct Path {
- static constexpr char Value[] = "value";
- static constexpr char ValueId[] = "valueId";
- static constexpr char ValueType[] = "valueType";
- static constexpr char ModelType[] = "Property";
- };
-public:
- virtual PropertyType getPropertyType() const = 0;
-
- virtual void setValueId(const std::string & valueId) = 0;
- virtual std::string getValueId() const = 0;
-};
-
-}
-}
-
-#endif /* API_IPROPERTY_H_ */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/ISingleProperty.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/ISingleProperty.h
deleted file mode 100644
index 885e9a3..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/ISingleProperty.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * ISingleProperty.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_SUBMODELELEMENT_PROPERTY_ISINGLEPROPERTY_
-#define AAS_SUBMODELELEMENT_PROPERTY_ISINGLEPROPERTY_
-
-
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-#include <BaSyx/shared/types.h>
-
-
-namespace basyx {
-namespace submodel {
-
-class ISingleProperty : public virtual IProperty
-{
-public:
- virtual ~ISingleProperty() = default;
-
- virtual basyx::object get() const = 0;
- virtual void set(const basyx::object & newValue) = 0;
- virtual std::string getValueType() const = 0;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/blob/IBlob.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/blob/IBlob.h
deleted file mode 100644
index 3fe95de..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/blob/IBlob.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * IBlob.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IBlob_H_
-#define BASYX_METAMODEL_IBlob_H_
-
-#include <BaSyx/shared/types.h>
-
-#include <BaSyx/submodel/api/submodelelement/IDataElement.h>
-
-namespace basyx {
-namespace submodel {
-
-
-class IBlob
- : public IDataElement
-{
-public:
- struct Path
- {
- static constexpr char MIMEType[] = "mimeType";
- static constexpr char Value[] = "value";
- static constexpr char ModelType[] = "blob";
- };
-public:
- virtual ~IBlob() = default;
-
- virtual const std::string & getValue() const = 0;
- virtual const std::string & getMimeType() const = 0;
-};
-
-}
-}
-
-#endif
-
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/file/IFile.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/file/IFile.h
deleted file mode 100644
index b9a046c..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/file/IFile.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * IFile.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IFile_H_
-#define BASYX_METAMODEL_IFile_H_
-
-#include <string>
-
-namespace basyx {
-namespace submodel {
-
-class IFile
-{
-public:
- struct Path
- {
- static constexpr char MIMEType[] = "mimeType";
- static constexpr char Value[] = "value";
- static constexpr char ModelType[] = "file";
- };
-public:
- virtual ~IFile() = default;
-
- virtual const std::string & getValue() const = 0;
- virtual const std::string & getMimeType() const = 0;
-};
-
-}
-}
-
-#endif
-
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/aas/IAssetAdministrationShell.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/aas/IAssetAdministrationShell.h
index 3e6df30..564fad2 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/aas/IAssetAdministrationShell.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/aas/IAssetAdministrationShell.h
@@ -38,5 +38,4 @@
}
}
-
#endif /* BASYX_SUBMODEL_API_V2_AAS_IASSETADMINISTRATIONSHELL_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/common/IElementContainer.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/common/IElementContainer.h
index 945a030..0bcc6b2 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/common/IElementContainer.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/common/IElementContainer.h
@@ -2,6 +2,7 @@
#define BASYX_SUBMODEL_API_V2_COMMON_IELEMENTCONTAINER_H
#include <BaSyx/submodel/api_v2/submodelelement/ISubmodelElement.h>
+#include <BaSyx/submodel/api_v2/qualifier/IReferable.h>
#include <BaSyx/util/util.h>
@@ -23,6 +24,7 @@
virtual IElementType * const getElement(const std::string & idShort) const = 0;
virtual IElementType * const getElement(std::size_t n) const = 0;
+ virtual IReferable * getParent() const = 0;
virtual void addElement(elementPtr_t element) = 0;
virtual std::size_t size() const = 0;
@@ -32,6 +34,7 @@
{
auto ptr = util::make_unique<SubElement_t>(std::forward<Args>(args)...);
auto ret = ptr.get();
+ ptr->setParent(this->getParent());
this->addElement(std::move(ptr));
return ret;
};
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/common/IModelType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/common/IModelType.h
index 2e36d68..4d715c4 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/common/IModelType.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/common/IModelType.h
@@ -20,4 +20,4 @@
}
}
-#endif /* BASYX_SUBMODEL_API_V2_COMMON_IELEMENTCONTAINER_H */
+#endif /* BASYX_SUBMODEL_API_V2_COMMON_IMODELTYPE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/constraint/IConstraint.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/constraint/IConstraint.h
index 9c84c09..269f461 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/constraint/IConstraint.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/constraint/IConstraint.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_API_V2_QUALIFIER_ICONSTRAINT_H
-#define BASYX_SUBMODEL_API_V2_QUALIFIER_ICONSTRAINT_H
+#ifndef BASYX_SUBMODEL_API_V2_CONSTRAINT_ICONSTRAINT_H
+#define BASYX_SUBMODEL_API_V2_CONSTRAINT_ICONSTRAINT_H
#include <BaSyx/submodel/api_v2/common/IModelType.h>
@@ -20,4 +20,4 @@
}
}
-#endif /* BASYX_SUBMODEL_API_V2_QUALIFIER_ICONSTRAINT_H */
\ No newline at end of file
+#endif /* BASYX_SUBMODEL_API_V2_CONSTRAINT_ICONSTRAINT_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/constraint/IFormula.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/constraint/IFormula.h
index 4b15bf7..5d1bf67 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/constraint/IFormula.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/constraint/IFormula.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_API_V2_QUALIFIER_IFORMULA_H
-#define BASYX_SUBMODEL_API_V2_QUALIFIER_IFORMULA_H
+#ifndef BASYX_SUBMODEL_API_V2_CONSTRAINT_IFORMULA_H
+#define BASYX_SUBMODEL_API_V2_CONSTRAINT_IFORMULA_H
#include <BaSyx/submodel/api_v2/constraint/IConstraint.h>
#include <BaSyx/submodel/simple/reference/Reference.h>
@@ -26,4 +26,4 @@
}
}
-#endif /* BASYX_SUBMODEL_API_V2_QUALIFIER_IFORMULA_H */
\ No newline at end of file
+#endif /* BASYX_SUBMODEL_API_V2_CONSTRAINT_IFORMULA_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/constraint/IQualifier.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/constraint/IQualifier.h
index 6b08881..36da62a 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/constraint/IQualifier.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/constraint/IQualifier.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_API_V2_QUALIFIER_IQUALIFIER_H
-#define BASYX_SUBMODEL_API_V2_QUALIFIER_IQUALIFIER_H
+#ifndef BASYX_SUBMODEL_API_V2_CONSTRAINT_IQUALIFIER_H
+#define BASYX_SUBMODEL_API_V2_CONSTRAINT_IQUALIFIER_H
#include <BaSyx/submodel/api_v2/constraint/IConstraint.h>
#include <BaSyx/submodel/api_v2/qualifier/IHasSemantics.h>
@@ -36,4 +36,4 @@
}
}
-#endif /* BASYX_SUBMODEL_API_V2_QUALIFIER_IQUALIFIER_H */
\ No newline at end of file
+#endif /* BASYX_SUBMODEL_API_V2_CONSTRAINT_IQUALIFIER_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IDataSpecification.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IDataSpecification.h
index c84c7c3..1864f28 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IDataSpecification.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IDataSpecification.h
@@ -21,8 +21,12 @@
virtual ~IDataSpecification() = 0;
virtual IDataSpecificationContent & getContent() = 0;
+
+ virtual KeyElements getKeyElementType() const override;
};
+inline KeyElements IDataSpecification::getKeyElementType() const { return KeyElements::DataElement; };
+
inline IDataSpecification::~IDataSpecification() = default;
}
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IDataSpecificationIEC61360.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IDataSpecificationIEC61360.h
index f53fa55..8b5cb60 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IDataSpecificationIEC61360.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IDataSpecificationIEC61360.h
@@ -50,4 +50,4 @@
}
}
-#endif /* BASYX_SUBMODEL_API_V2_DATASPECIFICATION_IDATASPECIFICATIONIEC61360_H */
\ No newline at end of file
+#endif /* BASYX_SUBMODEL_API_V2_DATASPECIFICATION_IDATASPECIFICATIONIEC61360_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IDataSpecificationPhysicalUnit.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IDataSpecificationPhysicalUnit.h
index 19b29f1..bac90b3 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IDataSpecificationPhysicalUnit.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IDataSpecificationPhysicalUnit.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_API_V2_SDK_IDATASPECIFICATIONPHYSICALUNIT_H
-#define BASYX_API_V2_SDK_IDATASPECIFICATIONPHYSICALUNIT_H
+#ifndef BASYX_SUBMODEL_API_V2_DATASPECIFICATION_IDATASPECIFICATIONPHYSICALUNIT_H
+#define BASYX_SUBMODEL_API_V2_DATASPECIFICATION_IDATASPECIFICATIONPHYSICALUNIT_H
#include <string>
@@ -64,4 +64,4 @@
}
}
}
-#endif //BASYX_API_V2_SDK_IDATASPECIFICATIONPHYSICALUNIT_H
+#endif /* BASYX_SUBMODEL_API_V2_DATASPECIFICATION_IDATASPECIFICATIONPHYSICALUNIT_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IEmbeddedDataSpecification.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IEmbeddedDataSpecification.h
index 1f5b8b7..cdf0927 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IEmbeddedDataSpecification.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IEmbeddedDataSpecification.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_API_V2_SDK_IEMBEDDEDDATASPECIFICATION_H
-#define BASYX_API_V2_SDK_IEMBEDDEDDATASPECIFICATION_H
+#ifndef BASYX_SUBMODEL_API_V2_DATASPECIFICATION_IEMBEDDEDDATASPECIFICATION_H
+#define BASYX_SUBMODEL_API_V2_DATASPECIFICATION_IEMBEDDEDDATASPECIFICATION_H
#include <BaSyx/submodel/api_v2/reference/IReference.h>
@@ -20,4 +20,4 @@
}
}
}
-#endif //BASYX_API_V2_SDK_IEMBEDDEDDATASPECIFICATION_H
+#endif /* BASYX_SUBMODEL_API_V2_DATASPECIFICATION_IEMBEDDEDDATASPECIFICATION_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IValueList.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IValueList.h
index 884f9ed..ee79691 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IValueList.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IValueList.h
@@ -22,4 +22,4 @@
}
}
-#endif
\ No newline at end of file
+#endif /* BASYX_SUBMODEL_API_V2_DATASPECIFICATION_IVALUELIST_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/parts/IConceptDictionary.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/parts/IConceptDictionary.h
index e09715e..b9a0208 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/parts/IConceptDictionary.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/parts/IConceptDictionary.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_API_V2_SDK_ICONCEPTDICTIONARY_H
-#define BASYX_API_V2_SDK_ICONCEPTDICTIONARY_H
+#ifndef BASYX_SUBMODEL_API_V2_PARTS_ICONCEPTDICTIONARY_H
+#define BASYX_SUBMODEL_API_V2_PARTS_ICONCEPTDICTIONARY_H
#include <BaSyx/submodel/api_v2/parts/IConceptDescription.h>
@@ -21,4 +21,4 @@
}
}
}
-#endif //BASYX_API_V2_SDK_ICONCEPTDICTIONARY_H
+#endif /* BASYX_SUBMODEL_API_V2_PARTS_ICONCEPTDICTIONARY_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/parts/IView.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/parts/IView.h
index bedbb41..88e3d51 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/parts/IView.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/parts/IView.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_API_V2_SDK_IVIEW_H
-#define BASYX_API_V2_SDK_IVIEW_H
+#ifndef BASYX_SUBMODEL_API_V2_PARTS_IVIEW_H
+#define BASYX_SUBMODEL_API_V2_PARTS_IVIEW_H
#include <BaSyx/submodel/api_v2/qualifier/IReferable.h>
#include <BaSyx/submodel/api_v2/qualifier/IHasDataSpecification.h>
@@ -26,4 +26,4 @@
}
}
}
-#endif //BASYX_API_V2_SDK_IVIEW_H
+#endif /* BASYX_SUBMODEL_API_V2_PARTS_IVIEW_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IAdministrativeInformation.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IAdministrativeInformation.h
new file mode 100644
index 0000000..c659d45
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IAdministrativeInformation.h
@@ -0,0 +1,33 @@
+#ifndef BASYX_SUBMODEL_API_V2_QUALIFIER_IADMINISTRATIVEINFORMATION_H
+#define BASYX_SUBMODEL_API_V2_QUALIFIER_IADMINISTRATIVEINFORMATION_H
+
+#include <BaSyx/submodel/api_v2/qualifier/IHasDataSpecification.h>
+
+#include <string>
+
+namespace basyx {
+namespace submodel {
+namespace api {
+
+class IAdministrativeInformation
+ : public virtual IHasDataSpecification
+{
+public:
+ virtual ~IAdministrativeInformation() = 0;
+
+ virtual void setVersion(const std::string & version) = 0;
+ virtual void setRevision(const std::string & revision) = 0;
+
+ virtual bool hasVersion() const = 0;
+ virtual bool hasRevision() const = 0;
+
+ virtual const std::string * const getVersion() const = 0;
+ virtual const std::string * const getRevision() const = 0;
+};
+
+inline IAdministrativeInformation::~IAdministrativeInformation() = default;
+
+}
+}
+}
+#endif /* BASYX_SUBMODEL_API_V2_QUALIFIER_IADMINISTRATIVEINFORMATION_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IHasDataSpecification.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IHasDataSpecification.h
index 9b8af08..c826aa6 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IHasDataSpecification.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IHasDataSpecification.h
@@ -1,12 +1,13 @@
#ifndef BASYX_SUBMODEL_API_V2_QUALIFIER_IHASDATASPECIFICATION_H
#define BASYX_SUBMODEL_API_V2_QUALIFIER_IHASDATASPECIFICATION_H
-#include <BaSyx/submodel/simple/reference/Reference.h>
-
#include <vector>
namespace basyx {
namespace submodel {
+
+namespace simple { class Reference; }
+
namespace api {
class IHasDataSpecification
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IIdentifiable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IIdentifiable.h
index 361d494..9eaebfe 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IIdentifiable.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IIdentifiable.h
@@ -1,19 +1,16 @@
#ifndef BASYX_SUBMODEL_API_V2_QUALIFIER_IIDENTIFIABLE_H
#define BASYX_SUBMODEL_API_V2_QUALIFIER_IIDENTIFIABLE_H
-#include <BaSyx/submodel/simple/identifier/Identifier.h>
-//#include <BaSyx/submodel/api_v2/qualifier/IAdministrativeInformation.h>
-
#include <BaSyx/submodel/api_v2/qualifier/IReferable.h>
+#include <BaSyx/submodel/api_v2/qualifier/IAdministrativeInformation.h>
+#include <BaSyx/submodel/simple/identifier/Identifier.h>
+
#include <string>
#include <memory>
namespace basyx {
namespace submodel {
-
-namespace simple { class AdministrativeInformation; }
-
namespace api {
class IIdentifiable : public virtual IReferable
@@ -21,12 +18,16 @@
public:
virtual ~IIdentifiable() = 0;
- virtual const simple::AdministrativeInformation & getAdministrativeInformation() const = 0;
- virtual simple::AdministrativeInformation & getAdministrativeInformation() = 0;
+ virtual const IAdministrativeInformation & getAdministrativeInformation() const = 0;
+ virtual IAdministrativeInformation & getAdministrativeInformation() = 0;
virtual simple::Identifier getIdentification() const = 0;
virtual bool hasAdministrativeInformation() const = 0;
+
+ virtual KeyType getKeyType() const {
+ return this->getIdentification().getIdType();
+ };
};
inline IIdentifiable::~IIdentifiable() = default;
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IQualifiable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IQualifiable.h
index 45ea82c..2687fe1 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IQualifiable.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IQualifiable.h
@@ -2,17 +2,20 @@
#define BASYX_SUBMODEL_API_V2_QUALIFIER_IQUALIFIABLE_H
#include <BaSyx/submodel/api_v2/constraint/IFormula.h>
-#include <BaSyx/submodel/api_v2/constraint/IQualifier.h>
#include <BaSyx/submodel/simple/constraint/Formula.h>
-#include <BaSyx/submodel/simple/constraint/Qualifier.h>
#include <vector>
namespace basyx {
namespace submodel {
+
+namespace simple { class Qualifier; }
+
namespace api {
+class IQualifier;
+
class IQualifiable
{
public:
@@ -31,4 +34,4 @@
}
}
-#endif /* BASYX_SUBMODEL_API_V2_QUALIFIER_IQUALIFIABLE_H */
\ No newline at end of file
+#endif /* BASYX_SUBMODEL_API_V2_QUALIFIER_IQUALIFIABLE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IReferable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IReferable.h
index 41b9f3b..7be8daf 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IReferable.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IReferable.h
@@ -3,6 +3,7 @@
#include <BaSyx/submodel/api_v2/reference/IReference.h>
#include <BaSyx/submodel/api_v2/common/ILangStringSet.h>
+#include <BaSyx/submodel/simple/reference/Reference.h>
#include <string>
#include <memory>
@@ -14,7 +15,7 @@
/**
* Mandatory members:
* idShort
- *
+ *
*/
class IReferable
{
@@ -26,7 +27,16 @@
virtual void setCategory(const std::string & category) = 0;
virtual ILangStringSet & getDescription() = 0;
virtual const ILangStringSet & getDescription() const = 0;
- virtual const IReferable * const getParent() const = 0;
+ virtual IReferable * getParent() const = 0;
+ virtual void setParent(IReferable * parent) = 0;
+ virtual simple::Reference getReference() const = 0;
+ virtual simple::Key getKey(bool local = true) const = 0;
+
+ virtual KeyElements getKeyElementType() const = 0;
+
+ virtual KeyType getKeyType() const {
+ return KeyType::IdShort;
+ };
};
inline IReferable::~IReferable() = default;
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IAnnotatedRelationshipElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IAnnotatedRelationshipElement.h
index da9a4a7..578175e 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IAnnotatedRelationshipElement.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IAnnotatedRelationshipElement.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_API_V2_SDK_IANNOTATEDRELATIONSHIPELEMENT_H
-#define BASYX_API_V2_SDK_IANNOTATEDRELATIONSHIPELEMENT_H
+#ifndef BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IANNOTATEDRELATIONSHIPELEMENT_H
+#define BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IANNOTATEDRELATIONSHIPELEMENT_H
#include <BaSyx/submodel/api_v2/submodelelement/IDataElement.h>
#include <BaSyx/submodel/api_v2/common/IElementContainer.h>
@@ -8,12 +8,14 @@
namespace submodel {
namespace api {
-class IAnnotatedRelationshipElement
+class IAnnotatedRelationshipElement : public IDataElement
{
public:
virtual ~IAnnotatedRelationshipElement() = 0;
virtual IElementContainer<IDataElement> & getAnnotation() const = 0;
+
+ virtual KeyElements getKeyElementType() const override { return KeyElements::AnnotatedRelationshipElement; };
};
inline IAnnotatedRelationshipElement::~IAnnotatedRelationshipElement() = default;
@@ -21,4 +23,4 @@
}
}
}
-#endif //BASYX_API_V2_SDK_IANNOTATEDRELATIONSHIPELEMENT_H
+#endif /* BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IANNOTATEDRELATIONSHIPELEMENT_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IBasicEvent.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IBasicEvent.h
index ffbc11a..fe9f5c4 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IBasicEvent.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IBasicEvent.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_API_V2_SDK_IBASICEVENT_H
-#define BASYX_API_V2_SDK_IBASICEVENT_H
+#ifndef BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IBASICEVENT_H
+#define BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IBASICEVENT_H
#include <BaSyx/submodel/api_v2/submodelelement/IBasicEvent.h>
@@ -21,4 +21,4 @@
}
}
}
-#endif //BASYX_API_V2_SDK_IBASICEVENT_H
+#endif /* BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IBASICEVENT_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/ICapability.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/ICapability.h
index 157f4e0..7653ef2 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/ICapability.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/ICapability.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_API_V2_SDK_ICAPABILITY_H
-#define BASYX_API_V2_SDK_ICAPABILITY_H
+#ifndef BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_ICAPABILITY_H
+#define BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_ICAPABILITY_H
#include <BaSyx/submodel/api_v2/submodelelement/ISubmodelElement.h>
@@ -12,6 +12,8 @@
{
public:
~ICapability() = 0;
+
+ virtual KeyElements getKeyElementType() const override { return KeyElements::Capability; };
};
inline ICapability::~ICapability() = default;
@@ -19,4 +21,4 @@
}
}
}
-#endif //BASYX_API_V2_SDK_ICAPABILITY_H
+#endif /* BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_ICAPABILITY_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IDataElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IDataElement.h
index 0ff489c..9a1cce5 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IDataElement.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IDataElement.h
@@ -12,6 +12,8 @@
{
public:
virtual ~IDataElement() = 0;
+
+ virtual KeyElements getKeyElementType() const override { return KeyElements::DataElement; };
};
inline IDataElement::~IDataElement() = default;
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IEntity.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IEntity.h
index 905e1f4..cd262ec 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IEntity.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IEntity.h
@@ -22,6 +22,8 @@
virtual const IReference * const getAssetRef() const = 0;
virtual void setAssetRef(const IReference & assetRef) = 0;
+
+ virtual KeyElements getKeyElementType() const override { return KeyElements::Entity; };
};
inline IEntity::~IEntity() = default;
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IEvent.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IEvent.h
index 762f1f3..6a0836d 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IEvent.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IEvent.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_API_V2_SDK_IEVENT_H
-#define BASYX_API_V2_SDK_IEVENT_H
+#ifndef BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IEVENT_H
+#define BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IEVENT_H
#include <BaSyx/submodel/api_v2/submodelelement/ISubmodelElement.h>
@@ -12,6 +12,8 @@
{
public:
~IEvent() = 0;
+
+ virtual KeyElements getKeyElementType() const override { return KeyElements::Event; };
};
inline IEvent::~IEvent() = default;
@@ -19,4 +21,4 @@
}
}
}
-#endif //BASYX_API_V2_SDK_IEVENT_H
+#endif /* BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IEVENT_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IRange.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IRange.h
index b452584..b5b9fb9 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IRange.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IRange.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_API_V2_SDK_IRANGE_H
-#define BASYX_API_V2_SDK_IRANGE_H
+#ifndef BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IRANGE_H
+#define BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IRANGE_H
#include <string>
@@ -28,6 +28,8 @@
virtual ValueDataType getMin() = 0;
virtual ValueDataType getMax() = 0;
+
+ virtual KeyElements getKeyElementType() const override { return KeyElements::Range; };
};
inline IRange::~IRange() = default;
@@ -35,4 +37,4 @@
}
}
}
-#endif //BASYX_API_V2_SDK_IRANGE_H
+#endif /* BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IRANGE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IRelationshipElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IRelationshipElement.h
index 39b7774..4c21018 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IRelationshipElement.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IRelationshipElement.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_API_V2_SDK_IRELATIONSHIPELEMENT_H
-#define BASYX_API_V2_SDK_IRELATIONSHIPELEMENT_H
+#ifndef BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IRELATIONSHIPELEMENT_H
+#define BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IRELATIONSHIPELEMENT_H
#include <BaSyx/submodel/api_v2/submodelelement/ISubmodelElement.h>
@@ -18,6 +18,8 @@
virtual IReferable & getFirst() const = 0;
virtual IReferable & getSecond() const = 0;
+
+ virtual KeyElements getKeyElementType() const override { return KeyElements::RelationshipElement; };
};
inline IRelationshipElement::~IRelationshipElement() = default;
@@ -25,4 +27,4 @@
}
}
}
-#endif //BASYX_API_V2_SDK_IRELATIONSHIPELEMENT_H
+#endif /* BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IRELATIONSHIPELEMENT_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/ISubmodelElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/ISubmodelElement.h
index c908a29..e6a6bad 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/ISubmodelElement.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/ISubmodelElement.h
@@ -1,6 +1,7 @@
#ifndef BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_ISUBMODELELEMENT_H
#define BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_ISUBMODELELEMENT_H
+#include <BaSyx/submodel/api_v2/qualifier/IQualifiable.h>
#include <BaSyx/submodel/api_v2/qualifier/IHasDataSpecification.h>
#include <BaSyx/submodel/api_v2/qualifier/IHasSemantics.h>
#include <BaSyx/submodel/api_v2/qualifier/IReferable.h>
@@ -8,17 +9,18 @@
#include <BaSyx/submodel/api_v2/common/IModelType.h>
+
namespace basyx {
namespace submodel {
namespace api {
-class ISubmodelElement :
- public virtual IHasDataSpecification,
- public virtual IReferable,
-// public virtual IQualifiable,
- public virtual IHasSemantics,
- public virtual IHasKind,
- public virtual IModelType
+class ISubmodelElement
+ : public virtual IHasDataSpecification
+ , public virtual IReferable
+ , public virtual IHasSemantics
+ , public virtual IQualifiable
+ , public virtual IHasKind
+ , public virtual IModelType
{
public:
virtual ~ISubmodelElement() = 0;
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/file/IBlob.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/file/IBlob.h
index 08044a8..b4435e8 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/file/IBlob.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/file/IBlob.h
@@ -27,6 +27,8 @@
virtual const MimeType getMimeType() const = 0;
virtual void setMimeType(const MimeType & mimeType) = 0;
+
+ virtual KeyElements getKeyElementType() const override { return KeyElements::Blob; };
};
inline IBlob::~IBlob() = default;
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/file/IFile.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/file/IFile.h
index 75fc4f6..88ad38f 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/file/IFile.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/file/IFile.h
@@ -24,6 +24,8 @@
virtual const MimeType getMimeType() const = 0;
virtual void setMimeType(const MimeType & mimeType) = 0;
+
+ virtual KeyElements getKeyElementType() const override { return KeyElements::File; };
};
inline IFile::~IFile() = default;
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/operation/IOperationVariable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/operation/IOperationVariable.h
index 6204374..37a589c 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/operation/IOperationVariable.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/operation/IOperationVariable.h
@@ -16,6 +16,8 @@
virtual ~IOperationVariable() = 0;
virtual ISubmodelElement & getValue() const = 0;
+
+ virtual KeyElements getKeyElementType() const override { return KeyElements::OperationVariable; };
};
inline IOperationVariable::~IOperationVariable() = default;
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/property/XSDAnySimpleType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/property/XSDAnySimpleType.h
new file mode 100644
index 0000000..f77885f
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/property/XSDAnySimpleType.h
@@ -0,0 +1,666 @@
+#ifndef BASYX_C_SDK_XSDANYSIMPLETYPE_H
+#define BASYX_C_SDK_XSDANYSIMPLETYPE_H
+
+#include <string>
+#include <ctime>
+#include <chrono>
+#include <iomanip>
+#include <regex>
+
+#include <BaSyx/submodel/simple/common/xsd_types/AnyURI.h>
+#include <BaSyx/submodel/simple/common/xsd_types/DateTime.h>
+#include <BaSyx/submodel/simple/common/xsd_types/Date.h>
+#include <BaSyx/submodel/simple/common/xsd_types/DayTimeDuration.h>
+#include <BaSyx/submodel/simple/common/xsd_types/YearMonthDuration.h>
+#include <BaSyx/submodel/simple/common/xsd_types/Time.h>
+#include <BaSyx/submodel/simple/common/xsd_types/GYearMonth.h>
+#include <BaSyx/submodel/simple/common/xsd_types/GYear.h>
+#include <BaSyx/submodel/simple/common/xsd_types/GMonthDay.h>
+#include <BaSyx/submodel/simple/common/xsd_types/GDay.h>
+#include <BaSyx/submodel/simple/common/xsd_types/GMonth.h>
+#include <sstream>
+
+
+namespace basyx {
+namespace xsd_types {
+using namespace submodel;
+
+ static const std::string getPrimitiveXSDType(type::valueType type)
+ {
+ switch(type)
+ {
+ case type::valueType::Bool:
+ return "boolean";
+ case type::valueType::Int:
+ return "integer";
+ case type::valueType::Float:
+ return "float";
+ case type::valueType::String:
+ return "string";
+ default:
+ return "Type not supported!";
+ }
+ }
+
+ template<typename T, typename Enable = void>
+ struct xsd_type
+ {
+ static constexpr int fail_vab_type_not_supported() { static_assert("Type not supported by VAB!"); return 0; };
+ static const std::string getDataTypeDef()
+ {
+ return "Not supported!";
+ };
+ };
+
+ template<>
+ struct xsd_type<bool>
+ {
+ static const std::string getDataTypeDef()
+ {
+ return "boolean";
+ }
+
+ static const inline bool getXSDRepresentation(const bool & bool_value)
+ {
+ return bool_value;
+ }
+
+ static const inline bool fromXSDRepresentation(basyx::object value)
+ {
+ return value.Get<bool>();
+ }
+ };
+
+ template<>
+ struct xsd_type<int>
+ {
+ static const std::string getDataTypeDef()
+ {
+ return "integer";
+ }
+
+ static const inline int getXSDRepresentation(const int & int_value)
+ {
+ return int_value;
+ }
+
+ static const inline int fromXSDRepresentation(basyx::object value)
+ {
+ return value.Get<int>();
+ }
+ };
+
+template<>
+ struct xsd_type<long>
+ {
+ static const std::string getDataTypeDef()
+ {
+ return "long";
+ }
+
+ static const inline long getXSDRepresentation(const long & long_value)
+ {
+ return long_value;
+ }
+
+ static const inline long fromXSDRepresentation(basyx::object value)
+ {
+ return value.Get<long>();
+ }
+ };
+
+ template<>
+ struct xsd_type<short>
+ {
+ static const std::string getDataTypeDef()
+ {
+ return "short";
+ }
+
+ static const inline short getXSDRepresentation(const short & short_value)
+ {
+ return short_value;
+ }
+
+ static const inline short fromXSDRepresentation(basyx::object value)
+ {
+ return value.Get<short>();
+ }
+ };
+
+ template<>
+ struct xsd_type<unsigned int>
+ {
+ static const std::string getDataTypeDef()
+ {
+ return "unsignedInt";
+ }
+
+ static const inline unsigned int getXSDRepresentation(const unsigned int & uint_value)
+ {
+ return uint_value;
+ }
+
+ static const inline unsigned int fromXSDRepresentation(basyx::object value)
+ {
+ return value.Get<unsigned int>();
+ }
+ };
+
+ template<>
+ struct xsd_type<unsigned short>
+ {
+ static const std::string getDataTypeDef()
+ {
+ return "unsignedShort";
+ }
+
+ static const inline unsigned short getXSDRepresentation(const unsigned short & ushort_value)
+ {
+ return ushort_value;
+ }
+
+ static const inline unsigned short fromXSDRepresentation(basyx::object value)
+ {
+ return value.Get<unsigned short>();
+ }
+ };
+
+ template<>
+ struct xsd_type<unsigned long>
+ {
+ static const std::string getDataTypeDef()
+ {
+ return "unsignedLong";
+ }
+
+ static const inline unsigned long getXSDRepresentation(const unsigned long & ulong_value)
+ {
+ return ulong_value;
+ }
+
+ static const inline unsigned long fromXSDRepresentation(basyx::object value)
+ {
+ return value.Get<unsigned long>();
+ }
+ };
+
+ template<>
+ struct xsd_type<double>
+ {
+ static const std::string getDataTypeDef()
+ {
+ return "double";
+ }
+
+ static const inline double getXSDRepresentation(const double & double_value)
+ {
+ return double_value;
+ }
+
+ static const inline double fromXSDRepresentation(basyx::object value)
+ {
+ return value.Get<double>();
+ }
+ };
+
+ template<>
+ struct xsd_type<float>
+ {
+ static const std::string getDataTypeDef()
+ {
+ return "float";
+ }
+
+ static const inline float getXSDRepresentation(const float & float_value)
+ {
+ return float_value;
+ }
+
+ static const inline float fromXSDRepresentation(basyx::object value)
+ {
+ return value.Get<float>();
+ }
+ };
+
+ template<>
+ struct xsd_type<std::string>
+ {
+ static const std::string getDataTypeDef()
+ {
+ return "string";
+ }
+
+ static const inline std::string getXSDRepresentation(const std::string & string)
+ {
+ return string;
+ }
+
+ static const inline std::string fromXSDRepresentation(basyx::object value)
+ {
+ return value.GetStringContent();
+ }
+ };
+
+ template<>
+ struct xsd_type<simple::AnyURI>
+ {
+ static const std::string getDataTypeDef()
+ {
+ return "anyURI";
+ }
+
+ static const inline std::string getXSDRepresentation(const simple::AnyURI & uri)
+ {
+ return uri.getUri();
+ }
+
+ static const inline simple::AnyURI fromXSDRepresentation(const std::string & value)
+ {
+ return value;
+ }
+ };
+
+ template<>
+ struct xsd_type<simple::Date>
+ {
+ static constexpr char format[] = "%Y-%m-%dZ";
+
+ static const std::string getDataTypeDef()
+ {
+ return "date";
+ }
+
+ static const inline std::string getXSDRepresentation(const simple::Date & date)
+ {
+ std::stringstream formatted;
+ formatted << std::put_time(&date.getDate(), format);
+
+ return formatted.str();
+ }
+
+ static const inline simple::Date fromXSDRepresentation(basyx::object value)
+ {
+ tm date;
+ // Daylight Saving is not in effect
+ date.tm_isdst = 0;
+
+ std::stringstream sstream;
+ sstream << value.GetStringContent();
+ sstream >> std::get_time(&date, format);
+
+ return simple::Date{date};
+ }
+ };
+
+ template<>
+ struct xsd_type<simple::DateTime>
+ {
+ static constexpr char format[] = "%Y-%m-%dT%TZ";
+
+ static const std::string getDataTypeDef()
+ {
+ return "dateTime";
+ }
+
+ static const inline std::string getXSDRepresentation(const simple::DateTime & dateTime)
+ {
+ std::stringstream formatted;
+ formatted << std::put_time(&dateTime.getTime(), format);
+
+ return formatted.str();
+ }
+
+ static const inline simple::DateTime fromXSDRepresentation(basyx::object value)
+ {
+ tm time;
+ // Daylight Saving Time is not in effect
+ time.tm_isdst = 0;
+
+ std::stringstream sstream;
+ sstream << value.GetStringContent();
+ sstream >> std::get_time(&time, format);
+
+ return simple::DateTime{time};
+ }
+ };
+
+ template<>
+ struct xsd_type<simple::DayTimeDuration>
+ {
+ static constexpr int seconds_per_day = 86400; //60*60*24
+ static constexpr int seconds_per_hour = 3600; //60*60
+ static constexpr int seconds_per_minute = 60;
+
+ static const std::string getDataTypeDef()
+ {
+ return "dayTimeDuration";
+ }
+
+ static const inline std::string getXSDRepresentation(const simple::DayTimeDuration & dayTimeDuration)
+ {
+ std::string xsd_str;
+ long duration = dayTimeDuration.getDuration().count();
+ if (duration < 0)
+ {
+ xsd_str = "-";
+ duration *= -1;
+ }
+
+ xsd_str += "P";
+ if (duration / seconds_per_day)
+ {
+ xsd_str += std::to_string(duration / seconds_per_day) + "D";
+ duration = duration % seconds_per_day;
+ }
+ if (duration / seconds_per_hour)
+ {
+ xsd_str += std::to_string(duration / seconds_per_hour) + "H";
+ duration = duration % seconds_per_hour;
+ }
+ if (duration / seconds_per_minute)
+ {
+ xsd_str += std::to_string(duration / seconds_per_minute) + "M";
+ duration = duration % seconds_per_minute;
+ }
+ if (duration)
+ xsd_str += std::to_string(duration) + "S";
+
+ return xsd_str;
+ }
+
+ static const inline simple::DayTimeDuration fromXSDRepresentation(basyx::object value)
+ {
+ std::string xsd_str = value.GetStringContent();
+
+ long seconds = 0;
+
+ std::smatch match;
+ std::regex regex("\\d+D");
+ if (std::regex_search(xsd_str, match, regex))
+ seconds += std::stol(match.str()) * seconds_per_day;
+ regex = "\\d+H";
+ if (std::regex_search(xsd_str, match, regex))
+ seconds += std::stol(match.str()) * seconds_per_hour;
+ regex = "\\d+M";
+ if (std::regex_search(xsd_str, match, regex))
+ seconds += std::stol(match.str()) * seconds_per_minute;
+ regex = "\\d+S";
+ if (std::regex_search(xsd_str, match, regex))
+ seconds += std::stol(match.str());
+
+ if (xsd_str.find('-') == 0)
+ seconds *= -1;
+
+ return simple::DayTimeDuration{std::chrono::duration<long>(seconds)};
+ }
+ };
+
+
+ template<>
+ struct xsd_type<simple::YearMonthDuration>
+ {
+ static const std::string getDataTypeDef()
+ {
+ return "yearMonthDuration";
+ }
+
+ static const inline std::string getXSDRepresentation(const simple::YearMonthDuration & yearMonthDuration)
+ {
+ std::string xsd_str;
+ int years = yearMonthDuration.getYears();
+ int months = yearMonthDuration.getMonths();
+ if (years < 0)
+ {
+ xsd_str += "-";
+ years *= -1;
+ } else if (months < 0 and years == 0)
+ {
+ xsd_str += "-";
+ months *= -1;
+ }
+
+ xsd_str += "P";
+ xsd_str += (years > 0) ? std::to_string(years) + "Y" : "";
+ xsd_str += (months > 0) ? std::to_string(months) + "M" : "";
+
+ return xsd_str;
+ }
+
+ static const inline simple::YearMonthDuration fromXSDRepresentation(basyx::object value)
+ {
+ std::string xsd_str = value.GetStringContent();
+
+ int years = 0, months = 0;
+
+ std::smatch match;
+ std::regex regex("\\d+Y");
+ if (std::regex_search(xsd_str, match, regex))
+ years = std::stoi(match.str());
+ regex = "\\d+M";
+ if (std::regex_search(xsd_str, match, regex))
+ months = std::stoi(match.str());
+
+ if (xsd_str.find('-') == 0)
+ (years == 0) ? months *= -1 : years *= -1;
+
+ simple::YearMonthDuration yearMonthDuration{years,months};
+
+ return yearMonthDuration;
+ }
+ };
+
+ template<>
+ struct xsd_type<simple::Time>
+ {
+ static const std::string getDataTypeDef()
+ {
+ return "time";
+ }
+
+ static const inline std::string getXSDRepresentation(const simple::Time & time)
+ {
+ char buffer[9];
+ snprintf(buffer, 9, "%02d:%02d:%02d", time.getHours(), time.getMinutes(), int(time.getSeconds()));
+ std::string xsd_str{buffer};
+
+ // check if number has decimal places
+ if (std::fmod(time.getSeconds(), 1.0) != 0)
+ {
+ snprintf(buffer, 9, "%.05f", time.getSeconds());
+
+ std::string decimal = buffer;
+ // find trailing zeros and erase them
+ decimal = decimal.erase(decimal.find_last_not_of('0') + 1, std::string::npos).substr(decimal.find("."));
+ xsd_str += decimal;
+ }
+
+ return xsd_str + std::string{time.getTimezone()};
+ }
+
+ static const inline simple::Time fromXSDRepresentation(basyx::object value)
+ {
+ std::string xsd_str = value.GetStringContent();
+
+ std::smatch match;
+ std::regex regex{"(\\d\\d):(\\d\\d):(\\d\\d(\\.\\d+)?)([Z|\\+|\\-].*)"};
+ std::regex_search(xsd_str, match, regex);
+
+ float second = 0;
+ uint8_t hour = std::stoi(match.str(1)); // first (\\d\\d)
+ uint8_t minute = std::stoi(match.str(2)); // second (\\d\\d)
+ second = std::stof(match.str(3)); // (\\d\\d(\\.\\d+)?) Two digits plus optional decimal point and arbitrary number of digits
+ std::string timezone = match.str(5); // ([Z|\+|\-]) "Z" or + or - and arbitrary characters
+
+ return simple::Time{hour, minute, second, timezone};
+ }
+ };
+
+ template<>
+ struct xsd_type<simple::GYearMonth>
+ {
+ static const std::string getDataTypeDef()
+ {
+ return "gYearMonth";
+ }
+
+ static const inline std::string getXSDRepresentation(const simple::GYearMonth & date)
+ {
+ char buffer[15];
+ if (date.getYear() < 0)
+ snprintf(buffer, 15, "%05d-%02d", date.getYear(), date.getMonth());
+ else
+ snprintf(buffer, 15, "%04d-%02d", date.getYear(), date.getMonth());
+
+ return buffer + std::string{date.getTimezone()};
+ }
+
+ static const inline simple::GYearMonth fromXSDRepresentation(basyx::object value)
+ {
+ std::string xsd_str = value.GetStringContent();
+
+ std::smatch match;
+ std::regex regex{"(-?\\d+)-(\\d\\d)([Z|\\+|\\-].*)"};
+ std::regex_search(xsd_str, match, regex);
+
+ int year = std::stoi(match.str(1)); // first (\\d+)
+ uint8_t month = std::stoi(match.str(2)); // second (\\d\\d)
+ std::string timezone = match.str(3);
+
+ return simple::GYearMonth{year, month, timezone};
+ }
+ };
+
+ template<>
+ struct xsd_type<simple::GYear>
+ {
+ static const std::string getDataTypeDef()
+ {
+ return "gYear";
+ }
+
+ static const inline std::string getXSDRepresentation(const simple::GYear & year)
+ {
+ char buffer[15];
+ if (year.getYear() < 0)
+ snprintf(buffer, 15, "%05d", year.getYear());
+ else
+ snprintf(buffer, 15, "%04d", year.getYear());
+
+ return buffer + std::string{year.getTimezone()};
+ }
+
+ static const inline simple::GYear fromXSDRepresentation(basyx::object value)
+ {
+ std::string xsd_str = value.GetStringContent();
+
+ std::smatch match;
+ std::regex regex{"(-?\\d+)([Z|\\+|\\-].*)"};
+ std::regex_search(xsd_str, match, regex);
+
+ int year = std::stoi(match.str(1)); // first (\\d+)
+ std::string timezone = match.str(2);
+
+ return simple::GYear{year, timezone};
+ }
+ };
+
+ template<>
+ struct xsd_type<simple::GMonthDay>
+ {
+ static const std::string getDataTypeDef()
+ {
+ return "gMonthDay";
+ }
+
+ static const inline std::string getXSDRepresentation(const simple::GMonthDay & monthDay)
+ {
+ char buffer[10];
+ snprintf(buffer, 8, "--%02d-%02d", monthDay.getMonth(), monthDay.getDay());
+
+ return buffer + std::string{monthDay.getTimezone()};
+ }
+
+ static const inline simple::GMonthDay fromXSDRepresentation(basyx::object value)
+ {
+ std::string xsd_str = value.GetStringContent();
+
+ std::smatch match;
+ std::regex regex{"\\-\\-(\\d\\d)\\-(\\d\\d)([Z|\\+|\\-].*)"};
+ std::regex_search(xsd_str, match, regex);
+
+ uint8_t month = std::stoi(match.str(1)); // first (\\d\\d)
+ uint8_t day = std::stoi(match.str(2)); // second (\\d\\d)
+ std::string timezone = match.str(3);
+
+ return simple::GMonthDay{month, day, timezone};
+ }
+ };
+
+ template<>
+ struct xsd_type<simple::GDay>
+ {
+ static const std::string getDataTypeDef()
+ {
+ return "gDay";
+ }
+
+ static const inline std::string getXSDRepresentation(const simple::GDay & day)
+ {
+ char buffer[7];
+ snprintf(buffer, 7, "---%02d", day.getDay());
+
+ return buffer + std::string{day.getTimezone()};
+ }
+
+ static const inline simple::GDay fromXSDRepresentation(basyx::object value)
+ {
+ std::string xsd_str = value.GetStringContent();
+
+ std::smatch match;
+ std::regex regex{"\\-\\-\\-(\\d\\d)([Z|\\+|\\-].*)"};
+ std::regex_search(xsd_str, match, regex);
+
+ uint8_t day = std::stoi(match.str(1)); // first (\\d\\d)
+ std::string timezone = match.str(2);
+
+ return simple::GDay{day, timezone};
+ }
+ };
+
+ template<>
+ struct xsd_type<simple::GMonth>
+ {
+ static const std::string getDataTypeDef()
+ {
+ return "gMonth";
+ }
+
+ static const inline std::string getXSDRepresentation(const simple::GMonth & month)
+ {
+ char buffer[6];
+ snprintf(buffer, 6, "--%02d", month.getMonth());
+
+ return buffer + std::string{month.getTimezone()};
+ }
+
+ static const inline simple::GMonth fromXSDRepresentation(basyx::object value)
+ {
+ std::string xsd_str = value.GetStringContent();
+
+ std::smatch match;
+ std::regex regex{"\\-\\-(\\d\\d)([Z|\\+|\\-].*)"};
+ std::regex_search(xsd_str, match, regex);
+
+ uint8_t month = std::stoi(match.str(1)); // first (\\d\\d)
+ std::string timezone = match.str(2);
+
+ return simple::GMonth{month, timezone};
+ }
+ };
+
+}
+}
+
+
+#endif //BASYX_C_SDK_XSDANYSIMPLETYPE_H
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/ConnectedElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/ConnectedElement.h
deleted file mode 100644
index 19a6bc1..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/ConnectedElement.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * ConnectedElement.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_CONNECTEDELEMENT_H_
-#define BASYX_METAMODEL_CONNECTEDELEMENT_H_
-
-
-#include <BaSyx/vab/core/proxy/VABElementProxy.h>
-#include <BaSyx/submodel/api/IElement.h>
-
-#include <BaSyx/shared/types.h>
-
-#include <string>
-#include <memory>
-
-namespace basyx {
-namespace submodel {
-
-class ConnectedElement : public IElement
-{
-public:
- ConnectedElement(const std::shared_ptr<vab::core::proxy::IVABElementProxy> & proxy);
- ConnectedElement(const std::shared_ptr<vab::core::proxy::IVABElementProxy> & proxy, std::shared_ptr<basyx::object::object_map_t> & local_values);
-
- virtual std::shared_ptr<vab::core::proxy::IVABElementProxy> getProxy() const;
-
- basyx::object getLocalValue(const std::string & path) const;
- void setLocalValue(const std::string & path, const basyx::object & value);
- void setLocalValues(const basyx::object::object_map_t & map);
- void updateLocalValue(const std::string & path, const basyx::object value);
-
- // Inherited via IElement
- virtual void setId(const std::string & id) override;
- virtual std::string getId() const override;
-
-
-private:
- std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy;
- std::shared_ptr<basyx::object::object_map_t> local_map;
-
-protected:
- std::string getProxyValue(const std::string & path) const;
- std::shared_ptr<basyx::object::object_map_t> getProxyMap(const std::string & path) const;
- void setProxyValue(const std::string & path, const basyx::object value) const;
-
-};
-
-}
-}
-
-#endif // !BASYX_METAMODEL_CONNECTEDELEMENT_H_
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/ConnectedSubmodel.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/ConnectedSubmodel.h
deleted file mode 100644
index 6aef83a..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/ConnectedSubmodel.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * ConnectedSubmodel.h
- *
- * Author: wendel
- */
-
-#ifndef CONNECTEDSUBMODEL_H_
-#define CONNECTEDSUBMODEL_H_
-
-#include <BaSyx/submodel/api/ISubModel.h>
-
-#include <BaSyx/submodel/map/IVABElementContainer.h>
-//#include <BaSyx/submodel/map/qualifier/Kind.h>
-#include <BaSyx/submodel/connected/ConnectedElement.h>
-#include <BaSyx/submodel/api/reference/IReference.h>
-
-namespace basyx {
-namespace submodel {
-
-class ConnectedSubmodel :
- public ISubModel,
- public ConnectedElement
-{
-public:
- ~ConnectedSubmodel() = default;
-
- // Inherited via ISubModel
- virtual std::shared_ptr<IReference> getSemanticId() const override;
- virtual std::shared_ptr<IAdministrativeInformation> getAdministration() const override;
- virtual std::shared_ptr<IIdentifier> getIdentification() const override;
- virtual basyx::specificCollection_t<IReference> getDataSpecificationReferences() const override;
- virtual Kind getHasKindReference() const override;
- virtual void setDataElements(const basyx::specificMap_t<IProperty> & properties);
- virtual void setOperations(const basyx::specificMap_t<IOperation> & operations);
- virtual std::string getIdShort() const override;
- virtual std::string getCategory() const override;
- virtual Description getDescription() const override;
- virtual std::shared_ptr<IReference> getParent() const override;
- virtual void addSubModelElement(const std::shared_ptr<ISubmodelElement> & element) override;
- virtual basyx::specificMap_t<IDataElement> getDataElements() const override;
- virtual basyx::specificMap_t<IOperation> getOperations() const override;
-
-private:
- basyx::object::object_map_t local_map;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/ConnectedVABModelMap.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/ConnectedVABModelMap.h
deleted file mode 100644
index 793090f..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/ConnectedVABModelMap.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * ConnectedVABModelMap.h
- *
- * Author: wendel
- */
-
-#ifndef CONNECTEDVABMODELMAP_H_
-#define CONNECTEDVABMODELMAP_H_
-
-#include <BaSyx/submodel/connected/ConnectedElement.h>
-
-namespace basyx {
-namespace submodel {
-namespace backend {
-
-class ConnectedVABModelMap : public ConnectedElement
-{
-public:
- ConnectedVABModelMap(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy);
- ~ConnectedVABModelMap() = default;
-};
-
-}
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/ConnectedDataElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/ConnectedDataElement.h
deleted file mode 100644
index 78f11c3..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/ConnectedDataElement.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * ConnectedDataElement.h
- *
- * Author: wendel
- */
-
-
-#ifndef BASYX_METAMODEL_CONNECTEDDATAELEMENT_H_
-#define BASYX_METAMODEL_CONNECTEDDATAELEMENT_H_
-
-#include <BaSyx/vab/core/proxy/IVABElementProxy.h>
-
-#include <BaSyx/submodel/api/reference/IReference.h>
-#include <BaSyx/submodel/api/qualifier/qualifiable/IConstraint.h>
-#include <BaSyx/submodel/connected/submodelelement/ConnectedSubmodelElement.h>
-#include <BaSyx/submodel/api/submodelelement/IDataElement.h>
-
-namespace basyx {
-namespace submodel {
-
-class ConnectedDataElement : public ConnectedSubmodelElement, public IDataElement
-{
-
-public:
- ConnectedDataElement(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy);
- ~ConnectedDataElement() = default;
-
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/ConnectedRelationshipElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/ConnectedRelationshipElement.h
deleted file mode 100644
index ac88a92..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/ConnectedRelationshipElement.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * ConnectedRelationshipElement.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_BACKEND_SUBMODELELEMENT_CONNECTEDRELATIONSHIPELEMENT_H_
-#define AAS_BACKEND_SUBMODELELEMENT_CONNECTEDRELATIONSHIPELEMENT_H_
-
-#include <BaSyx/shared/types.h>
-
-#include <BaSyx/vab/core/proxy/IVABElementProxy.h>
-
-#include <BaSyx/submodel/api/submodelelement/ISubmodelElement.h>
-#include <BaSyx/submodel/api/submodelelement/IRelationshipElement.h>
-#include <BaSyx/submodel/connected/submodelelement/ConnectedSubmodelElement.h>
-
-#include <string>
-
-namespace basyx {
-namespace submodel {
-
-class ConnectedRelationshipElement : public ConnectedSubmodelElement, public IRelationshipElement
-{
-public:
- ConnectedRelationshipElement(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy);
- ~ConnectedRelationshipElement() = default;
-
- // Inherited via IRelationshipElement
- virtual void setFirst(const IReference & first) override;
- virtual std::shared_ptr<IReference> getFirst() const override;
- virtual void setSecond(const IReference & second) override;
- virtual std::shared_ptr<IReference> getSecond() const override;
-};
-
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/ConnectedSubmodelElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/ConnectedSubmodelElement.h
deleted file mode 100644
index 6fa216d..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/ConnectedSubmodelElement.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * ConnectedSubmodelElement.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_BACKEND_SUBMODELELEMENT_CONNECTED_CONNECTEDSUBMODELELEMENT_H_
-#define AAS_BACKEND_SUBMODELELEMENT_CONNECTED_CONNECTEDSUBMODELELEMENT_H_
-
-#include <BaSyx/submodel/api/submodelelement/ISubmodelElement.h>
-#include <BaSyx/submodel/connected/ConnectedElement.h>
-#include <BaSyx/vab/core/proxy/IVABElementProxy.h>
-
-namespace basyx {
-namespace submodel {
-
-class ConnectedSubmodelElement : public ConnectedElement, public ISubmodelElement
-{
-public:
- ConnectedSubmodelElement(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy);
- ~ConnectedSubmodelElement() = default;
-
- basyx::specificCollection_t<IReference> getDataSpecificationReferences() const override;
- std::string getIdShort() const override;
- std::string getCategory() const override;
- Description getDescription() const override;
- std::shared_ptr<IReference> getParent() const override;
- basyx::specificCollection_t<IConstraint> getQualifier() const override;
- std::shared_ptr<IReference> getSemanticId() const override;
- Kind getHasKindReference() const override;
-
-protected:
- std::string getIdWithLocalCheck() const;
- void setIdWithLocalCheck(const std::string & id);
- basyx::object::object_list_t getProxyCollection(const std::string & path) const;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/ConnectedSubmodelElementCollection.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/ConnectedSubmodelElementCollection.h
deleted file mode 100644
index b9848ad..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/ConnectedSubmodelElementCollection.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * ConnectedSubmodelElementCollection.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_BACKEND_SUBMODELELEMENT_CONNECTEDSUBMODELELEMENTCOLLECTION_H_
-#define AAS_BACKEND_SUBMODELELEMENT_CONNECTEDSUBMODELELEMENTCOLLECTION_H_
-
-#include <BaSyx/submodel/connected/submodelelement/ConnectedSubmodelElement.h>
-#include <BaSyx/submodel/api/submodelelement/ISubmodelElementCollection.h>
-
-namespace basyx {
-namespace submodel {
-
-
-class ConnectedSubmodelElementCollection : public ConnectedSubmodelElement, ISubmodelElementCollection
-{
-public:
- ConnectedSubmodelElementCollection(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy);
- ~ConnectedSubmodelElementCollection() = default;
-
- // Inherited via ISubmodelElementCollection
- virtual void setValue(const basyx::specificCollection_t<ISubmodelElement> & value) ;
- virtual basyx::specificCollection_t<ISubmodelElement> getValue() const override;
- virtual void setOrdered(const bool & value) ;
- virtual bool isOrdered() const override;
- virtual void setAllowDuplicates(const bool & value) ;
- virtual bool isAllowDuplicates() const override;
- virtual void setElements(const basyx::specificMap_t<ISubmodelElement> & elements) ;
- virtual basyx::specificMap_t<ISubmodelElement> getElements() const override;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/operation/ConnectedOperation.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/operation/ConnectedOperation.h
deleted file mode 100644
index 682019b..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/operation/ConnectedOperation.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * ConnectedOperation.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_BACKEND_SUBMODELELEMENT_OPERATION_CONNECTEDOPERATION_H_
-#define AAS_BACKEND_SUBMODELELEMENT_OPERATION_CONNECTEDOPERATION_H_
-
-#include <BaSyx/submodel/api/submodelelement/operation/IOperation.h>
-#include <BaSyx/vab/core/proxy/IVABElementProxy.h>
-#include <BaSyx/submodel/connected/submodelelement/ConnectedSubmodelElement.h>
-
-namespace basyx {
-namespace submodel {
-
-class ConnectedOperation : public ConnectedSubmodelElement, public IOperation
-{
-public:
- ConnectedOperation(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy);
- ~ConnectedOperation() = default;
-
- // Inherited via IOperation
- virtual void setId(const std::string & id) override;
- virtual std::string getId() const override;
-
- virtual basyx::specificCollection_t<IOperationVariable> getParameterTypes() const override;
- virtual std::shared_ptr<IOperationVariable> getReturnType() const override;
- virtual basyx::object invoke(basyx::object & parameters) const override;
- virtual basyx::object getInvocable() const override;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedCollectionProperty.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedCollectionProperty.h
deleted file mode 100644
index 17f8a4e..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedCollectionProperty.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * ConnectedCollectionProperty.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDCOLLECTIONPROPERTY_H_
-#define AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDCOLLECTIONPROPERTY_H_
-
-#include <BaSyx/submodel/api/submodelelement/property/ICollectionProperty.h>
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedProperty.h>
-
-namespace basyx {
-namespace submodel {
-
-class ConnectedCollectionProperty : public ConnectedProperty, submodelelement::property::ICollectionProperty
-{
-public:
- ConnectedCollectionProperty(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy);
- ~ConnectedCollectionProperty() = default;
-
- virtual void set(const basyx::object::object_list_t & collection) const override;
- virtual void add(const basyx::object & newValue) override;
- virtual void remove(basyx::object & objectRef) override;
- virtual basyx::object::object_list_t getElements() const override;
- virtual int getElementCount() const override;
-
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedContainerProperty.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedContainerProperty.h
deleted file mode 100644
index d339c0f..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedContainerProperty.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * ConnectedContainerProperty.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDCONTAINERPROPERTY_H_
-#define AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDCONTAINERPROPERTY_H_
-
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedCollectionProperty.h>
-
-namespace basyx {
-namespace submodel {
-namespace backend {
-namespace connected {
-
-using ConnectedContainerProperty = ConnectedCollectionProperty;
-
-}
-}
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedMapProperty.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedMapProperty.h
deleted file mode 100644
index d6ecb67..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedMapProperty.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * ConnectedMapProperty.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDMAPPROPERTY_H_
-#define AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDMAPPROPERTY_H_
-
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedProperty.h>
-#include <BaSyx/submodel/api/submodelelement/property/IMapProperty.h>
-
-namespace basyx {
-namespace submodel {
-
-class ConnectedMapProperty : public submodelelement::property::IMapProperty, public ConnectedProperty
-{
-public:
- ConnectedMapProperty(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy);
- ~ConnectedMapProperty() = default;
-
- // Inherited via IMapProperty
- virtual basyx::object getValue(const std::string & key) const override;
- virtual void put(const std::string & key, const basyx::object & value) const override;
- virtual void set(const basyx::object::object_map_t & map) const override;
- virtual basyx::object::object_list_t getKeys() const override;
- virtual int getEntryCount() const override;
- virtual void remove(const std::string & key) const override;
-
-private:
- basyx::object::object_map_t getMap() const;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedProperty.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedProperty.h
deleted file mode 100644
index 88b7732..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedProperty.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * ConnectedProperty.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_BACKEND_CONNECTEDPROPERTY_H_
-#define AAS_BACKEND_CONNECTEDPROPERTY_H_
-
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-#include <BaSyx/submodel/connected/submodelelement/ConnectedDataElement.h>
-#include <BaSyx/shared/types.h>
-#include <BaSyx/shared/object.h>
-
-namespace basyx {
-namespace submodel {
-
-class ConnectedProperty : public ConnectedDataElement, public IProperty
-{
-
-public:
- ConnectedProperty(PropertyType type, std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy);
-
- // Inherited via IProperty
- virtual PropertyType getPropertyType() const override;
-
- //Inherited via IProperty : IElement
- virtual void setId(const std::string & id) override;
- virtual std::string getId() const override;
-
-protected:
- basyx::object retrieveObject() const;
-
-private:
- PropertyType type;
-
- // Inherited via IProperty
- virtual void setValueId(const std::string & valueId) override;
- virtual std::string getValueId() const override;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedPropertyFactory.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedPropertyFactory.h
deleted file mode 100644
index 13fd67d..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedPropertyFactory.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * ConnectedPropertyFactory.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDPROPERTYFACTORY_H_
-#define AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDPROPERTYFACTORY_H_
-
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-#include <BaSyx/vab/core/proxy/IVABElementProxy.h>
-#include <BaSyx/submodel/api/ISubModel.h>
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedContainerProperty.h>
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedMapProperty.h>
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedSingleProperty.h>
-#include <BaSyx/submodel/api/submodelelement/property/ISingleProperty.h>
-#include <BaSyx/submodel/map/submodelelement/property/valuetypedef/PropertyValueTypeDef.h>
-
-
-namespace basyx {
-namespace submodel {
-namespace backend {
-namespace connected {
-namespace support {
-
-using namespace submodelelement::property;
-
-namespace ConnectedPropertyFactory {
-// Forward declaration
-static std::shared_ptr<ConnectedProperty> createSuitableProperty(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy, basyx::object::object_map_t & originalPropertyMap, basyx::object::object_map_t & valueTypeMap);
-static std::shared_ptr<ConnectedProperty> createSingleProperty(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy, basyx::object::object_map_t & originalPropertyMap);
-static std::shared_ptr<ConnectedProperty> createProperty(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy)
-{
- auto property = proxy->readElementValue("").Get<basyx::object::object_map_t>();
-
-
- // todo
- //if ( property.find(api::ISubModel::SubmodelPaths::PROPERTIES) != property.end() )
- //{
- // return std::make_shared<ConnectedContainerProperty>(proxy);
- //}
-
- auto valueTypePtr = property.find(IProperty::Path::ValueType);
- // Check if valueType is set
- if ( valueTypePtr != property.end() )
- {
- auto valueType = valueTypePtr->second.Get<basyx::object::object_map_t>();
- return createSuitableProperty(proxy, property, valueType);
- }
-
- // Property with no value type set
- if ( property.find(IProperty::Path::Value) != property.end() and property.find(IReferable::Path::IdShort) != property.end() )
- {
- return createSingleProperty(proxy, property);
- }
-
- // If nothing suits return null
- return nullptr;
-}
-
-static std::shared_ptr<ConnectedProperty> createSuitableProperty(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy, basyx::object::object_map_t & originalPropertyMap, basyx::object::object_map_t & valueTypeMap)
-{
- auto valueType_typeObject = valueTypeMap.at(impl::metamodel::PropertyValueTypeIdentifier::TYPE_OBJECT).Get<basyx::object::object_map_t>();
- auto propertyValueTypeName = valueType_typeObject.at(impl::metamodel::PropertyValueTypeIdentifier::TYPE_NAME).GetStringContent();
-
- // if map -> create map todo
- //if ( propertyValueTypeName.compare(impl::metamodel::PropertyValueTypeDef::Map) == 0 )
- //{
- // return std::make_shared<ConnectedMapProperty>(proxy);
- //}
-
- // if collection -> create collection todo
- //if ( propertyValueTypeName.compare(impl::metamodel::PropertyValueTypeDef::Collection) == 0 )
- //{
- // return std::make_shared<ConnectedCollectionProperty>(proxy);
- //}
-
- // if no map and no collection -> must be single property
- //else
- //{
- // return createSingleProperty(proxy, originalPropertyMap);
- //}
- return nullptr;
-}
-
-static std::shared_ptr<ConnectedProperty> createSingleProperty(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy, basyx::object::object_map_t & originalPropertyMap)
-{
- ConnectedSingleProperty singleProperty(proxy);
- for ( auto & element : originalPropertyMap )
- {
- singleProperty.setLocalValue(element.first, element.second);
- }
- return std::make_shared<ConnectedCollectionProperty>(proxy);
-}
-}
-
-}
-}
-}
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedReferenceElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedReferenceElement.h
deleted file mode 100644
index 4d371a7..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedReferenceElement.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * ConnectedReferenceElement.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDREFERENCEELEMENT_H_
-#define AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDREFERENCEELEMENT_H_
-
-#include <BaSyx/submodel/connected/submodelelement/ConnectedDataElement.h>
-#include <BaSyx/submodel/api/submodelelement/IReferenceElement.h>
-
-namespace basyx {
-namespace submodel {
-
-class ConnectedReferenceElement : public ConnectedDataElement, public IReferenceElement
-{
-public:
- ConnectedReferenceElement(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy);
- ~ConnectedReferenceElement() = default;
-
- virtual void setValue(const IReference & ref);
- virtual std::shared_ptr<IReference> getValue() const override;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedSingleProperty.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedSingleProperty.h
deleted file mode 100644
index e1a0ba7..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedSingleProperty.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * ConnectedSingleProperty.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDSINGLEPROPERTY_H_
-#define AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDSINGLEPROPERTY_H_
-
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedProperty.h>
-#include <BaSyx/submodel/api/submodelelement/property/ISingleProperty.h>
-
-namespace basyx {
-namespace submodel {
-
-class ConnectedSingleProperty : public ConnectedProperty, public ISingleProperty
-{
-public:
- ConnectedSingleProperty(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy);
- ~ConnectedSingleProperty() = default;
-
- virtual basyx::object get() const override;
- virtual void set(const basyx::object & value) override;
- virtual std::string getValueType() const override;
-
-
- // Inherited via ConnectedProperty
- virtual void setValueId(const std::string & valueId) override;
- virtual std::string getValueId() const override;
- virtual PropertyType getPropertyType() const override;
-
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/blob/ConnectedBlob.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/blob/ConnectedBlob.h
deleted file mode 100644
index 8659ef7..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/blob/ConnectedBlob.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * ConnectedBlob.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDBLOB_H_
-#define AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDBLOB_H_
-
-#include <BaSyx/submodel/api/submodelelement/property/blob/IBlob.h>
-#include <BaSyx/submodel/connected/submodelelement/ConnectedDataElement.h>
-//#include <BaSyx/aas/BlobType.h>
-//#include <BaSyx/aas/MimeType.h>
-
-namespace basyx {
-namespace submodel {
-
-class ConnectedBlob : public IBlob, ConnectedDataElement
-{
-public:
- ConnectedBlob(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy);
- ~ConnectedBlob() = default;
-
- // Inherited via IBlob
- virtual void setValue(const std::string & value);
-
- virtual const std::string & getValue() const override;
-
- virtual void setMimeType(const std::string & mimeType);
-
- virtual const std::string & getMimeType() const override;
-
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/file/ConnectedFile.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/file/ConnectedFile.h
deleted file mode 100644
index 5ac4a88..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/file/ConnectedFile.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * ConnectedFile.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDFILE_H_
-#define AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDFILE_H_
-
-#include <BaSyx/submodel/api/submodelelement/property/file/IFile.h>
-#include <BaSyx/submodel/connected/submodelelement/ConnectedDataElement.h>
-
-namespace basyx {
-namespace submodel {
-
-class ConnectedFile : public IFile, ConnectedDataElement
-{
-public:
- ConnectedFile(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy);
- ~ConnectedFile() = default;
-
- virtual void setValue(const std::string & value);
- virtual const std::string & getValue() const override;
-
- virtual void setMimeType(const std::string & mimeType);
- virtual const std::string & getMimeType() const override;
-
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/AssetKind.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/AssetKind.h
index 4576d7f..277bd0f 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/AssetKind.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/AssetKind.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_ENUM_AssetKind_H
-#define BASYX_SUBMODEL_ENUM_AssetKind_H
+#ifndef BASYX_SUBMODEL_ENUMERATIONS_ASSETKIND_H
+#define BASYX_SUBMODEL_ENUMERATIONS_ASSETKIND_H
#include <string>
@@ -23,4 +23,4 @@
}
}
-#endif
+#endif /* BASYX_SUBMODEL_ENUMERATIONS_ASSETKIND_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/Conversions.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/Conversions.h
new file mode 100644
index 0000000..944934b
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/Conversions.h
@@ -0,0 +1,79 @@
+#ifndef BASYX_SUBMODEL_ENUMERATIONS_CONVERSIONS_H
+#define BASYX_SUBMODEL_ENUMERATIONS_CONVERSIONS_H
+
+#include <BaSyx/submodel/enumerations/KeyElements.h>
+#include <BaSyx/submodel/enumerations/ModelTypes.h>
+
+namespace basyx {
+namespace submodel {
+namespace enums {
+
+inline KeyElements convert_modeltype_to_keyelement(const ModelTypes modelType)
+{
+ switch (modelType) {
+ case ModelTypes::Asset:
+ return KeyElements::Asset;
+ case ModelTypes::AssetAdministrationShell:
+ return KeyElements::AssetAdministrationShell;
+ case ModelTypes::ConceptDescription:
+ return KeyElements::ConceptDescription;
+ case ModelTypes::Submodel:
+ return KeyElements::Submodel;
+ case ModelTypes::AccessPermissionRule:
+ return KeyElements::AccessPermissionRule;
+ case ModelTypes::AnnotatedRelationshipElement:
+ return KeyElements::AnnotatedRelationshipElement;
+ case ModelTypes::BasicEvent:
+ return KeyElements::BasicEvent;
+ case ModelTypes::Blob:
+ return KeyElements::Blob;
+ case ModelTypes::Capability:
+ return KeyElements::Capability;
+ case ModelTypes::ConceptDictionary:
+ return KeyElements::ConceptDictionary;
+ case ModelTypes::DataElement:
+ return KeyElements::DataElement;
+ case ModelTypes::File:
+ return KeyElements::File;
+ case ModelTypes::Entity:
+ return KeyElements::Entity;
+ case ModelTypes::Event:
+ return KeyElements::Event;
+ case ModelTypes::MultiLanguageProperty:
+ return KeyElements::MultiLanguageProperty;
+ case ModelTypes::Operation:
+ return KeyElements::Operation;
+ case ModelTypes::OperationVariable:
+ return KeyElements::OperationVariable;
+ case ModelTypes::Property:
+ return KeyElements::Property;
+ case ModelTypes::Range:
+ return KeyElements::Range;
+ case ModelTypes::ReferenceElement:
+ return KeyElements::ReferenceElement;
+ case ModelTypes::RelationshipElement:
+ return KeyElements::RelationshipElement;
+ case ModelTypes::SubmodelElement:
+ return KeyElements::SubmodelElement;
+ case ModelTypes::SubmodelElementCollection:
+ return KeyElements::SubmodelElementCollection;
+ case ModelTypes::View:
+ return KeyElements::View;
+ case ModelTypes::GlobalReference:
+ return KeyElements::GlobalReference;
+ case ModelTypes::FragmentReference:
+ return KeyElements::FragmentReference;
+ case ModelTypes::Constraint:
+ return KeyElements::Unknown;
+ case ModelTypes::Formula:
+ return KeyElements::Unknown;
+ case ModelTypes::Qualifier:
+ return KeyElements::Unknown;
+ };
+};
+
+}
+}
+}
+
+#endif /* BASYX_SUBMODEL_ENUMERATIONS_CONVERSIONS_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/DataTypeIEC61360.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/DataTypeIEC61360.h
index 634c85b..a06b777 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/DataTypeIEC61360.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/DataTypeIEC61360.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_ENUM_DataTypeIEC61360_H
-#define BASYX_SUBMODEL_ENUM_DataTypeIEC61360_H
+#ifndef BASYX_SUBMODEL_ENUMERATIONS_DATATYPEIEC61360_H
+#define BASYX_SUBMODEL_ENUMERATIONS_DATATYPEIEC61360_H
#include <string>
@@ -33,4 +33,4 @@
}
}
-#endif
+#endif /* BASYX_SUBMODEL_ENUMERATIONS_DATATYPEIEC61360_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/EntityType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/EntityType.h
index c5fd70e..7459c3b 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/EntityType.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/EntityType.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_ENUM_EntityType_H
-#define BASYX_SUBMODEL_ENUM_EntityType_H
+#ifndef BASYX_SUBMODEL_ENUMERATIONS_ENTITYTYPE_H
+#define BASYX_SUBMODEL_ENUMERATIONS_ENTITYTYPE_H
#include <string>
@@ -22,4 +22,4 @@
}
}
-#endif
+#endif /* BASYX_SUBMODEL_ENUMERATIONS_ENTITYTYPE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/IdentifiableElements.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/IdentifiableElements.h
index bc824f1..1ecc764 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/IdentifiableElements.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/IdentifiableElements.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_ENUM_IdentifiableElements_H
-#define BASYX_SUBMODEL_ENUM_IdentifiableElements_H
+#ifndef BASYX_SUBMODEL_ENUMERATIONS_IDENTIFIABLEELEMENTS_H
+#define BASYX_SUBMODEL_ENUMERATIONS_IDENTIFIABLEELEMENTS_H
#include <string>
@@ -7,24 +7,10 @@
namespace submodel {
enum class IdentifiableElements {
- AccessPermissionRule,
- AnnotatedRelationshipElemenBasicEvent,
- Blob,
- Capability,
- ConceptDictionary,
- DataElement,
- Entity,
- Event,
- File,
- MultiLanguageProperty,
- Operation,
- Property,
- Range,
- ReferenceElement,
- RelationshipElement,
- SubmodelElement,
- SubmodelElementCollection,
- View,
+ Asset,
+ AssetAdministrationShell,
+ ConceptDescription,
+ Submodel,
};
class IdentifiableElements_
@@ -38,4 +24,4 @@
}
}
-#endif
+#endif /* BASYX_SUBMODEL_ENUMERATIONS_IDENTIFIABLEELEMENTS_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/IdentifierType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/IdentifierType.h
index 3357dd5..b021cb9 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/IdentifierType.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/IdentifierType.h
@@ -1,27 +1,32 @@
-#ifndef BASYX_SUBMODEL_ENUM_IdentifierType_H
-#define BASYX_SUBMODEL_ENUM_IdentifierType_H
+#ifndef BASYX_SUBMODEL_ENUMERATIONS_IDENTIFIERTYPE_H
+#define BASYX_SUBMODEL_ENUMERATIONS_IDENTIFIERTYPE_H
+
+#include <BaSyx/submodel/enumerations/KeyType.h>
#include <string>
namespace basyx {
namespace submodel {
-enum class IdentifierType {
- Custom,
- IRDI,
- URI,
- Unknown,
-};
+using IdentifierType = KeyType;
+using IdentifierType_ = KeyType_;
-class IdentifierType_
-{
-public:
- static IdentifierType from_string(const std::string & name);
- static const char * to_string(IdentifierType value);
-};
+//enum class IdentifierType {
+// Custom,
+// IRDI,
+// URI,
+// Unknown,
+//};
+//
+//class IdentifierType_
+//{
+//public:
+// static IdentifierType from_string(const std::string & name);
+// static const char * to_string(IdentifierType value);
+//};
}
}
-#endif
+#endif /* BASYX_SUBMODEL_ENUMERATIONS_IDENTIFIERTYPE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/KeyElements.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/KeyElements.h
index e6248d7..ef616a5 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/KeyElements.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/KeyElements.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_ENUM_KeyElements_H
-#define BASYX_SUBMODEL_ENUM_KeyElements_H
+#ifndef BASYX_SUBMODEL_ENUMERATIONS_KEYELEMENTS_H
+#define BASYX_SUBMODEL_ENUMERATIONS_KEYELEMENTS_H
#include <string>
@@ -21,6 +21,7 @@
File,
MultiLanguageProperty,
Operation,
+ OperationVariable,
Property,
Range,
ReferenceElement,
@@ -46,4 +47,4 @@
}
}
-#endif
+#endif /* BASYX_SUBMODEL_ENUMERATIONS_KEYELEMENTS_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/KeyType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/KeyType.h
index 2111f59..9918683 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/KeyType.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/KeyType.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_ENUM_KeyType_H
-#define BASYX_SUBMODEL_ENUM_KeyType_H
+#ifndef BASYX_SUBMODEL_ENUMERATIONS_KEYTYPE_H
+#define BASYX_SUBMODEL_ENUMERATIONS_KEYTYPE_H
#include <string>
@@ -26,4 +26,4 @@
}
}
-#endif
+#endif /* BASYX_SUBMODEL_ENUMERATIONS_KEYTYPE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/LevelType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/LevelType.h
index b2231e6..502a9ae 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/LevelType.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/LevelType.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_ENUM_LevelType_H
-#define BASYX_SUBMODEL_ENUM_LevelType_H
+#ifndef BASYX_SUBMODEL_ENUMERATIONS_LEVELTYPE_H
+#define BASYX_SUBMODEL_ENUMERATIONS_LEVELTYPE_H
#include <string>
@@ -25,4 +25,4 @@
}
}
-#endif
+#endif /* BASYX_SUBMODEL_ENUMERATIONS_LEVELTYPE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/LocalKeyType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/LocalKeyType.h
index 1ea373a..929c7f5 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/LocalKeyType.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/LocalKeyType.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_ENUM_LocalKeyType_H
-#define BASYX_SUBMODEL_ENUM_LocalKeyType_H
+#ifndef BASYX_SUBMODEL_ENUMERATIONS_LOCALKEYTYPE_H
+#define BASYX_SUBMODEL_ENUMERATIONS_LOCALKEYTYPE_H
#include <string>
@@ -22,4 +22,4 @@
}
}
-#endif
+#endif /* BASYX_SUBMODEL_ENUMERATIONS_LOCALKEYTYPE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/ModelTypes.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/ModelTypes.h
index 808a567..4d831a4 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/ModelTypes.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/ModelTypes.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_ENUM_ModelTypes_H
-#define BASYX_SUBMODEL_ENUM_ModelTypes_H
+#ifndef BASYX_SUBMODEL_ENUMERATIONS_MODELTYPES_H
+#define BASYX_SUBMODEL_ENUMERATIONS_MODELTYPES_H
#include <string>
@@ -49,4 +49,4 @@
}
}
-#endif
+#endif /* BASYX_SUBMODEL_ENUMERATIONS_MODELTYPES_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/ModelingKind.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/ModelingKind.h
index 4824974..c8f2cdb 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/ModelingKind.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/ModelingKind.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_ENUM_ModelingKind_H
-#define BASYX_SUBMODEL_ENUM_ModelingKind_H
+#ifndef BASYX_SUBMODEL_ENUMERATIONS_MODELINGKIND_H
+#define BASYX_SUBMODEL_ENUMERATIONS_MODELINGKIND_H
#include <string>
@@ -22,4 +22,4 @@
}
}
-#endif
+#endif /* BASYX_SUBMODEL_ENUMERATIONS_MODELINGKIND_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/ReferableElements.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/ReferableElements.h
index 3bffca8..5a37c73 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/ReferableElements.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/ReferableElements.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_ENUM_ReferableElements_H
-#define BASYX_SUBMODEL_ENUM_ReferableElements_H
+#ifndef BASYX_SUBMODEL_ENUMERATIONS_REFERABLEELEMENTS_H
+#define BASYX_SUBMODEL_ENUMERATIONS_REFERABLEELEMENTS_H
#include <string>
@@ -38,4 +38,4 @@
}
}
-#endif
+#endif /* BASYX_SUBMODEL_ENUMERATIONS_REFERABLEELEMENTS_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/BlobType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/BlobType.h
deleted file mode 100644
index e7fde69..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/BlobType.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * BlobType.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_BLOBTYPE_H_
-#define AAS_BLOBTYPE_H_
-
-class BlobType
-{
-public:
- BlobType();
- ~BlobType();
-};
-
-#endif
-
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/IVABElementContainer.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/IVABElementContainer.h
deleted file mode 100644
index dd94ca4..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/IVABElementContainer.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * IVABElementContainer.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_IMPL_HASHMAP_IVABELEMENTCONTAINER_H_
-#define AAS_IMPL_HASHMAP_IVABELEMENTCONTAINER_H_
-
-#include <BaSyx/shared/types.h>
-#include <BaSyx/submodel/api/submodelelement/IDataElement.h>
-#include <BaSyx/submodel/api/submodelelement/operation/IOperation.h>
-
-namespace basyx {
-namespace submodel {
-namespace map {
-
-class IVABElementContainer
-{
-public:
- ~IVABElementContainer() = default;
-
- virtual void addSubModelElement(const std::shared_ptr<ISubmodelElement> & element) = 0;
- virtual basyx::specificMap_t<IDataElement> getDataElements() const = 0;
- virtual basyx::specificMap_t<IOperation> getOperations() const = 0;
-};
-
-}
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/MimeType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/MimeType.h
deleted file mode 100644
index fbe836e..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/MimeType.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * MimeType.h
- *
- * Author: wendel
- */
-
-
-#ifndef AAS_MIMETYPE_H_
-#define AAS_MIMETYPE_H_
-
-class MimeType
-{
-public:
- MimeType();
- ~MimeType();
-};
-
-#endif
-
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/PathType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/PathType.h
deleted file mode 100644
index 3c8f60c..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/PathType.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * PathType.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_PATHTYPE_H_
-#define AAS_PATHTYPE_H_
-
-class PathType
-{
-public:
- PathType();
- ~PathType();
-};
-
-#endif
-
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/SubModel.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/SubModel.h
deleted file mode 100644
index 3ded138..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/SubModel.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * SubModel.h
- *
- * Author: kuhn, wendel
- */
-
-#ifndef BASYX_AAS_SUBMODEL_H_
-#define BASYX_AAS_SUBMODEL_H_
-
-
-/* *********************************************************************************
- * Includes
- * *********************************************************************************/
-
-// BaSyx includes
-#include <BaSyx/submodel/api/ISubModel.h>
-#include <BaSyx/submodel/api/qualifier/IHasSemantics.h>
-#include <BaSyx/submodel/api/submodelelement/operation/IOperation.h>
-#include <BaSyx/submodel/map/qualifier/HasSemantics.h>
-#include <BaSyx/submodel/map/qualifier/Identifiable.h>
-#include <BaSyx/submodel/map/qualifier/HasDataSpecification.h>
-#include <BaSyx/submodel/map/qualifier/qualifiable/Qualifiable.h>
-#include <BaSyx/submodel/map/qualifier/HasKind.h>
-#include <BaSyx/submodel/map/modeltype/ModelType.h>
-
-#include <memory>
-
-
-namespace basyx {
-namespace submodel {
-
-/* *********************************************************************************
- * Sub Model base class
- * *********************************************************************************/
-class SubModel :
- public virtual ISubModel,
- public virtual HasDataSpecification,
- public virtual HasKind,
- public virtual HasSemantics,
- public virtual Identifiable,
- public virtual Qualifiable,
- public virtual ModelType,
- public virtual vab::ElementMap
-{
-public:
- using vab::ElementMap::ElementMap;
-
- SubModel();
- SubModel(const IHasSemantics & semantics, const IIdentifiable & identifiable, const IQualifiable & qualifiable, const IHasDataSpecification & specification, const IHasKind & hasKind);
- SubModel(const ISubModel & submodel);
-
- // Inherited via ISubModel
- virtual void setDataElements(const basyx::specificMap_t<IDataElement> & properties);
- virtual void setOperations(const basyx::specificMap_t<IOperation> & operations);
-
- virtual void addSubModelElement(const std::shared_ptr<ISubmodelElement>& element);
- virtual void addOperation(const IOperation & operation);
- virtual void addDataElement(const IDataElement & dataElement);
-
- virtual basyx::specificMap_t<ISubmodelElement> getSubmodelElements() const override;
- virtual basyx::specificMap_t<IDataElement> getDataElements() const override;
- virtual basyx::specificMap_t<IOperation> getOperations() const override;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/dataspecification/DataSpecification.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/dataspecification/DataSpecification.h
deleted file mode 100644
index 697cc59..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/dataspecification/DataSpecification.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * DataSpecification.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_AAS_DATASPECIFICATION_H_
-#define BASYX_AAS_DATASPECIFICATION_H_
-
-#include <BaSyx/submodel/api/dataspecification/IDataSpecification.h>
-
-#include <BaSyx/submodel/map/qualifier/Identifiable.h>
-#include <BaSyx/submodel/map/qualifier/Referable.h>
-
-namespace basyx {
-namespace submodel {
-
-class DataSpecification
- : public IDataSpecification
- , public virtual submodel::Identifiable
- , public virtual submodel::Referable
- , public virtual vab::ElementMap
-{
-public:
- ~DataSpecification() = default;
-
- DataSpecification(basyx::object obj);
-
- // Inherited via IDataSpecification
- virtual std::shared_ptr<IDataSpecificationContent> getContent() const override;
-
- void setContent(const std::shared_ptr<IDataSpecificationContent> & content);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/dataspecification/DataSpecificationContent.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/dataspecification/DataSpecificationContent.h
deleted file mode 100644
index 2fbfcb2..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/dataspecification/DataSpecificationContent.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * DataSpecificationContent.h
- *
- * Author: wendel
- */
-
-#ifndef DATASPECIFICATIONCONTENT_H_
-#define DATASPECIFICATIONCONTENT_H_
-
-#include <BaSyx/submodel/api/dataspecification/IDataSpecificationContent.h>
-
-namespace basyx {
-namespace submodel {
-
-
-class DataSpecificationContent
- : public IDataSpecificationContent
- , public virtual vab::ElementMap
-{
-public:
- using vab::ElementMap::ElementMap;
-
- DataSpecificationContent() = default;
- DataSpecificationContent(const IDataSpecificationContent & other);
-
- ~DataSpecificationContent() = default;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/dataspecification/DataSpecificationIEC61360.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/dataspecification/DataSpecificationIEC61360.h
deleted file mode 100644
index 9f8a99e..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/dataspecification/DataSpecificationIEC61360.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * DataSpecificationIEC61360.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_AAS_DATASPECIFICATIONIEC61360_H_
-#define BASYX_AAS_DATASPECIFICATIONIEC61360_H_
-
-#include <BaSyx/submodel/api/dataspecification/IDataSpecificationIEC61360.h>
-
-#include <BaSyx/submodel/map/dataspecification/DataSpecificationContent.h>
-
-//#include <BaSyx/submodel/api/dataspecification/datatypes/LevelType.h>
-
-//#include "datatypes/DataTypeIEC61360.hpp"
-//#include "datatypes/LevelType.hpp"
-
-namespace basyx {
-namespace submodel {
-
-class DataSpecificationIEC61360
- : public IDataSpecificationIEC61360
- , public DataSpecificationContent
- , public virtual vab::ElementMap
-{
-public:
- using vab::ElementMap::ElementMap;
- DataSpecificationIEC61360();
- ~DataSpecificationIEC61360() = default;
-public:
-
- // Inherited via IDataSpecificationIEC61360
- virtual std::shared_ptr<ILangStringSet> PreferredName() override;
- virtual std::shared_ptr<ILangStringSet> ShortName() override;
- virtual std::string getUnit() const override;
- virtual std::shared_ptr<submodel::IReference> getUnitId() const override;
- virtual std::string getSourceOfDefinition() const override;
- virtual DataTypeIEC61360 getDataType() const override;
- virtual std::shared_ptr<ILangStringSet> Definition() override;
- virtual std::string getValueFormat() const override;
- virtual basyx::object getValueList() const override;
- virtual std::shared_ptr<submodel::IReference> getValueId() const override;
- virtual LevelType getLevelType() const override;
-
-// void setPreferredName(const std::string & preferredName);
-// void setShortName(const std::string & shortName);
- void setUnit(const std::string & unit);
- void setUnitId(const submodel::IReference & unitId);
- void setSourceOfDefinition(const std::string & sourceOfDefinition);
- void setDataType(const std::string & dataType);
-// void setDefinition(const std::string & definition);
- void setValueFormat(const std::string & valueFormat);
- void setValueList(const basyx::object & valueList);
- void setValueId(const IReference & valueId);
- void setLevelType(const LevelType & levelType);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/identifier/Identifier.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/identifier/Identifier.h
deleted file mode 100644
index cf33ff6..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/identifier/Identifier.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Identifier.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_IMPL_METAMODEL_IDENTIFIER_H_
-#define AAS_IMPL_METAMODEL_IDENTIFIER_H_
-
-#include <BaSyx/submodel/api/identifier/IIdentifier.h>
-
-#include <BaSyx/shared/types.h>
-#include <BaSyx/shared/object.h>
-
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace submodel {
-
-class Identifier :
- public virtual IIdentifier,
- public virtual vab::ElementMap
-{
-public:
- ~Identifier() = default;
-
- Identifier();
- Identifier(const std::string & id, const std::string & idType);
- Identifier(basyx::object object);
- Identifier(const std::shared_ptr<IIdentifier> & other);
- Identifier(const IIdentifier & other);
-
- // Inherited via IIdentifier
- virtual std::string getIdType() const override;
- virtual std::string getId() const override;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/identifier/IdentifierType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/identifier/IdentifierType.h
deleted file mode 100644
index 62f0286..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/identifier/IdentifierType.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * IdentifierType.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_IMPL_METAMODEL_IDENTIFIERTYPE_H_
-#define AAS_IMPL_METAMODEL_IDENTIFIERTYPE_H_
-
-namespace basyx {
-namespace submodel {
-
-struct IdentifierType
-{
- static constexpr char IRDI[] = "IRDI";
- static constexpr char URI[] = "URI";
- static constexpr char Custom[] = "Custom";
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/modeltype/ModelType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/modeltype/ModelType.h
deleted file mode 100644
index 41bf674..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/modeltype/ModelType.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Constraint.h
- *
- * Author: wendel
- */
-
-#ifndef SUBMODEL_SUBMODEL_MAP_MODELTYPE_MODELTYPE_H
-#define SUBMODEL_SUBMODEL_MAP_MODELTYPE_MODELTYPE_H
-
-
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace submodel {
-
-class ModelType : public virtual vab::ElementMap {
-public:
- struct Path {
- static constexpr char ModelType[] = "modelType";
- static constexpr char Name[] = "name";
- };
-public:
- ModelType();
- ModelType(const std::string & type);
-// explicit ModelType(basyx::object object);
-
- ~ModelType() = default;
-};
-
-}
-}
-
-#endif /* SUBMODEL_SUBMODEL_MAP_MODELTYPE_MODELTYPE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/parts/ConceptDescription.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/parts/ConceptDescription.h
deleted file mode 100644
index 95bcf9c..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/parts/ConceptDescription.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * ConceptDictionary.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_IMPL_METAMODEL_HASHMAP_PARTS_CONCEPTDESCRIPTION_H_
-#define AAS_IMPL_METAMODEL_HASHMAP_PARTS_CONCEPTDESCRIPTION_H_
-
-#include <BaSyx/submodel/api/parts/IConceptDescription.h>
-#include <BaSyx/submodel/api/dataspecification/IDataSpecificationIEC61360.h>
-
-#include <BaSyx/submodel/map/qualifier/HasDataSpecification.h>
-#include <BaSyx/submodel/map/qualifier/Identifiable.h>
-#include <BaSyx/submodel/map/modeltype/ModelType.h>
-
-namespace basyx {
-namespace submodel {
-
-class ConceptDescription
- : public virtual IConceptDescription
- , public virtual submodel::HasDataSpecification
- , public virtual submodel::Identifiable
- , public virtual submodel::ModelType
- , public virtual vab::ElementMap
-{
-public:
- ~ConceptDescription() = default;
-
- ConceptDescription(basyx::object obj);
- ConceptDescription();
- ConceptDescription(IConceptDescription & other);
-
- void addDataSpecification(const IDataSpecificationIEC61360 & dataSpec) {};
-
- // Inherited via IConceptDescription
- virtual basyx::specificCollection_t<submodel::IReference> getIsCaseOf() const override;
-
- virtual void setIsCaseOf(const basyx::specificCollection_t<submodel::IReference>& references) override;
-
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/AdministrativeInformation.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/AdministrativeInformation.h
deleted file mode 100644
index c53b81f..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/AdministrativeInformation.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * AdministrativeInformation.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_IMPL_METAMODEL_ADMINISTRATIVEINFORMATION_H_
-#define AAS_IMPL_METAMODEL_ADMINISTRATIVEINFORMATION_H_
-
-#include <BaSyx/submodel/api/qualifier/IAdministrativeInformation.h>
-#include <BaSyx/submodel/map/qualifier/HasDataSpecification.h>
-
-#include <BaSyx/shared/object.h>
-
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace submodel {
-
-class AdministrativeInformation :
- public virtual IAdministrativeInformation,
- public virtual HasDataSpecification,
- public virtual vab::ElementMap
-{
-public:
- ~AdministrativeInformation() = default;
-
- AdministrativeInformation();
- AdministrativeInformation(const std::string & version, const std::string & revision);
- AdministrativeInformation(basyx::object object);
- AdministrativeInformation(const IAdministrativeInformation & other);
-
- void setVersion(const std::string & version);
- void setRevision(const std::string & revision);
-
- virtual std::string getVersion() const override;
- virtual std::string getRevision() const override;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/Description.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/Description.h
deleted file mode 100644
index e79e0f2..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/Description.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Description.h
- *
- * Author: wendel
- */
-
-#ifndef IMPL_METAMODEL_QUALIFIER_DESCRIPTION_H_
-#define IMPL_METAMODEL_QUALIFIER_DESCRIPTION_H_
-
-#include <BaSyx/vab/ElementMap.h>
-
-#include <BaSyx/shared/types.h>
-#include <BaSyx/shared/object.h>
-
-#include <string>
-
-namespace basyx {
-namespace submodel {
-
-class Description : public vab::ElementMap
-{
-public:
- struct Path {
- static constexpr char Language[] = "language";
- static constexpr char Text[] = "text";
- };
-public:
- ~Description() = default;
-
- Description();
- Description(const std::string & language, const std::string & text);
- Description(basyx::object object);
-
- std::string getLanguage() const;
- std::string getText() const;
-
- friend bool operator==(const Description & left, const Description & right);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/HasDataSpecification.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/HasDataSpecification.h
deleted file mode 100644
index 4f792eb..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/HasDataSpecification.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * HasDataSpecification.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_HASDATASPECIFICATION_H_
-#define BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_HASDATASPECIFICATION_H_
-
-#include <BaSyx/submodel/api/qualifier/IHasDataSpecification.h>
-#include <BaSyx/submodel/api/reference/IReference.h>
-
-#include <BaSyx/shared/object.h>
-
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace submodel {
-
-class HasDataSpecification :
- public virtual IHasDataSpecification,
- public virtual vab::ElementMap
-{
-public:
- HasDataSpecification();
- HasDataSpecification(basyx::object & obj);
- HasDataSpecification(const basyx::specificCollection_t<IReference> & refs);
- HasDataSpecification(const IHasDataSpecification & hasDataSpecification);
-
- ~HasDataSpecification() = default;
-
- // Inherited via IHasDataSpecification
- virtual basyx::specificCollection_t<IReference> getDataSpecificationReferences() const override;
-
- void setDataSpecificationReferences(const basyx::specificCollection_t<IReference> & references);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/HasKind.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/HasKind.h
deleted file mode 100644
index 2aa0d4f..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/HasKind.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * HasKind.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_KIND_HASKIND_H_
-#define BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_KIND_HASKIND_H_
-
-#include <BaSyx/submodel/api/qualifier/IHasKind.h>
-
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace submodel {
-
-class HasKind :
- public virtual IHasKind,
- public virtual basyx::vab::ElementMap
-{
-public:
- // constructors
- HasKind(Kind kind = Kind::Instance);
- HasKind(basyx::object object);
- HasKind(const IHasKind & other);
-
- void Init(Kind kind = Kind::Instance);
-
- ~HasKind() = default;
-
- // Inherited via IHasKind
- virtual Kind getHasKindReference() const override;
-
- // not inherited
- void setHasKindReference(Kind kind);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/HasSemantics.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/HasSemantics.h
deleted file mode 100644
index 1a0eb71..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/HasSemantics.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * HasSemantics.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_HASSEMANTICS_H_
-#define BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_HASSEMANTICS_H_
-
-#include <BaSyx/submodel/api/qualifier/IHasSemantics.h>
-#include <BaSyx/submodel/api/reference/IReference.h>
-
-#include <BaSyx/shared/object.h>
-
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace submodel {
-
-
-class HasSemantics :
- public virtual IHasSemantics,
- public virtual vab::ElementMap
-{
-public:
- ~HasSemantics() = default;
-
- HasSemantics();
- HasSemantics(basyx::object object);
- HasSemantics(const std::shared_ptr<IReference> & reference);
- HasSemantics(const IHasSemantics & semantics);
-
- void setSemanticId(const std::shared_ptr<IReference> & reference);
- void setSemanticId(const IReference & reference);
-
- // Inherited via IHasSemantics
- virtual std::shared_ptr<IReference> getSemanticId() const override;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/Identifiable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/Identifiable.h
deleted file mode 100644
index eb400d7..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/Identifiable.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Identifiable.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_IDENTIFIABLE_H_
-#define BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_IDENTIFIABLE_H_
-
-#include <BaSyx/shared/object.h>
-
-#include <BaSyx/submodel/api/qualifier/IIdentifiable.h>
-#include <BaSyx/submodel/map/qualifier/Referable.h>
-
-namespace basyx {
-namespace submodel {
-
-class Identifiable :
- public virtual IIdentifiable,
- public virtual Referable,
- public virtual vab::ElementMap
-{
-public:
-
-public:
- ~Identifiable() = default;
-
- // constructors
- Identifiable();
- Identifiable(const IIdentifiable & identifiable);
- Identifiable(const basyx::object & obj);
- Identifiable(const IIdentifier & identifier, const IAdministrativeInformation & administration);
- Identifiable(
- const std::string & version,
- const std::string & revision,
- const std::string & idShort,
- const std::string & category,
- const Description & description,
- const std::string & idType,
- const std::string & id);
-
- // Inherited via IIdentifiable
- virtual std::shared_ptr<IAdministrativeInformation> getAdministration() const override;
- virtual std::shared_ptr<IIdentifier> getIdentification() const override;
-
- // not inherited
- void setAdministration(const IAdministrativeInformation & administration);
- void setIdentification(const IIdentifier & identification);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/Referable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/Referable.h
deleted file mode 100644
index 24b62af..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/Referable.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Referable.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_REFERABLE_H_
-#define BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_REFERABLE_H_
-
-#include <BaSyx/submodel/api/qualifier/IReferable.h>
-
-#include <BaSyx/shared/object.h>
-
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace submodel {
-
-class Referable :
- public virtual IReferable,
- public virtual vab::ElementMap
-{
-public:
- ~Referable() = default;
-
- // Constructors
- Referable();
- Referable(basyx::object & obj);
- Referable(const std::string & shortID, const std::string & category, const Description & description);
- Referable(const IReferable & other);
-
- // Inherited via IReferable
- virtual std::string getIdShort() const override;
- virtual std::string getCategory() const override;
- virtual Description getDescription() const override;
- virtual std::shared_ptr<IReference> getParent() const override;
-
- // not inherited
- void setIdShort(const std::string & shortID);
- void setCategory(const std::string & category);
- void setDescription(const Description & description);
- void setParent(const IReference & parentReference);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/Constraint.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/Constraint.h
deleted file mode 100644
index 431aabb..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/Constraint.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Constraint.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_QUALIFIABLE_CONSTRAINT_H_
-#define BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_QUALIFIABLE_CONSTRAINT_H_
-
-#include <BaSyx/submodel/api/qualifier/qualifiable/IConstraint.h>
-
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace submodel {
-
-class Constraint :
- public virtual IConstraint,
- public virtual vab::ElementMap
-{
-public:
- Constraint();
- Constraint(basyx::object object);
- Constraint(const IConstraint & constraint);
-
- ~Constraint() = default;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/Formula.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/Formula.h
deleted file mode 100644
index d859eba..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/Formula.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Formula.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_QUALIFIABLE_FORMULA_H_
-#define BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_QUALIFIABLE_FORMULA_H_
-
-#include <BaSyx/submodel/api/qualifier/qualifiable/IFormula.h>
-#include <BaSyx/submodel/map/qualifier/qualifiable/Constraint.h>
-
-namespace basyx {
-namespace submodel {
-
-class Formula
- : public virtual Constraint
- , public IFormula
- , public virtual vab::ElementMap
-{
-public:
- ~Formula() = default;
-
- // constructors
- Formula();
- Formula(const basyx::specificCollection_t<IReference> & dependsOn);
-
- // Inherited via IFormula
- virtual basyx::specificCollection_t<IReference> getDependsOn() const override;
-
- // not inherited
- void setDependsOn(const basyx::specificCollection_t<IReference> & dependsOn);
-
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/Qualifiable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/Qualifiable.h
deleted file mode 100644
index 2e9cfe3..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/Qualifiable.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Qualifiable.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_QUALIFIABLE_QUALIFIABLE_H_
-#define BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_QUALIFIABLE_QUALIFIABLE_H_
-
-#include <BaSyx/submodel/api/qualifier/qualifiable/IQualifiable.h>
-
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace submodel {
-
-class Qualifiable :
- public virtual IQualifiable,
- public virtual vab::ElementMap
-{
-public:
- ~Qualifiable() = default;
-
- // constructors
- Qualifiable();
- Qualifiable(const std::shared_ptr<IQualifiable> & other);
- Qualifiable(const IQualifiable & other);
- Qualifiable(basyx::object object);
- Qualifiable(const std::shared_ptr<IConstraint> & constraint);
- Qualifiable(const basyx::specificCollection_t<IConstraint> & constraints);
-
- // Inherited via IQualifiable
- virtual basyx::specificCollection_t<IConstraint> getQualifier() const override;
-
- // not inherited
- void setQualifier(const basyx::specificCollection_t<IConstraint> & qualifiers);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/Qualifier.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/Qualifier.h
deleted file mode 100644
index 4b17eeb..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/Qualifier.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Qualifier.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_QUALIFIABLE_QUALIFIER_H_
-#define BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_QUALIFIABLE_QUALIFIER_H_
-
-#include <BaSyx/submodel/map/qualifier/qualifiable/Constraint.h>
-#include <BaSyx/submodel/api/qualifier/qualifiable/IQualifier.h>
-#include <BaSyx/submodel/map/qualifier/HasSemantics.h>
-#include <BaSyx/shared/object.h>
-
-namespace basyx {
-namespace submodel {
-
-class Qualifier
- : public Constraint
- , public virtual IQualifier
- , public virtual HasSemantics
- , public virtual basyx::vab::ElementMap
-{
-public:
- ~Qualifier() = default;
-
- // constructors
- Qualifier();
- Qualifier(
- const std::string & qualifierType,
- const basyx::object & qualifierValue,
- const IReference & valueId);
-
- // Inherited via IQualifier
- virtual std::string getQualifierType() const override;
- virtual basyx::object getQualifierValue() const override;
- virtual std::shared_ptr<IReference> getQualifierValueId() const override;
-
- // not inherited
- void setQualifierType(const std::string & qualifierType);
- void setQualifierValue(const basyx::object & qualifierValue);
- void setQualifierValueId(const IReference & valueId);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/QualifierType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/QualifierType.h
deleted file mode 100644
index 7bc80c8..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/QualifierType.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * QualifierType.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_QUALIFIABLE_QUALIFIERTYPE_H_
-#define BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_QUALIFIABLE_QUALIFIERTYPE_H_
-
-namespace basyx {
-namespace submodel {
-
-class QualifierType
-{
-public:
- ~QualifierType() = default;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/reference/Key.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/reference/Key.h
deleted file mode 100644
index 8f4e129..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/reference/Key.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Key.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_IMPL_METAMODEL_HASHMAP_REFERENCE_KEY_H_
-#define AAS_IMPL_METAMODEL_HASHMAP_REFERENCE_KEY_H_
-
-
-#include <BaSyx/submodel/api/reference/IKey.h>
-
-#include <BaSyx/shared/object.h>
-
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace submodel {
-
-class Key
- : public IKey
- , public virtual vab::ElementMap
-{
-public:
- struct KeyType {
- static constexpr char IRDI[] = "IRDI";
- };
-
- struct KeyElements {
- static constexpr char ConceptDictionary[] = "ConceptDictionary";
- };
-public:
- virtual ~Key() = default;
-
- //constructor
- Key(const std::string & type, const bool & local, const std::string & value, const std::string & idType);
- Key(basyx::object obj);
-
- // Inherited via IKey
- virtual std::string getType() const override;
- virtual bool isLocal() const override;
- virtual std::string getValue() const override;
- virtual std::string getidType() const override;
-
- // not inherited
- void setType(const std::string & type);
- void setLocal(const bool & local);
- void setValue(const std::string & value);
- void setIdType(const std::string & idType);
-
- friend bool operator==(const IKey & left, const IKey & right);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/reference/Reference.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/reference/Reference.h
deleted file mode 100644
index b3cf36d..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/reference/Reference.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Reference.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_IMPL_METAMODEL_HASHMAP_REFERENCE_H_
-#define AAS_IMPL_METAMODEL_HASHMAP_REFERENCE_H_
-
-#include <BaSyx/submodel/api/reference/IReference.h>
-
-#include <BaSyx/submodel/map/reference/Key.h>
-#include <BaSyx/submodel/api/qualifier/IIdentifiable.h>
-
-#include <BaSyx/shared/object.h>
-
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace submodel {
-
-class Reference :
- public IReference,
- public vab::ElementMap
-{
-public:
- using vab::ElementMap::ElementMap;
-
- virtual ~Reference() = default;
-
- Reference();
- Reference(const basyx::specificCollection_t<IKey> & keys);
- Reference(const std::initializer_list<Key> keys);
- Reference(const IReference & reference);
-
- // Inherited via IReference
- virtual const basyx::specificCollection_t<IKey> getKeys() const override;
- virtual void setKeys(const basyx::specificCollection_t<IKey> & keys) override;
-public:
- static Reference FromIdentifiable(const std::string & keyElementType, bool local, const IIdentifiable & identifiable);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/DataElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/DataElement.h
deleted file mode 100644
index 0d0e40f..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/DataElement.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * DataElement.h
- *
- * Author: wendel
- */
-
-#ifndef IMPL_METAMODEL_MAP_AAS_SUBMODELELEMENT_DATAELEMENT_H_
-#define IMPL_METAMODEL_MAP_AAS_SUBMODELELEMENT_DATAELEMENT_H_
-
-#include <BaSyx/submodel/map/submodelelement/SubmodelElement.h>
-#include <BaSyx/submodel/api/submodelelement/IDataElement.h>
-
-namespace basyx {
-namespace submodel {
-
-class DataElement :
- public virtual vab::ElementMap,
- public virtual SubmodelElement,
- public virtual IDataElement
-{
-public:
- ~DataElement() = default;
-
- // constructors
- DataElement();
- DataElement(basyx::object object);
- DataElement(const IDataElement & other);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/ReferenceElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/ReferenceElement.h
deleted file mode 100644
index 32c3a5e..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/ReferenceElement.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * ReferenceElement.h
- *
- * Author: wendel
- */
-
-#ifndef IMPL_METAMODEL_MAP_AAS_SUBMODELELEMENT_REFERENCEELEMENT_H_
-#define IMPL_METAMODEL_MAP_AAS_SUBMODELELEMENT_REFERENCEELEMENT_H_
-
-#include <BaSyx/submodel/map/submodelelement/DataElement.h>
-#include <BaSyx/submodel/api/submodelelement/IReferenceElement.h>
-
-namespace basyx {
-namespace submodel {
-
-class ReferenceElement :
- public virtual vab::ElementMap,
- public DataElement,
- public IReferenceElement
-{
-public:
- ~ReferenceElement() = default;
-
- // construtors
- ReferenceElement();
- ReferenceElement(const IReference & reference);
- ReferenceElement(const basyx::object & map);
-
- // Inherited via IReferenceElement
- virtual void setValue(const IReference & ref);
- virtual std::shared_ptr<IReference> getValue() const override;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/RelationshipElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/RelationshipElement.h
deleted file mode 100644
index cc8e4b5..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/RelationshipElement.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * RelationshipElement.h
- *
- * Author: wendel
- */
-
-#ifndef IMPL_METAMODEL_MAP_AAS_SUBMODELELEMENT_RELATIONSHIPELEMENT_H_
-#define IMPL_METAMODEL_MAP_AAS_SUBMODELELEMENT_RELATIONSHIPELEMENT_H_
-
-#include <BaSyx/submodel/api/submodelelement/ISubmodelElement.h>
-#include <BaSyx/submodel/api/submodelelement/IRelationshipElement.h>
-#include <BaSyx/submodel/api/reference/IReference.h>
-#include <BaSyx/submodel/map/submodelelement/SubmodelElement.h>
-
-namespace basyx {
-namespace submodel {
-
-class RelationshipElement :
- public virtual vab::ElementMap,
- public virtual SubmodelElement,
- public virtual IRelationshipElement
-{
-public:
- ~RelationshipElement() = default;
-
- //constructors
- RelationshipElement();
- RelationshipElement(const IReference & first, const IReference & second);
-
- // Inherited via IRelationshipElement
- virtual void setFirst(const IReference & first) override;
- virtual std::shared_ptr<IReference> getFirst() const override;
- virtual void setSecond(const IReference & second) override;
- virtual std::shared_ptr<IReference> getSecond() const override;
-};
-
-}
-}
-
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/SubmodelElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/SubmodelElement.h
deleted file mode 100644
index 82d4889..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/SubmodelElement.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * SubmodelElement.h
- *
- * Author: wendel
- */
-
-#ifndef IMPL_METAMODEL_MAP_AAS_SUBMODELELEMENT_SUBMODELELEMENT_H_
-#define IMPL_METAMODEL_MAP_AAS_SUBMODELELEMENT_SUBMODELELEMENT_H_
-
-#include <BaSyx/submodel/api/submodelelement/ISubmodelElement.h>
-
-#include <BaSyx/submodel/map/qualifier/HasKind.h>
-#include <BaSyx/submodel/map/qualifier/HasDataSpecification.h>
-#include <BaSyx/submodel/map/qualifier/HasSemantics.h>
-#include <BaSyx/submodel/map/qualifier/Referable.h>
-#include <BaSyx/submodel/map/qualifier/qualifiable/Qualifiable.h>
-#include <BaSyx/submodel/map/modeltype/ModelType.h>
-
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace submodel {
-
-class SubmodelElement :
- public virtual vab::ElementMap,
- public virtual ModelType,
- public virtual HasDataSpecification,
- public virtual HasKind,
- public virtual HasSemantics,
- public virtual Qualifiable,
- public virtual Referable,
- public virtual ISubmodelElement
-{
-public:
- ~SubmodelElement() = default;
-
- // constructors
- SubmodelElement();
-
- using vab::ElementMap::ElementMap;
-
- /**
- * Constructs an SubmodelElement object from a map given that the map contains all required elements.
- *
- * @param submodelElementMap the map representig the submodel.
- */
-// SubmodelElement(basyx::object object);
-
- SubmodelElement(const ISubmodelElement & abstractSubmodelElement);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/SubmodelElementCollection.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/SubmodelElementCollection.h
deleted file mode 100644
index f27ceff..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/SubmodelElementCollection.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * SubmodelElementCollection.h
- *
- * Author: wendel
- */
-
-#ifndef IMPL_METAMODEL_MAP_AAS_SUBMODELELEMENT_SUBMODELELEMENTCOLLECTION_H_
-#define IMPL_METAMODEL_MAP_AAS_SUBMODELELEMENT_SUBMODELELEMENTCOLLECTION_H_
-
-#include <BaSyx/submodel/map/submodelelement/SubmodelElement.h>
-#include <BaSyx/submodel/api/submodelelement/ISubmodelElementCollection.h>
-
-namespace basyx {
-namespace submodel {
-
-class SubmodelElementCollection :
- public virtual vab::ElementMap,
- public SubmodelElement,
- public ISubmodelElementCollection
-{
-private:
- virtual void setOrdered(const bool & value);
- virtual void setAllowDuplicates(const bool & value);
-public:
- ~SubmodelElementCollection() = default;
-
- // constructors
- /**
- * Default constructor, sets ordered and allowDuplicates to false.
- */
- SubmodelElementCollection();
-
- /**
- * @param value
- * Submodel element contained in the collection
- * @param ordered
- * If ordered=false then the elements in the property collection are
- * not ordered. If ordered=true then the elements in the collection
- * are ordered.
- * @param allowDuplicates
- * If allowDuplicates=true then it is allowed that the collection
- * contains the same element several times
- */
- SubmodelElementCollection(const basyx::specificCollection_t<ISubmodelElement> & value, const bool ordered, const bool allowDuplicates);
-
- virtual void setValue(const basyx::specificCollection_t<ISubmodelElement> & value);
- virtual void setElements(const basyx::specificMap_t<ISubmodelElement> & value);
-
- virtual basyx::specificCollection_t<ISubmodelElement> getValue() const override;
- virtual bool isOrdered() const override;
- virtual bool isAllowDuplicates() const override;
- virtual basyx::specificMap_t<ISubmodelElement> getElements() const override;
-
- virtual void addSubmodelElement(const ISubmodelElement & element);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/entity/Entity.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/entity/Entity.h
deleted file mode 100644
index e2857d7..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/entity/Entity.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef BASYX_METAMODEL_MAP_ENTITY_H_
-#define BASYX_METAMODEL_MAP_ENTITY_H_
-
-#include <BaSyx/submodel/api/submodelelement/entity/IEntity.h>
-#include <BaSyx/submodel/map/submodelelement/SubmodelElement.h>
-
-namespace basyx {
-namespace submodel {
-
-
-class Entity
- : public virtual IEntity
- , public virtual SubmodelElement
-{
-public:
- Entity(EntityType entityType = EntityType::SelfManagedEntity);
- Entity(basyx::object object);
- Entity(const IEntity & entity);
-
- virtual ~Entity() = default;
-public:
- virtual basyx::specificCollection_t<ISubmodelElement> getStatements() override;
-
- virtual EntityType getEntityType() const override;
-
- virtual std::shared_ptr<IReference> getAsset() const override;
-};
-
-
-}
-}
-
-
-
-
-
-
-
-#endif
-
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/langstring/LangStringSet.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/langstring/LangStringSet.h
deleted file mode 100644
index 9bf839a..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/langstring/LangStringSet.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef _LANGSTRINGSET_H
-#define _LANGSTRINGSET_H
-
-#include <BaSyx/submodel/api/submodelelement/langstring/ILangStringSet.h>
-
-#include <BaSyx/shared/object.h>
-
-#include <BaSyx/vab/ElementMap.h>
-
-#include <string>
-#include <initializer_list>
-
-namespace basyx {
-namespace submodel {
-
-class LangStringSet
- : public ILangStringSet
- , public virtual vab::ElementMap
-{
-public:
- using langCodeSet_t = const std::vector<std::reference_wrapper<const std::string>>;
-public:
- using vab::ElementMap::ElementMap;
-
- LangStringSet();
- LangStringSet(std::initializer_list<std::pair<std::string, std::string>> il);
-
- langCodeSet_t getLanguageCodes() const;
-
- const std::string & getLangString(const std::string & languageCode) const;
- void addLangString(const std::string & languageCode, const std::string & langString);
-};
-
-}
-}
-
-#endif /* _LANGSTRINGSET_H */
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/operation/Operation.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/operation/Operation.h
deleted file mode 100644
index 9b76cec..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/operation/Operation.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Operation.h
- *
- * Author: wendel
- */
-
-#ifndef SUBMODEL_METAMODEL_SUBMODELEMENT_OPERATION_OPERATION_H_
-#define SUBMODEL_METAMODEL_SUBMODELEMENT_OPERATION_OPERATION_H_
-
-#include <BaSyx/shared/object.h>
-#include <BaSyx/shared/types.h>
-
-#include <BaSyx/submodel/api/submodelelement/operation/IOperationVariable.h>
-#include <BaSyx/submodel/api/submodelelement/operation/IOperation.h>
-#include <BaSyx/submodel/map/submodelelement/SubmodelElement.h>
-#include <BaSyx/submodel/map/submodelelement/operation/OperationVariable.h>
-
-
-namespace basyx {
-namespace submodel {
-
-class Operation :
- public virtual SubmodelElement,
- public virtual IOperation
-{
-public:
- using Path = IOperation::Path;
-public:
- ~Operation() = default;
-
- // constructors
- Operation();
- Operation(const IOperation & other);
- Operation(const basyx::object & obj);
-
- // Inherited via IOperation
- virtual basyx::specificCollection_t<IOperationVariable> getParameterTypes() const override;
- virtual std::shared_ptr<IOperationVariable> getReturnType() const override;
- virtual basyx::object getInvocable() const override;
-
- // not inherited
- void setParameterTypes(const basyx::specificCollection_t<IOperationVariable> & parameterTypes);
- void setReturnTypes(const std::shared_ptr<IOperationVariable> & returnTypes);
- void setInvocable(basyx::object invocable);
-
- // helper methods
- template<typename T>
- void addParameter(const std::string & name)
- {
- OperationVariable op_var;
- op_var.setIdShort(name);
- op_var.setType(util::to_string<basyx::type::basyx_type<T>::value_type>());
- this->map.getProperty(Path::Input).insert(op_var.getMap());
- };
-
- template<typename T>
- void setReturnType(const std::string & name)
- {
- OperationVariable ret_var;
- ret_var.setIdShort(name);
- ret_var.setType(util::to_string<basyx::type::basyx_type<T>::value_type>());
- this->map.insertKey(Path::Output, ret_var.getMap(), true);
- };
-
- virtual basyx::object invoke(basyx::object & parameters) const override;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/operation/OperationVariable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/operation/OperationVariable.h
deleted file mode 100644
index bf36317..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/operation/OperationVariable.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * ModelType.h
- *
- * Author: wendel
- */
-
-#ifndef SUBMODEL_METAMODEL_SUBMODELEMENT_OPERATION_OPERATIONVARIABLE_H_
-#define SUBMODEL_METAMODEL_SUBMODELEMENT_OPERATION_OPERATIONVARIABLE_H_
-
-#include <BaSyx/submodel/api/submodelelement/operation/IOperationVariable.h>
-#include <BaSyx/submodel/map/submodelelement/SubmodelElement.h>
-
-#include <BaSyx/shared/object.h>
-
-namespace basyx {
-namespace submodel {
-
-class OperationVariable :
- public virtual SubmodelElement,
- public virtual IOperationVariable
-{
-public:
- using Path = IOperationVariable::Path;
-public:
- ~OperationVariable() = default;
-
- // constructors
- OperationVariable();
- OperationVariable(basyx::object object);
-
- // Inherited via IOperationVariable
- virtual std::shared_ptr<ISubmodelElement> getValue() const override;
- virtual std::string getType() const override;
-
- // not inherited
- void setValue(const SubmodelElement & value);
-
- void setValue(const ISubmodelElement & value);
- void setType(const std::string & string);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/Blob.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/Blob.h
deleted file mode 100644
index 33def54..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/Blob.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef SUBMODEL_METAMODEL_SUBMODELEMENT_BLOB_H_
-#define SUBMODEL_METAMODEL_SUBMODELEMENT_BLOB_H_
-
-#include <BaSyx/shared/object.h>
-#include <BaSyx/shared/types.h>
-
-#include <BaSyx/submodel/api/submodelelement/property/blob/IBlob.h>
-#include <BaSyx/submodel/map/submodelelement/SubmodelElement.h>
-#include <BaSyx/submodel/map/submodelelement/DataElement.h>
-
-
-namespace basyx {
-namespace submodel {
-
-class Blob :
- public virtual IBlob,
- public virtual ModelType,
- public virtual DataElement,
- public virtual vab::ElementMap
-{
-public:
- using Path = IBlob::Path;
-public:
- Blob() : ModelType{Path::ModelType}
- {
- map.insertKey(Path::Value, basyx::object::make_null());
- };
-
- Blob(const IBlob & other)
- : ModelType{Path::ModelType}
- , vab::ElementMap{}
- {
- }
-
- virtual const std::string & getValue() const override;
- virtual const std::string & getMimeType() const override;
-
- void setValue(const std::string & bytes);
- void setValue(const char * c, std::size_t length);
-
- void setMimeType(const std::string & mimeType);
-};
-
-}
-}
-
-#endif
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/File.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/File.h
deleted file mode 100644
index 2d09b52..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/File.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef SUBMODEL_METAMODEL_SUBMODELEMENT_PROPERTY_H_
-#define SUBMODEL_METAMODEL_SUBMODELEMENT_PROPERTY_H_
-
-#include <BaSyx/shared/object.h>
-#include <BaSyx/shared/types.h>
-
-#include <BaSyx/submodel/api/submodelelement/property/file/IFile.h>
-#include <BaSyx/submodel/api/submodelelement/property/ISingleProperty.h>
-#include <BaSyx/submodel/map/submodelelement/SubmodelElement.h>
-#include <BaSyx/submodel/map/submodelelement/DataElement.h>
-
-
-namespace basyx {
-namespace submodel {
-
-class File :
- public virtual IFile,
- public virtual ModelType,
- public virtual DataElement,
- public virtual vab::ElementMap
-{
-public:
- virtual const std::string & getValue() const override;
- virtual const std::string & getMimeType() const override;
-
- void setValue(const std::string & bytes);
- void setMimeType(const std::string & mimeType);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/Property.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/Property.h
deleted file mode 100644
index eb7d256..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/Property.h
+++ /dev/null
@@ -1,105 +0,0 @@
-#ifndef SUBMODEL_METAMODEL_SUBMODELEMENT_PROPERTY_H_
-#define SUBMODEL_METAMODEL_SUBMODELEMENT_PROPERTY_H_
-
-#include <BaSyx/shared/object.h>
-#include <BaSyx/shared/types.h>
-
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-#include <BaSyx/submodel/api/submodelelement/property/ISingleProperty.h>
-#include <BaSyx/submodel/map/submodelelement/SubmodelElement.h>
-#include <BaSyx/submodel/map/submodelelement/DataElement.h>
-
-
-namespace basyx {
-namespace submodel {
-
-template<typename T>
-class Property :
- public virtual ISingleProperty,
- public virtual DataElement,
- public virtual vab::ElementMap
-{
-public:
- using Path = IProperty::Path;
-public:
- using vab::ElementMap::ElementMap;
-
- Property() : ModelType{Path::ModelType}
- {
- map.insertKey(Path::Value, basyx::object::make_null());
- map.insertKey(Path::ValueId, basyx::object::make_null());
- };
-
- Property(const IProperty & other) :
- ModelType{Path::ModelType},
- DataElement{other}
- {
- //this->setValue(other.getValue());
- this->setValueId(other.getValueId());
- }
-
- T & getValue()
- {
- return map.getProperty(Path::Value).Get<T&>();
- };
-
- void setValue(const T & t)
- {
- map.insertKey(Path::Value, t, true);
- //map.insertKey(Path::ValueType, util::from_string<basyx::type::basyx_type<T>::value_type>());
- };
-
- basyx::object get()
- {
- return map.getProperty(Path::Value);
- };
-
- void set(const basyx::object & object)
- {
- if (!object.InstanceOf<T>())
- {
- map.insertKey(Path::Value, basyx::object::make_null(), true);
- //map.insertKey(Path::ValueType, util::from_string<basyx::type::valueType::Null>(), true);
- }
- else
- {
- map.insertKey(Path::Value, object, true);
- //map.insertKey(Path::ValueType, util::from_string<basyx::type::basyx_type<T>::value_type>(), true);
- }
- };
-
- const T & getValue() const
- {
- return map.getProperty(Path::Value).Get<T&>();
- };
-
- // Inherited via ISingleProperty
- virtual PropertyType getPropertyType() const override
- {
- return PropertyType();
- }
-
- virtual void setValueId(const std::string & valueId) override
- {
- }
-
- virtual std::string getValueId() const override
- {
- return std::string();
- }
-
- virtual basyx::object get() const override
- {
- return basyx::object();
- }
-
- virtual std::string getValueType() const override
- {
- return std::string();
- }
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/valuetypedef/PropertyValueTypeDef.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/valuetypedef/PropertyValueTypeDef.h
deleted file mode 100644
index 642201a..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/valuetypedef/PropertyValueTypeDef.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * PropertyValueTypeDef.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_IMPL_SUBMODELELEMENT_PROPERTY_VALUETYPEDEF_PROPERTYVALUETYPEDEF_H_
-#define AAS_IMPL_SUBMODELELEMENT_PROPERTY_VALUETYPEDEF_PROPERTYVALUETYPEDEF_H_
-
-namespace basyx {
-namespace submodel {
-namespace impl {
-namespace metamodel {
-
-namespace PropertyValueTypeDef {
- static constexpr char Double[] = "double";
- static constexpr char Float[] = "float";
- static constexpr char Integer[] = "int";
- static constexpr char String[] = "string";
- static constexpr char Boolean[] = "boolean";
- static constexpr char Map[] = "map";
- static constexpr char Collection[] = "collection";
- static constexpr char Void[] = "void";
- static constexpr char Null[] = "null";
- static constexpr char Container[] = "container";
-}
-
-namespace PropertyValueTypeIdentifier {
- static constexpr char TYPE_NAME[] = "name";
- static constexpr char TYPE_OBJECT[] = "dataObjectType";
-}
-
-}
-}
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/valuetypedef/PropertyValueTypeDefHelper.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/valuetypedef/PropertyValueTypeDefHelper.h
deleted file mode 100644
index 0263161..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/valuetypedef/PropertyValueTypeDefHelper.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * PropertyValueTypeDefHelper.h
- *
- * Author: wendel
- */
-
-#ifndef AAS_IMPL_SUBMODELELEMENT_PROPERTY_VALUETYPEDEF_PROPERTYVALUETYPEDEFHELPER_H_
-#define AAS_IMPL_SUBMODELELEMENT_PROPERTY_VALUETYPEDEF_PROPERTYVALUETYPEDEFHELPER_H_
-
-#include "PropertyValueTypeDef.h"
-
-namespace basyx {
-namespace submodel {
-namespace impl {
-namespace metamodel {
-
-class PropertyValueTypeDefHelper
-{
-public:
- ~PropertyValueTypeDefHelper();
-
-private:
-
-};
-
-}
-}
-}
-}
-
-#endif
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/SubModel.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/SubModel.h
index 559fad8..824668c 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/SubModel.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/SubModel.h
@@ -21,7 +21,6 @@
namespace submodel {
namespace map {
-
class SubModel :
public virtual api::ISubModel,
public Identifiable,
@@ -30,6 +29,12 @@
public ModelType<ModelTypes::Submodel>,
public virtual vab::ElementMap
{
+public:
+ struct Path {
+ static constexpr char SubmodelElements[] = "submodelElements";
+ static constexpr char SemanticId[] = "semanticId";
+ static constexpr char Kind[] = "kind";
+ };
private:
Reference semanticId;
ElementContainer<api::ISubmodelElement> elementContainer;
@@ -47,6 +52,8 @@
// Inherited via IHasSemantics
virtual const api::IReference & getSemanticId() const override;
virtual void setSemanticId(const api::IReference & semanticId) override;
+
+ virtual KeyElements getKeyElementType() const override { return KeyElements::Submodel; };
};
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/aas/Asset.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/aas/Asset.h
index dd55fcd..511959d 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/aas/Asset.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/aas/Asset.h
@@ -19,6 +19,12 @@
public map::ModelType<ModelTypes::Asset>,
public virtual vab::ElementMap
{
+public:
+ struct Path {
+ static constexpr char Kind[] = "kind";
+ static constexpr char AssetIdentificationModelRef[] = "assetIdentificationModelRef";
+ static constexpr char BillOfMaterialRef[] = "billOfMaterialRef";
+ };
private:
Reference assetIdentificationModelRef;
Reference billOfMaterialRef;
@@ -27,13 +33,15 @@
Asset(const std::string & idShort, const simple::Identifier & identifier, AssetKind kind = AssetKind::Instance);
virtual ~Asset() = default;
- virtual AssetKind getKind();
+ virtual AssetKind getKind() override;
virtual api::IReference * const getAssetIdentificationModel() override;
virtual void setAssetIdentificationModel(const api::IReference & assetIdentificationModelRef) override;
virtual api::IReference * const getBillOfMaterial() override;
virtual void setBillOfMaterial(const api::IReference & billOfMaterialRef) override;
+
+ virtual KeyElements getKeyElementType() const override { return KeyElements::Asset; };
};
}
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/aas/AssetAdministrationShell.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/aas/AssetAdministrationShell.h
index 5174146..34a467d 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/aas/AssetAdministrationShell.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/aas/AssetAdministrationShell.h
@@ -22,6 +22,11 @@
public map::ModelType<ModelTypes::AssetAdministrationShell>,
public virtual vab::ElementMap
{
+public:
+ struct Path {
+ static constexpr char Submodels[] = "submodels";
+ static constexpr char Asset[] = "asset";
+ };
private:
Reference derivedFrom;
Asset asset;
@@ -39,6 +44,8 @@
virtual api::IReference * getDerivedFrom() override;
virtual void setDerivedFrom(const api::IReference & reference) override;
virtual SubmodelContainer_t & getSubmodels() override;
+
+ virtual KeyElements getKeyElementType() const override { return KeyElements::AssetAdministrationShell; };
};
}
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/ElementContainer.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/ElementContainer.h
index 5739f81..f6700cc 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/ElementContainer.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/ElementContainer.h
@@ -5,6 +5,7 @@
#include <BaSyx/submodel/map_v2/common/ElementFactory.h>
#include <BaSyx/submodel/map_v2/qualifier/Referable.h>
#include <BaSyx/submodel/map_v2/qualifier/Identifiable.h>
+#include <BaSyx/submodel/map_v2/reference/Reference.h>
#include <BaSyx/submodel/map_v2/submodelelement/SubmodelElementFactory.h>
#include <BaSyx/vab/ElementMap.h>
@@ -15,6 +16,10 @@
namespace submodel {
namespace map {
+struct ElementContainerPath {
+ static constexpr char IdShort[] = "idShort";
+};
+
template<typename IElementType>
class ElementContainer : public api::IElementContainer<IElementType>, public virtual vab::ElementMap
{
@@ -22,20 +27,29 @@
using elementPtr_t = typename api::IElementContainer<IElementType>::elementPtr_t;
using cache_t = std::unordered_map<std::string, elementPtr_t>;
private:
+ api::IReferable * parent;
mutable cache_t cache;
+ basyx::object keyList;
public:
using vab::ElementMap::ElementMap;
- ElementContainer()
- : vab::ElementMap(basyx::object::make_object_list())
+ ElementContainer(api::IReferable * parent = nullptr)
+ : vab::ElementMap(basyx::object::make_map())
+ , keyList(basyx::object::make_object_list())
+ , parent(parent)
{
};
virtual ~ElementContainer() = default;
public:
+ basyx::object getKeyMap() { return this->keyList; };
+public:
virtual std::size_t size() const override;
+ virtual api::IReferable * getParent() const override;
+
virtual IElementType * const getElement(const std::string & idShort) const override;
virtual IElementType * const getElement(std::size_t n) const override;
virtual void addElement(elementPtr_t element) override;
+// virtual std::vector<simple::Identifier> getIdentifierList();
};
template<typename IElementType>
@@ -45,20 +59,19 @@
};
template<typename IElementType>
+api::IReferable * ElementContainer<IElementType>::getParent() const
+{
+ return this->parent;
+};
+
+template<typename IElementType>
IElementType * const ElementContainer<IElementType>::getElement(const std::string & idShort) const
{
// Find element in object tree
- auto & objectList = this->getMap().template Get<basyx::object::object_list_t&>();
-
- auto objectIterator = std::find_if(
- objectList.begin(), objectList.end(),
- [&idShort](basyx::object & obj) {
- const auto & id = obj.getProperty(map::Identifiable::Path::IdShort).Get<std::string&>();
- return idShort == id;
- });
+ auto && object = this->map.getProperty(idShort);
// element doesn't exist, remove from cache and return nullptr
- if (objectIterator == objectList.end()) {
+ if (object.IsNull() || object.IsError()) {
this->cache.erase(idShort);
return nullptr;
}
@@ -67,7 +80,7 @@
auto element = cache.find(idShort);
if (element == cache.end()) {
// not in cache, re-create elementPtr and return
- elementPtr_t elementPtr = ElementFactory<IElementType>::Create(vab::ElementMap(*objectIterator));
+ elementPtr_t elementPtr = ElementFactory<IElementType>::Create(vab::ElementMap(object));
auto ptr = this->cache.emplace(idShort, std::move(elementPtr));
ptr.first->second.get();
}
@@ -85,13 +98,20 @@
if (n > this->size())
return nullptr;
- // Find element in object tree
- auto & objectList = this->getMap().template Get<basyx::object::object_list_t&>();
- auto & obj = objectList.at(n);
+ // Iterate through object map
+ int i = 0;
+
+ for(const auto & entry : map.Get<basyx::object::object_map_t&>())
+ {
+ if (i++ == n)
+ {
+ // Get id of object and create temporary
+ const auto & id = entry.first;
+ return this->getElement(id);
+ };
+ };
- // Get id of object and create temporary
- const auto & id = obj.getProperty(map::Identifiable::Path::IdShort).Get<std::string&>();
- return this->getElement(id);
+ return nullptr;
};
@@ -103,7 +123,11 @@
auto elementMap = dynamic_cast<vab::ElementMap*>(element.get());
if (elementMap != nullptr)
{
- this->map.insert(elementMap->getMap());
+ // Get reference from element
+ map::Reference reference(element->getReference());
+
+ this->keyList.insert(reference.getMap());
+ this->map.insertKey(shortId, elementMap->getMap());
this->cache.emplace(shortId, std::move(element));
};
};
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/ElementFactory.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/ElementFactory.h
index 9019107..ed3755a 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/ElementFactory.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/ElementFactory.h
@@ -31,4 +31,4 @@
}
-#endif /* BASYX_SUBMODEL_MAP_V2_COMMON_ELEMENTFACTORY_H */
\ No newline at end of file
+#endif /* BASYX_SUBMODEL_MAP_V2_COMMON_ELEMENTFACTORY_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/ModelType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/ModelType.h
index 71f19d2..6151372 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/ModelType.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/ModelType.h
@@ -8,6 +8,11 @@
namespace submodel {
namespace map {
+struct ModelTypePath {
+ static constexpr char Name[] = "name";
+ static constexpr char ModelType[] = "modelType";
+};
+
template<ModelTypes modelType>
class ModelType :
public virtual api::IModelType,
@@ -27,14 +32,14 @@
ModelType<modelType>::ModelType()
{
auto modelTypeMap = basyx::object::make_map();
- modelTypeMap.insertKey("name", ModelTypes_::to_string(modelType));
- this->map.insertKey("modelType", modelTypeMap);
+ modelTypeMap.insertKey(ModelTypePath::Name, ModelTypes_::to_string(modelType));
+ this->map.insertKey(ModelTypePath::ModelType, modelTypeMap);
};
template<ModelTypes modelType>
ModelTypes ModelType<modelType>::GetModelType() const
{
- auto model_type = this->map.getProperty("modelType").getProperty("name").Get<std::string&>();
+ auto model_type = this->map.getProperty(ModelTypePath::ModelType).getProperty(ModelTypePath::Name).Get<std::string&>();
return ModelTypes_::from_string(model_type);
};
@@ -42,4 +47,4 @@
}
}
-#endif /* BASYX_SUBMODEL_MAP_V2_COMMON_LANGSTRINGSET_H */
+#endif /* BASYX_SUBMODEL_MAP_V2_COMMON_MODELTYPE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/SubModelContainer.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/SubModelContainer.h
new file mode 100644
index 0000000..1053159
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/SubModelContainer.h
@@ -0,0 +1,26 @@
+#ifndef BASYX_SUBMODEL_MAP_V2_COMMON_SUBMODELCONTAINER_H
+#define BASYX_SUBMODEL_MAP_V2_COMMON_SUBMODELCONTAINER_H
+
+#include <BaSyx/submodel/api_v2/ISubModel.h>
+#include <BaSyx/submodel/map_v2/common/ElementContainer.h>
+#include <BaSyx/vab/ElementMap.h>
+
+#include <unordered_map>
+#include <algorithm>
+
+namespace basyx {
+namespace submodel {
+namespace map {
+
+class SubModelContainer : public map::ElementContainer<api::ISubModel>
+{
+public:
+
+};
+
+
+}
+}
+}
+
+#endif /* BASYX_SUBMODEL_MAP_V2_COMMON_SUBMODELCONTAINER_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/constraint/Formula.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/constraint/Formula.h
index 5ce2085..efb431a 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/constraint/Formula.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/constraint/Formula.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_MAP_V2_QUALIFIER_FORMULA_H
-#define BASYX_SUBMODEL_MAP_V2_QUALIFIER_FORMULA_H
+#ifndef BASYX_SUBMODEL_MAP_V2_CONSTRAINT_FORMULA_H
+#define BASYX_SUBMODEL_MAP_V2_CONSTRAINT_FORMULA_H
#include <BaSyx/submodel/api_v2/constraint/IFormula.h>
#include <BaSyx/submodel/map_v2/common/ModelType.h>
@@ -17,6 +17,11 @@
public virtual vab::ElementMap
{
public:
+ struct Path {
+ static constexpr char Dependencies[] = "dependencies";
+ };
+
+public:
using vab::ElementMap::ElementMap;
Formula();
@@ -39,4 +44,4 @@
}
}
-#endif /* BASYX_SUBMODEL_API_V2_QUALIFIER_IFORMULA_H */
\ No newline at end of file
+#endif /* BASYX_SUBMODEL_MAP_V2_CONSTRAINT_FORMULA_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/constraint/Qualifier.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/constraint/Qualifier.h
index 69d6b76..b98998f 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/constraint/Qualifier.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/constraint/Qualifier.h
@@ -17,6 +17,16 @@
public ModelType<ModelTypes::Qualifier>,
public virtual vab::ElementMap
{
+public:
+ struct Path {
+ static constexpr char ValueDataType[] = "valueDataType";
+ static constexpr char QualifierType[] = "qualifierType";
+ static constexpr char ValueType[] = "valueType";
+ static constexpr char SemanticId[] = "semanticId";
+ static constexpr char ValueId[] = "valueId";
+ };
+
+
private:
Reference valueId;
Reference semanticId;
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecification.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecification.h
index b63072a..d0de685 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecification.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecification.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_MAP_V2_SDK_DATASPECIFICATION
-#define BASYX_MAP_V2_SDK_DATASPECIFICATION
+#ifndef BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_DATASPECIFICATION_H
+#define BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_DATASPECIFICATION_H
#include <BaSyx/submodel/api_v2/dataspecification/IDataSpecification.h>
#include <BaSyx/submodel/map_v2/dataspecification/DataSpecificationContent.h>
@@ -17,6 +17,11 @@
public virtual Identifiable,
public virtual vab::ElementMap
{
+public:
+ struct Path {
+ static constexpr char DataSpecificationContent[] = "dataSpecificationContent";
+ };
+
private:
std::unique_ptr<DataSpecificationContent> content;
public:
@@ -26,9 +31,10 @@
api::IDataSpecificationContent & getContent() override;
void setContent(std::unique_ptr<DataSpecificationContent> content);
+ virtual KeyElements getKeyElementType() const override { return KeyElements::Unknown; };
};
}
}
}
-#endif //BASYX_MAP_V2_SDK_DATASPECIFICATION_H
+#endif /* BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_DATASPECIFICATION_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecificationContent.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecificationContent.h
index cd64864..d87c8e2 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecificationContent.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecificationContent.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_MAP_V2_SDK_DATASPECIFICATIONCONTENT_H
-#define BASYX_MAP_V2_SDK_DATASPECIFICATIONCONTENT_H
+#ifndef BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_DATASPECIFICATIONCONTENT_H
+#define BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_DATASPECIFICATIONCONTENT_H
#include <BaSyx/submodel/api_v2/dataspecification/IDataSpecificationContent.h>
@@ -17,4 +17,4 @@
}
}
}
-#endif //BASYX_MAP_V2_SDK_DATASPECIFICATIONCONTENT_H
+#endif /* BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_DATASPECIFICATIONCONTENT_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecificationIEC61360.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecificationIEC61360.h
index 53860e2..fad7225 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecificationIEC61360.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecificationIEC61360.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_MAP_V2_SDK_DATASPECIFICATIONIEC61360_H
-#define BASYX_MAP_V2_SDK_DATASPECIFICATIONIEC61360_H
+#ifndef BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_DATASPECIFICATIONIEC61360_H
+#define BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_DATASPECIFICATIONIEC61360_H
#include <BaSyx/submodel/api_v2/dataspecification/IDataSpecificationIEC61360.h>
@@ -76,4 +76,4 @@
}
}
}
-#endif //BASYX_MAP_V2_SDK_DATASPECIFICATIONIEC61360_H
+#endif /* BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_DATASPECIFICATIONIEC61360_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecificationPhysicalUnit.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecificationPhysicalUnit.h
index c1107da..b91925b 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecificationPhysicalUnit.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecificationPhysicalUnit.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_MAP_V2_SDK_DATASPECIFICATIONPHYSICALUNIT_H_
-#define BASYX_MAP_V2_SDK_DATASPECIFICATIONPHYSICALUNIT_H_
+#ifndef BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_DATASPECIFICATIONPHYSICALUNIT_H
+#define BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_DATASPECIFICATIONPHYSICALUNIT_H
#include <BaSyx/submodel/api_v2/dataspecification/IDataSpecificationPhysicalUnit.h>
#include <BaSyx/submodel/map_v2/common/LangStringSet.h>
@@ -83,4 +83,4 @@
}
}
-#endif //BASYX_MAP_V2_SDK_DATASPECIFICATIONPHYSICALUNIT_H_
+#endif /* BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_DATASPECIFICATIONPHYSICALUNIT_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/ValueList.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/ValueList.h
index b4dbb6b..5342c51 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/ValueList.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/ValueList.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_C_SDK_VALUELIST_H
-#define BASYX_C_SDK_VALUELIST_H
+#ifndef BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_VALUELIST_H
+#define BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_VALUELIST_H
#include <BaSyx/submodel/api_v2/dataspecification/IValueList.h>
#include <BaSyx/vab/ElementMap.h>
@@ -13,6 +13,12 @@
, public vab::ElementMap
{
public:
+ struct Path {
+ static constexpr char Value[] = "value";
+ static constexpr char ValueId[] = "valueId";
+ };
+
+public:
ValueList();
explicit ValueList(const std::vector<simple::ValueReferencePair> & list);
@@ -24,4 +30,4 @@
}
}
-#endif //BASYX_C_SDK_VALUELIST_H
+#endif /* BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_VALUELIST_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/parts/ConceptDescription.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/parts/ConceptDescription.h
index 590be73..873c5b2 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/parts/ConceptDescription.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/parts/ConceptDescription.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_MAP_V2_SDK_CONCEPTDESCRIPTION_H
-#define BASYX_MAP_V2_SDK_CONCEPTDESCRIPTION_H
+#ifndef BASYX_SUBMODEL_MAP_V2_PARTS_CONCEPTDESCRIPTION_H
+#define BASYX_SUBMODEL_MAP_V2_PARTS_CONCEPTDESCRIPTION_H
#include <BaSyx/vab/ElementMap.h>
#include <BaSyx/submodel/api_v2/parts/IConceptDescription.h>
@@ -40,9 +40,11 @@
//not inherited
void addIsCaseOf(std::unique_ptr<Reference> reference);
void addEmbeddedDataSpecification(std::unique_ptr<DataSpecification> data_specification);
+
+ virtual KeyElements getKeyElementType() const override { return KeyElements::ConceptDescription; };
};
}
}
}
-#endif //BASYX_MAP_V2_SDK_CONCEPTDESCRIPTION_H
+#endif /* BASYX_SUBMODEL_MAP_V2_PARTS_CONCEPTDESCRIPTION_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/parts/ConceptDictionary.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/parts/ConceptDictionary.h
index 45e3655..d555dff 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/parts/ConceptDictionary.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/parts/ConceptDictionary.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_MAP_V2_SDK_CONCEPTDICTIONARY_H
-#define BASYX_MAP_V2_SDK_CONCEPTDICTIONARY_H
+#ifndef BASYX_SUBMODEL_MAP_V2_PARTS_CONCEPTDICTIONARY_H
+#define BASYX_SUBMODEL_MAP_V2_PARTS_CONCEPTDICTIONARY_H
#include <BaSyx/submodel/api_v2/parts/IConceptDictionary.h>
#include <BaSyx/submodel/map_v2/qualifier/Referable.h>
@@ -16,8 +16,14 @@
, public virtual Referable
, public virtual vab::ElementMap
{
+public:
+ struct Path {
+ static constexpr char ConceptDescriptions[] = "conceptDescriptions";
+ };
+
private:
ElementContainer<api::IConceptDescription> concept_descriptions;
+
public:
ConceptDictionary(const std::string & idShort);
@@ -26,9 +32,12 @@
// not inherited
void addConceptDescription(std::unique_ptr<ConceptDescription> description);
+
+ virtual KeyElements getKeyElementType() const override { return KeyElements::ConceptDictionary; };
+
};
}
}
}
-#endif //BASYX_MAP_V2_SDK_CONCEPTDICTIONARY_H
+#endif /* BASYX_SUBMODEL_MAP_V2_PARTS_CONCEPTDICTIONARY_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/parts/View.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/parts/View.h
index a1936fd..208b197 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/parts/View.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/parts/View.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_MAP_V2_SDK_VIEW_H
-#define BASYX_MAP_V2_SDK_VIEW_H
+#ifndef BASYX_SUBMODEL_MAP_V2_PARTS_VIEW_H
+#define BASYX_SUBMODEL_MAP_V2_PARTS_VIEW_H
#include <BaSyx/submodel/api_v2/parts/IView.h>
@@ -19,11 +19,18 @@
, public virtual Referable
, public virtual vab::ElementMap
{
+public:
+ struct Path {
+ static constexpr char ContainedElements[] = "containedElements";
+ static constexpr char SemanticId[] = "semanticId";
+ };
+
private:
ElementContainer<IReferable> contained_elements;
Reference semanticId;
public:
- View(const std::string & idShort, const Referable * parent = nullptr);
+ View(const std::string & idShort, Referable * parent = nullptr);
+ virtual ~View() = default;
//inherited via api::IView
const api::IElementContainer<IReferable> & getContainedElements() const override;
@@ -34,9 +41,11 @@
//inherited via IHasSemantics
const api::IReference & getSemanticId() const override;
void setSemanticId(const api::IReference & reference) override;
+
+ virtual KeyElements getKeyElementType() const override { return KeyElements::View; };
};
}
}
}
-#endif //BASYX_MAP_V2_SDK_VIEW_H
+#endif /* BASYX_SUBMODEL_MAP_V2_PARTS_VIEW_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/AdministrativeInformation.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/AdministrativeInformation.h
new file mode 100644
index 0000000..c3aa385
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/AdministrativeInformation.h
@@ -0,0 +1,41 @@
+#ifndef BASYX_SUBMODEL_MAP_V2_QUALIFIER_ADMINISTRATIVEINFORMATION_H
+#define BASYX_SUBMODEL_MAP_V2_QUALIFIER_ADMINISTRATIVEINFORMATION_H
+
+#include <BaSyx/submodel/api_v2/qualifier/IAdministrativeInformation.h>
+
+#include <BaSyx/submodel/map_v2/qualifier/HasDataSpecification.h>
+#include <BaSyx/vab/ElementMap.h>
+
+namespace basyx {
+namespace submodel {
+namespace map {
+
+class AdministrativeInformation
+ : public virtual api::IAdministrativeInformation
+ , public HasDataSpecification
+ , public virtual vab::ElementMap
+{
+public:
+ struct Path {
+ static constexpr char Version[] = "version";
+ static constexpr char Revision[] = "revision";
+ };
+
+public:
+ AdministrativeInformation();
+ AdministrativeInformation(const std::string & version, const std::string & revision);
+
+ void setVersion(const std::string & version) override;
+ void setRevision(const std::string & revision) override;
+
+ bool hasVersion() const override;
+ bool hasRevision() const override;
+
+ const std::string * const getVersion() const override;
+ const std::string * const getRevision() const override;
+};
+
+}
+}
+}
+#endif /* BASYX_SUBMODEL_MAP_V2_QUALIFIER_ADMINISTRATIVEINFORMATION_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/HasDataSpecification.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/HasDataSpecification.h
index fd88eeb..a631c4e 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/HasDataSpecification.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/HasDataSpecification.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_METAMODEL_MAPv2_QUALIFIER_HASDATASPECIFICATION_H_
-#define BASYX_SUBMODEL_METAMODEL_MAPv2_QUALIFIER_HASDATASPECIFICATION_H_
+#ifndef BASYX_SUBMODEL_MAP_V2_QUALIFIER_HASDATASPECIFICATION_H
+#define BASYX_SUBMODEL_MAP_V2_QUALIFIER_HASDATASPECIFICATION_H
#include <BaSyx/submodel/api_v2/qualifier/IHasDataSpecification.h>
@@ -13,6 +13,11 @@
public virtual api::IHasDataSpecification,
public virtual vab::ElementMap
{
+public:
+ struct Path {
+ static constexpr char DataSpecification[] = "dataSpecification";
+ };
+
private:
basyx::object::object_list_t dataSpecification;
public:
@@ -28,4 +33,4 @@
}
}
-#endif
\ No newline at end of file
+#endif /* BASYX_SUBMODEL_MAP_V2_QUALIFIER_HASDATASPECIFICATION_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/Identifiable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/Identifiable.h
index 87ecc5d..9fe83cb 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/Identifiable.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/Identifiable.h
@@ -3,7 +3,7 @@
#include <BaSyx/submodel/api_v2/qualifier/IIdentifiable.h>
#include <BaSyx/submodel/map_v2/qualifier/Referable.h>
-#include <BaSyx/submodel/simple/qualifier/AdministrativeInformation.h>
+#include <BaSyx/submodel/map_v2/qualifier/AdministrativeInformation.h>
namespace basyx {
namespace submodel {
@@ -13,26 +13,30 @@
public virtual api::IIdentifiable,
public Referable
{
+public:
+ struct Path {
+ static constexpr char IdType[] = "idType";
+ static constexpr char Id[] = "id";
+ static constexpr char AdministrativeInformation[] = "administrativeInformation";
+ static constexpr char Identifier[] = "identification";
+ };
private:
-// Referable referable;
- simple::AdministrativeInformation administrativeInformation;
+ map::AdministrativeInformation administrativeInformation;
public:
virtual ~Identifiable() = default;
// Constructors
Identifiable(const std::string & idShort, const simple::Identifier & identifier);
- //// Member-access
- //inline const Referable & getReferable() const noexcept { return this->referable; };
- //inline Referable & getReferable() noexcept { return this->referable; };
-
- bool hasAdministrativeInformation() const noexcept;
+ bool hasAdministrativeInformation() const noexcept override;
// Inherited via IIdentifiable
- virtual const simple::AdministrativeInformation & getAdministrativeInformation() const override;
- virtual simple::AdministrativeInformation & getAdministrativeInformation() override;
+ const api::IAdministrativeInformation & getAdministrativeInformation() const override;
+ api::IAdministrativeInformation & getAdministrativeInformation() override;
virtual simple::Identifier getIdentification() const override;
+
+ void setAdministrativeInformation(const AdministrativeInformation & administrativeInformation);
};
}
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/Qualifiable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/Qualifiable.h
index f8e74e1..8ff2fbb 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/Qualifiable.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/Qualifiable.h
@@ -2,7 +2,7 @@
#define BASYX_SUBMODEL_MAP_V2_QUALIFIER_QUALIFIABLE_H
#include <BaSyx/submodel/api_v2/qualifier/IQualifiable.h>
-
+#include <BaSyx/submodel/simple/constraint/Qualifier.h>
#include <BaSyx/vab/ElementMap.h>
namespace basyx {
@@ -15,6 +15,10 @@
public virtual vab::ElementMap
{
public:
+ struct Path {
+ static constexpr char Qualifier[] = "qualifier";
+ };
+public:
Qualifiable() = default;
Qualifiable(const std::vector<simple::Formula> & formulas, const std::vector<simple::Qualifier> & qualifiers);
@@ -37,4 +41,4 @@
}
}
-#endif /* BASYX_SUBMODEL_MAP_V2_QUALIFIER_IQUALIFIABLE_H */
\ No newline at end of file
+#endif /* BASYX_SUBMODEL_MAP_V2_QUALIFIER_QUALIFIABLE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/Referable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/Referable.h
index 9ca9295..8052f9b 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/Referable.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/Referable.h
@@ -24,12 +24,12 @@
};
private:
map::LangStringSet description;
- const IReferable * const parent = nullptr;
+ IReferable * parent = nullptr;
public:
virtual ~Referable() = default;
// Constructors
- Referable(const std::string & idShort, const Referable * parent = nullptr);
+ Referable(const std::string & idShort, Referable * parent = nullptr);
//Referable(const IReferable & other);
// Inherited via IReferable
@@ -38,15 +38,19 @@
virtual LangStringSet & getDescription() override;
virtual const LangStringSet & getDescription() const override;
- virtual const IReferable * const getParent() const override;
+ virtual void setParent(IReferable * parent) override;
+ virtual IReferable * getParent() const override;
- // not inherited
void setIdShort(const std::string & shortID);
void setCategory(const std::string & category) override;
bool hasParent() const noexcept;
bool hasDescription() const noexcept;
bool hasCategory() const noexcept;
+
+ virtual KeyElements getKeyElementType() const override { return KeyElements::Unknown; };
+ virtual simple::Reference getReference() const override;
+ virtual simple::Key getKey(bool local = true) const override;
};
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/reference/Reference.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/reference/Reference.h
index efada7a..19e9adf 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/reference/Reference.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/reference/Reference.h
@@ -15,9 +15,13 @@
public virtual vab::ElementMap
{
public:
- struct Path {
- static constexpr char Keys[] = "keys";
- };
+ struct Path {
+ static constexpr char IdType[] = "idType";
+ static constexpr char Type[] = "type";
+ static constexpr char Value[] = "value";
+ static constexpr char Local[] = "local";
+ static constexpr char Keys[] = "keys";
+ };
public:
Reference();
public:
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/SubmodelElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/SubmodelElement.h
index 16e0f08..94d5903 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/SubmodelElement.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/SubmodelElement.h
@@ -3,34 +3,44 @@
#include <BaSyx/submodel/api_v2/submodelelement/ISubmodelElement.h>
+#include <BaSyx/submodel/map_v2/common/ModelType.h>
#include <BaSyx/submodel/map_v2/qualifier/HasDataSpecification.h>
+#include <BaSyx/submodel/map_v2/qualifier/Qualifiable.h>
#include <BaSyx/submodel/map_v2/qualifier/Referable.h>
#include <BaSyx/submodel/map_v2/reference/Reference.h>
-
namespace basyx {
namespace submodel {
namespace map {
-class SubmodelElement :
- public virtual api::ISubmodelElement,
- public virtual vab::ElementMap,
- public Referable,
- public HasDataSpecification
+class SubmodelElement
+ : public virtual api::ISubmodelElement
+ , public virtual vab::ElementMap
+ , public virtual Qualifiable
+ , public Referable
+ , public HasDataSpecification
{
-private:
- Reference semanticId;
public:
- SubmodelElement(const std::string & idShort, ModelingKind kind = ModelingKind::Instance);
+ struct Path {
+ static constexpr char Kind[] = "kind";
+ static constexpr char SemanticId[] = "semanticId";
+ };
+private:
+ Reference semanticId;
- virtual ~SubmodelElement() = default;
+public:
+ SubmodelElement(const std::string& idShort, ModelingKind kind = ModelingKind::Instance);
- // Inherited via IHasDataSemantics
- virtual const api::IReference & getSemanticId() const override;
- void setSemanticId(const api::IReference & reference);
+ virtual ~SubmodelElement() = default;
- // Inherited via IHasKind
- virtual ModelingKind getKind() const override;
+ // Inherited via IHasDataSemantics
+ virtual const api::IReference& getSemanticId() const override;
+ void setSemanticId(const api::IReference& reference) override;
+
+ // Inherited via IHasKind
+ virtual ModelingKind getKind() const override;
+
+ virtual KeyElements getKeyElementType() const override { return KeyElements::SubmodelElement; };
};
}
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/SubmodelElementCollection.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/SubmodelElementCollection.h
index 02d7ce3..061326f 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/SubmodelElementCollection.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/SubmodelElementCollection.h
@@ -33,6 +33,8 @@
virtual bool isOrdered() const override;
virtual bool isAllowDuplicates() const override;
+
+ virtual KeyElements getKeyElementType() const override { return KeyElements::SubmodelElementCollection; };
};
}
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/SubmodelElementFactory.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/SubmodelElementFactory.h
index 0438908..cf34721 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/SubmodelElementFactory.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/SubmodelElementFactory.h
@@ -11,6 +11,10 @@
class SubmodelElementFactory
{
+public:
+ struct Path {
+ static constexpr char Value[] = "value";
+ };
private:
static std::unique_ptr<api::ISubmodelElement> CreateProperty(const vab::ElementMap & elementMap);
public:
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/operation/Operation.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/operation/Operation.h
index 19d8636..96efd50 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/operation/Operation.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/operation/Operation.h
@@ -15,6 +15,13 @@
public SubmodelElement,
public ModelType<ModelTypes::Operation>
{
+public:
+ struct Path {
+ static constexpr char Invokable[] = "invokable";
+ static constexpr char InputVariable[] = "inputVariable";
+ static constexpr char OutputVariable[] = "outputVariable";
+ static constexpr char InoutputVariable[] = "inoutputVariable";
+ };
private:
ElementContainer<ISubmodelElement> inputVariables;
ElementContainer<ISubmodelElement> outputVariables;
@@ -30,6 +37,8 @@
virtual api::IElementContainer<ISubmodelElement> & getOutputVariables() override;
virtual api::IElementContainer<ISubmodelElement> & getInOutputVariables() override;
virtual basyx::object invoke(basyx::object args) override;
+
+ virtual KeyElements getKeyElementType() const override { return KeyElements::Operation; };
};
}
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/operation/OperationVariable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/operation/OperationVariable.h
index d835e3b..b688d42 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/operation/OperationVariable.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/operation/OperationVariable.h
@@ -8,6 +8,12 @@
namespace submodel {
namespace map {
+struct OperationVariablePath {
+ static constexpr char Value[] = "value";
+};
+
+constexpr char OperationVariablePath::Value[];
+
template<typename T>
class OperationVariable :
public SubmodelElement,
@@ -21,7 +27,7 @@
: SubmodelElement(idShort, ModelingKind::Template)
, value(std::move(value))
{
- this->map.insertKey("value", this->value->getMap());
+ this->map.insertKey(OperationVariablePath::Value, this->value->getMap());
};
OperationVariable(const OperationVariable & other) = default;
@@ -37,6 +43,8 @@
{
return *this->value;
};
+
+ virtual inline KeyElements getKeyElementType() const override { return KeyElements::OperationVariable; };
};
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/property/MultiLanguageProperty.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/property/MultiLanguageProperty.h
index 8ecc6f8..d108f75 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/property/MultiLanguageProperty.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/property/MultiLanguageProperty.h
@@ -17,6 +17,12 @@
public SubmodelElement,
public ModelType<ModelTypes::MultiLanguageProperty>
{
+public:
+ struct Path {
+ static constexpr char Value[] = "value";
+ static constexpr char ValueId[] = "valueId";
+ static constexpr char Kind[] = "kind";
+ };
private:
LangStringSet value;
Reference valueId;
@@ -28,6 +34,8 @@
virtual const api::IReference * const getValueId() const override;
virtual void setValueId(const api::IReference & valueId) override;
+
+ virtual KeyElements getKeyElementType() const override { return KeyElements::MultiLanguageProperty; };
};
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/property/Property.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/property/Property.h
index debb500..082733f 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/property/Property.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/property/Property.h
@@ -4,6 +4,8 @@
#include <BaSyx/submodel/api_v2/submodelelement/property/IProperty.h>
#include <BaSyx/submodel/map_v2/submodelelement/SubmodelElement.h>
#include <BaSyx/submodel/map_v2/common/ModelType.h>
+#include <BaSyx/submodel/map_v2/qualifier/Qualifiable.h>
+#include <BaSyx/submodel/api_v2/submodelelement/property/XSDAnySimpleType.h>
#include <BaSyx/shared/object.h>
@@ -11,66 +13,94 @@
namespace submodel {
namespace map {
+struct PropertyPath {
+ static constexpr char Value[] = "value";
+ static constexpr char ValueType[] = "valueType";
+ static constexpr char ValueId[] = "valueId";
+};
+
template<typename T>
class Property
- : public virtual api::IProperty
- , public virtual SubmodelElement
- , public virtual vab::ElementMap
- , public ModelType<ModelTypes::Property>
+ : public virtual api::IProperty
+ , public virtual SubmodelElement
+ , public virtual vab::ElementMap
+ , public virtual Qualifiable
+ , public ModelType<ModelTypes::Property>
{
+private:
+ std::unique_ptr<Reference> valueId;
+
public:
- Property(const std::string & idShort)
- : SubmodelElement(idShort, ModelingKind::Instance)
- {
- };
+ Property(const std::string & idShort)
+ : SubmodelElement(idShort, ModelingKind::Instance)
+ {
+ this->setValueType(xsd_types::xsd_type<T>::getDataTypeDef());
+ };
- Property(const vab::ElementMap & elementMap)
- : vab::ElementMap(elementMap.getMap())
- , SubmodelElement(elementMap.getMap().getProperty(Referable::Path::IdShort).GetStringContent(), ModelingKind::Instance)
- {
- };
+ Property(const vab::ElementMap & elementMap)
+ : vab::ElementMap(elementMap.getMap())
+ , SubmodelElement(elementMap.getMap().getProperty(Referable::Path::IdShort).GetStringContent(), ModelingKind::Instance)
+ {
+ };
- virtual ~Property() = default;
+ virtual ~Property() = default;
- void setValue(const T & t)
- {
- this->map.insertKey("value", t);
- }
+ void setValue(const T & t)
+ {
+ this->map.insertKey(PropertyPath::Value, xsd_types::xsd_type<T>::getXSDRepresentation(t));
+ }
- const T & getValue() const
- {
- return this->map.getProperty("value").template Get<T&>();
- }
+ const T getValue() const
+ {
+ return xsd_types::xsd_type<T>::fromXSDRepresentation(this->map.getProperty(PropertyPath::Value));
+ }
- virtual const std::string & getValueType() const override
- {
- return this->map.getProperty("valueType").template Get<std::string&>();
- }
+ virtual const std::string & getValueType() const override
+ {
+ return this->map.getProperty(PropertyPath::ValueType).template Get<std::string&>();
+ }
- virtual void setValueType(const std::string & valueType) override
- {
- this->map.insertKey("valueType", valueType);
- }
+ virtual void setValueType(const std::string & valueType) override
+ {
+ this->map.insertKey(PropertyPath::ValueType, valueType);
+ }
- virtual void setObject(basyx::object & object) override
- {
- if (object.InstanceOf<T>())
- this->map.insertKey("value", object);
- }
+ virtual void setObject(basyx::object & object) override
+ {
+ // store only if valuetype is defined
+ if (object.hasProperty(PropertyPath::ValueType))
+ this->map = object;
- virtual basyx::object getObject() override
- {
- return this->map.getProperty("value");
- }
+ // or if it's a primitive type, not null or object
+ if (object.GetObjectType() == type::objectType::Primitive)
+ {
+ if (object.GetValueType() != type::valueType::Null and object.GetValueType() != type::valueType::Object)
+ this->map.insertKey(PropertyPath::Value, object);
+ this->map.insertKey(PropertyPath::ValueType, xsd_types::getPrimitiveXSDType(object.GetValueType()));
+ }
+ }
- virtual const Reference * const getValueId() const override
- {
- return nullptr;
- }
+ virtual basyx::object getObject() override
+ {
+ return this->map.getProperty(PropertyPath::Value);
+ }
- virtual void setValueId(const api::IReference & valueId) override
- {
- }
+ virtual const Reference * const getValueId() const override
+ {
+ if (&this->valueId)
+ {
+ return this->valueId.get();
+ }
+ return nullptr;
+ }
+
+ virtual void setValueId(const api::IReference & valueId) override
+ {
+ this->valueId = util::make_unique<Reference>(valueId);
+ this->map.insertKey(PropertyPath::ValueId, this->valueId->getMap());
+ }
+
+ virtual KeyElements getKeyElementType() const override { return KeyElements::Property; };
};
}
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/property/ReferenceElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/property/ReferenceElement.h
index 8fdaa6c..fa94b34 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/property/ReferenceElement.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/property/ReferenceElement.h
@@ -2,29 +2,33 @@
#define BASYX_SUBMODEL_MAP_V2_SUBMODELELEMENT_PROPERTY_REFERENCEELEMENT_H
#include <BaSyx/submodel/api_v2/submodelelement/property/IReferenceElement.h>
-#include <BaSyx/submodel/map_v2/submodelelement/SubmodelElement.h>
-#include <BaSyx/submodel/map_v2/reference/Reference.h>
#include <BaSyx/submodel/map_v2/common/ModelType.h>
-
+#include <BaSyx/submodel/map_v2/reference/Reference.h>
+#include <BaSyx/submodel/map_v2/submodelelement/SubmodelElement.h>
namespace basyx {
namespace submodel {
namespace map {
-
-class ReferenceElement :
- public api::IReferenceElement,
- public SubmodelElement,
- public ModelType<ModelTypes::ReferenceElement>
+class ReferenceElement : public api::IReferenceElement,
+ public SubmodelElement,
+ public ModelType<ModelTypes::ReferenceElement>
{
-private:
- Reference value;
public:
- ReferenceElement(const std::string & idShort, ModelingKind kind = ModelingKind::Instance);
- virtual ~ReferenceElement() = default;
+ struct Path {
+ static constexpr char Value[] = "value";
+ static constexpr char Kind[] = "kind";
+ };
+private:
+ Reference value;
+public:
+ ReferenceElement(const std::string& idShort, ModelingKind kind = ModelingKind::Instance);
+ virtual ~ReferenceElement() = default;
- virtual const api::IReference * const getValue() const = 0;
- virtual void setValue(const api::IReference & value) = 0;
+ virtual const api::IReference* const getValue() const override = 0;
+ virtual void setValue(const api::IReference& value) override = 0;
+
+ virtual KeyElements getKeyElementType() const override { return KeyElements::ReferenceElement; };
};
}
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/SubModel.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/SubModel.h
index 78f7904..88e2cee 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/SubModel.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/SubModel.h
@@ -47,8 +47,10 @@
virtual void setCategory(const std::string & category) override;
virtual simple::LangStringSet & getDescription() override;
virtual const simple::LangStringSet & getDescription() const override;
- virtual const IReferable * const getParent() const override;
-
+
+ virtual IReferable * getParent() const override;
+ virtual void setParent(IReferable * parent) override;
+
// Inherited via IIdentifiable
virtual const AdministrativeInformation & getAdministrativeInformation() const override;
virtual AdministrativeInformation & getAdministrativeInformation() override;
@@ -71,6 +73,10 @@
virtual std::vector<simple::Formula> getFormulas() const override;
virtual std::vector<simple::Qualifier> getQualifiers() const override;
+
+ virtual KeyElements getKeyElementType() const override { return KeyElements::Submodel; };
+ virtual simple::Reference getReference() const override;
+ virtual simple::Key getKey(bool local = true) const override;
};
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/aas/Asset.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/aas/Asset.h
index fc0cd26..39b1a3d 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/aas/Asset.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/aas/Asset.h
@@ -22,7 +22,7 @@
Asset(const std::string & idShort, const Identifier & identifier, AssetKind kind = AssetKind::Instance);
virtual ~Asset() = default;
- virtual AssetKind getKind();
+ virtual AssetKind getKind() override;
virtual Reference * const getAssetIdentificationModel() override;
virtual void setAssetIdentificationModel(const api::IReference & assetIdentificationModelRef) override;
@@ -37,7 +37,9 @@
virtual void setCategory(const std::string & category) override;
virtual simple::LangStringSet & getDescription() override;
virtual const simple::LangStringSet & getDescription() const override;
- virtual const IReferable * const getParent() const override;
+ virtual void setParent(api::IReferable * parent) override;
+ virtual IReferable * getParent() const override;
+ virtual simple::Reference getReference() const override;
// Inherited via IIdentifiable
virtual const AdministrativeInformation & getAdministrativeInformation() const override;
@@ -45,13 +47,15 @@
virtual Identifier getIdentification() const override;
- virtual bool hasAdministrativeInformation() const;
+ virtual bool hasAdministrativeInformation() const override;
// Inherited via IHasDataSpecification
virtual void addDataSpecification(const Reference & reference) override;
virtual const std::vector<Reference> getDataSpecificationReference() const override;
virtual inline ModelTypes GetModelType() const override { return ModelTypes::Asset; };
+ virtual KeyElements getKeyElementType() const override { return KeyElements::Asset; };
+ virtual Key getKey(bool local = true) const override;
};
}
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/aas/AssetAdministrationShell.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/aas/AssetAdministrationShell.h
index 634d414..be14ce2 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/aas/AssetAdministrationShell.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/aas/AssetAdministrationShell.h
@@ -16,6 +16,8 @@
class AssetAdministrationShell : public api::IAssetAdministrationShell
{
+public:
+ using asset_t = basyx::submodel::simple::Asset;
private:
Identifiable identifiable;
HasDataSpecification dataSpecification;
@@ -43,19 +45,26 @@
virtual void setCategory(const std::string & category) override;
virtual simple::LangStringSet & getDescription() override;
virtual const simple::LangStringSet & getDescription() const override;
- virtual const IReferable * const getParent() const override;
+ virtual void setParent(api::IReferable * parent) override;
+ virtual IReferable * getParent() const override;
+ virtual simple::Reference getReference() const override;
// Inherited via IIdentifiable
- virtual const AdministrativeInformation & getAdministrativeInformation() const override;
- virtual AdministrativeInformation & getAdministrativeInformation() override;
+ virtual const api::IAdministrativeInformation & getAdministrativeInformation() const override;
+ virtual api::IAdministrativeInformation & getAdministrativeInformation() override;
virtual Identifier getIdentification() const override;
- virtual bool hasAdministrativeInformation() const;
+ virtual bool hasAdministrativeInformation() const override;
// Inherited via IHasDataSpecification
virtual void addDataSpecification(const Reference & reference) override;
virtual const std::vector<Reference> getDataSpecificationReference() const override;
+
+ // Inherited via IModelType
+ virtual ModelTypes GetModelType() const override;
+ virtual KeyElements getKeyElementType() const override { return KeyElements::AssetAdministrationShell; };
+ virtual Key getKey(bool local = true) const override;
};
}
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/ElementContainer.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/ElementContainer.h
index 5b22928..6f45a4a 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/ElementContainer.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/ElementContainer.h
@@ -17,12 +17,15 @@
using container_t = std::vector<elementPtr_t>;
private:
container_t container;
+ api::IReferable * parent;
public:
- ElementContainer() = default;
+ ElementContainer(api::IReferable * parent = nullptr) : parent(parent) {};
virtual ~ElementContainer() = default;
public:
// Inherited via IElementContainer
virtual std::size_t size() const override;
+ virtual api::IReferable * getParent() const override;
+
virtual IElementType * const getElement(const std::string & idShort) const override;
virtual IElementType * const getElement(std::size_t n) const override;
virtual void addElement(elementPtr_t element) override;
@@ -45,6 +48,12 @@
};
template<typename IElementType>
+api::IReferable * ElementContainer<IElementType>::getParent() const
+{
+ return this->parent;
+};
+
+template<typename IElementType>
IElementType * const ElementContainer<IElementType>::getElement(const std::string & idShort) const
{
auto ret = std::find_if(container.begin(), container.end(),
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/LangStringSet.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/LangStringSet.h
index b46249d..d9ff7d1 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/LangStringSet.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/LangStringSet.h
@@ -22,16 +22,16 @@
LangStringSet();
LangStringSet(const std::string & languageCode, const std::string & langString);
LangStringSet(std::initializer_list<langStringMap_t::value_type>);
- LangStringSet(const api::ILangStringSet & other);
+ LangStringSet(const api::ILangStringSet & other);
virtual ~LangStringSet() = default;
langCodeSet_t getLanguageCodes() const override;
- const std::string & get(const std::string & languageCode) const override;
- void add(const std::string & languageCode, const std::string & langString) override;
+ const std::string & get(const std::string & languageCode) const override;
+ void add(const std::string & languageCode, const std::string & langString) override;
bool empty() const noexcept override;
- friend bool api::operator==(const api::ILangStringSet & left, const api::ILangStringSet & right);
+ friend bool api::operator==(const api::ILangStringSet & left, const api::ILangStringSet & right);
};
}
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/AnyURI.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/AnyURI.h
new file mode 100644
index 0000000..65e225a
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/AnyURI.h
@@ -0,0 +1,25 @@
+#ifndef BASYX_SIMPLE_SDK_ANYURI_H
+#define BASYX_SIMPLE_SDK_ANYURI_H
+
+#include <BaSyx/vab/ElementMap.h>
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+class AnyURI
+{
+private:
+ std::string uri;
+
+public:
+ AnyURI(const std::string & uri);
+
+ const std::string & getUri() const;
+ void setURI(const std::string & uri);
+};
+
+}
+}
+}
+#endif //BASYX_MAP_V2_SDK_ANYURI_H
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/Date.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/Date.h
new file mode 100644
index 0000000..b746364
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/Date.h
@@ -0,0 +1,25 @@
+#ifndef BASYX_SIMPLE_SDK_DATE_H
+#define BASYX_SIMPLE_SDK_DATE_H
+
+#include <ctime>
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+class Date
+{
+private:
+ tm date;
+
+public:
+ Date(const tm &);
+
+ const tm & getDate() const;
+ void setDate(const tm &);
+};
+
+}
+}
+}
+#endif /* BASYX_SIMPLE_SDK_DATE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/DateTime.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/DateTime.h
new file mode 100644
index 0000000..eaa665c
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/DateTime.h
@@ -0,0 +1,25 @@
+#ifndef BASYX_SIMPLE_SDK_DATETIME_H
+#define BASYX_SIMPLE_SDK_DATETIME_H
+
+#include <ctime>
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+class DateTime
+{
+private:
+ tm time;
+
+public:
+ DateTime(const tm &);
+
+ const tm & getTime() const;
+ void setTime(const tm & time);
+};
+
+}
+}
+}
+#endif //BASYX_MAP_V2_SDK_DATETIME_H
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/DayTimeDuration.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/DayTimeDuration.h
new file mode 100644
index 0000000..03701b0
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/DayTimeDuration.h
@@ -0,0 +1,24 @@
+#ifndef BASYX_SIMPLE_SDK_DAYTIMEDURATION_H
+#define BASYX_SIMPLE_SDK_DAYTIMEDURATION_H
+
+#include <chrono>
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+class DayTimeDuration
+{
+private:
+ std::chrono::duration<long> duration_in_sec;
+public:
+ DayTimeDuration(const std::chrono::duration<long> &);
+
+ const std::chrono::duration<long> & getDuration() const;
+ void setDuration(const std::chrono::duration<long> &);
+};
+
+}
+}
+}
+#endif /* BASYX_SIMPLE_SDK_DAYTIMEDURATION_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GDay.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GDay.h
new file mode 100644
index 0000000..099aba1
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GDay.h
@@ -0,0 +1,29 @@
+#ifndef BASYX_SIMPLE_SDK_GDAY_H
+#define BASYX_SIMPLE_SDK_GDAY_H
+
+#include <BaSyx/submodel/simple/common/xsd_types/Timezone.h>
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+class GDay
+{
+private:
+uint8_t day;
+ Timezone timezone;
+
+public:
+ GDay(uint8_t day, const Timezone & timezone = "Z");
+
+ uint8_t getDay() const;
+ void setDay(uint8_t day);
+
+ const Timezone & getTimezone() const;
+ void setTimezone(const Timezone &timezone);
+};
+
+}
+}
+}
+#endif /* BASYX_SIMPLE_SDK_GDAY_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GMonth.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GMonth.h
new file mode 100644
index 0000000..8010d78
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GMonth.h
@@ -0,0 +1,29 @@
+#ifndef BASYX_SIMPLE_SDK_GMONTH_H
+#define BASYX_SIMPLE_SDK_GMONTH_H
+
+#include <BaSyx/submodel/simple/common/xsd_types/Timezone.h>
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+class GMonth
+{
+private:
+ uint8_t month;
+ Timezone timezone;
+
+public:
+ GMonth(uint8_t month, const Timezone & timezone = "Z");
+
+ uint8_t getMonth() const;
+ void setMonth(uint8_t month);
+
+ const Timezone & getTimezone() const;
+ void setTimezone(const Timezone &timezone);
+};
+
+}
+}
+}
+#endif /* BASYX_SIMPLE_SDK_GMONTH_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GMonthDay.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GMonthDay.h
new file mode 100644
index 0000000..23c597b
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GMonthDay.h
@@ -0,0 +1,35 @@
+#ifndef BASYX_SIMPLE_SDK_GMONTHDAY_H
+#define BASYX_SIMPLE_SDK_GMONTHDAY_H
+
+#include "Timezone.h"
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+class GMonthDay
+{
+private:
+ uint8_t month, day;
+ Timezone timezone;
+
+ const uint8_t month_days[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+public:
+ GMonthDay(uint8_t month, uint8_t day, const Timezone & timezone = "Z");
+
+ uint8_t getMonth() const;
+ void setMonth(uint8_t month);
+
+ uint8_t getDay() const;
+ void setDay(uint8_t day);
+
+
+ const Timezone & getTimezone() const;
+ void setTimezone(const Timezone &timezone);
+};
+
+}
+}
+}
+#endif /* BASYX_SIMPLE_SDK_GMONTHDAY_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GYear.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GYear.h
new file mode 100644
index 0000000..a3f654f
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GYear.h
@@ -0,0 +1,31 @@
+#ifndef BASYX_SIMPLE_SDK_GYEAR_H
+#define BASYX_SIMPLE_SDK_GYEAR_H
+
+#include <BaSyx/submodel/simple/common/xsd_types/Timezone.h>
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+class GYear
+{
+private:
+ int year;
+ Timezone timezone;
+
+public:
+ GYear(int year, const Timezone & timezone = "Z");
+
+ int getYear() const;
+ void setYear(int year);
+
+ const Timezone & getTimezone() const;
+ void setTimezone(const Timezone &timezone);
+
+
+};
+
+}
+}
+}
+#endif /* BASYX_SIMPLE_SDK_GYEAR_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GYearMonth.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GYearMonth.h
new file mode 100644
index 0000000..27ad161
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GYearMonth.h
@@ -0,0 +1,33 @@
+#ifndef BASYX_SIMPLE_SDK_GYEARMONTH_H
+#define BASYX_SIMPLE_SDK_GYEARMONTH_H
+
+#include "Timezone.h"
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+class GYearMonth
+{
+private:
+ int year;
+ uint8_t month;
+private:
+ Timezone timezone;
+public:
+ GYearMonth(int year, uint8_t month, const Timezone & = Timezone{});
+
+ int getYear() const;
+ void setYear(int year);
+
+ uint8_t getMonth() const;
+ void setMonth(uint8_t month);
+
+ const Timezone &getTimezone() const;
+ void setTimezone(const Timezone &timezone);
+};
+
+}
+}
+}
+#endif /* BASYX_SIMPLE_SDK_GYEARMONTH_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/Time.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/Time.h
new file mode 100644
index 0000000..7c4e9ed
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/Time.h
@@ -0,0 +1,42 @@
+#ifndef BASYX_SIMPLE_SDK_TIME_H
+#define BASYX_SIMPLE_SDK_TIME_H
+
+#include "Timezone.h"
+
+#include <cstdint>
+#include <string>
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+/**
+ * Time represents instants of time that recur at the same point in each calendar day, or that occur in some arbitrary calendar day.
+ */
+class Time
+{
+private:
+ uint8_t hours, minutes;
+ float seconds;
+ Timezone timezone;
+public:
+ Time(uint8_t hours, uint8_t minutes, float seconds, const Timezone & timezone = "Z");
+
+ uint8_t getHours() const;
+ void setHours(uint8_t hours);
+
+ uint8_t getMinutes() const;
+ void setMinutes(uint8_t minutes);
+
+ float getSeconds() const;
+ void setSeconds(float seconds);
+
+ const Timezone & getTimezone() const;
+ void setTimezone(const Timezone &);
+};
+
+}
+}
+}
+
+#endif /* BASYX_SIMPLE_SDK_TIME_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/Timezone.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/Timezone.h
new file mode 100644
index 0000000..080e168
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/Timezone.h
@@ -0,0 +1,31 @@
+#ifndef BASYX_SIMPLE_SDK_TIMEZONE_H
+#define BASYX_SIMPLE_SDK_TIMEZONE_H
+
+#include <string>
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+class Timezone
+{
+private:
+ std::string timezone;
+
+public:
+ Timezone();
+ Timezone(const std::string &);
+ Timezone(const char*);
+
+ const std::string &getTimezone() const;
+ void setTimezone(const std::string &timezone);
+
+ bool isUTC() const;
+
+ operator const std::string & () const;
+};
+
+}
+}
+}
+#endif /* BASYX_SIMPLE_SDK_TIMEZONE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/YearMonthDuration.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/YearMonthDuration.h
new file mode 100644
index 0000000..0eb0f2d
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/YearMonthDuration.h
@@ -0,0 +1,25 @@
+#ifndef BASYX_SIMPLE_SDK_YEARMONTHDURATION_H
+#define BASYX_SIMPLE_SDK_YEARMONTHDURATION_H
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+class YearMonthDuration
+{
+private:
+ int years = 0, months = 0;
+public:
+ YearMonthDuration(int years, int months);
+
+ int getYears() const;
+ int getMonths() const;
+
+ void setYears(const int &);
+ void setMonths(const int &);
+};
+
+}
+}
+}
+#endif /* BASYX_SIMPLE_SDK_YEARMONTHDURATION_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/DataSpecification.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/DataSpecification.h
index bbd5771..c148e01 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/DataSpecification.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/DataSpecification.h
@@ -26,14 +26,19 @@
// Inherited via IIdentifiable
virtual const std::string & getIdShort() const override;
virtual const std::string * const getCategory() const override;
- void setCategory(const std::string & category) override;
+ void setCategory(const std::string & category) override;
virtual simple::LangStringSet & getDescription() override;
virtual const simple::LangStringSet & getDescription() const override;
- virtual const IReferable * const getParent() const override;
+ virtual IReferable * getParent() const override;
+ virtual void setParent(IReferable * parent) override;
virtual const AdministrativeInformation & getAdministrativeInformation() const override;
virtual AdministrativeInformation & getAdministrativeInformation() override;
virtual Identifier getIdentification() const override;
virtual bool hasAdministrativeInformation() const override;
+ virtual simple::Reference getReference() const override;
+
+ virtual Key getKey(bool local = true) const override { return ident.getKey(); }
+
};
}
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/DataSpecificationPhysicalUnit.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/DataSpecificationPhysicalUnit.h
index 379b75c..8dbf3cf 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/DataSpecificationPhysicalUnit.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/DataSpecificationPhysicalUnit.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SIMPLE_SDK_DATASPECIFICATIONPHYSICALUNIT_H
-#define BASYX_SIMPLE_SDK_DATASPECIFICATIONPHYSICALUNIT_H
+#ifndef BASYX_SUBMODEL_SIMPLE_DATASPECIFICATION_DATASPECIFICATIONPHYSICALUNIT_H
+#define BASYX_SUBMODEL_SIMPLE_DATASPECIFICATION_DATASPECIFICATIONPHYSICALUNIT_H
#include <BaSyx/submodel/api_v2/dataspecification/IDataSpecificationPhysicalUnit.h>
#include <BaSyx/submodel/simple/common/LangStringSet.h>
@@ -75,4 +75,4 @@
}
}
}
-#endif //BASYX_SIMPLE_SDK_DATASPECIFICATIONPHYSICALUNIT_H
+#endif /* BASYX_SUBMODEL_SIMPLE_DATASPECIFICATION_DATASPECIFICATIONPHYSICALUNIT_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/ValueList.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/ValueList.h
index df22b8c..16306d8 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/ValueList.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/ValueList.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_C_SDK_SIMPLE_VALUELIST_H
-#define BASYX_C_SDK_SIMPLE_VALUELIST_H
+#ifndef BASYX_SUBMODEL_SIMPLE_DATASPECIFICATION_VALUELIST_H
+#define BASYX_SUBMODEL_SIMPLE_DATASPECIFICATION_VALUELIST_H
#include <BaSyx/submodel/api_v2/dataspecification/IValueList.h>
@@ -8,21 +8,20 @@
namespace simple {
class ValueList
- : public api::IValueList
-{
+ : public api::IValueList {
public:
- ValueList() = default;
- explicit ValueList(const std::vector<simple::ValueReferencePair> & list);
+ ValueList() = default;
+ explicit ValueList(const std::vector<simple::ValueReferencePair>& list);
- void addValueReferencePair(const simple::ValueReferencePair & valueRefPair) override;
- std::vector<simple::ValueReferencePair> getValueReferencePairs() override;
+ void addValueReferencePair(const simple::ValueReferencePair& valueRefPair) override;
+ std::vector<simple::ValueReferencePair> getValueReferencePairs() override;
private:
- std::vector<simple::ValueReferencePair> list;
+ std::vector<simple::ValueReferencePair> list;
};
}
}
}
-#endif //BASYX_C_SDK_VALUELIST_H
+#endif /* BASYX_SUBMODEL_SIMPLE_DATASPECIFICATION_VALUELIST_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/ValueReferencePair.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/ValueReferencePair.h
index 6e9a484..bbdcfbb 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/ValueReferencePair.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/ValueReferencePair.h
@@ -40,4 +40,4 @@
}
}
-#endif
\ No newline at end of file
+#endif /* BASYX_SUBMODEL_SIMPLE_DATASPECIFICATION_VALUEREFERENCEPAIR_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/datatypes--/DataTypeIEC61360.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/datatypes--/DataTypeIEC61360.h
deleted file mode 100644
index dce216f..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/datatypes--/DataTypeIEC61360.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * DataTypeIEC61360.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_SUBMODEL_SIMPLE_DATASPECIFICATION_DATATYPES--_DATATYPEIEC61360_H
-#define BASYX_SUBMODEL_SIMPLE_DATASPECIFICATION_DATATYPES--_DATATYPEIEC61360_H
-
-#include <string>
-#include <unordered_map>
-
-#include <BaSyx/util/util.h>
-
-namespace basyx {
-namespace submodel {
-
- enum class DataTypeIEC61360 : char
- {
- Date,
- String,
- String_Translatable,
- Real_Measure,
- Real_Count,
- Real_Currency,
- Boolean,
- Url,
- Rational,
- Rational_Measure,
- Time,
- Timestamp
- };
-}
-}
-
-namespace util {
- const std::string & to_string(basyx::submodel::DataTypeIEC61360 type);
-
- template<>
- basyx::submodel::DataTypeIEC61360 from_string<basyx::submodel::DataTypeIEC61360>(const std::string & str);
-}
-
-#endif /* BASYX_SUBMODEL_SIMPLE_DATASPECIFICATION_DATATYPES--_DATATYPEIEC61360_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/datatypes--/LevelType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/datatypes--/LevelType.h
deleted file mode 100644
index aba9ad8..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/datatypes--/LevelType.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * LevelType.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_SUBMODEL_SIMPLE_DATASPECIFICATION_DATATYPES--_LEVELTYPE_H
-#define BASYX_SUBMODEL_SIMPLE_DATASPECIFICATION_DATATYPES--_LEVELTYPE_H
-
-#include <unordered_map>
-#include <string>
-
-#include <BaSyx/util/util.h>
-
-namespace basyx {
-namespace submodel {
-
- enum class LevelType : char
- {
- Min,
- Max,
- Nom,
- Typ
- };
-}
-}
-
-namespace util {
-
- const std::string & to_string(basyx::submodel::LevelType levelType);
-
- template<>
- basyx::submodel::LevelType from_string<basyx::submodel::LevelType>(const std::string & str);
-}
-
-#endif /* BASYX_SUBMODEL_SIMPLE_DATASPECIFICATION_DATATYPES--_LEVELTYPE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/parts/ConceptDescription.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/parts/ConceptDescription.h
index 5d8f123..477f71e 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/parts/ConceptDescription.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/parts/ConceptDescription.h
@@ -14,9 +14,9 @@
class ConceptDescription
: public virtual api::IConceptDescription
- , public Identifiable
{
private:
+ Identifiable identifiable;
HasDataSpecification dataSpec;
std::vector<std::unique_ptr<api::IReference>> isCaseOf;
ElementContainer<api::IDataSpecification> embeddedDataSpecs;
@@ -33,9 +33,30 @@
void addDataSpecification(const Reference & reference) override;
const std::vector<Reference> getDataSpecificationReference() const override;
- //not inherited
- void addIsCaseOf(std::unique_ptr<simple::Reference> reference);
- void addEmbeddedDataSpecification(std::unique_ptr<DataSpecification> data_specification);
+ // Inherited via IReferable
+ virtual const std::string & getIdShort() const override;
+ virtual const std::string * const getCategory() const override;
+ virtual void setCategory(const std::string & category) override;
+ virtual simple::LangStringSet & getDescription() override;
+ virtual const simple::LangStringSet & getDescription() const override;
+ virtual void setParent(api::IReferable * parent) override;
+ virtual IReferable * getParent() const override;
+ virtual simple::Reference getReference() const override;
+
+ // Inherited via IIdentifiable
+ virtual const AdministrativeInformation & getAdministrativeInformation() const override;
+ virtual AdministrativeInformation & getAdministrativeInformation() override;
+
+ virtual Identifier getIdentification() const override;
+
+ virtual bool hasAdministrativeInformation() const override;
+
+ //not inherited
+ void addIsCaseOf(std::unique_ptr<simple::Reference> reference);
+ void addEmbeddedDataSpecification(std::unique_ptr<DataSpecification> data_specification);
+
+ virtual Key getKey(bool local = true) const override { return identifiable.getKey(); }
+ virtual KeyElements getKeyElementType() const override { return KeyElements::ConceptDescription; };
};
}
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/parts/ConceptDictionary.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/parts/ConceptDictionary.h
index 5cbce0d..813d583 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/parts/ConceptDictionary.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/parts/ConceptDictionary.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SIMPLE_SDK_CONCEPTDICTIONARY_H
-#define BASYX_SIMPLE_SDK_CONCEPTDICTIONARY_H
+#ifndef BASYX_SUBMODEL_SIMPLE_PARTS_CONCEPTDICTIONARY_H
+#define BASYX_SUBMODEL_SIMPLE_PARTS_CONCEPTDICTIONARY_H
#include <BaSyx/submodel/api_v2/parts/IConceptDictionary.h>
@@ -14,22 +14,34 @@
class ConceptDictionary
: public api::IConceptDictionary
- , public Referable
{
private:
- ElementContainer<api::IConceptDescription> conecpt_descriptions;
-
+ Referable referable;
+ ElementContainer<api::IConceptDescription> conceptDescriptions;
public:
- ConceptDictionary(const std::string & idShort);
+ ConceptDictionary(const std::string & idShort);
- //inherited via IConceptDictionary
- const api::IElementContainer<api::IConceptDescription> & getConceptDescriptions() const override;
+ //inherited via IConceptDictionary
+ const api::IElementContainer<api::IConceptDescription> & getConceptDescriptions() const override;
- //not inherited
- void addConceptDescription(std::unique_ptr<ConceptDescription> description);
+ // inherited via IReferable
+ virtual const std::string & getIdShort() const override;
+ virtual const std::string * const getCategory() const override;
+ virtual void setCategory(const std::string & category) override;
+ virtual simple::LangStringSet & getDescription() override;
+ virtual const simple::LangStringSet & getDescription() const override;
+ virtual void setParent(api::IReferable * parent) override;
+ virtual IReferable * getParent() const override;
+ virtual simple::Reference getReference() const override;
+
+ //not inherited
+ void addConceptDescription(std::unique_ptr<ConceptDescription> description);
+
+ virtual Key getKey(bool local = true) const override { return referable.getKey(); }
+ virtual KeyElements getKeyElementType() const override { return KeyElements::ConceptDictionary; };
};
}
}
}
-#endif //BASYX_SIMPLE_SDK_CONCEPTDICTIONARY_H
+#endif /* BASYX_SUBMODEL_SIMPLE_PARTS_CONCEPTDICTIONARY_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/parts/View.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/parts/View.h
index 76966c1..6de2420 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/parts/View.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/parts/View.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SIMPLE_SDK_VIEW_H
-#define BASYX_SIMPLE_SDK_VIEW_H
+#ifndef BASYX_SUBMODEL_SIMPLE_PARTS_VIEW_H
+#define BASYX_SUBMODEL_SIMPLE_PARTS_VIEW_H
#include <BaSyx/submodel/api_v2/parts/IView.h>
@@ -13,14 +13,15 @@
class View
: public virtual api::IView
- , public virtual HasDataSpecification
- , public virtual Referable
{
private:
+ HasDataSpecification dataSpec;
+ Referable referable;
+
ElementContainer<api::IReferable> contained_elements;
Reference semanticId;
public:
- View(const std::string & idShort, const Referable * parent = nullptr);
+ View(const std::string & idShort, Referable * parent = nullptr);
//Inherited via api::IView
const api::IElementContainer<IReferable> & getContainedElements() const override;
@@ -28,12 +29,29 @@
//not inherited
void addContainedElement(std::unique_ptr<Referable> referable);
+ // Inherited via IHasDataSpecification
+ virtual void addDataSpecification(const simple::Reference & reference) override;
+ virtual const std::vector<simple::Reference> getDataSpecificationReference() const override;
+
//inherited via IHasSemantics
const api::IReference & getSemanticId() const override;
void setSemanticId(const api::IReference & reference) override;
+
+ // Inherited via IReferable
+ virtual const std::string & getIdShort() const override;
+ virtual const std::string * const getCategory() const override;
+ virtual void setCategory(const std::string & category) override;
+ virtual simple::LangStringSet & getDescription() override;
+ virtual const simple::LangStringSet & getDescription() const override;
+ virtual void setParent(api::IReferable * parent) override;
+ virtual IReferable * getParent() const override;
+ virtual simple::Reference getReference() const override;
+
+ virtual Key getKey(bool local = true) const override { return referable.getKey(); }
+ virtual KeyElements getKeyElementType() const override { return KeyElements::View; };
};
}
}
}
-#endif //BASYX_SIMPLE_SDK_VIEW_H
+#endif /* BASYX_SUBMODEL_SIMPLE_PARTS_VIEW_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/AdministrativeInformation.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/AdministrativeInformation.h
index 7003666..7f0903e 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/AdministrativeInformation.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/AdministrativeInformation.h
@@ -7,18 +7,18 @@
#ifndef BASYX_SUBMODEL_SIMPLE_QUALIFIER_ADMINISTRATIVEINFORMATION_H
#define BASYX_SUBMODEL_SIMPLE_QUALIFIER_ADMINISTRATIVEINFORMATION_H
-//#include <BaSyx/submodel/api_v2/qualifier/IAdministrativeInformation.h>
#include <BaSyx/submodel/simple/qualifier/HasDataSpecification.h>
+#include <BaSyx/submodel/api_v2/qualifier/IAdministrativeInformation.h>
namespace basyx {
namespace submodel {
namespace simple {
-class AdministrativeInformation : public api::IHasDataSpecification
+class AdministrativeInformation
+ : public api::IAdministrativeInformation
+ , public HasDataSpecification
{
private:
- HasDataSpecification hasDataSpecification;
-
std::string version;
std::string revision;
public:
@@ -26,22 +26,18 @@
AdministrativeInformation();
AdministrativeInformation(const std::string & version, const std::string & revision);
-// AdministrativeInformation(const IAdministrativeInformation & other);
+ explicit AdministrativeInformation(const IAdministrativeInformation & other);
- void setVersion(const std::string & version);
- void setRevision(const std::string & revision);
+ void setVersion(const std::string & version) override;
+ void setRevision(const std::string & revision) override;
- inline bool hasVersion() const { return version.empty(); };
- inline bool hasRevision() const { return revision.empty(); };
+ inline bool hasVersion() const override { return !version.empty(); };
+ inline bool hasRevision() const override { return !revision.empty(); };
inline bool exists() const noexcept { return !version.empty() && !revision.empty(); };
- virtual std::string getVersion() const;
- virtual std::string getRevision() const;
-
- // Inherited via IHasDataSpecification
- virtual void addDataSpecification(const Reference & reference) override;
- const std::vector<Reference> getDataSpecificationReference() const override;
+ virtual const std::string * const getVersion() const override;
+ virtual const std::string * const getRevision() const override;
};
}
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/Identifiable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/Identifiable.h
index c44b4ad..ec717af 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/Identifiable.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/Identifiable.h
@@ -21,7 +21,7 @@
// Constructors
Identifiable(const std::string & idShort, const Identifier & identifier);
- explicit Identifiable(const api::IIdentifiable & other);
+ explicit Identifiable(const api::IIdentifiable & other);
bool hasAdministrativeInformation() const noexcept override;
@@ -31,7 +31,7 @@
Identifier getIdentification() const override;
- void setAdministrativeInformation(const AdministrativeInformation & administrativeInformation);
+ void setAdministrativeInformation(const AdministrativeInformation & administrativeInformation);
};
}
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/Qualifiable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/Qualifiable.h
index 6521a47..74016be 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/Qualifiable.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/Qualifiable.h
@@ -3,6 +3,7 @@
#include <BaSyx/submodel/api_v2/qualifier/IQualifiable.h>
+#include <BaSyx/submodel/simple/constraint/Qualifier.h>
namespace basyx {
namespace submodel {
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/Referable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/Referable.h
index 22127b8..86ec5f4 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/Referable.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/Referable.h
@@ -15,12 +15,14 @@
std::string idShort;
std::string category;
LangStringSet description;
- const IReferable * const parent;
+ IReferable * parent;
+
+ KeyElements keyElementType;
public:
virtual ~Referable() = default;
// Constructors
- Referable(const std::string & idShort, const Referable * parent = nullptr);
+ Referable(const std::string & idShort, Referable * parent = nullptr);
Referable(const IReferable & other);
// Inherited via IReferable
@@ -29,7 +31,8 @@
virtual LangStringSet & getDescription() override;
virtual const LangStringSet & getDescription() const override;
- virtual const IReferable * const getParent() const override;
+ virtual void setParent(IReferable * parent) override;
+ virtual IReferable * getParent() const override;
// not inherited
void setIdShort(const std::string & shortID);
@@ -38,6 +41,11 @@
bool hasParent() const noexcept;
bool hasDescription() const noexcept;
bool hasCategory() const noexcept;
+
+ simple::Reference getReference() const override;
+ simple::Key getKey(bool local = true) const override;
+
+ KeyElements getKeyElementType() const override;
};
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/reference/Key.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/reference/Key.h
index ddadb29..8fca8be 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/reference/Key.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/reference/Key.h
@@ -3,7 +3,7 @@
#include <BaSyx/submodel/enumerations/KeyType.h>
#include <BaSyx/submodel/enumerations/KeyElements.h>
-#include <BaSyx/submodel/api_v2/reference/IKey.h>
+//#include <BaSyx/submodel/api_v2/reference/IKey.h>
#include <string>
@@ -11,7 +11,7 @@
namespace submodel {
namespace simple {
-class Key : public api::IKey
+class Key // : public api::IKey
{
private:
KeyElements type;
@@ -24,10 +24,13 @@
bool operator!=(const Key & other) const;
inline bool operator==(const Key & other) const { return !(*this != other); };
public:
- KeyElements getType() const noexcept override;
- KeyType getIdType() const noexcept override;
- bool isLocal() const noexcept override;
- std::string getValue() const noexcept override;
+ KeyElements getType() const noexcept;
+ KeyType getIdType() const noexcept;
+ bool isLocal() const noexcept;
+ std::string getValue() const noexcept;
+
+ bool isGlobalKey() const noexcept;
+ bool isModelKey() const noexcept;
};
}
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/reference/Reference.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/reference/Reference.h
index 8a8e0f7..0ddbe82 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/reference/Reference.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/reference/Reference.h
@@ -2,7 +2,6 @@
#define BASYX_SUBMODEL_SIMPLE_REFERENCE_REFERENCE_H
#include <BaSyx/submodel/api_v2/reference/IReference.h>
-#include <BaSyx/submodel/api_v2/qualifier/IIdentifiable.h>
#include <BaSyx/submodel/simple/reference/Key.h>
@@ -43,8 +42,6 @@
void addKey(const Key & key) override;
bool empty() const override;
-public:
- static Reference FromIdentifiable(KeyElements keyElementType, const api::IIdentifiable & identifiable);
};
}
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/submodelelement/SubmodelElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/submodelelement/SubmodelElement.h
index 05c55fe..6a1670b 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/submodelelement/SubmodelElement.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/submodelelement/SubmodelElement.h
@@ -6,41 +6,58 @@
#include <BaSyx/submodel/simple/qualifier/HasDataSpecification.h>
#include <BaSyx/submodel/api_v2/qualifier/IHasKind.h>
#include <BaSyx/submodel/simple/qualifier/Referable.h>
+#include <BaSyx/submodel/simple/qualifier/Qualifiable.h>
namespace basyx {
namespace submodel {
namespace simple {
-class SubmodelElement : public virtual api::ISubmodelElement
+class SubmodelElement
+ : public api::ISubmodelElement
{
private:
HasDataSpecification dataSpecification;
ModelingKind kind;
Reference semanticId;
Referable referable;
+ Qualifiable qualifiable;
+ ModelTypes modelType;
public:
SubmodelElement(const std::string & idShort, ModelingKind kind = ModelingKind::Instance);
- virtual ~SubmodelElement() = default;
+ ~SubmodelElement() = default;
// Inherited via IHasDataSemantics
- virtual const api::IReference & getSemanticId() const override;
- void setSemanticId(Reference reference);
+ const api::IReference & getSemanticId() const override;
+ void setSemanticId(const api::IReference & reference) override;
// Inherited via IHasDataSpecification
- virtual void addDataSpecification(const Reference & reference) override;
- virtual const std::vector<Reference> getDataSpecificationReference() const override;
+ void addDataSpecification(const Reference & reference) override;
+ const std::vector<Reference> getDataSpecificationReference() const override;
// Inherited via IReferable
- virtual const std::string & getIdShort() const override;
- virtual const std::string * const getCategory() const override;
- virtual simple::LangStringSet & getDescription() override;
- virtual const simple::LangStringSet & getDescription() const override;
- virtual const IReferable * const getParent() const override;
+ const std::string & getIdShort() const override;
+ const std::string * const getCategory() const override;
+ void setCategory(const std::string & category) override;
+ simple::LangStringSet & getDescription() override;
+ const simple::LangStringSet & getDescription() const override;
+ IReferable * getParent() const override;
+ void setParent(IReferable * parent) override;
+ Key getKey(bool local) const override;
+ simple::Reference getReference() const override;
// Inherited via IHasKind
- virtual ModelingKind getKind() const override;
+ ModelingKind getKind() const override;
+
+ // Inherited via IQualifiable
+ std::vector<Formula> getFormulas() const override;
+ std::vector<Qualifier> getQualifiers() const override;
+ void addFormula(const api::IFormula & formula) override;
+ void addQualifier(const api::IQualifier & qualifier) override;
+
+ // Inherited vie IModelType
+ ModelTypes GetModelType() const override;
};
}
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/submodelelement/property/Property.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/submodelelement/property/Property.h
index d254313..2eb2efb 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/submodelelement/property/Property.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/submodelelement/property/Property.h
@@ -13,7 +13,9 @@
namespace simple {
template<typename T>
-class Property : public SubmodelElement, public IProperty
+class Property
+ : public SubmodelElement
+ , public virtual api::IProperty
{
private:
std::string valueType;
@@ -63,10 +65,12 @@
return &this->valueId;
}
- virtual void setValueId(const Reference & valueId) override
+ virtual void setValueId(const api::IReference & valueId) override
{
this->valueId = valueId;
}
+
+ virtual KeyElements getKeyElementType() const override { return KeyElements::Property; };
};
}
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/util/tools/StringTools.h b/sdks/c++/basys.sdk.cc/include/BaSyx/util/tools/StringTools.h
index 315d3c0..f4a5bb0 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/util/tools/StringTools.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/util/tools/StringTools.h
@@ -29,7 +29,7 @@
* Assumes that target is big enough to carry the content of str
*/
static std::size_t toArray(std::string const& str, char* target) {
- CoderTools::setInt32(target, 0, str.length());
+ CoderTools::setInt32(target, 0, static_cast<uint32_t>(str.length()));
target += 4;
std::memcpy(target, str.c_str(), str.length());
return str.length() + 4;
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/vab/backend/connector/JSONProvider.h b/sdks/c++/basys.sdk.cc/include/BaSyx/vab/backend/connector/JSONProvider.h
index b38d701..3d077a0 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/vab/backend/connector/JSONProvider.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/vab/backend/connector/JSONProvider.h
@@ -109,9 +109,7 @@
std::string serializeSuccess()
{
- nlohmann::json retJson { { "success", true } };
-
- return retJson.dump(4);
+ return "";
}
};
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/vab/backend/connector/native/BaSyxConnector.h b/sdks/c++/basys.sdk.cc/include/BaSyx/vab/backend/connector/native/BaSyxConnector.h
index fc19d2a..686b08f 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/vab/backend/connector/native/BaSyxConnector.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/vab/backend/connector/native/BaSyxConnector.h
@@ -22,7 +22,7 @@
class NativeConnector : public IBaSyxConnector {
public:
- static constexpr std::size_t default_buffer_length = 4096;
+ static constexpr std::size_t default_buffer_length = 8192;
private:
basyx::net::tcp::Socket socket;
std::array<char, default_buffer_length> buffer;
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/vab/provider/VABModelProvider.h b/sdks/c++/basys.sdk.cc/include/BaSyx/vab/provider/VABModelProvider.h
index e7e2d61..0349585 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/vab/provider/VABModelProvider.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/vab/provider/VABModelProvider.h
@@ -17,7 +17,7 @@
class VABModelProvider : public vab::core::IModelProvider
{
-private:
+protected:
basyx::log log;
basyx::object elements;
public:
diff --git a/sdks/c++/basys.sdk.cc/src/aas/BaSyxAASConfig.cmake.in b/sdks/c++/basys.sdk.cc/src/aas/BaSyxAASConfig.cmake.in
deleted file mode 100644
index 74d9791..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/BaSyxAASConfig.cmake.in
+++ /dev/null
@@ -1,12 +0,0 @@
-include(CMakeFindDependencyMacro)
-
-set(BASYX_AAS_VERSION_STRING "@PROJECT_VERSION@")
-
-find_dependency(BaSyxShared)
-find_dependency(BaSyxAbstraction)
-find_dependency(BaSyxVAB)
-find_dependency(BaSyxSubmodel)
-
-include("${CMAKE_CURRENT_LIST_DIR}/@BASYX_AAS_LIBRARY_NAME@Targets.cmake")
-
-@PACKAGE_INIT@
diff --git a/sdks/c++/basys.sdk.cc/src/aas/CMakeLists.txt b/sdks/c++/basys.sdk.cc/src/aas/CMakeLists.txt
deleted file mode 100644
index aae27db..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/CMakeLists.txt
+++ /dev/null
@@ -1,98 +0,0 @@
-###############################################
-### BaSyx::AAS ###
-###############################################
-include(CMakePackageConfigHelpers)
-
-set (BASYX_AAS_LIB_SUFFIX "AAS")
-
-set (BASYX_AAS_LIBRARY_NAME "${PROJECT_SHORTNAME}${BASYX_AAS_LIB_SUFFIX}")
-
-set (BASYX_AAS_INCLUDE_DIR "${BASYX_INCLUDE_DIR}/BaSyx/aas")
-set (PROJECT_INCLUDE_DIR BASYX_AAS_INCLUDE_DIR)
-
-add_library(${BASYX_AAS_LIB_SUFFIX})
-
-set_target_properties(${BASYX_AAS_LIB_SUFFIX} PROPERTIES VERSION ${PROJECT_VERSION})
-set_target_properties(${BASYX_AAS_LIB_SUFFIX} PROPERTIES SOVERSION ${BASYX_PACKAGE_VERSION_MAJOR})
-set_target_properties(${BASYX_AAS_LIB_SUFFIX} PROPERTIES PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_SHORTNAME}")
-
-target_include_directories(${BASYX_AAS_LIB_SUFFIX}
- INTERFACE ${CMAKE_INSTALL_PREFIX}/include
- ${CMAKE_INSTALL_PREFIX}/include/${PROJECT_SHORTNAME})
-
-target_sources(${BASYX_AAS_LIB_SUFFIX}
- PRIVATE
- ${CMAKE_CURRENT_SOURCE_DIR}/aas/map/constant_definitions.cpp
- ${BASYX_AAS_INCLUDE_DIR}/api/manager/IAssetAdministrationShellManager.h
- ${BASYX_AAS_INCLUDE_DIR}/api/metamodel/IAssetAdministrationShell.h
- ${BASYX_AAS_INCLUDE_DIR}/api/parts/IAsset.h
- ${BASYX_AAS_INCLUDE_DIR}/api/parts/IConceptDictionary.h
- ${BASYX_AAS_INCLUDE_DIR}/api/parts/IView.h
- ${BASYX_AAS_INCLUDE_DIR}/api/policypoints/IAccessControlPolicyPoints.h
- ${BASYX_AAS_INCLUDE_DIR}/api/security/ISecurity.h
-# ${CMAKE_CURRENT_SOURCE_DIR}/aas/connected/aas/ConnectedAssetAdministrationShell.cpp
-# ${BASYX_AAS_INCLUDE_DIR}/connected/aas/ConnectedAssetAdministrationShell.h
-# ${CMAKE_CURRENT_SOURCE_DIR}/aas/connected/aas/ConnectedAssetAdministrationShellManager.cpp
-# ${BASYX_AAS_INCLUDE_DIR}/connected/aas/ConnectedAssetAdministrationShellManager.h
- ${CMAKE_CURRENT_SOURCE_DIR}/aas/map/descriptor/ModelDescriptor.cpp
- ${BASYX_AAS_INCLUDE_DIR}/map/descriptor/ModelDescriptor.h
- ${CMAKE_CURRENT_SOURCE_DIR}/aas/map/descriptor/SubModelDescriptor.cpp
- ${BASYX_AAS_INCLUDE_DIR}/map/descriptor/SubModelDescriptor.h
- ${CMAKE_CURRENT_SOURCE_DIR}/aas/map/metamodel/AssetAdministrationShell.cpp
- ${BASYX_AAS_INCLUDE_DIR}/map/metamodel/AssetAdministrationShell.h
- ${CMAKE_CURRENT_SOURCE_DIR}/aas/map/manager/AssetAdministrationShellManager.cpp
- ${BASYX_AAS_INCLUDE_DIR}/map/manager/AssetAdministrationShellManager.h
- ${CMAKE_CURRENT_SOURCE_DIR}/aas/map/modelurn/ModelUrn.cpp
- ${BASYX_AAS_INCLUDE_DIR}/map/modelurn/ModelUrn.h
- ${CMAKE_CURRENT_SOURCE_DIR}/aas/map/parts/Asset.cpp
- ${BASYX_AAS_INCLUDE_DIR}/map/parts/Asset.h
- ${CMAKE_CURRENT_SOURCE_DIR}/aas/map/parts/ConceptDictionary.cpp
- ${BASYX_AAS_INCLUDE_DIR}/map/parts/ConceptDictionary.h
- ${CMAKE_CURRENT_SOURCE_DIR}/aas/map/parts/View.cpp
- ${BASYX_AAS_INCLUDE_DIR}/map/parts/View.h
- ${CMAKE_CURRENT_SOURCE_DIR}/aas/map/security/Security.cpp
- ${BASYX_AAS_INCLUDE_DIR}/map/security/Security.h
-)
-
-
-target_include_directories(${BASYX_AAS_LIB_SUFFIX} PRIVATE ${PROJECT_SOURCE_DIR})
-target_link_libraries(${BASYX_AAS_LIB_SUFFIX} PUBLIC BaSyx::Shared BaSyx::Abstraction BaSyx::VAB BaSyx::Submodel)
-
-add_library(basyx::aas ALIAS ${BASYX_AAS_LIB_SUFFIX})
-add_library(${PROJECT_SHORTNAME}::${BASYX_AAS_LIB_SUFFIX} ALIAS ${BASYX_AAS_LIB_SUFFIX})
-
-diagnostics_print(${BASYX_AAS_LIB_SUFFIX})
-
-###############################################
-### Install section ###
-###############################################
-if(${BASYX_INSTALL_SDK})
-configure_package_config_file(
- ${CMAKE_CURRENT_SOURCE_DIR}/${BASYX_AAS_LIBRARY_NAME}Config.cmake.in
- ${CMAKE_CURRENT_BINARY_DIR}/${BASYX_AAS_LIBRARY_NAME}Config.cmake
- INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${BASYX_AAS_LIBRARY_NAME}
- PATH_VARS
- CMAKE_INSTALL_PREFIX
-)
-
-install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${BASYX_AAS_LIBRARY_NAME}Config.cmake
- DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${BASYX_AAS_LIBRARY_NAME}
- )
-
-install(EXPORT ${BASYX_AAS_LIB_SUFFIX}Targets
- NAMESPACE ${PROJECT_SHORTNAME}::
- FILE ${BASYX_AAS_LIBRARY_NAME}Targets.cmake
- DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${BASYX_AAS_LIBRARY_NAME}
- )
-
-install(TARGETS ${BASYX_AAS_LIB_SUFFIX}
- EXPORT ${BASYX_AAS_LIB_SUFFIX}Targets
- ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
- LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
- )
-
-install(DIRECTORY "${BASYX_INCLUDE_DIR}/${PROJECT_SHORTNAME}/aas"
- DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_SHORTNAME}"
- FILES_MATCHING PATTERN "*.h"
- )
-endif()
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/aas/aas/connected/aas/ConnectedAssetAdministrationShell.cpp b/sdks/c++/basys.sdk.cc/src/aas/aas/connected/aas/ConnectedAssetAdministrationShell.cpp
deleted file mode 100644
index 0521f0b..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/aas/connected/aas/ConnectedAssetAdministrationShell.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * ConnectedAssetAdministrationShell.cpp
- *
- * Author: wendel
- */
-
-#include "BaSyx/aas/connected/ConnectedAssetAdministrationShell.h"
-
-
-namespace basyx {
-namespace aas {
-namespace backend {
-
-ConnectedAssetAdministrationShell::ConnectedAssetAdministrationShell(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy, std::shared_ptr<api::manager::IAssetAdministrationShellManager> manager) :
- ConnectedVABModelMap(proxy),
- manager(manager)
-{}
-
-basyx::specificCollection_t<submodel::IReference> ConnectedAssetAdministrationShell::getDataSpecificationReferences() const
-{
- return basyx::specificCollection_t<submodel::IReference>();
-}
-
-std::string ConnectedAssetAdministrationShell::getIdShort() const
-{
- return std::string();
-}
-
-std::string ConnectedAssetAdministrationShell::getCategory() const
-{
- return std::string();
-}
-
-submodel::Description ConnectedAssetAdministrationShell::getDescription() const
-{
- return submodel::Description("","");
-}
-
-std::shared_ptr<submodel::IReference> ConnectedAssetAdministrationShell::getParent() const
-{
- return std::shared_ptr<submodel::IReference>();
-}
-
-std::shared_ptr<submodel::IAdministrativeInformation> ConnectedAssetAdministrationShell::getAdministration() const
-{
- return nullptr;
-}
-
-std::shared_ptr<submodel::IIdentifier> ConnectedAssetAdministrationShell::getIdentification() const
-{
- return std::shared_ptr<submodel::IIdentifier>();
-}
-
-basyx::specificMap_t<submodel::ISubModel> ConnectedAssetAdministrationShell::getSubModels() const
-{
- return basyx::specificMap_t<submodel::ISubModel>();
-}
-
-void ConnectedAssetAdministrationShell::addSubModel(const descriptor::SubModelDescriptor & subModelDescriptor)
-{}
-
-std::shared_ptr<security::ISecurity> ConnectedAssetAdministrationShell::getSecurity() const
-{
- return std::shared_ptr<security::ISecurity>();
-}
-
-std::shared_ptr<submodel::IReference> ConnectedAssetAdministrationShell::getDerivedFrom() const
-{
- return std::shared_ptr<submodel::IReference>();
-}
-
-std::shared_ptr<aas::IAsset> ConnectedAssetAdministrationShell::getAsset() const
-{
- return std::shared_ptr<aas::IAsset>();
-}
-
-void ConnectedAssetAdministrationShell::setSubmodels(const basyx::specificCollection_t<descriptor::SubModelDescriptor> & submodels)
-{}
-
-basyx::specificCollection_t<descriptor::SubModelDescriptor> ConnectedAssetAdministrationShell::getSubModelDescriptors() const
-{
- return basyx::specificCollection_t<descriptor::SubModelDescriptor>();
-}
-
-basyx::specificCollection_t<IView> ConnectedAssetAdministrationShell::getViews() const
-{
- return basyx::specificCollection_t<IView>();
-}
-
-basyx::specificCollection_t<IConceptDictionary> ConnectedAssetAdministrationShell::getConceptDictionary() const
-{
- return basyx::specificCollection_t<IConceptDictionary>();
-}
-
-
-}
-}
-}
-
diff --git a/sdks/c++/basys.sdk.cc/src/aas/aas/connected/aas/ConnectedAssetAdministrationShellManager.cpp b/sdks/c++/basys.sdk.cc/src/aas/aas/connected/aas/ConnectedAssetAdministrationShellManager.cpp
deleted file mode 100644
index e3cf9a4..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/aas/connected/aas/ConnectedAssetAdministrationShellManager.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * ConnectedAssetAdministrationShellManager.cpp
- *
- * Author: wendel
- */
-
-#include "BaSyx/aas/connected/ConnectedAssetAdministrationShellManager.h"
diff --git a/sdks/c++/basys.sdk.cc/src/aas/aas/connected/aas/dataspecification/IDataSpecification.h b/sdks/c++/basys.sdk.cc/src/aas/aas/connected/aas/dataspecification/IDataSpecification.h
deleted file mode 100644
index 64a8866..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/aas/connected/aas/dataspecification/IDataSpecification.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * IDataSpecification.h
- *
- * Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IDATASPECIFICATION_H_
-#define BASYX_METAMODEL_IDATASPECIFICATION_H_
-
-#include "aas/reference/IReference.h"
-
-#include "BaSyx/types.h"
-
-#include <string>
-namespace basyx {
-namespace aas {
-namespace backend {
-namespace connected {
-namespace dataspecification {
-
-namespace PathSpecification
-{
-long serialVersionUID = 1L;
-std::string PREFERREDNAME = "preferredName";
-std::string SHORTNAME = "shortName";
-std::string UNIT = "unit";
-std::string UNITID = "unitId";
-std::string SOURCEOFDEFINITION = "sourceOfDefinition";
-std::string SYMBOL = "symbol";
-std::string DATATYPE = "dataType";
-std::string DEFINITION = "definition";
-std::string VALUEFORMAT = "valueFormat";
-std::string VALUELIST = "valueList";
-std::string CODE = "code";
-}
-
-class IDataSpecification
-{
-public:
- virtual ~IDataSpecification() = default;
-
- virtual std::string getPreferredName() const = 0;
- virtual std::string getShortName() const = 0;
- virtual std::string getUnit() const = 0;
- //virtual IReference getUnitId() const = 0;
- virtual std::string getSourceOfDefinition() const = 0;
- virtual std::string getSymbol() const = 0;
- virtual std::string getDataType() const = 0;
- virtual std::string getDefinition() const = 0;
- virtual std::string getValueFormat() const = 0;
- virtual std::string getValueList() const = 0;
- virtual std::string getCode() const = 0;
-
- virtual void setPreferredName(const std::string & preferredName) = 0;
- virtual void setShortName(const std::string & shortName) = 0;
- virtual void setUnit(const std::string & uni) = 0;
- virtual void setUnitId(const IReference & unitId) = 0;
- virtual void setSourceOfDefinition(const std::string & sourceOfDefinition) = 0;
- virtual void setSymbol(const std::string & symbol) = 0;
- virtual void setDataType(const std::string & dataType) = 0;
- virtual void setDefinition(const std::string & definition) = 0;
- virtual void setValueFormat(const std::string & valueFormat) = 0;
- virtual void setValueList(const basyx::object & obj) = 0;
- virtual void setCode(const basyx::object & obj) = 0;
-};
-
-#endif
-}
-}
-}
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/aas/aas/map/constant_definitions.cpp b/sdks/c++/basys.sdk.cc/src/aas/aas/map/constant_definitions.cpp
deleted file mode 100644
index 06148e2..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/aas/map/constant_definitions.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#include <BaSyx/aas/api/parts/IConceptDictionary.h>
-#include <BaSyx/aas/api/parts/IAsset.h>
-#include <BaSyx/aas/api/parts/IView.h>
-#include <BaSyx/aas/api/security/ISecurity.h>
-#include <BaSyx/aas/api/metamodel/IAssetAdministrationShell.h>
-
-namespace basyx {
-namespace aas {
-
-constexpr char IConceptDictionary::Path::ConceptDescription[];
-constexpr char IConceptDictionary::Path::ConceptDescriptions[];
-
-constexpr char IAsset::Path::AssetIdentificationModel[];
-constexpr char IAsset::Path::BillOfMaterial[];
-constexpr char IAsset::Path::ModelType[];
-
-constexpr char IView::Path::ModelType[];
-constexpr char IView::Path::ContainedElement[];
-
-constexpr char ISecurity::Path::AccessControlPolicyPoints[];
-constexpr char ISecurity::Path::TrustAnchor[];
-
-constexpr char IAssetAdministrationShell::Path::DerivedFrom[];
-constexpr char IAssetAdministrationShell::Path::ModelType[];
-constexpr char IAssetAdministrationShell::Path::Security[];
-
-
-}
-}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/aas/aas/map/descriptor/ModelDescriptor.cpp b/sdks/c++/basys.sdk.cc/src/aas/aas/map/descriptor/ModelDescriptor.cpp
deleted file mode 100644
index dd87e53..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/aas/map/descriptor/ModelDescriptor.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * ModelDescriptor.cpp
- *
- * Author: wendel
- */
-
-#include "BaSyx/aas/map/descriptor/ModelDescriptor.h"
diff --git a/sdks/c++/basys.sdk.cc/src/aas/aas/map/descriptor/SubModelDescriptor.cpp b/sdks/c++/basys.sdk.cc/src/aas/aas/map/descriptor/SubModelDescriptor.cpp
deleted file mode 100644
index b2ecfac..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/aas/map/descriptor/SubModelDescriptor.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * SubModelDescriptor.cpp
- *
- * Author: wendel
- */
-
-#include "BaSyx/aas/map/descriptor/SubModelDescriptor.h"
diff --git a/sdks/c++/basys.sdk.cc/src/aas/aas/map/manager/AssetAdministrationShellManager.cpp b/sdks/c++/basys.sdk.cc/src/aas/aas/map/manager/AssetAdministrationShellManager.cpp
deleted file mode 100644
index f1d9bbe..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/aas/map/manager/AssetAdministrationShellManager.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * AssetAdministrationShellManager.cpp
- *
- * Author: wendel
- */
-
-#include "BaSyx/aas/map/manager/AssetAdministrationShellManager.h"
diff --git a/sdks/c++/basys.sdk.cc/src/aas/aas/map/metamodel/AssetAdministrationShell.cpp b/sdks/c++/basys.sdk.cc/src/aas/aas/map/metamodel/AssetAdministrationShell.cpp
deleted file mode 100644
index 94ae032..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/aas/map/metamodel/AssetAdministrationShell.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * AssetAdministrationShell.cpp
- *
- * Author: wendel
- */
-
-#include "BaSyx/aas/map/metamodel/AssetAdministrationShell.h"
-
-#include <BaSyx/aas/map/security/Security.h>
-#include <BaSyx/submodel/map/reference/Reference.h>
-
-namespace basyx {
-namespace aas {
-
-using namespace submodel;
-
-AssetAdministrationShell::AssetAdministrationShell()
- : vab::ElementMap()
- , ModelType(IAssetAdministrationShell::Path::ModelType)
-{}
-
-AssetAdministrationShell::AssetAdministrationShell(basyx::object obj)
- : vab::ElementMap(obj)
- , ModelType(IAssetAdministrationShell::Path::ModelType)
-{}
-
-AssetAdministrationShell::AssetAdministrationShell(std::shared_ptr<submodel::IReference> parentAAS)
- : vab::ElementMap()
- , ModelType(IAssetAdministrationShell::Path::ModelType)
-{
- this->setDerivedFrom(parentAAS);
-}
-
-std::shared_ptr<ISecurity> AssetAdministrationShell::getSecurity() const
-{
- return std::make_shared<Security>(this->map.getProperty(IAssetAdministrationShell::Path::Security));
-}
-
-void AssetAdministrationShell::setSecurity(std::shared_ptr<ISecurity> security) const
-{
- this->map.insertKey(IAssetAdministrationShell::Path::Security, Security(*security).getMap());
-}
-
-std::shared_ptr<submodel::IReference> AssetAdministrationShell::getDerivedFrom() const
-{
- return std::make_shared<Reference>(this->map.getProperty(IAssetAdministrationShell::Path::DerivedFrom));
-}
-
-void AssetAdministrationShell::setDerivedFrom(std::shared_ptr<submodel::IReference> derived_from) const
-{
- this->map.insertKey(IAssetAdministrationShell::Path::DerivedFrom, Reference(*derived_from).getMap());
-}
-
-}
-}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/aas/aas/map/modelurn/ModelUrn.cpp b/sdks/c++/basys.sdk.cc/src/aas/aas/map/modelurn/ModelUrn.cpp
deleted file mode 100644
index 5f25390..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/aas/map/modelurn/ModelUrn.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * ModelUrn.cpp
- *
- * Author: wendel
- */
-
-#include "BaSyx/aas/map/modelurn/ModelUrn.h"
diff --git a/sdks/c++/basys.sdk.cc/src/aas/aas/map/parts/Asset.cpp b/sdks/c++/basys.sdk.cc/src/aas/aas/map/parts/Asset.cpp
deleted file mode 100644
index 781e469..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/aas/map/parts/Asset.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Asset.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/aas/map/parts/Asset.h>
-
-#include <BaSyx/submodel/map/reference/Reference.h>
-
-namespace basyx {
-namespace aas {
-
-using namespace submodel;
-
-Asset::Asset()
- : ModelType(IAsset::Path::ModelType)
-{}
-
-Asset::Asset(const std::shared_ptr<submodel::IReference> & submodel)
- : ModelType(IAsset::Path::ModelType)
-{
- this->setAssetIdentificationModel(submodel);
-}
-
-std::shared_ptr<submodel::IReference> Asset::getAssetIdentificationModel() const
-{
- return std::make_shared<Reference>(this->map.getProperty(IAsset::Path::AssetIdentificationModel));
-}
-
-std::shared_ptr<submodel::IReference> Asset::getBillOfMaterial() const
-{
- return std::make_shared<Reference>(this->map.getProperty(IAsset::Path::BillOfMaterial));
-}
-
-
-void Asset::setAssetIdentificationModel(const std::shared_ptr<submodel::IReference>& submodel)
-{
- this->map.insertKey(IAsset::Path::AssetIdentificationModel, submodel::Reference(*submodel).getMap());
-}
-
-void Asset::setBillOfMaterial(const std::shared_ptr<submodel::IReference>& submodel)
-{
- this->map.insertKey(IAsset::Path::BillOfMaterial, submodel::Reference(*submodel).getMap());
-}
-
-}
-}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/aas/aas/map/parts/ConceptDictionary.cpp b/sdks/c++/basys.sdk.cc/src/aas/aas/map/parts/ConceptDictionary.cpp
deleted file mode 100644
index 9d8b861..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/aas/map/parts/ConceptDictionary.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * ConceptDictionary.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/aas/map/parts/ConceptDictionary.h>
-
-#include <BaSyx/submodel/map/reference/Reference.h>
-
-using namespace basyx::submodel;
-
-namespace basyx {
-namespace aas {
-
-ConceptDictionary::ConceptDictionary(basyx::object obj)
- : vab::ElementMap(obj)
-{}
-
-ConceptDictionary::ConceptDictionary(basyx::specificCollection_t<submodel::IReference> concept_descriptions)
- : vab::ElementMap()
-{
- this->setConceptDescription(concept_descriptions);
-}
-
-basyx::specificCollection_t<submodel::IReference> ConceptDictionary::getConceptDescription() const
-{
- auto description_objects = this->map.getProperty(IConceptDictionary::Path::ConceptDescriptions).Get<basyx::object::object_list_t>();
- return vab::ElementMap::make_specific_collection<IReference, Reference>(description_objects);
-}
-
-void ConceptDictionary::setConceptDescription(const basyx::specificCollection_t<submodel::IReference>& references)
-{
- auto description_objects = vab::ElementMap::make_object_list<IReference, Reference>(references);
- this->map.insertKey(IConceptDictionary::Path::ConceptDescriptions, description_objects);
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/aas/aas/map/parts/View.cpp b/sdks/c++/basys.sdk.cc/src/aas/aas/map/parts/View.cpp
deleted file mode 100644
index 9f652a7..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/aas/map/parts/View.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * View.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/aas/map/parts/View.h>
-
-#include <BaSyx/submodel/map/reference/Reference.h>
-
-using namespace basyx::submodel;
-
-namespace basyx {
-namespace aas {
-
-View::View(basyx::object obj)
- : vab::ElementMap(obj)
-{}
-
-View::View()
- : vab::ElementMap()
- , ModelType(IView::Path::ModelType)
-{}
-
-View::View(const basyx::specificCollection_t<submodel::IReference>& references)
- : vab::ElementMap()
- , ModelType(IView::Path::ModelType)
-{
- this->setContainedElements(references);
-}
-
-void View::setContainedElements(const basyx::specificCollection_t<submodel::IReference>& references)
-{
- auto description_objects = vab::ElementMap::make_object_list<IReference, Reference>(references);
- this->map.insertKey(IView::Path::ContainedElement, description_objects);
-}
-
-basyx::specificCollection_t<submodel::IReference> View::getContainedElements() const
-{
- auto description_objects = this->map.getProperty(IView::Path::ContainedElement).Get<basyx::object::object_list_t>();
- return vab::ElementMap::make_specific_collection<IReference, Reference>(description_objects);
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/aas/aas/map/security/Security.cpp b/sdks/c++/basys.sdk.cc/src/aas/aas/map/security/Security.cpp
deleted file mode 100644
index 590fd8a..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/aas/map/security/Security.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Security.cpp
- *
- * Author: wendel
- */
-
-#include "BaSyx/aas/map/security/Security.h"
-
-namespace basyx {
-namespace aas {
-
-Security::Security(ISecurity & other)
- : vab::ElementMap()
-{}
-
-Security::Security(basyx::object obj)
- : vab::ElementMap(obj)
-{}
-
-basyx::object Security::getAccessControlPolicyPoints() const
-{
- return this->map.getProperty(ISecurity::Path::AccessControlPolicyPoints);
-}
-
-basyx::object Security::getTrustAnchor() const
-{
- return this->map.getProperty(ISecurity::Path::TrustAnchor);
-}
-
-void Security::setAccessControlPolicyPoints(const basyx::object & obj)
-{
- this->map.insertKey(ISecurity::Path::AccessControlPolicyPoints, obj);
-}
-
-void Security::setTrustAnchor(const basyx::object & obj)
-{
- this->map.insertKey(ISecurity::Path::TrustAnchor, obj);
-}
-
-}
-}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/abstraction/CMakeLists.txt b/sdks/c++/basys.sdk.cc/src/abstraction/CMakeLists.txt
index 2b733ab..921ffbf 100644
--- a/sdks/c++/basys.sdk.cc/src/abstraction/CMakeLists.txt
+++ b/sdks/c++/basys.sdk.cc/src/abstraction/CMakeLists.txt
@@ -16,7 +16,10 @@
set_target_properties(${BASYX_ABSTRACTION_LIB_SUFFIX} PROPERTIES PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_SHORTNAME}")
target_include_directories(${BASYX_ABSTRACTION_LIB_SUFFIX}
INTERFACE ${CMAKE_INSTALL_PREFIX}/include
- ${CMAKE_INSTALL_PREFIX}/include/${PROJECT_SHORTNAME})
+ PUBLIC
+ $<BUILD_INTERFACE:${BASYX_INCLUDE_DIR}>
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>
+)
## basyx::thread sources ##
@@ -91,7 +94,15 @@
add_library(basyx::abstraction ALIAS ${BASYX_ABSTRACTION_LIB_SUFFIX})
add_library(${PROJECT_SHORTNAME}::${BASYX_ABSTRACTION_LIB_SUFFIX} ALIAS ${BASYX_ABSTRACTION_LIB_SUFFIX})
-diagnostics_print(${BASYX_ABSTRACTION_LIB_SUFFIX})
+if(BASYX_IS_SUBMODULE)
+ set_target_properties(${BASYX_ABSTRACTION_LIB_SUFFIX} PROPERTIES FOLDER BaSyx)
+endif()
+
+if(BASYX_VERBOSE_CMAKE_OUTPUT)
+ diagnostics_print(${BASYX_ABSTRACTION_LIB_SUFFIX})
+endif()
+
+build_source_group(${BASYX_ABSTRACTION_LIB_SUFFIX})
###############################################
### Install section ###
diff --git a/sdks/c++/basys.sdk.cc/src/controlcomponent/CMakeLists.txt b/sdks/c++/basys.sdk.cc/src/controlcomponent/CMakeLists.txt
new file mode 100644
index 0000000..ec7be80
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/controlcomponent/CMakeLists.txt
@@ -0,0 +1,70 @@
+######################################################
+### BaSyx::ControlComponent ###
+######################################################
+
+include(CMakePackageConfigHelpers)
+
+set (BASYX_CONTROLCOMPONENT_LIB_SUFFIX "Controlcomponent")
+
+set (BASYX_CONTROLCOMPONENT_LIBRARY_NAME "${PROJECT_SHORTNAME}${BASYX_CONTROLCOMPONENT_LIB_SUFFIX}")
+
+set (BASYX_CONTROLCOMPONENT_INCLUDE_DIR "${BASYX_INCLUDE_DIR}/BaSyx/controlcomponent")
+set (PROJECT_INCLUDE_DIR BASYX_CONTROLCOMPONENT_INCLUDE_DIR)
+
+add_library(${BASYX_CONTROLCOMPONENT_LIB_SUFFIX})
+
+set_target_properties(${BASYX_CONTROLCOMPONENT_LIB_SUFFIX} PROPERTIES VERSION ${PROJECT_VERSION})
+set_target_properties(${BASYX_CONTROLCOMPONENT_LIB_SUFFIX} PROPERTIES SOVERSION ${BASYX_PACKAGE_VERSION_MAJOR})
+set_target_properties(${BASYX_CONTROLCOMPONENT_LIB_SUFFIX} PROPERTIES PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_SHORTNAME}")
+set_target_properties(${BASYX_CONTROLCOMPONENT_LIB_SUFFIX} PROPERTIES LINKER_LANGUAGE CXX)
+
+target_include_directories(${BASYX_CONTROLCOMPONENT_LIB_SUFFIX}
+ PUBLIC
+ $<BUILD_INTERFACE:${BASYX_INCLUDE_DIR}>
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>
+)
+
+
+
+#Implementation files
+target_sources(${BASYX_CONTROLCOMPONENT_LIB_SUFFIX}
+ PRIVATE
+ ${CMAKE_CURRENT_SOURCE_DIR}/enumerations/ControlComponentConstants.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/enumerations/ExecutionOrder.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/enumerations/ExecutionState.cpp
+
+ ${CMAKE_CURRENT_SOURCE_DIR}/map/ControlComponent.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/simple/ControlComponent.cpp
+)
+
+#Header files
+target_sources(${BASYX_CONTROLCOMPONENT_LIB_SUFFIX}
+ PRIVATE
+ ${BASYX_CONTROLCOMPONENT_INCLUDE_DIR}/interfaces/IControlComponentChangeListener.h
+ ${BASYX_CONTROLCOMPONENT_INCLUDE_DIR}/interfaces/IControlComponent.h
+
+ ${BASYX_CONTROLCOMPONENT_INCLUDE_DIR}/enumerations/ControlComponentConstants.h
+ ${BASYX_CONTROLCOMPONENT_INCLUDE_DIR}/enumerations/ExecutionMode.h
+ ${BASYX_CONTROLCOMPONENT_INCLUDE_DIR}/enumerations/ExecutionOrder.h
+ ${BASYX_CONTROLCOMPONENT_INCLUDE_DIR}/enumerations/ExecutionState.h
+ ${BASYX_CONTROLCOMPONENT_INCLUDE_DIR}/enumerations/OccupationState.h
+
+ ${BASYX_CONTROLCOMPONENT_INCLUDE_DIR}/map/ControlComponent.h
+ ${BASYX_CONTROLCOMPONENT_INCLUDE_DIR}/simple/ControlComponent.h
+ )
+
+add_library(basyx::controlcomponent ALIAS ${BASYX_CONTROLCOMPONENT_LIB_SUFFIX})
+add_library(${PROJECT_SHORTNAME}::${BASYX_CONTROLCOMPONENT_LIB_SUFFIX} ALIAS ${BASYX_CONTROLCOMPONENT_LIB_SUFFIX})
+
+target_include_directories(${BASYX_CONTROLCOMPONENT_LIB_SUFFIX} PRIVATE ${PROJECT_SOURCE_DIR})
+target_link_libraries(${BASYX_CONTROLCOMPONENT_LIB_SUFFIX}
+ PUBLIC
+ BaSyx::Shared
+ BaSyx::VAB
+)
+
+if(BASYX_IS_SUBMODULE)
+ set_target_properties(${BASYX_CONTROLCOMPONENT_LIB_SUFFIX} PROPERTIES FOLDER BaSyx)
+endif()
+
+build_source_group(${BASYX_CONTROLCOMPONENT_LIB_SUFFIX})
diff --git a/sdks/c++/basys.sdk.cc/src/controlcomponent/enumerations/ControlComponentConstants.cpp b/sdks/c++/basys.sdk.cc/src/controlcomponent/enumerations/ControlComponentConstants.cpp
new file mode 100644
index 0000000..4703f6c
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/controlcomponent/enumerations/ControlComponentConstants.cpp
@@ -0,0 +1,69 @@
+#include <BaSyx/controlcomponent/enumerations/ControlComponentConstants.h>
+
+#include <array>
+#include <algorithm>
+#include <memory>
+#include <string>
+
+using namespace basyx::controlcomponent;
+
+using enum_pair_t = std::pair<const char*, ControlComponentConstants>;
+
+static const std::array<enum_pair_t, 34> string_to_enum =
+{
+ std::make_pair("status", ControlComponentConstants::status),
+ std::make_pair("orderList", ControlComponentConstants::orderList),
+ std::make_pair("LOCAL", ControlComponentConstants::LOCAL),
+ std::make_pair("operations", ControlComponentConstants::operations),
+ std::make_pair("service", ControlComponentConstants::service),
+ std::make_pair("clear", ControlComponentConstants::clear),
+ std::make_pair("stop", ControlComponentConstants::stop),
+ std::make_pair("abort", ControlComponentConstants::abort),
+ std::make_pair("unsuspend", ControlComponentConstants::unsuspend),
+ std::make_pair("suspend", ControlComponentConstants::suspend),
+ std::make_pair("unhold", ControlComponentConstants::unhold),
+ std::make_pair("hold", ControlComponentConstants::hold),
+ std::make_pair("reset", ControlComponentConstants::reset),
+ std::make_pair("start", ControlComponentConstants::start),
+ std::make_pair("simulation", ControlComponentConstants::simulation),
+ std::make_pair("manual", ControlComponentConstants::manual),
+ std::make_pair("auto", ControlComponentConstants::Auto),
+ std::make_pair("semiauto", ControlComponentConstants::semiauto),
+ std::make_pair("priority", ControlComponentConstants::priority),
+ std::make_pair("occupy", ControlComponentConstants::occupy),
+ std::make_pair("free", ControlComponentConstants::free),
+ std::make_pair("bstate", ControlComponentConstants::bstate),
+ std::make_pair("cmd", ControlComponentConstants::cmd),
+ std::make_pair("localOverwriteFree", ControlComponentConstants::localOverwriteFree),
+ std::make_pair("localOverwrite", ControlComponentConstants::localOverwrite),
+ std::make_pair("prevError", ControlComponentConstants::prevError),
+ std::make_pair("errorState", ControlComponentConstants::errorState),
+ std::make_pair("workState", ControlComponentConstants::workState),
+ std::make_pair("opMode", ControlComponentConstants::opMode),
+ std::make_pair("exState", ControlComponentConstants::exState),
+ std::make_pair("exMode", ControlComponentConstants::exMode),
+ std::make_pair("lastOccupier", ControlComponentConstants::lastOccupier),
+ std::make_pair("occupier", ControlComponentConstants::occupier),
+ std::make_pair("occupationState", ControlComponentConstants::occupationState),
+};
+
+ControlComponentConstants ControlComponentConstants_::from_string(const std::string & name)
+{
+ auto pair = std::find_if(string_to_enum.begin(), string_to_enum.end(),
+ [&name](const enum_pair_t & pair) {
+ return !name.compare(pair.first);
+ });
+
+ return pair->second;
+}
+
+const char * ControlComponentConstants_::to_string(ControlComponentConstants value)
+{
+ auto pair = std::find_if(string_to_enum.begin(), string_to_enum.end(),
+ [value](const enum_pair_t & pair) {
+ return value == pair.second;
+ });
+
+ return pair->first;
+}
+
diff --git a/sdks/c++/basys.sdk.cc/src/controlcomponent/enumerations/ExecutionOrder.cpp b/sdks/c++/basys.sdk.cc/src/controlcomponent/enumerations/ExecutionOrder.cpp
new file mode 100644
index 0000000..3b70e04
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/controlcomponent/enumerations/ExecutionOrder.cpp
@@ -0,0 +1,45 @@
+#include <BaSyx/controlcomponent/enumerations/ExecutionOrder.h>
+
+#include <array>
+#include <algorithm>
+#include <memory>
+#include <string>
+
+using namespace basyx::controlcomponent;
+
+using enum_pair_t = std::pair<const char*, ExecutionOrder>;
+
+static const std::array<enum_pair_t, 10> string_to_enum =
+{
+ std::make_pair("start", ExecutionOrder::start),
+ std::make_pair("complete", ExecutionOrder::complete),
+ std::make_pair("reset", ExecutionOrder::reset),
+ std::make_pair("hold", ExecutionOrder::hold),
+ std::make_pair("unhold", ExecutionOrder::unhold),
+ std::make_pair("suspend", ExecutionOrder::suspend),
+ std::make_pair("unsuspend", ExecutionOrder::unsuspend),
+ std::make_pair("clear", ExecutionOrder::clear),
+ std::make_pair("stop", ExecutionOrder::stop),
+ std::make_pair("abort", ExecutionOrder::abort),
+};
+
+ExecutionOrder ExecutionOrder_::from_string(const std::string & name)
+{
+ auto pair = std::find_if(string_to_enum.begin(), string_to_enum.end(),
+ [&name](const enum_pair_t & pair) {
+ return !name.compare(pair.first);
+ });
+
+ return pair->second;
+}
+
+const char * ExecutionOrder_::to_string(ExecutionOrder value)
+{
+ auto pair = std::find_if(string_to_enum.begin(), string_to_enum.end(),
+ [value](const enum_pair_t & pair) {
+ return value == pair.second;
+ });
+
+ return pair->first;
+}
+
diff --git a/sdks/c++/basys.sdk.cc/src/controlcomponent/enumerations/ExecutionState.cpp b/sdks/c++/basys.sdk.cc/src/controlcomponent/enumerations/ExecutionState.cpp
new file mode 100644
index 0000000..7c97d75
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/controlcomponent/enumerations/ExecutionState.cpp
@@ -0,0 +1,52 @@
+#include <BaSyx/controlcomponent/enumerations/ExecutionState.h>
+
+#include <array>
+#include <algorithm>
+#include <memory>
+#include <string>
+
+using namespace basyx::controlcomponent;
+
+using enum_pair_t = std::pair<const char*, ExecutionState>;
+
+static const std::array<enum_pair_t, 17> string_to_enum =
+{
+ std::make_pair("idle", ExecutionState::idle),
+ std::make_pair("starting", ExecutionState::starting),
+ std::make_pair("execute", ExecutionState::execute),
+ std::make_pair("completing", ExecutionState::completing),
+ std::make_pair("complete", ExecutionState::complete),
+ std::make_pair("resetting", ExecutionState::resetting),
+ std::make_pair("holding", ExecutionState::holding),
+ std::make_pair("held", ExecutionState::held),
+ std::make_pair("unholding", ExecutionState::unholding),
+ std::make_pair("suspending", ExecutionState::suspending),
+ std::make_pair("suspended", ExecutionState::suspended),
+ std::make_pair("unsuspending", ExecutionState::unsuspending),
+ std::make_pair("stopping", ExecutionState::stopping),
+ std::make_pair("stopped", ExecutionState::stopped),
+ std::make_pair("aborting", ExecutionState::aborting),
+ std::make_pair("aborted", ExecutionState::aborted),
+ std::make_pair("clearing", ExecutionState::clearing),
+};
+
+ExecutionState ExecutionState_::from_string(const std::string & name)
+{
+ auto pair = std::find_if(string_to_enum.begin(), string_to_enum.end(),
+ [&name](const enum_pair_t & pair) {
+ return !name.compare(pair.first);
+ });
+
+ return pair->second;
+}
+
+const char * ExecutionState_::to_string(ExecutionState value)
+{
+ auto pair = std::find_if(string_to_enum.begin(), string_to_enum.end(),
+ [value](const enum_pair_t & pair) {
+ return value == pair.second;
+ });
+
+ return pair->first;
+}
+
diff --git a/sdks/c++/basys.sdk.cc/src/controlcomponent/map/ControlComponent.cpp b/sdks/c++/basys.sdk.cc/src/controlcomponent/map/ControlComponent.cpp
new file mode 100644
index 0000000..f8f431a
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/controlcomponent/map/ControlComponent.cpp
@@ -0,0 +1,703 @@
+#include <BaSyx/controlcomponent/map/ControlComponent.h>
+#include <BaSyx/controlcomponent/enumerations/ControlComponentConstants.h>
+
+namespace basyx {
+namespace controlcomponent {
+namespace map {
+
+using constants = basyx::controlcomponent::ControlComponentConstants;
+using constants_ = basyx::controlcomponent::ControlComponentConstants_;
+
+ControlComponent::ControlComponent()
+ : vab::ElementMap {}, savedOccupierId {""}, status_map {object::make_map()}, operations {object::make_map()}
+{
+ this->map.insertKey(constants_::to_string(constants::orderList), std::vector<std::string>{});
+
+ //initialize status map
+ this->map.insertKey(constants_::to_string(constants::status), this->status_map);
+ this->insert_status(constants::occupationState, (int) OccupationState::free);
+ this->insert_status(constants::occupier, "");
+ this->insert_status(constants::lastOccupier, "");
+ this->insert_status(constants::exMode, (int) ExecutionMode::Auto);
+ this->insert_status(constants::exState, ExecutionState_::to_string(ExecutionState::idle));
+ this->insert_status(constants::opMode, "");
+ this->insert_status(constants::workState, "");
+ this->insert_status(constants::errorState, "");
+ this->insert_status(constants::prevError, "");
+
+ //initialize input signals
+ this->map.insertKey(constants_::to_string(constants::cmd), "");
+ this->map.insertKey(constants_::to_string(constants::localOverwrite), "");
+ this->map.insertKey(constants_::to_string(constants::localOverwriteFree), "");
+
+ // Add operations map
+ this->map.insertKey(constants_::to_string(constants::operations), this->operations);
+ this->operations.insertKey(constants_::to_string(constants::service), init_service_operations());
+}
+
+void ControlComponent::addControlComponentChangeListener(const std::shared_ptr<IControlComponentChangeListener> listener)
+{
+ this->componentChangeListeners.emplace(listener->getUniqueID(), listener);
+}
+
+void ControlComponent::removeControlComponentChangeListener(const std::shared_ptr<IControlComponentChangeListener> listener)
+{
+ this->componentChangeListeners.erase(listener->getUniqueID());
+}
+
+const basyx::object ControlComponent::getServiceOperationMap()
+{
+ return this->map.getProperty(constants_::to_string(constants::operations)).getProperty(constants_::to_string(constants::service));
+}
+
+void ControlComponent::put(const std::string &key, object value)
+{
+ this->map.insertKey(key, value);
+
+ // Indicate value change
+ for (auto listener : componentChangeListeners)
+ {
+ listener.second->onVariableChange(key, value);
+ }
+
+ // Process variable changes
+ switch (constants_::from_string(key))
+ {
+ case constants::cmd:
+ {
+ this->changeExecutionState(ExecutionOrder_::from_string(value.Get<std::string>()));
+ break;
+ }
+ case constants::localOverwrite:
+ {
+ this->invokeLocalOverwrite();
+ break;
+ }
+ case constants::localOverwriteFree:
+ {
+ this->clearLocalOverwrite();
+ break;
+ }
+ }
+}
+
+void ControlComponent::finishState()
+{
+ switch (this->getExecutionState())
+ {
+ case ExecutionState::starting:
+ {
+ this->setExecutionState(ExecutionState::execute);
+ return;
+ }
+ case ExecutionState::execute:
+ {
+ this->setExecutionState(ExecutionState::completing);
+ return;
+ }
+ case ExecutionState::completing:
+ {
+ this->setExecutionState(ExecutionState::complete);
+ return;
+ }
+ case ExecutionState::resetting:
+ {
+ this->setExecutionState(ExecutionState::idle);
+ return;
+ }
+ case ExecutionState::holding:
+ {
+ this->setExecutionState(ExecutionState::held);
+ return;
+ }
+ case ExecutionState::unholding:
+ {
+ this->setExecutionState(ExecutionState::execute);
+ return;
+ }
+ case ExecutionState::suspending:
+ {
+ this->setExecutionState(ExecutionState::suspended);
+ return;
+ }
+ case ExecutionState::unsuspending:
+ {
+ this->setExecutionState(ExecutionState::execute);
+ return;
+ }
+ case ExecutionState::stopping:
+ {
+ this->setExecutionState(ExecutionState::stopped);
+ return;
+ }
+ case ExecutionState::stopped:
+ {
+ this->setExecutionState(ExecutionState::idle);
+ return;
+ }
+ case ExecutionState::aborting:
+ {
+ this->setExecutionState(ExecutionState::aborted);
+ return;
+ }
+ case ExecutionState::clearing:
+ {
+ this->setExecutionState(ExecutionState::stopped);
+ return;
+ }
+ }
+}
+
+const std::vector<std::string> & ControlComponent::getOrderList()
+{
+ return *this->map.getProperty(constants_::to_string(constants::orderList)).GetPtr<std::vector<std::string>>();
+}
+
+void ControlComponent::addOrder(const std::string &newOrder)
+{
+ this->map.getProperty(constants_::to_string(constants::orderList)).GetPtr<std::vector<std::string>>()->push_back(newOrder);
+}
+
+void ControlComponent::clearOrder()
+{
+ this->map.getProperty(constants_::to_string(constants::orderList)).GetPtr<object::list_t<std::string>>()->clear();
+}
+
+OccupationState ControlComponent::getOccupationState()
+{
+ return static_cast<OccupationState>(this->status_map.getProperty(constants_::to_string(constants::occupationState)).Get<int>());
+}
+
+void ControlComponent::setOccupationState(const OccupationState &occState)
+{
+ this->insert_status(constants::occupationState, (int) occState);
+
+ for (auto listener : this->componentChangeListeners)
+ {
+ listener.second->onNewOccupationState(occState);
+ }
+}
+
+std::string ControlComponent::getOccupierID()
+{
+ return this->get_status<std::string>(constants::occupier);
+}
+
+void ControlComponent::setOccupierID(const std::string &occId)
+{
+ this->insert_status(constants::occupier, occId);
+
+ for (auto listener : this->componentChangeListeners)
+ {
+ listener.second->onNewOccupier(occId);
+ }
+}
+
+std::string ControlComponent::getLastOccupierID()
+{
+ return this->get_status<std::string>(constants::lastOccupier);
+}
+
+void ControlComponent::setLastOccupierID(const std::string &occId)
+{
+ this->insert_status(constants::lastOccupier, occId);
+
+ for (auto listener : this->componentChangeListeners)
+ {
+ listener.second->onLastOccupier(occId);
+ }
+}
+
+ExecutionMode ControlComponent::getExecutionMode()
+{
+ return (ExecutionMode) this->get_status<int>(constants::exMode);
+}
+
+void ControlComponent::setExecutionMode(const ExecutionMode &exMode)
+{
+ this->insert_status(constants::exMode, (int) exMode);
+
+ for (auto listener : this->componentChangeListeners)
+ {
+ listener.second->onChangedExecutionMode(exMode);
+ }
+}
+
+ExecutionState ControlComponent::getExecutionState()
+{
+ return ExecutionState_::from_string(this->get_status<std::string>(constants::exState));
+}
+
+void ControlComponent::setExecutionState(const ExecutionState &newSt)
+{
+ this->insert_status(constants::exState, ExecutionState_::to_string(newSt));
+
+ for (auto listener : this->componentChangeListeners)
+ {
+ listener.second->onChangedExecutionState(newSt);
+ }
+}
+
+std::string ControlComponent::getOperationMode()
+{
+ return this->get_status<std::string>(constants::opMode);
+}
+
+void ControlComponent::setOperationMode(const std::string &opMode)
+{
+ this->insert_status(constants::opMode, opMode);
+
+ for (auto listener : this->componentChangeListeners)
+ {
+ listener.second->onChangedOperationMode(opMode);
+ }
+}
+
+std::string ControlComponent::getWorkState()
+{
+ return this->get_status<std::string>(constants::workState);
+}
+
+void ControlComponent::setWorkState(const std::string &workState)
+{
+ this->insert_status(constants::workState, workState);
+
+ for (auto listener : this->componentChangeListeners)
+ {
+ listener.second->onChangedWorkState(workState);
+ }
+}
+
+std::string ControlComponent::getErrorState()
+{
+ return this->get_status<std::string>(constants::errorState);
+}
+
+void ControlComponent::setErrorState(const std::string &errorState)
+{
+ this->insert_status(constants::errorState, errorState);
+
+ for (auto listener : this->componentChangeListeners)
+ {
+ listener.second->onChangedErrorState(errorState);
+ }
+}
+
+std::string ControlComponent::getLastErrorState()
+{
+ return this->get_status<std::string>(constants::prevError);
+}
+
+void ControlComponent::setLastErrorState(const std::string &lastErrorState)
+{
+ this->insert_status(constants::errorState, lastErrorState);
+
+ for (auto listener : this->componentChangeListeners)
+ {
+ listener.second->onChangedPrevError(lastErrorState);
+ }
+}
+
+std::string ControlComponent::getCommand()
+{
+ return this->map.getProperty(constants_::to_string(constants::cmd)).GetStringContent();
+}
+
+void ControlComponent::setCommand(const std::string &cmd)
+{
+ this->map.insertKey(constants_::to_string(constants::cmd), cmd);
+}
+
+std::string ControlComponent::getLocalOverwrite()
+{
+ return this->map.getProperty(constants_::to_string(constants::localOverwrite)).GetStringContent();
+}
+
+void ControlComponent::setLocalOverwrite(const std::string &cmd)
+{
+ this->map.insertKey(constants_::to_string(constants::localOverwrite), cmd);
+}
+
+std::string ControlComponent::getLocalOverwriteFree()
+{
+ return this->map.getProperty(constants_::to_string(constants::localOverwriteFree)).GetStringContent();
+}
+
+void ControlComponent::setLocalOverwriteFree(const std::string &cmd)
+{
+ this->map.insertKey(constants_::to_string(constants::localOverwriteFree), cmd);
+}
+
+void ControlComponent::changeExecutionState(const ExecutionOrder &ex_order)
+{
+ // Check if execution order leads to valid state in current state
+ switch (this->getExecutionState())
+ {
+ case ExecutionState::idle:
+ // Process expected orders
+ if (ex_order == ExecutionOrder::start)
+ {
+ this->setExecutionState(ExecutionState::starting);
+ return;
+ }
+ if (ex_order == ExecutionOrder::stop)
+ {
+ this->setExecutionState(ExecutionState::stopping);
+ return;
+ }
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+
+ case ExecutionState::starting:
+ if (ex_order == ExecutionOrder::stop)
+ {
+ this->setExecutionState(ExecutionState::stopping);
+ return;
+ }
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+
+ case ExecutionState::execute:
+ // Process expected orders
+ if (ex_order == ExecutionOrder::complete)
+ {
+ this->setExecutionState(ExecutionState::completing);
+ return;
+ }
+ if (ex_order == ExecutionOrder::hold)
+ {
+ this->setExecutionState(ExecutionState::holding);
+ return;
+ }
+ if (ex_order == ExecutionOrder::suspend)
+ {
+ this->setExecutionState(ExecutionState::suspending);
+ return;
+ }
+ if (ex_order == ExecutionOrder::stop)
+ {
+ this->setExecutionState(ExecutionState::stopping);
+ return;
+ }
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+
+ case ExecutionState::completing:
+ if (ex_order == ExecutionOrder::stop)
+ {
+ this->setExecutionState(ExecutionState::stopping);
+ return;
+ }
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+
+ case ExecutionState::complete:
+ if (ex_order == ExecutionOrder::reset)
+ {
+ this->setExecutionState(ExecutionState::resetting);
+ return;
+ }
+ if (ex_order == ExecutionOrder::stop)
+ {
+ this->setExecutionState(ExecutionState::stopping);
+ return;
+ }
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+
+ case ExecutionState::resetting:
+ if (ex_order == ExecutionOrder::stop)
+ {
+ this->setExecutionState(ExecutionState::stopping);
+ return;
+ }
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+
+ case ExecutionState::holding:
+ if (ex_order == ExecutionOrder::stop)
+ {
+ this->setExecutionState(ExecutionState::stopping);
+ return;
+ }
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+
+ case ExecutionState::held:
+ if (ex_order == ExecutionOrder::unhold)
+ {
+ this->setExecutionState(ExecutionState::unholding);
+ return;
+ }
+ if (ex_order == ExecutionOrder::stop)
+ {
+ this->setExecutionState(ExecutionState::stopping);
+ return;
+ }
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+
+ case ExecutionState::unholding:
+ if (ex_order == ExecutionOrder::stop)
+ {
+ this->setExecutionState(ExecutionState::stopping);
+ return;
+ }
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+
+ case ExecutionState::suspending:
+ if (ex_order == ExecutionOrder::stop)
+ {
+ this->setExecutionState(ExecutionState::stopping);
+ return;
+ }
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+
+ case ExecutionState::suspended:
+ if (ex_order == ExecutionOrder::unsuspend)
+ {
+ this->setExecutionState(ExecutionState::unsuspending);
+ return;
+ }
+ if (ex_order == ExecutionOrder::stop)
+ {
+ this->setExecutionState(ExecutionState::stopping);
+ return;
+ }
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+
+ case ExecutionState::unsuspending:
+ if (ex_order == ExecutionOrder::stop)
+ {
+ this->setExecutionState(ExecutionState::stopping);
+ return;
+ }
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+
+ case ExecutionState::stopping:
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+
+ case ExecutionState::stopped:
+ if (ex_order == ExecutionOrder::reset)
+ {
+ this->setExecutionState(ExecutionState::resetting);
+ return;
+ }
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+ case ExecutionState::aborted:
+ if (ex_order == ExecutionOrder::clear)
+ {
+ this->setExecutionState(ExecutionState::clearing);
+ return;
+ }
+
+ case ExecutionState::clearing:
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+ }
+
+}
+
+void ControlComponent::invokeLocalOverwrite()
+{
+ // Store current occupier because we need to restore it later
+ this->savedOccupierId = this->getOccupierID();
+
+ // Enter local overwrite state
+ this->setOccupationState(OccupationState::local);
+ this->setOccupierID(constants_::to_string(constants::LOCAL));
+}
+
+void ControlComponent::clearLocalOverwrite()
+{
+ this->setOccupierID(this->savedOccupierId);
+
+ // Restore occupier state based on variables
+ if (this->savedOccupierId.empty())
+ this->setOccupationState(OccupationState::free);
+ else if (this->getLastOccupierID().empty())
+ this->setOccupationState(OccupationState::occupied);
+ else
+ this->setOccupationState(OccupationState::priority);
+}
+
+template<typename T> void ControlComponent::insert_status(const ControlComponentConstants &status_key, T status)
+{
+ this->status_map.insertKey(constants_::to_string(status_key), status);
+ for (auto listener : this->componentChangeListeners)
+ {
+ listener.second->onVariableChange(constants_::to_string(status_key), status);
+ }
+}
+
+template<typename T> T ControlComponent::get_status(const basyx::controlcomponent::ControlComponentConstants &key)
+{
+ return this->status_map.getProperty(constants_::to_string(key)).Get<T>();
+}
+
+object ControlComponent::init_service_operations()
+{
+ object map = object::make_map();
+
+ // All lambdas returning bool since this is supported by vab
+ map.insertKey(constants_::to_string(constants::free), object::make_function([this](std::string senderId) {
+ this->freeControlComponent(senderId);
+ return true;
+ }));
+ map.insertKey(constants_::to_string(constants::occupy), object::make_function([this](std::string occupier) {
+ this->occupyControlComponent(occupier);
+ return true;
+ }));
+ map.insertKey(constants_::to_string(constants::priority), object::make_function([this](std::string occupier) {
+ this->priorityOccupation(occupier);
+ return true;
+ }));
+
+ map.insertKey(constants_::to_string(constants::Auto), object::make_function([this]() {
+ this->setExecutionMode(ExecutionMode::Auto);
+ return true;
+ }));
+ map.insertKey(constants_::to_string(constants::semiauto), object::make_function([this]() {
+ this->setExecutionMode(ExecutionMode::Semiauto);
+ return true;
+ }));
+ map.insertKey(constants_::to_string(constants::manual), object::make_function([this]() {
+ this->setExecutionMode(ExecutionMode::Manual);
+ return true;
+ }));
+ map.insertKey(constants_::to_string(constants::simulation), object::make_function([this]() {
+ this->setExecutionMode(ExecutionMode::Simulation);
+ return true;
+ }));
+
+ map.insertKey(constants_::to_string(constants::start), object::make_function([this]() {
+ this->changeExecutionState(ExecutionOrder::start);
+ return true;
+ }));
+ map.insertKey(constants_::to_string(constants::reset), object::make_function([this]() {
+ this->changeExecutionState(ExecutionOrder::reset);
+ return true;
+ }));
+ map.insertKey(constants_::to_string(constants::hold), object::make_function([this]() {
+ this->changeExecutionState(ExecutionOrder::hold);
+ return true;
+ }));
+ map.insertKey(constants_::to_string(constants::unhold), object::make_function([this]() {
+ this->changeExecutionState(ExecutionOrder::unhold);
+ return true;
+ }));
+ map.insertKey(constants_::to_string(constants::suspend), object::make_function([this]() {
+ this->changeExecutionState(ExecutionOrder::suspend);
+ return true;
+ }));
+ map.insertKey(constants_::to_string(constants::unsuspend), object::make_function([this]() {
+ this->changeExecutionState(ExecutionOrder::unsuspend);
+ return true;
+ }));
+ map.insertKey(constants_::to_string(constants::abort), object::make_function([this]() {
+ this->changeExecutionState(ExecutionOrder::abort);
+ return true;
+ }));
+ map.insertKey(constants_::to_string(constants::stop), object::make_function([this]() {
+ this->changeExecutionState(ExecutionOrder::stop);
+ return true;
+ }));
+ map.insertKey(constants_::to_string(constants::clear), object::make_function([this]() {
+ this->changeExecutionState(ExecutionOrder::clear);
+ return true;
+ }));
+
+ map.insertKey(constants_::to_string(constants::bstate), object::make_function([this]() {
+ this->setOperationMode(std::string {"BSTATE"});
+ return true;
+ }));
+
+ return map;
+}
+
+void ControlComponent::freeControlComponent(const std::string &senderId)
+{
+ if (this->getOccupierID().compare(senderId) == 0)
+ {
+ this->setOccupierID(this->getLastOccupierID());
+ this->setLastOccupierID("");
+ if (this->getOccupierID().empty())
+ this->setOccupationState(OccupationState::free);
+ else
+ this->setOccupationState(OccupationState::occupied);
+ }
+}
+
+void ControlComponent::occupyControlComponent(const std::string &occupier)
+{
+ if (this->getOccupationState() == OccupationState::free)
+ {
+ this->setOccupierID(occupier);
+ this->setOccupationState(OccupationState::occupied);
+ }
+}
+
+void ControlComponent::priorityOccupation(const std::string &occupier)
+{
+ if ((this->getOccupationState() == OccupationState::free) or (this->getOccupationState() == OccupationState::occupied))
+ {
+ this->setLastOccupierID(this->getOccupierID());
+ this->setOccupierID(occupier);
+ this->setOccupationState(OccupationState::priority);
+ }
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/controlcomponent/simple/ControlComponent.cpp b/sdks/c++/basys.sdk.cc/src/controlcomponent/simple/ControlComponent.cpp
new file mode 100644
index 0000000..da523da
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/controlcomponent/simple/ControlComponent.cpp
@@ -0,0 +1,663 @@
+#include <BaSyx/controlcomponent/simple/ControlComponent.h>
+#include <BaSyx/controlcomponent/enumerations/ControlComponentConstants.h>
+
+namespace basyx {
+namespace controlcomponent {
+namespace simple {
+
+using constants = basyx::controlcomponent::ControlComponentConstants;
+using constants_ = basyx::controlcomponent::ControlComponentConstants_;
+
+ControlComponent::ControlComponent()
+ : savedOccupierId {""}
+ , occupationState{OccupationState::free}
+ , occupier{""}
+ , lastOccupier{""}
+ , exMode{ExecutionMode::Auto}
+ , exState{ExecutionState::idle}
+ , opMode{""}
+ , workState{""}
+ , errorState{""}
+ , prevError{""}
+ , cmd{""}
+ , localOverwrite{""}
+ , localOverwriteFree{""}
+ , service_operations{object::make_map()}
+{
+ this->init_service_operations();
+}
+
+void ControlComponent::addControlComponentChangeListener(const std::shared_ptr<IControlComponentChangeListener> listener)
+{
+ this->componentChangeListeners.emplace(listener->getUniqueID(), listener);
+}
+
+void ControlComponent::removeControlComponentChangeListener(const std::shared_ptr<IControlComponentChangeListener> listener)
+{
+ this->componentChangeListeners.erase(listener->getUniqueID());
+}
+
+const basyx::object ControlComponent::getServiceOperationMap()
+{
+ return this->service_operations;
+}
+
+void ControlComponent::finishState()
+{
+ switch (this->getExecutionState())
+ {
+ case ExecutionState::starting:
+ {
+ this->setExecutionState(ExecutionState::execute);
+ return;
+ }
+ case ExecutionState::execute:
+ {
+ this->setExecutionState(ExecutionState::completing);
+ return;
+ }
+ case ExecutionState::completing:
+ {
+ this->setExecutionState(ExecutionState::complete);
+ return;
+ }
+ case ExecutionState::resetting:
+ {
+ this->setExecutionState(ExecutionState::idle);
+ return;
+ }
+ case ExecutionState::holding:
+ {
+ this->setExecutionState(ExecutionState::held);
+ return;
+ }
+ case ExecutionState::unholding:
+ {
+ this->setExecutionState(ExecutionState::execute);
+ return;
+ }
+ case ExecutionState::suspending:
+ {
+ this->setExecutionState(ExecutionState::suspended);
+ return;
+ }
+ case ExecutionState::unsuspending:
+ {
+ this->setExecutionState(ExecutionState::execute);
+ return;
+ }
+ case ExecutionState::stopping:
+ {
+ this->setExecutionState(ExecutionState::stopped);
+ return;
+ }
+ case ExecutionState::stopped:
+ {
+ this->setExecutionState(ExecutionState::idle);
+ return;
+ }
+ case ExecutionState::aborting:
+ {
+ this->setExecutionState(ExecutionState::aborted);
+ return;
+ }
+ case ExecutionState::clearing:
+ {
+ this->setExecutionState(ExecutionState::stopped);
+ return;
+ }
+ }
+}
+
+const std::vector<std::string> & ControlComponent::getOrderList()
+{
+ return this->orderList;
+}
+
+void ControlComponent::addOrder(const std::string &newOrder)
+{
+ this->orderList.push_back(newOrder);
+}
+
+void ControlComponent::clearOrder()
+{
+ this->orderList.clear();
+}
+
+OccupationState ControlComponent::getOccupationState()
+{
+ return static_cast<OccupationState>(this->occupationState);
+}
+
+void ControlComponent::setOccupationState(const OccupationState &occState)
+{
+ this->occupationState = occState;
+ this->notify_change_listeners_on_variable_change(constants::occupationState, (int) occState);
+
+ for (auto listener : this->componentChangeListeners)
+ {
+ listener.second->onNewOccupationState(occState);
+ }
+}
+
+std::string ControlComponent::getOccupierID()
+{
+ return this->occupier;
+}
+
+void ControlComponent::setOccupierID(const std::string &occId)
+{
+ this->occupier = occId;
+ this->notify_change_listeners_on_variable_change(constants::occupier, occId);
+
+ for (auto listener : this->componentChangeListeners)
+ {
+ listener.second->onNewOccupier(occId);
+ }
+}
+
+std::string ControlComponent::getLastOccupierID()
+{
+ return this->lastOccupier;
+}
+
+void ControlComponent::setLastOccupierID(const std::string &occId)
+{
+ this->lastOccupier = occId;
+ this->notify_change_listeners_on_variable_change(constants::lastOccupier, occId);
+
+ for (auto listener : this->componentChangeListeners)
+ {
+ listener.second->onLastOccupier(occId);
+ }
+}
+
+ExecutionMode ControlComponent::getExecutionMode()
+{
+ return this->exMode;
+}
+
+void ControlComponent::setExecutionMode(const ExecutionMode &exMode)
+{
+ this->exMode = exMode;
+ this->notify_change_listeners_on_variable_change(constants::exMode, (int) exMode);
+
+ for (auto listener : this->componentChangeListeners)
+ {
+ listener.second->onChangedExecutionMode(exMode);
+ }
+}
+
+ExecutionState ControlComponent::getExecutionState()
+{
+ return this->exState;
+}
+
+void ControlComponent::setExecutionState(const ExecutionState &newSt)
+{
+ this->exState = newSt;
+ this->notify_change_listeners_on_variable_change(constants::exState, ExecutionState_::to_string(newSt));
+
+ for (auto listener : this->componentChangeListeners)
+ {
+ listener.second->onChangedExecutionState(newSt);
+ }
+}
+
+std::string ControlComponent::getOperationMode()
+{
+ return this->opMode;
+}
+
+void ControlComponent::setOperationMode(const std::string &opMode)
+{
+ this->opMode = opMode;
+ this->notify_change_listeners_on_variable_change(constants::opMode, opMode);
+
+ for (auto listener : this->componentChangeListeners)
+ {
+ listener.second->onChangedOperationMode(opMode);
+ }
+}
+
+std::string ControlComponent::getWorkState()
+{
+ return this->workState;
+}
+
+void ControlComponent::setWorkState(const std::string &workState)
+{
+ this->workState = workState;
+ this->notify_change_listeners_on_variable_change(constants::workState, workState);
+
+ for (auto listener : this->componentChangeListeners)
+ {
+ listener.second->onChangedWorkState(workState);
+ }
+}
+
+std::string ControlComponent::getErrorState()
+{
+ return this->errorState;
+}
+
+void ControlComponent::setErrorState(const std::string &errorState)
+{
+ this->errorState = errorState;
+ this->notify_change_listeners_on_variable_change(constants::errorState, errorState);
+
+ for (auto listener : this->componentChangeListeners)
+ {
+ listener.second->onChangedErrorState(errorState);
+ }
+}
+
+std::string ControlComponent::getLastErrorState()
+{
+ return this->prevError;
+}
+
+void ControlComponent::setLastErrorState(const std::string &lastErrorState)
+{
+ this->errorState = lastErrorState;
+ this->notify_change_listeners_on_variable_change(constants::errorState, lastErrorState);
+
+ for (auto listener : this->componentChangeListeners)
+ {
+ listener.second->onChangedPrevError(lastErrorState);
+ }
+}
+
+std::string ControlComponent::getCommand()
+{
+ return this->cmd;
+}
+
+void ControlComponent::setCommand(const std::string &cmd)
+{
+ this->cmd = cmd;
+}
+
+std::string ControlComponent::getLocalOverwrite()
+{
+ return this->localOverwrite;
+}
+
+void ControlComponent::setLocalOverwrite(const std::string &cmd)
+{
+ this->localOverwrite = cmd;
+}
+
+std::string ControlComponent::getLocalOverwriteFree()
+{
+ return this->localOverwriteFree;
+}
+
+void ControlComponent::setLocalOverwriteFree(const std::string &cmd)
+{
+ this->localOverwriteFree = cmd;
+}
+
+void ControlComponent::changeExecutionState(const ExecutionOrder &ex_order)
+{
+ // Check if execution order leads to valid state in current state
+ switch (this->getExecutionState())
+ {
+ case ExecutionState::idle:
+ // Process expected orders
+ if (ex_order == ExecutionOrder::start)
+ {
+ this->setExecutionState(ExecutionState::starting);
+ return;
+ }
+ if (ex_order == ExecutionOrder::stop)
+ {
+ this->setExecutionState(ExecutionState::stopping);
+ return;
+ }
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+
+ case ExecutionState::starting:
+ if (ex_order == ExecutionOrder::stop)
+ {
+ this->setExecutionState(ExecutionState::stopping);
+ return;
+ }
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+
+ case ExecutionState::execute:
+ // Process expected orders
+ if (ex_order == ExecutionOrder::complete)
+ {
+ this->setExecutionState(ExecutionState::completing);
+ return;
+ }
+ if (ex_order == ExecutionOrder::hold)
+ {
+ this->setExecutionState(ExecutionState::holding);
+ return;
+ }
+ if (ex_order == ExecutionOrder::suspend)
+ {
+ this->setExecutionState(ExecutionState::suspending);
+ return;
+ }
+ if (ex_order == ExecutionOrder::stop)
+ {
+ this->setExecutionState(ExecutionState::stopping);
+ return;
+ }
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+
+ case ExecutionState::completing:
+ if (ex_order == ExecutionOrder::stop)
+ {
+ this->setExecutionState(ExecutionState::stopping);
+ return;
+ }
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+
+ case ExecutionState::complete:
+ if (ex_order == ExecutionOrder::reset)
+ {
+ this->setExecutionState(ExecutionState::resetting);
+ return;
+ }
+ if (ex_order == ExecutionOrder::stop)
+ {
+ this->setExecutionState(ExecutionState::stopping);
+ return;
+ }
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+
+ case ExecutionState::resetting:
+ if (ex_order == ExecutionOrder::stop)
+ {
+ this->setExecutionState(ExecutionState::stopping);
+ return;
+ }
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+
+ case ExecutionState::holding:
+ if (ex_order == ExecutionOrder::stop)
+ {
+ this->setExecutionState(ExecutionState::stopping);
+ return;
+ }
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+
+ case ExecutionState::held:
+ if (ex_order == ExecutionOrder::unhold)
+ {
+ this->setExecutionState(ExecutionState::unholding);
+ return;
+ }
+ if (ex_order == ExecutionOrder::stop)
+ {
+ this->setExecutionState(ExecutionState::stopping);
+ return;
+ }
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+
+ case ExecutionState::unholding:
+ if (ex_order == ExecutionOrder::stop)
+ {
+ this->setExecutionState(ExecutionState::stopping);
+ return;
+ }
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+
+ case ExecutionState::suspending:
+ if (ex_order == ExecutionOrder::stop)
+ {
+ this->setExecutionState(ExecutionState::stopping);
+ return;
+ }
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+
+ case ExecutionState::suspended:
+ if (ex_order == ExecutionOrder::unsuspend)
+ {
+ this->setExecutionState(ExecutionState::unsuspending);
+ return;
+ }
+ if (ex_order == ExecutionOrder::stop)
+ {
+ this->setExecutionState(ExecutionState::stopping);
+ return;
+ }
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+
+ case ExecutionState::unsuspending:
+ if (ex_order == ExecutionOrder::stop)
+ {
+ this->setExecutionState(ExecutionState::stopping);
+ return;
+ }
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+
+ case ExecutionState::stopping:
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+
+ case ExecutionState::stopped:
+ if (ex_order == ExecutionOrder::reset)
+ {
+ this->setExecutionState(ExecutionState::resetting);
+ return;
+ }
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+ case ExecutionState::aborted:
+ if (ex_order == ExecutionOrder::clear)
+ {
+ this->setExecutionState(ExecutionState::clearing);
+ return;
+ }
+
+ case ExecutionState::clearing:
+ if (ex_order == ExecutionOrder::abort)
+ {
+ this->setExecutionState(ExecutionState::aborting);
+ return;
+ }
+ }
+
+}
+
+void ControlComponent::invokeLocalOverwrite()
+{
+ // Store current occupier because we need to restore it later
+ this->savedOccupierId = this->getOccupierID();
+
+ // Enter local overwrite state
+ this->setOccupationState(OccupationState::local);
+ this->setOccupierID(constants_::to_string(constants::LOCAL));
+}
+
+void ControlComponent::clearLocalOverwrite()
+{
+ this->setOccupierID(this->savedOccupierId);
+
+ // Restore occupier state based on variables
+ if (this->savedOccupierId.empty())
+ this->setOccupationState(OccupationState::free);
+ else if (this->getLastOccupierID().empty())
+ this->setOccupationState(OccupationState::occupied);
+ else
+ this->setOccupationState(OccupationState::priority);
+}
+
+template<typename T> void ControlComponent::notify_change_listeners_on_variable_change(const ControlComponentConstants &status_key, T status)
+{
+ for (auto listener : this->componentChangeListeners)
+ {
+ listener.second->onVariableChange(constants_::to_string(status_key), status);
+ }
+}
+
+void ControlComponent::init_service_operations()
+{
+ // All lambdas returning bool since this is supported by vab
+ this->service_operations.insertKey(constants_::to_string(constants::free), object::make_function([this](std::string senderId) {
+ this->freeControlComponent(senderId);
+ return true;
+ }));
+ this->service_operations.insertKey(constants_::to_string(constants::occupy), object::make_function([this](std::string occupier) {
+ this->occupyControlComponent(occupier);
+ return true;
+ }));
+ this->service_operations.insertKey(constants_::to_string(constants::priority), object::make_function([this](std::string occupier) {
+ this->priorityOccupation(occupier);
+ return true;
+ }));
+
+ this->service_operations.insertKey(constants_::to_string(constants::Auto), object::make_function([this]() {
+ this->setExecutionMode(ExecutionMode::Auto);
+ return true;
+ }));
+ this->service_operations.insertKey(constants_::to_string(constants::semiauto), object::make_function([this]() {
+ this->setExecutionMode(ExecutionMode::Semiauto);
+ return true;
+ }));
+ this->service_operations.insertKey(constants_::to_string(constants::manual), object::make_function([this]() {
+ this->setExecutionMode(ExecutionMode::Manual);
+ return true;
+ }));
+ this->service_operations.insertKey(constants_::to_string(constants::simulation), object::make_function([this]() {
+ this->setExecutionMode(ExecutionMode::Simulation);
+ return true;
+ }));
+
+ this->service_operations.insertKey(constants_::to_string(constants::start), object::make_function([this]() {
+ this->changeExecutionState(ExecutionOrder::start);
+ return true;
+ }));
+ this->service_operations.insertKey(constants_::to_string(constants::reset), object::make_function([this]() {
+ this->changeExecutionState(ExecutionOrder::reset);
+ return true;
+ }));
+ this->service_operations.insertKey(constants_::to_string(constants::hold), object::make_function([this]() {
+ this->changeExecutionState(ExecutionOrder::hold);
+ return true;
+ }));
+ this->service_operations.insertKey(constants_::to_string(constants::unhold), object::make_function([this]() {
+ this->changeExecutionState(ExecutionOrder::unhold);
+ return true;
+ }));
+ this->service_operations.insertKey(constants_::to_string(constants::suspend), object::make_function([this]() {
+ this->changeExecutionState(ExecutionOrder::suspend);
+ return true;
+ }));
+ this->service_operations.insertKey(constants_::to_string(constants::unsuspend), object::make_function([this]() {
+ this->changeExecutionState(ExecutionOrder::unsuspend);
+ return true;
+ }));
+ this->service_operations.insertKey(constants_::to_string(constants::abort), object::make_function([this]() {
+ this->changeExecutionState(ExecutionOrder::abort);
+ return true;
+ }));
+ this->service_operations.insertKey(constants_::to_string(constants::stop), object::make_function([this]() {
+ this->changeExecutionState(ExecutionOrder::stop);
+ return true;
+ }));
+ this->service_operations.insertKey(constants_::to_string(constants::clear), object::make_function([this]() {
+ this->changeExecutionState(ExecutionOrder::clear);
+ return true;
+ }));
+
+ this->service_operations.insertKey(constants_::to_string(constants::bstate), object::make_function([this]() {
+ this->setOperationMode(std::string {"BSTATE"});
+ return true;
+ }));
+}
+
+void ControlComponent::freeControlComponent(const std::string &senderId)
+{
+ if (this->getOccupierID().compare(senderId) == 0)
+ {
+ this->setOccupierID(this->getLastOccupierID());
+ this->setLastOccupierID("");
+ if (this->getOccupierID().empty())
+ this->setOccupationState(OccupationState::free);
+ else
+ this->setOccupationState(OccupationState::occupied);
+ }
+}
+
+void ControlComponent::occupyControlComponent(const std::string &occupier)
+{
+ if (this->getOccupationState() == OccupationState::free)
+ {
+ this->setOccupierID(occupier);
+ this->setOccupationState(OccupationState::occupied);
+ }
+}
+
+void ControlComponent::priorityOccupation(const std::string &occupier)
+{
+ if ((this->getOccupationState() == OccupationState::free) or (this->getOccupationState() == OccupationState::occupied))
+ {
+ this->setLastOccupierID(this->getOccupierID());
+ this->setOccupierID(occupier);
+ this->setOccupationState(OccupationState::priority);
+ }
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/logging/CMakeLists.txt b/sdks/c++/basys.sdk.cc/src/logging/CMakeLists.txt
index 5ebe52e..7b1c395 100644
--- a/sdks/c++/basys.sdk.cc/src/logging/CMakeLists.txt
+++ b/sdks/c++/basys.sdk.cc/src/logging/CMakeLists.txt
@@ -15,8 +15,10 @@
set_target_properties(${BASYX_LOG_LIB_SUFFIX} PROPERTIES SOVERSION ${BASYX_PACKAGE_VERSION_MAJOR})
set_target_properties(${BASYX_LOG_LIB_SUFFIX} PROPERTIES PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_SHORTNAME}")
target_include_directories(${BASYX_LOG_LIB_SUFFIX}
-INTERFACE ${CMAKE_INSTALL_PREFIX}/include
- ${CMAKE_INSTALL_PREFIX}/include/${PROJECT_SHORTNAME})
+ PUBLIC
+ $<BUILD_INTERFACE:${BASYX_INCLUDE_DIR}>
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>
+)
target_sources(${BASYX_LOG_LIB_SUFFIX}
PRIVATE
@@ -38,7 +40,15 @@
add_library(basyx::log ALIAS ${BASYX_LOG_LIB_SUFFIX})
add_library(${PROJECT_SHORTNAME}::${BASYX_LOG_LIB_SUFFIX} ALIAS ${BASYX_LOG_LIB_SUFFIX})
-diagnostics_print(${BASYX_LOG_LIB_SUFFIX})
+if(BASYX_IS_SUBMODULE)
+ set_target_properties(${BASYX_LOG_LIB_SUFFIX} PROPERTIES FOLDER BaSyx)
+endif()
+
+if(BASYX_VERBOSE_CMAKE_OUTPUT)
+ diagnostics_print(${BASYX_LOG_LIB_SUFFIX})
+endif()
+
+build_source_group(${BASYX_LOG_LIB_SUFFIX})
###############################################
### Install section ###
diff --git a/sdks/c++/basys.sdk.cc/src/server/CMakeLists.txt b/sdks/c++/basys.sdk.cc/src/server/CMakeLists.txt
index 8d40802..367a9b6 100644
--- a/sdks/c++/basys.sdk.cc/src/server/CMakeLists.txt
+++ b/sdks/c++/basys.sdk.cc/src/server/CMakeLists.txt
@@ -14,8 +14,10 @@
set_target_properties(${BASYX_SERVER_LIB_SUFFIX} PROPERTIES SOVERSION ${BASYX_PACKAGE_VERSION_MAJOR})
set_target_properties(${BASYX_SERVER_LIB_SUFFIX} PROPERTIES PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_SHORTNAME}")
target_include_directories(${BASYX_SERVER_LIB_SUFFIX}
-INTERFACE ${CMAKE_INSTALL_PREFIX}/include
- ${CMAKE_INSTALL_PREFIX}/include/${PROJECT_SHORTNAME})
+ PUBLIC
+ $<BUILD_INTERFACE:${BASYX_INCLUDE_DIR}>
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>
+)
if(${BASYX_DEBUG_PRINT_FRAMES})
target_compile_definitions(${BASYX_SERVER_LIB_SUFFIX} PUBLIC PRINT_FRAME)
@@ -23,6 +25,7 @@
target_sources(${BASYX_SERVER_LIB_SUFFIX}
PRIVATE
+ ${CMAKE_CURRENT_SOURCE_DIR}/server/TCPServer.cpp
${BASYX_SHARED_INCLUDE_DIR}/TCPServer.h
${BASYX_SHARED_INCLUDE_DIR}/BaSyxNativeProvider.h
)
@@ -43,7 +46,15 @@
add_library(basyx::server ALIAS ${BASYX_SERVER_LIB_SUFFIX})
add_library(${PROJECT_SHORTNAME}::${BASYX_SERVER_LIB_SUFFIX} ALIAS ${BASYX_SERVER_LIB_SUFFIX})
-diagnostics_print(${BASYX_SERVER_LIB_SUFFIX})
+if(BASYX_IS_SUBMODULE)
+ set_target_properties(${BASYX_SERVER_LIB_SUFFIX} PROPERTIES FOLDER BaSyx)
+endif()
+
+if(BASYX_VERBOSE_CMAKE_OUTPUT)
+ diagnostics_print(${BASYX_SERVER_LIB_SUFFIX})
+endif()
+
+build_source_group(${BASYX_SERVER_LIB_SUFFIX})
###############################################
### Install section ###
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/property/Property.cpp b/sdks/c++/basys.sdk.cc/src/server/server/TCPServer.cpp
similarity index 100%
rename from sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/property/Property.cpp
rename to sdks/c++/basys.sdk.cc/src/server/server/TCPServer.cpp
diff --git a/sdks/c++/basys.sdk.cc/src/shared/CMakeLists.txt b/sdks/c++/basys.sdk.cc/src/shared/CMakeLists.txt
index 98e2bc5..b477cb7 100644
--- a/sdks/c++/basys.sdk.cc/src/shared/CMakeLists.txt
+++ b/sdks/c++/basys.sdk.cc/src/shared/CMakeLists.txt
@@ -16,8 +16,10 @@
set_target_properties(${BASYX_SHARED_TARGET_NAME} PROPERTIES SOVERSION ${BASYX_PACKAGE_VERSION_MAJOR})
set_target_properties(${BASYX_SHARED_TARGET_NAME} PROPERTIES PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_SHORTNAME}")
target_include_directories(${BASYX_SHARED_TARGET_NAME}
-INTERFACE ${CMAKE_INSTALL_PREFIX}/include
- ${CMAKE_INSTALL_PREFIX}/include/${PROJECT_SHORTNAME})
+ PUBLIC
+ $<BUILD_INTERFACE:${BASYX_INCLUDE_DIR}>
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>
+)
target_sources(${BASYX_SHARED_TARGET_NAME}
PRIVATE
@@ -63,7 +65,15 @@
add_library(basyx::shared ALIAS ${BASYX_SHARED_TARGET_NAME})
add_library(${PROJECT_SHORTNAME}::${BASYX_SHARED_LIB_SUFFIX} ALIAS ${BASYX_SHARED_TARGET_NAME})
-diagnostics_print(${BASYX_SHARED_TARGET_NAME})
+if(BASYX_IS_SUBMODULE)
+ set_target_properties(${BASYX_SHARED_TARGET_NAME} PROPERTIES FOLDER BaSyx)
+endif()
+
+if(BASYX_VERBOSE_CMAKE_OUTPUT)
+ diagnostics_print(${BASYX_SHARED_TARGET_NAME})
+endif()
+
+build_source_group(${BASYX_SHARED_TARGET_NAME})
###############################################
### Install section ###
diff --git a/sdks/c++/basys.sdk.cc/src/shared/shared/object/impl/object_impl.cpp b/sdks/c++/basys.sdk.cc/src/shared/shared/object/impl/object_impl.cpp
index 257e74d..d251e0c 100644
--- a/sdks/c++/basys.sdk.cc/src/shared/shared/object/impl/object_impl.cpp
+++ b/sdks/c++/basys.sdk.cc/src/shared/shared/object/impl/object_impl.cpp
@@ -4,278 +4,273 @@
#include <BaSyx/shared/object/obj_error_holder.h>
basyx::object::object()
- : content{ nullptr } {};
+ : content{ nullptr } {};
basyx::object::object(const char * c)
- : object{ std::string(c) }
+ : object{ std::string(c) }
{
};
bool basyx::object::empty()
{
- if (!this->content)
- return true;
+ if (!this->content)
+ return true;
- auto object_type = this->GetObjectType();
- auto value_type = this->GetValueType();
+ auto object_type = this->GetObjectType();
+ auto value_type = this->GetValueType();
- if (object_type == basyx::type::objectType::Primitive)
- return false;
+ if (object_type == basyx::type::objectType::Primitive)
+ return false;
- switch (this->content->object_type())
- {
- case basyx::type::objectType::List:
- switch (value_type)
- {
- case basyx::type::valueType::Bool:
- return this->Get<object::list_t<bool>&>().empty();
- break;
- case basyx::type::valueType::Int:
- return this->Get<object::list_t<int>&>().empty();
- break;
- case basyx::type::valueType::Float:
- return this->Get<object::list_t<double>&>().empty();
- break;
- case basyx::type::valueType::String:
- return this->Get<object::list_t<std::string>&>().empty();
- break;
- case basyx::type::valueType::Object:
- return this->Get<object::object_list_t&>().empty();
- break;
- };
- case basyx::type::objectType::Map:
- return this->Get<object::object_map_t&>().empty();
- break;
- }
+ switch (this->content->object_type())
+ {
+ case basyx::type::objectType::List:
+ switch (value_type)
+ {
+ case basyx::type::valueType::Bool:
+ return this->Get<object::list_t<bool>&>().empty();
+ case basyx::type::valueType::Int:
+ return this->Get<object::list_t<int>&>().empty();
+ case basyx::type::valueType::Float:
+ return this->Get<object::list_t<double>&>().empty();
+ case basyx::type::valueType::String:
+ return this->Get<object::list_t<std::string>&>().empty();
+ case basyx::type::valueType::Object:
+ return this->Get<object::object_list_t&>().empty();
+ default:
+ break;
+ };
+ case basyx::type::objectType::Map:
+ return this->Get<object::object_map_t&>().empty();
+ default:
+ break;
+ }
- return true;
+ return true;
};
bool basyx::object::insert(basyx::object obj)
{
- if (!this->content)
- return false;
+ if (!this->content)
+ return false;
- auto object_type = obj.content->object_type();
- auto value_type = obj.content->value_type();
+ auto object_type = obj.content->object_type();
+ auto value_type = obj.content->value_type();
- //if (object_type != basyx::type::objectType::Primitive)
- // return false;
+ //if (object_type != basyx::type::objectType::Primitive)
+ // return false;
- switch (this->content->object_type())
- {
- case basyx::type::objectType::List:
- if (this->content->value_type() == basyx::type::valueType::Object)
- {
- this->Get<basyx::object::object_list_t&>().emplace_back(obj);
- return true;
- }
+ switch (this->content->object_type())
+ {
+ case basyx::type::objectType::List:
+ if (this->content->value_type() == basyx::type::valueType::Object)
+ {
+ this->Get<basyx::object::object_list_t&>().emplace_back(obj);
+ return true;
+ }
- if (this->content->value_type() == value_type)
- {
- switch (value_type)
- {
- case basyx::type::valueType::Bool:
- return this->insert(obj.Get<bool&>());
- break;
- case basyx::type::valueType::Int:
- return this->insert(obj.Get<int&>());
- break;
- case basyx::type::valueType::Float:
- return this->insert(obj.Get<float&>());
- break;
- case basyx::type::valueType::String:
- return this->insert(obj.Get<std::string&>());
- break;
- };
- }
- break;
- };
+ if (this->content->value_type() == value_type)
+ {
+ switch (value_type)
+ {
+ case basyx::type::valueType::Bool:
+ return this->insert(obj.Get<bool&>());
+ case basyx::type::valueType::Int:
+ return this->insert(obj.Get<int&>());
+ case basyx::type::valueType::Float:
+ return this->insert(obj.Get<float&>());
+ case basyx::type::valueType::String:
+ return this->insert(obj.Get<std::string&>());
+ default:
+ break;
+ };
+ };
+ default:
+ break;
+ };
- return false;
+ return false;
};
bool basyx::object::hasProperty(const std::string & propertyName)
{
- if (!this->content || this->GetObjectType() != basyx::type::objectType::Map)
- return false;
+ if (!this->content || this->GetObjectType() != basyx::type::objectType::Map)
+ return false;
- auto & map = this->Get<basyx::object::object_map_t&>();
+ auto & map = this->Get<basyx::object::object_map_t&>();
- if (map.find(propertyName) != map.end()) {
- return true;
- }
+ if (map.find(propertyName) != map.end()) {
+ return true;
+ }
- return false;
+ return false;
};
basyx::object basyx::object::getProperty(const std::string & propertyName)
{
- if (!this->content || this->GetObjectType() != basyx::type::objectType::Map)
- return basyx::object::make_error(error::PropertyNotFound, "Property access only supported on maps!");
+ if (!this->content || this->GetObjectType() != basyx::type::objectType::Map)
+ return basyx::object::make_error(error::PropertyNotFound, "Property access only supported on maps!");
- auto & map = this->Get<basyx::object::object_map_t&>();
+ auto & map = this->Get<basyx::object::object_map_t&>();
- if (map.find(propertyName) != map.end()) {
- return map[propertyName];
- }
+ if (map.find(propertyName) != map.end()) {
+ return map[propertyName];
+ }
- return basyx::object::make_error(error::PropertyNotFound, "Property " + propertyName + " not found!");
+ return basyx::object::make_error(error::PropertyNotFound, "Property " + propertyName + " not found!");
};
bool basyx::object::removeProperty(const std::string & propertyName)
{
- if (!this->content)
- return false;
+ if (!this->content)
+ return false;
- if (this->InstanceOf<object::object_map_t>())
- {
- auto & map = this->Get<object::object_map_t&>();
- auto found = map.find(propertyName);
- if (found != map.end()) {
- map.erase(found);
- return true;
- }
- };
+ if (this->InstanceOf<object::object_map_t>())
+ {
+ auto & map = this->Get<object::object_map_t&>();
+ auto found = map.find(propertyName);
+ if (found != map.end()) {
+ map.erase(found);
+ return true;
+ }
+ };
- return false;
+ return false;
};
bool basyx::object::operator==(const basyx::object& rhs) const
{
- if (rhs.IsNull())
- return false;
+ if (rhs.IsNull())
+ return false;
- return this->content->compare(rhs.content.get());
+ return this->content->compare(rhs.content.get());
}
std::size_t basyx::object::size()
{
- if (!this->content)
- return -1;
+ if (!this->content)
+ return -1;
- auto valueType = this->GetValueType();
+ auto valueType = this->GetValueType();
- // Check if contained object is list or set
- switch (content->object_type())
- {
- case basyx::type::objectType::List:
- switch (valueType)
- {
- case basyx::type::valueType::Bool:
- return this->Get<object::list_t<bool>&>().size();
- break;
- case basyx::type::valueType::Int:
- return this->Get<object::list_t<int>&>().size();
- break;
- case basyx::type::valueType::Float:
- return this->Get<object::list_t<float>&>().size();
- break;
- case basyx::type::valueType::String:
- return this->Get<object::list_t<std::string>&>().size();
- break;
- case basyx::type::valueType::Object:
- return this->Get<object::object_list_t&>().size();
- break;
- };
- break;
- case basyx::type::objectType::Map:
- return this->Get<object::object_map_t&>().size();
- break;
- };
+ // Check if contained object is list or set
+ switch (content->object_type())
+ {
+ case basyx::type::objectType::List:
+ switch (valueType)
+ {
+ case basyx::type::valueType::Bool:
+ return this->Get<object::list_t<bool>&>().size();
+ case basyx::type::valueType::Int:
+ return this->Get<object::list_t<int>&>().size();
+ case basyx::type::valueType::Float:
+ return this->Get<object::list_t<float>&>().size();
+ case basyx::type::valueType::String:
+ return this->Get<object::list_t<std::string>&>().size();
+ case basyx::type::valueType::Object:
+ return this->Get<object::object_list_t&>().size();
+ default:
+ break;
+ };
+ break;
+ case basyx::type::objectType::Map:
+ return this->Get<object::object_map_t&>().size();
+ default:
+ break;
+ };
- return 1;
+ return 1;
};
basyx::object basyx::object::make_null()
{
- return basyx::object{ nullptr };
+ return basyx::object{ nullptr };
};
basyx::object basyx::object::make_error(basyx::object::error error_code)
{
- basyx::object obj;
- obj.content = std::make_shared<basyx::detail::objErrorHolder>(error_code);
- return obj;
+ basyx::object obj;
+ obj.content = std::make_shared<basyx::detail::objErrorHolder>(error_code);
+ return obj;
};
basyx::object basyx::object::make_error(basyx::object::error error_code, const std::string & msg)
{
- basyx::object obj;
- obj.content = std::make_shared<basyx::detail::objErrorHolder>(error_code, msg);
- return obj;
+ basyx::object obj;
+ obj.content = std::make_shared<basyx::detail::objErrorHolder>(error_code, msg);
+ return obj;
};
basyx::object::error basyx::object::getError() const
{
- if (this->GetObjectType() != basyx::type::objectType::Error)
- return basyx::object::error::None;
+ if (this->GetObjectType() != basyx::type::objectType::Error)
+ return basyx::object::error::None;
- auto & errorHolder = dynamic_cast<basyx::detail::objErrorHolder&>(*this->content);
- return errorHolder.error;
+ auto & errorHolder = dynamic_cast<basyx::detail::objErrorHolder&>(*this->content);
+ return errorHolder.error;
}
const std::string & basyx::object::getErrorMessage() const
{
- auto & errorHolder = dynamic_cast<basyx::detail::objErrorHolder&>(*this->content);
- return errorHolder.message;
+ auto & errorHolder = dynamic_cast<basyx::detail::objErrorHolder&>(*this->content);
+ return errorHolder.message;
}
basyx::object basyx::object::invoke()
{
- if (this->IsNull() || this->GetObjectType() != basyx::type::objectType::Function)
- return basyx::object::make_error(basyx::object::error::NotInvokable, "Object not invokable!");
+ if (this->IsNull() || this->GetObjectType() != basyx::type::objectType::Function)
+ return basyx::object::make_error(basyx::object::error::NotInvokable, "Object not invokable!");
- return this->Get<basyx::detail::functionWrapper>().invoke();
+ return this->Get<basyx::detail::functionWrapper>().invoke();
};
basyx::object basyx::object::invoke(basyx::object& obj)
{
- if (this->IsNull() || this->GetObjectType() != basyx::type::objectType::Function)
- return basyx::object::make_error(basyx::object::error::NotInvokable, "Object not invokable!");
+ if (this->IsNull() || this->GetObjectType() != basyx::type::objectType::Function)
+ return basyx::object::make_error(basyx::object::error::NotInvokable, "Object not invokable!");
- auto param = obj;
+ auto param = obj;
- auto object_type = obj.GetObjectType();
- auto value_type = obj.GetValueType();
+ auto object_type = obj.GetObjectType();
+ auto value_type = obj.GetValueType();
- // Transpose to object list if necessary
- if (object_type == basyx::type::objectType::List)
- {
- if (value_type == basyx::type::valueType::Bool)
- {
- auto & list = obj.Get<basyx::object::list_t<bool>&>();
- param = basyx::object::make_list<basyx::object>();
- for (bool b : list) {
- param.insert(basyx::object{ b });
- };
- }
- else if (value_type == basyx::type::valueType::Int)
- {
- auto & list = obj.Get<basyx::object::list_t<int>&>();
- param = basyx::object::make_list<basyx::object>(list.begin(), list.end());
- }
- else if (value_type == basyx::type::valueType::Float)
- {
- auto & list = obj.Get<basyx::object::list_t<double>&>();
- param = basyx::object::make_list<basyx::object>(list.begin(), list.end());
- }
- else if (value_type == basyx::type::valueType::String)
- {
- auto & list = obj.Get<basyx::object::list_t<std::string>&>();
- param = basyx::object::make_list<basyx::object>();
- for (auto & str : list) {
- param.insert(basyx::object::make_object_ref(&str));
- };
- }
- };
+ // Transpose to object list if necessary
+ if (object_type == basyx::type::objectType::List)
+ {
+ if (value_type == basyx::type::valueType::Bool)
+ {
+ auto & list = obj.Get<basyx::object::list_t<bool>&>();
+ param = basyx::object::make_list<basyx::object>();
+ for (bool b : list) {
+ param.insert(basyx::object{ b });
+ };
+ }
+ else if (value_type == basyx::type::valueType::Int)
+ {
+ auto & list = obj.Get<basyx::object::list_t<int>&>();
+ param = basyx::object::make_list<basyx::object>(list.begin(), list.end());
+ }
+ else if (value_type == basyx::type::valueType::Float)
+ {
+ auto & list = obj.Get<basyx::object::list_t<double>&>();
+ param = basyx::object::make_list<basyx::object>(list.begin(), list.end());
+ }
+ else if (value_type == basyx::type::valueType::String)
+ {
+ auto & list = obj.Get<basyx::object::list_t<std::string>&>();
+ param = basyx::object::make_list<basyx::object>();
+ for (auto & str : list) {
+ param.insert(basyx::object::make_object_ref(&str));
+ };
+ }
+ };
- return this->Get<basyx::detail::functionWrapper>().invoke(param);
+ return this->Get<basyx::detail::functionWrapper>().invoke(param);
};
void basyx::to_json(nlohmann::json& json, const basyx::object& object)
{
- object.content->to_json(json);
+ object.content->to_json(json);
};
@@ -290,4 +285,4 @@
constexpr basyx::type::valueType basyx::type::basyx_type<std::string>::value_type;
constexpr basyx::type::objectType basyx::type::basyx_type<basyx::detail::functionWrapper>::object_type;
-constexpr basyx::type::valueType basyx::type::basyx_type<basyx::detail::functionWrapper>::value_type;
\ No newline at end of file
+constexpr basyx::type::valueType basyx::type::basyx_type<basyx::detail::functionWrapper>::value_type;
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/CMakeLists.txt b/sdks/c++/basys.sdk.cc/src/submodel/CMakeLists.txt
index cfd61d2..3d25e32 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/CMakeLists.txt
+++ b/sdks/c++/basys.sdk.cc/src/submodel/CMakeLists.txt
@@ -17,12 +17,15 @@
set_target_properties(${BASYX_SUBMODEL_LIB_SUFFIX} PROPERTIES SOVERSION ${BASYX_PACKAGE_VERSION_MAJOR})
set_target_properties(${BASYX_SUBMODEL_LIB_SUFFIX} PROPERTIES PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_SHORTNAME}")
target_include_directories(${BASYX_SUBMODEL_LIB_SUFFIX}
-INTERFACE ${CMAKE_INSTALL_PREFIX}/include
- ${CMAKE_INSTALL_PREFIX}/include/${PROJECT_SHORTNAME})
-
+ PUBLIC
+ $<BUILD_INTERFACE:${BASYX_INCLUDE_DIR}>
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>
+)
target_sources(${BASYX_SUBMODEL_LIB_SUFFIX}
PRIVATE
+ ${CMAKE_CURRENT_SOURCE_DIR}/submodel/map_v2/constexpr.cpp
+
${CMAKE_CURRENT_SOURCE_DIR}/submodel/enumerations/AssetKind.cpp
${CMAKE_CURRENT_SOURCE_DIR}/submodel/enumerations/DataTypeIEC61360.cpp
${CMAKE_CURRENT_SOURCE_DIR}/submodel/enumerations/LevelType.cpp
@@ -45,6 +48,7 @@
${CMAKE_CURRENT_SOURCE_DIR}/submodel/map_v2/parts/ConceptDictionary.cpp
${CMAKE_CURRENT_SOURCE_DIR}/submodel/map_v2/parts/ConceptDescription.cpp
${CMAKE_CURRENT_SOURCE_DIR}/submodel/map_v2/parts/View.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/submodel/map_v2/qualifier/AdministrativeInformation.cpp
${CMAKE_CURRENT_SOURCE_DIR}/submodel/map_v2/qualifier/HasDataSpecification.cpp
${CMAKE_CURRENT_SOURCE_DIR}/submodel/map_v2/qualifier/Identifiable.cpp
${CMAKE_CURRENT_SOURCE_DIR}/submodel/map_v2/qualifier/Qualifiable.cpp
@@ -66,6 +70,18 @@
${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/aas/AssetAdministrationShell.cpp
${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/aas/Asset.cpp
${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/common/LangStringSet.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/common/xsd_types/Timezone.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/common/xsd_types/AnyURI.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/common/xsd_types/DateTime.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/common/xsd_types/Date.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/common/xsd_types/DayTimeDuration.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/common/xsd_types/YearMonthDuration.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/common/xsd_types/Time.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/common/xsd_types/GYearMonth.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/common/xsd_types/GYear.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/common/xsd_types/GMonthDay.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/common/xsd_types/GDay.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/common/xsd_types/GMonth.cpp
${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/constraint/Formula.cpp
${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/constraint/Qualifier.cpp
${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/dataspecification/DataSpecification.cpp
@@ -110,6 +126,7 @@
${BASYX_SUBMODEL_INCLUDE_DIR}/enumerations/KeyType.h
${BASYX_SUBMODEL_INCLUDE_DIR}/enumerations/KeyElements.h
${BASYX_SUBMODEL_INCLUDE_DIR}/enumerations/IdentifiableElements.h
+ ${BASYX_SUBMODEL_INCLUDE_DIR}/enumerations/Conversions.h
${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/aas/IAssetAdministrationShell.h
${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/aas/IAsset.h
@@ -130,6 +147,7 @@
${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/parts/IConceptDescription.h
${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/parts/IConceptDictionary.h
${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/parts/IView.h
+ ${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/qualifier/IAdministrativeInformation.h
${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/qualifier/IHasDataSpecification.h
${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/qualifier/IHasKind.h
${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/qualifier/IHasSemantics.h
@@ -148,6 +166,7 @@
${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/submodelelement/operation/IOperationVariable.h
${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/submodelelement/property/IMultiLanguageProperty.h
${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/submodelelement/property/IProperty.h
+ ${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/submodelelement/property/XSDAnySimpleType.h
${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/submodelelement/property/IReferenceElement.h
${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/submodelelement/IRelationshipElement.h
${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/submodelelement/IAnnotatedRelationshipElement.h
@@ -159,6 +178,7 @@
${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/aas/AssetAdministrationShell.h
${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/aas/Asset.h
${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/common/ElementContainer.h
+ ${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/common/SubModelContainer.h
${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/common/ElementFactory.h
${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/common/LangStringSet.h
${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/common/ModelType.h
@@ -171,6 +191,7 @@
${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/parts/View.h
${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/constraint/Formula.h
${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/constraint/Qualifier.h
+ ${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/qualifier/AdministrativeInformation.h
${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/qualifier/HasDataSpecification.h
${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/qualifier/Identifiable.h
${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/qualifier/Qualifiable.h
@@ -192,6 +213,18 @@
${BASYX_SUBMODEL_INCLUDE_DIR}/simple/aas/Asset.h
${BASYX_SUBMODEL_INCLUDE_DIR}/simple/common/ElementContainer.h
${BASYX_SUBMODEL_INCLUDE_DIR}/simple/common/LangStringSet.h
+ ${BASYX_SUBMODEL_INCLUDE_DIR}/simple/common/xsd_types/Timezone.h
+ ${BASYX_SUBMODEL_INCLUDE_DIR}/simple/common/xsd_types/AnyURI.h
+ ${BASYX_SUBMODEL_INCLUDE_DIR}/simple/common/xsd_types/DateTime.h
+ ${BASYX_SUBMODEL_INCLUDE_DIR}/simple/common/xsd_types/Date.h
+ ${BASYX_SUBMODEL_INCLUDE_DIR}/simple/common/xsd_types/DayTimeDuration.h
+ ${BASYX_SUBMODEL_INCLUDE_DIR}/simple/common/xsd_types/YearMonthDuration.h
+ ${BASYX_SUBMODEL_INCLUDE_DIR}/simple/common/xsd_types/Time.h
+ ${BASYX_SUBMODEL_INCLUDE_DIR}/simple/common/xsd_types/GYearMonth.h
+ ${BASYX_SUBMODEL_INCLUDE_DIR}/simple/common/xsd_types/GYear.h
+ ${BASYX_SUBMODEL_INCLUDE_DIR}/simple/common/xsd_types/GMonthDay.h
+ ${BASYX_SUBMODEL_INCLUDE_DIR}/simple/common/xsd_types/GDay.h
+ ${BASYX_SUBMODEL_INCLUDE_DIR}/simple/common/xsd_types/GMonth.h
${BASYX_SUBMODEL_INCLUDE_DIR}/simple/constraint/Formula.h
${BASYX_SUBMODEL_INCLUDE_DIR}/simple/constraint/Qualifier.h
${BASYX_SUBMODEL_INCLUDE_DIR}/simple/dataspecification/DataSpecification.h
@@ -233,7 +266,20 @@
add_library(basyx::submodel ALIAS ${BASYX_SUBMODEL_LIB_SUFFIX})
add_library(${PROJECT_SHORTNAME}::${BASYX_SUBMODEL_LIB_SUFFIX} ALIAS ${BASYX_SUBMODEL_LIB_SUFFIX})
-diagnostics_print(${BASYX_SUBMODEL_LIB_SUFFIX})
+# Disable inheritance by dominance warning in MSVC
+if(MSVC)
+ target_compile_options(${BASYX_SUBMODEL_LIB_SUFFIX} PUBLIC /wd4250)
+endif()
+
+if(BASYX_IS_SUBMODULE)
+ set_target_properties(${BASYX_SUBMODEL_LIB_SUFFIX} PROPERTIES FOLDER BaSyx)
+endif()
+
+if(BASYX_VERBOSE_CMAKE_OUTPUT)
+ diagnostics_print(${BASYX_SUBMODEL_LIB_SUFFIX})
+endif()
+
+build_source_group(${BASYX_SUBMODEL_LIB_SUFFIX})
###############################################
### Install section ###
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/api/constant_definitions.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/api/constant_definitions.cpp
deleted file mode 100644
index 7e1a3d6..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/api/constant_definitions.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-#include <BaSyx/submodel/map/modeltype/ModelType.h>
-#include <BaSyx/submodel/map/identifier/IdentifierType.h>
-#include <BaSyx/submodel/api/identifier/IIdentifier.h>
-#include <BaSyx/submodel/api/qualifier/IReferable.h>
-#include <BaSyx/submodel/api/qualifier/IHasSemantics.h>
-#include <BaSyx/submodel/api/qualifier/IHasKind.h>
-#include <BaSyx/submodel/api/qualifier/IHasDataSpecification.h>
-#include <BaSyx/submodel/api/qualifier/IAdministrativeInformation.h>
-#include <BaSyx/submodel/api/qualifier/qualifiable/IQualifier.h>
-#include <BaSyx/submodel/api/qualifier/qualifiable/IQualifiable.h>
-#include <BaSyx/submodel/api/qualifier/qualifiable/IConstraint.h>
-#include <BaSyx/submodel/api/submodelelement/ISubmodelElement.h>
-#include <BaSyx/submodel/api/submodelelement/operation/IOperation.h>
-#include <BaSyx/submodel/api/submodelelement/operation/IOperationVariable.h>
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-#include <BaSyx/submodel/api/reference/IReference.h>
-#include <BaSyx/submodel/api/ISubModel.h>
-#include <BaSyx/submodel/api/qualifier/qualifiable/IFormula.h>
-#include <BaSyx/submodel/api/qualifier/IIdentifiable.h>
-#include <BaSyx/submodel/api/submodelelement/IReferenceElement.h>
-#include <BaSyx/submodel/api/submodelelement/IRelationshipElement.h>
-#include <BaSyx/submodel/api/submodelelement/ISubmodelElementCollection.h>
-
-#include <BaSyx/submodel/api/submodelelement/property/blob/IBlob.h>
-#include <BaSyx/submodel/api/submodelelement/property/file/IFile.h>
-
-#include <BaSyx/submodel/api/submodelelement/langstring/ILangStringSet.h>
-
-#include <BaSyx/submodel/api/dataspecification/datatypes/DataTypeIEC61360.h>
-#include <BaSyx/submodel/api/dataspecification/datatypes/LevelType.h>
-#include <BaSyx/submodel/api/dataspecification/IDataSpecificationContent.h>
-#include <BaSyx/submodel/api/dataspecification/IDataSpecification.h>
-#include <BaSyx/submodel/api/dataspecification/IDataSpecificationIEC61360.h>
-
-
-#include <BaSyx/submodel/api/submodelelement/entity/IEntity.h>
-#include <BaSyx/submodel/api/parts/IConceptDescription.h>
-
-
-namespace basyx {
-namespace submodel {
-
-constexpr char IOperationVariable::Path::Type[];
-constexpr char IOperationVariable::Path::ModelType[];
-constexpr char IOperationVariable::Path::Value[];
-
-constexpr char IProperty::Path::Value[];
-constexpr char IProperty::Path::ValueId[];
-constexpr char IProperty::Path::ValueType[];
-constexpr char IProperty::Path::ModelType[];
-
-constexpr char IOperation::Path::Input[];
-constexpr char IOperation::Path::Output[];
-constexpr char IOperation::Path::Invokable[];
-constexpr char IOperation::Path::ModelType[];
-
-constexpr char IReference::Path::DataSpecifications[];
-constexpr char IReference::Path::Key[];
-constexpr char IReference::Path::Parents[];
-constexpr char IReference::Path::Qualifiers[];
-constexpr char IReference::Path::ReferencePath[];
-constexpr char IReference::Path::SemanticIds[];
-
-constexpr char IConstraint::Path::ModelType[];
-
-constexpr char ISubmodelElement::Path::ModelType[];
-
-constexpr char ModelType::Path::ModelType[];
-constexpr char ModelType::Path::Name[];
-
-constexpr char IReferable::Path::IdShort[];
-constexpr char IReferable::Path::Category[];
-constexpr char IReferable::Path::Description[];
-constexpr char IReferable::Path::Parent[];
-
-constexpr char IHasSemantics::Path::SemanticId[];
-
-constexpr char IHasKind::Path::Kind[];
-
-constexpr char IQualifier::Path::Qualifier[];
-constexpr char IQualifier::Path::QualifierType[];
-constexpr char IQualifier::Path::QualifierValue[];
-constexpr char IQualifier::Path::QualifierValueID[];
-constexpr char IQualifier::Path::Modeltype[];
-
-constexpr char IQualifiable::Path::Constraints[];
-
-constexpr char IHasDataSpecification::Path::HasDataSpecification[];
-
-constexpr char IIdentifier::Path::IdentifierPath[];
-constexpr char IIdentifier::Path::IdType[];
-constexpr char IIdentifier::Path::Id[];
-
-constexpr char IAdministrativeInformation::Path::AdministrationPath[];
-constexpr char IAdministrativeInformation::Path::Version[];
-constexpr char IAdministrativeInformation::Path::Revision[];
-
-constexpr char ISubModel::Path::Submodelelement[];
-constexpr char ISubModel::Path::DataElements[];
-constexpr char ISubModel::Path::Operations[];
-constexpr char ISubModel::Path::ModelType[];
-
-constexpr char Description::Path::Language[];
-constexpr char Description::Path::Text[];
-
-constexpr char IFormula::Path::Dependson[];
-constexpr char IFormula::Path::Modeltype[];
-
-constexpr char IIdentifiable::Path::Administration[];
-constexpr char IIdentifiable::Path::Identification[];
-
-constexpr char IReferenceElement::Path::Modeltype[];
-
-constexpr char IRelationshipElement::Path::First[];
-constexpr char IRelationshipElement::Path::Second[];
-constexpr char IRelationshipElement::Path::ModelType[];
-
-constexpr char ISubmodelElementCollection::Path::AllowDuplicates[];
-constexpr char ISubmodelElementCollection::Path::Ordered[];
-constexpr char ISubmodelElementCollection::Path::ModelType[];
-
-constexpr char IKey::Path::IdType[];
-constexpr char IKey::Path::Local[];
-constexpr char IKey::Path::Type[];
-constexpr char IKey::Path::Value[];
-
-constexpr char IdentifierType::Custom[];
-constexpr char IdentifierType::IRDI[];
-constexpr char IdentifierType::URI[];
-
-
-
-constexpr char IBlob::Path::Value[];
-constexpr char IBlob::Path::MIMEType[];
-
-
-constexpr char IDataSpecificationIEC61360::Path::Definition[];
-constexpr char IDataSpecificationIEC61360::Path::LevelType[];
-constexpr char IDataSpecificationIEC61360::Path::ValueId[];
-constexpr char IDataSpecificationIEC61360::Path::SourceOfDefinition[];
-constexpr char IDataSpecificationIEC61360::Path::ShortName[];
-constexpr char IDataSpecificationIEC61360::Path::ValueFormat[];
-constexpr char IFile::Path::MIMEType[];
-constexpr char IDataSpecificationIEC61360::Path::UnitId[];
-constexpr char IDataSpecificationIEC61360::Path::Unit[];
-constexpr char IDataSpecificationIEC61360::Path::PreferredName[];
-constexpr char IFile::Path::Value[];
-constexpr char IConceptDescription::Path::ModelType[];
-constexpr char IConceptDescription::Path::IsCaseOf[];
-constexpr char IDataSpecification::Path::Content[];
-constexpr char IDataSpecificationIEC61360::Path::ValueList[];
-constexpr char IEntity::Path::EntityType[];
-constexpr char IDataSpecificationIEC61360::Path::DataType[];
-
-
-constexpr char ILangStringSet::Path::Language[];
-constexpr char ILangStringSet::Path::Text[];
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/api/dataspecification/datatypes/DataTypeIEC61360.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/api/dataspecification/datatypes/DataTypeIEC61360.cpp
deleted file mode 100644
index 31bd29d..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/api/dataspecification/datatypes/DataTypeIEC61360.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-#include <BaSyx/submodel/api/dataspecification/datatypes/DataTypeIEC61360.h>
-
-#include <unordered_map>
-#include <string>
-
-#include <BaSyx/util/util.h>
-
-using namespace basyx::submodel;
-
-static const std::string DataTypeIEC61360_to_string[] =
-{
- "Date",
- "String",
- "String_Translatable",
- "Real_Measure",
- "Real_Count",
- "Real_Currency",
- "Boolean",
- "Url",
- "Rational",
- "Rational_Measure",
- "Time",
- "Timestamp"
-};
-
-static const std::unordered_map<std::string, basyx::submodel::DataTypeIEC61360> string_to_DataTypeIEC61360
-{
- {DataTypeIEC61360_to_string[static_cast<char>(DataTypeIEC61360::Date)], DataTypeIEC61360::Date},
- {DataTypeIEC61360_to_string[static_cast<char>(DataTypeIEC61360::String)], DataTypeIEC61360::String},
- {DataTypeIEC61360_to_string[static_cast<char>(DataTypeIEC61360::String_Translatable)], DataTypeIEC61360::String_Translatable},
- {DataTypeIEC61360_to_string[static_cast<char>(DataTypeIEC61360::Real_Measure)], DataTypeIEC61360::Real_Measure},
- {DataTypeIEC61360_to_string[static_cast<char>(DataTypeIEC61360::Real_Count)], DataTypeIEC61360::Real_Count},
- {DataTypeIEC61360_to_string[static_cast<char>(DataTypeIEC61360::Real_Currency)], DataTypeIEC61360::Real_Currency},
- {DataTypeIEC61360_to_string[static_cast<char>(DataTypeIEC61360::Boolean)], DataTypeIEC61360::Boolean},
- {DataTypeIEC61360_to_string[static_cast<char>(DataTypeIEC61360::Url)], DataTypeIEC61360::Url},
- {DataTypeIEC61360_to_string[static_cast<char>(DataTypeIEC61360::Rational)], DataTypeIEC61360::Rational},
- {DataTypeIEC61360_to_string[static_cast<char>(DataTypeIEC61360::Rational_Measure)], DataTypeIEC61360::Rational_Measure},
- {DataTypeIEC61360_to_string[static_cast<char>(DataTypeIEC61360::Time)], DataTypeIEC61360::Time},
- {DataTypeIEC61360_to_string[static_cast<char>(DataTypeIEC61360::Timestamp)], DataTypeIEC61360::Timestamp}
-};
-
-const std::string & util::to_string(basyx::submodel::DataTypeIEC61360 type)
-{
- return DataTypeIEC61360_to_string[static_cast<char>(type)];
-}
-
-template<>
-basyx::submodel::DataTypeIEC61360 util::from_string<basyx::submodel::DataTypeIEC61360>(const std::string & str)
-{
- return string_to_DataTypeIEC61360.at(str);
-}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/api/dataspecification/datatypes/LevelType.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/api/dataspecification/datatypes/LevelType.cpp
deleted file mode 100644
index e3bfc57..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/api/dataspecification/datatypes/LevelType.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-#include <BaSyx/submodel/api/dataspecification/datatypes/LevelType.h>
-
-#include <unordered_map>
-#include <string>
-
-#include <BaSyx/util/util.h>
-
-using namespace basyx::submodel;
-
-static const std::string LevelType_to_string[4] =
-{
- "Min",
- "Max",
- "Nom",
- "Typ"
-};
-
-static const std::unordered_map<std::string, basyx::submodel::LevelType> string_to_LevelType
-{
- {LevelType_to_string[static_cast<char>(LevelType::Min)], LevelType::Min},
- {LevelType_to_string[static_cast<char>(LevelType::Max)], LevelType::Max},
- {LevelType_to_string[static_cast<char>(LevelType::Nom)], LevelType::Nom},
- {LevelType_to_string[static_cast<char>(LevelType::Typ)], LevelType::Typ}
-};
-
-const std::string & util::to_string(basyx::submodel::LevelType levelType)
-{
- return LevelType_to_string[static_cast<char>(levelType)];
-}
-
-template<>
-basyx::submodel::LevelType util::from_string<basyx::submodel::LevelType>(const std::string & str)
-{
- return string_to_LevelType.at(str);
-}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/ConnectedElement.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/ConnectedElement.cpp
deleted file mode 100644
index 054a591..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/ConnectedElement.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * ConnectedElement.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/connected/ConnectedElement.h>
-#include <BaSyx/submodel/api/qualifier/IReferable.h>
-
-namespace basyx {
-namespace submodel {
-
-ConnectedElement::ConnectedElement(const std::shared_ptr<vab::core::proxy::IVABElementProxy> & proxy) :
- proxy(proxy),
- local_map(new basyx::object::object_map_t)
-{}
-
-ConnectedElement::ConnectedElement(const std::shared_ptr<vab::core::proxy::IVABElementProxy>& proxy, std::shared_ptr<basyx::object::object_map_t> & local_values) :
- proxy(proxy),
- local_map(local_values)
-{}
-
-std::shared_ptr<vab::core::proxy::IVABElementProxy> ConnectedElement::getProxy() const
-{
- return this->proxy;
-}
-
-basyx::object ConnectedElement::getLocalValue(const std::string & path) const
-{
- auto element_ptr = this->local_map->find(path);
- if ( element_ptr != this->local_map->end() )
- return element_ptr->second;
- return basyx::object(nullptr);
-}
-
-void ConnectedElement::setLocalValue(const std::string & path, const basyx::object & value)
-{
- this->local_map->emplace(path, value);
-}
-
-void ConnectedElement::setLocalValues(const basyx::object::object_map_t & values)
-{
- for ( auto & val : values )
- {
- this->local_map->emplace(val.first, val.second);
- }
-}
-
-void ConnectedElement::updateLocalValue(const std::string & path, const basyx::object value)
-{
- this->local_map->operator[](path) = value;
-}
-
-
-void ConnectedElement::setId(const std::string & id)
-{
- this->setProxyValue(IReferable::Path::IdShort, id);
-}
-
-std::string ConnectedElement::getId() const
-{
- return this->getProxyValue(IReferable::Path::IdShort);
-}
-
-
-void ConnectedElement::setProxyValue(const std::string & path, const basyx::object value) const
-{
- this->getProxy()->updateElementValue(path, value);
-}
-
-std::string ConnectedElement::getProxyValue(const std::string & path) const
-{
- auto value = getProxy()->readElementValue(path);
- return value.Get<std::string>();
-}
-
-std::shared_ptr<basyx::object::object_map_t> ConnectedElement::getProxyMap(const std::string & path) const
-{
- auto value = getProxy()->readElementValue(path);
- return std::make_shared<basyx::object::object_map_t>(value.Get<basyx::object::object_map_t>());
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/ConnectedSubmodel.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/ConnectedSubmodel.cpp
deleted file mode 100644
index c0f5765..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/ConnectedSubmodel.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * ConnectedSubmodel.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/connected/ConnectedSubmodel.h>
-
-#include <BaSyx/submodel/connected/submodelelement/operation/ConnectedOperation.h>
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedSingleProperty.h>
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedPropertyFactory.h>
-#include <BaSyx/vab/core/util/VABPath.h>
-#include <BaSyx/submodel/map/qualifier/AdministrativeInformation.h>
-#include <BaSyx/submodel/map/identifier/Identifier.h>
-#include <BaSyx/submodel/map/reference/Reference.h>
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedProperty.h>
-
-namespace basyx {
-namespace submodel {
-
-std::shared_ptr<IReference> ConnectedSubmodel::getSemanticId() const
-{
- return std::make_shared<Reference>(*this->getProxyMap(IReference::Path::ReferencePath));
-}
-
-std::shared_ptr<IAdministrativeInformation> ConnectedSubmodel::getAdministration() const
-{
- return std::make_shared<AdministrativeInformation>(*this->getProxyMap(IAdministrativeInformation::Path::AdministrationPath));
-}
-
-std::shared_ptr<IIdentifier> ConnectedSubmodel::getIdentification() const
-{
- return std::make_shared<Identifier>(*this->getProxyMap(IIdentifier::Path::IdentifierPath));
-}
-
-basyx::specificCollection_t<IReference> ConnectedSubmodel::getDataSpecificationReferences() const
-{
- AdministrativeInformation administrative_information(*this->getProxyMap(IAdministrativeInformation::Path::AdministrationPath));
- return administrative_information.getDataSpecificationReferences();
-}
-
-Kind ConnectedSubmodel::getHasKindReference() const
-{
- //todo
- return Kind::NotSpecified;
-}
-
-void ConnectedSubmodel::setDataElements(const basyx::specificMap_t<IProperty> & properties)
-{}
-
-void ConnectedSubmodel::setOperations(const basyx::specificMap_t<IOperation> & operations)
-{}
-
-std::string ConnectedSubmodel::getIdShort() const
-{
- return this->getProxyValue(IReferable::Path::IdShort);
-}
-
-std::string ConnectedSubmodel::getCategory() const
-{
- return this->getProxyValue(IReferable::Path::Category);
-}
-
-Description ConnectedSubmodel::getDescription() const
-{
- return Description(*this->getProxyMap(IReferable::Path::Description));
-}
-
-std::shared_ptr<IReference> ConnectedSubmodel::getParent() const
-{
- return std::make_shared<Reference>(*this->getProxyMap(IReferable::Path::Parent));
-}
-
-void ConnectedSubmodel::addSubModelElement(const std::shared_ptr<ISubmodelElement> & element)
-{
- // Todo: May need a wrapper?
- //this->getProxy()->createElement(SubmodelPaths::SUBMODELELEMENT, element);
-
- //if ( dynamic_cast<IDataElement*>(element.get()) != nullptr )
- //{
- // this->getProxy()->createElement(SubmodelPaths::PROPERTIES, element);
- //}
- //else if ( dynamic_cast<operation::IOperation*>(element.get()) != nullptr )
- //{
- // this->getProxy()->createElement(SubmodelPaths::OPERATIONS, element);
- //}
-}
-
-basyx::specificMap_t<IDataElement> ConnectedSubmodel::getDataElements() const
-{
- basyx::specificMap_t<IDataElement> map;
- auto operations = this->getProxy()->readElementValue(Path::DataElements).Get<basyx::object::object_list_t>();
-
- for ( auto & operation : operations )
- {
- auto data_element_map = operation.Get<basyx::object::object_map_t>();
- auto id = data_element_map.at(IReferable::Path::IdShort).GetStringContent();
-
- vab::core::VABPath path(Path::Operations);
- path = path + id;
- auto connected_property =
- backend::connected::support::ConnectedPropertyFactory::createProperty(this->getProxy()->getDeepProxy(path));
-
- //todo map.emplace( id, std::dynamic_pointer_cast<IDataElement>(connected_property) );
- }
-
- return map;
-}
-
-basyx::specificMap_t<IOperation> ConnectedSubmodel::getOperations() const
-{
- basyx::specificMap_t<IOperation> map;
- auto operations = this->getProxy()->readElementValue(Path::Operations).Get<basyx::object::object_list_t>();
-
- for ( auto & operation : operations )
- {
- auto operation_map = operation.Get<basyx::object::object_map_t>();
- auto id = operation_map.at(IReferable::Path::IdShort).GetStringContent();
-
- vab::core::VABPath path(Path::Operations);
- path = path + id;
- auto connected_operation = std::make_shared<ConnectedOperation>(this->getProxy()->getDeepProxy(path));
- connected_operation->setLocalValues(operation_map);
-
- map.emplace(id, connected_operation);
- }
-
- return map;
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/ConnectedVABModelMap.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/ConnectedVABModelMap.cpp
deleted file mode 100644
index 7a943ba..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/ConnectedVABModelMap.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * ConnectedVABModelMap.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/connected/ConnectedVABModelMap.h>
-
-namespace basyx {
-namespace submodel {
-namespace backend {
-
-ConnectedVABModelMap::ConnectedVABModelMap(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy) :
- ConnectedElement(proxy)
-{}
-
-}
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/ConnectedDataElement.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/ConnectedDataElement.cpp
deleted file mode 100644
index a1daf74..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/ConnectedDataElement.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * ConnectedDataElement.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/connected/submodelelement/ConnectedDataElement.h>
-#include <BaSyx/shared/types.h>
-
-#include <memory>
-
-
-namespace basyx {
-namespace submodel {
-
-ConnectedDataElement::ConnectedDataElement(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy) :
- ConnectedSubmodelElement(proxy)
-{}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/ConnectedRelationshipElement.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/ConnectedRelationshipElement.cpp
deleted file mode 100644
index d1a2743..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/ConnectedRelationshipElement.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * ConnectedRelationshipElement.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/connected/submodelelement/ConnectedRelationshipElement.h>
-
-namespace basyx {
-namespace submodel {
-
-ConnectedRelationshipElement::ConnectedRelationshipElement(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy) :
- ConnectedSubmodelElement(proxy)
-{}
-
-void ConnectedRelationshipElement::setFirst(const IReference & first)
-{
- //todo
- //this->setProxyValue(submodelelement::RelationshipElementPath::FIRST, first);
-}
-
-std::shared_ptr<IReference> ConnectedRelationshipElement::getFirst() const
-{
- //todo
- return nullptr;// this->getProxyValue(submodelelement::RelationshipElementPath::FIRST);
-}
-
-void ConnectedRelationshipElement::setSecond(const IReference & second)
-{
- //todo
- //this->setProxyValue(submodelelement::RelationshipElementPath::SECOND, second);
-}
-
-std::shared_ptr<IReference> ConnectedRelationshipElement::getSecond() const
-{
- //todo
- return nullptr;// this->getProxyValue(submodelelement::RelationshipElementPath::SECOND);
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/ConnectedSubmodelElement.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/ConnectedSubmodelElement.cpp
deleted file mode 100644
index 9aa081f..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/ConnectedSubmodelElement.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * ConnectedSubmodelElement.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/connected/submodelelement/ConnectedSubmodelElement.h>
-#include <BaSyx/submodel/connected/ConnectedElement.h>
-#include <BaSyx/submodel/map/reference/Reference.h>
-#include <BaSyx/shared/types.h>
-
-namespace basyx {
-namespace submodel {
-
-ConnectedSubmodelElement::ConnectedSubmodelElement(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy) :
- ConnectedElement(proxy)
-{}
-
-basyx::specificCollection_t<IReference> ConnectedSubmodelElement::getDataSpecificationReferences() const
-{
- auto data_specs = this->getProxyCollection(IReference::IReference::Path::DataSpecifications);
-
- basyx::specificCollection_t<IReference> specific_data_specs;
- for ( auto & spec : data_specs )
- {
- Reference data_ref(spec.Get<basyx::object::object_map_t>());
- specific_data_specs.push_back(std::make_shared<Reference>(data_ref));
- }
-
- return specific_data_specs;
-}
-
-std::string ConnectedSubmodelElement::getIdShort() const
-{
- return this->getProxyValue(IReferable::Path::IdShort);
-}
-
-std::string ConnectedSubmodelElement::getCategory() const
-{
- return this->getProxyValue(IReferable::Path::Category);
-}
-
-Description ConnectedSubmodelElement::getDescription() const
-{
- return Description(*this->getProxyMap(IReferable::Path::Description));
-}
-
-std::shared_ptr<IReference> ConnectedSubmodelElement::getParent() const
-{
- return std::make_shared<Reference>(*this->getProxyMap(IReference::Path::Parents));
-}
-
-basyx::specificCollection_t<IConstraint> ConnectedSubmodelElement::getQualifier() const
-{
- //TODO not implemented
- return basyx::specificCollection_t<IConstraint>();
-}
-
-std::shared_ptr<IReference> ConnectedSubmodelElement::getSemanticId() const
-{
- return std::make_shared<Reference>(*this->getProxyMap(IReference::Path::SemanticIds));
-}
-
-Kind ConnectedSubmodelElement::getHasKindReference() const
-{
- //todo
- return Kind::NotSpecified;
-}
-
-
-basyx::object::object_list_t ConnectedSubmodelElement::getProxyCollection(const std::string & path) const
-{
- auto value = this->getProxy()->readElementValue(path);
- return value.Get<basyx::object::object_list_t>();
-}
-
-std::string ConnectedSubmodelElement::getIdWithLocalCheck() const
-{
- basyx::object localId = this->getLocalValue(IReferable::Path::IdShort);
- if ( not localId.IsNull() ) {
- return localId.Get<std::string>();
- }
- return this->getIdShort();
-}
-
-void ConnectedSubmodelElement::setIdWithLocalCheck(const std::string & id)
-{
- auto localId = this->getLocalValue(IReferable::Path::IdShort);
- if ( not localId.IsNull() ) {
- this->updateLocalValue(IReferable::Path::IdShort, id);
- return;
- }
- this->setProxyValue(IReferable::Path::IdShort, id);
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/ConnectedSubmodelElementCollection.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/ConnectedSubmodelElementCollection.cpp
deleted file mode 100644
index 6919848..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/ConnectedSubmodelElementCollection.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * ConnectedSubmodelElementCollection.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/connected/submodelelement/ConnectedSubmodelElementCollection.h>
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-#include <BaSyx/submodel/api/ISubModel.h>
-
-namespace basyx {
-namespace submodel {
-
-
-ConnectedSubmodelElementCollection::ConnectedSubmodelElementCollection(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy):
- ConnectedSubmodelElement(proxy)
-{}
-
-void ConnectedSubmodelElementCollection::setValue(const basyx::specificCollection_t<ISubmodelElement> & value)
-{
- //todo
- //this->setProxyValue(property::PropertyPaths::VALUE, value);
-}
-
-basyx::specificCollection_t<ISubmodelElement> ConnectedSubmodelElementCollection::getValue() const
-{
- //todo
- return basyx::specificCollection_t<ISubmodelElement>(); // this->getProxyCollection(property::PropertyPaths::VALUE);
-}
-
-void ConnectedSubmodelElementCollection::setOrdered(const bool & value)
-{
- this->setProxyValue(ISubmodelElementCollection::Path::Ordered, value);
-}
-
-bool ConnectedSubmodelElementCollection::isOrdered() const
-{
- auto element = this->getProxy()->readElementValue(ISubmodelElementCollection::Path::Ordered);
- return element.Get<bool>();
-}
-
-void ConnectedSubmodelElementCollection::setAllowDuplicates(const bool & value)
-{
- this->setProxyValue(ISubmodelElementCollection::Path::AllowDuplicates, value);
-}
-
-bool ConnectedSubmodelElementCollection::isAllowDuplicates() const
-{
- auto element = this->getProxy()->readElementValue(ISubmodelElementCollection::Path::AllowDuplicates);
- return element.Get<bool>();
-}
-
-void ConnectedSubmodelElementCollection::setElements(const basyx::specificMap_t<ISubmodelElement> & elements)
-{
- //todo
- //this->setProxyValue(SubmodelPaths::SUBMODELELEMENT, elements);
-}
-
-basyx::specificMap_t<ISubmodelElement> ConnectedSubmodelElementCollection::getElements() const
-{
- //todo
-
- //auto elements = this->getProxy()->readElementValue(SubmodelPaths::SUBMODELELEMENT);
- return basyx::specificMap_t<ISubmodelElement>();
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/operation/ConnectedOperation.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/operation/ConnectedOperation.cpp
deleted file mode 100644
index dcf2666..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/operation/ConnectedOperation.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * ConnectedOperation.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/connected/submodelelement/operation/ConnectedOperation.h>
-
-namespace basyx {
-namespace submodel {
-
-ConnectedOperation::ConnectedOperation(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy) :
- ConnectedSubmodelElement(proxy)
-{}
-
-void ConnectedOperation::setId(const std::string & id)
-{
- this->setIdWithLocalCheck(id);
-}
-
-std::string ConnectedOperation::getId() const
-{
- return this->getIdWithLocalCheck();
-}
-
-basyx::specificCollection_t<IOperationVariable> ConnectedOperation::getParameterTypes() const
-{
- // todo
- return basyx::specificCollection_t<IOperationVariable>(); // this->getProxyCollection(std::string(submodelelement::operation::OperationPaths::INPUT));
-}
-
-std::shared_ptr<IOperationVariable>ConnectedOperation::getReturnType() const
-{
- // todo
- return std::shared_ptr<IOperationVariable>(); // this->getProxyCollection(std::string(submodelelement::operation::OperationPaths::INPUT));
-}
-
-basyx::object ConnectedOperation::invoke(basyx::object & parameters) const
-{
- return this->getProxy()->invoke("", parameters);
-
-}
-
-basyx::object ConnectedOperation::getInvocable() const
-{
- // Not supported on remote side.
- return basyx::detail::functionWrapper();
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedCollectionProperty.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedCollectionProperty.cpp
deleted file mode 100644
index 13cb50b..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedCollectionProperty.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * ConnectedCollectionProperty.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedCollectionProperty.h>
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-
-namespace basyx {
-namespace submodel {
-
-using namespace submodelelement::property;
-
-ConnectedCollectionProperty::ConnectedCollectionProperty(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy) :
- ConnectedProperty(PropertyType::Collection, proxy)
-{}
-
-void ConnectedCollectionProperty::set(const basyx::object::object_list_t & collection) const
-{
- this->getProxy()->updateElementValue(IProperty::Path::Value, collection);
-}
-
-void ConnectedCollectionProperty::add(const basyx::object & newValue)
-{
- this->getProxy()->createElement(IProperty::Path::Value, newValue);
-}
-
-void ConnectedCollectionProperty::remove(basyx::object & objectRef)
-{
- this->getProxy()->deleteElement(IProperty::Path::Value, objectRef);
-}
-
-basyx::object::object_list_t ConnectedCollectionProperty::getElements() const
-{
- return this->retrieveObject().Get<basyx::object::object_list_t>();
-}
-
-int ConnectedCollectionProperty::getElementCount() const
-{
- return this->retrieveObject().Get<basyx::object::object_list_t>().size();
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedMapProperty.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedMapProperty.cpp
deleted file mode 100644
index 14619f8..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedMapProperty.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * ConnectedMapProperty.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedMapProperty.h>
-#include <BaSyx/vab/core/util/VABPath.h>
-
-namespace basyx {
-namespace submodel {
-
-using namespace submodelelement::property;
-
-ConnectedMapProperty::ConnectedMapProperty(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy) :
- ConnectedProperty(PropertyType::Map, proxy)
-{}
-
-basyx::object ConnectedMapProperty::getValue(const std::string & key) const
-{
- return this->getMap().at(key);
-}
-
-void ConnectedMapProperty::put(const std::string & key, const basyx::object & value) const
-{
- basyx::vab::core::VABPath path(IProperty::Path::Value);
- path.append(key);
- this->setProxyValue(path, value);
-}
-
-void ConnectedMapProperty::set( const basyx::object::object_map_t & map ) const
-{
- this->setProxyValue(IProperty::Path::Value, map);
-}
-
-basyx::object::object_list_t ConnectedMapProperty::getKeys() const
-{
- auto map = this->getMap();
- basyx::object::object_list_t keys;
- keys.reserve(map.size());
-
- for ( auto entry : map ) {
- keys.push_back(entry.first);
- }
-
- return keys;
-}
-
-int ConnectedMapProperty::getEntryCount() const
-{
- return this->getMap().size();
-}
-
-void ConnectedMapProperty::remove(const std::string & key) const
-{
- basyx::vab::core::VABPath path(IProperty::Path::Value);
- path.append(key);
- this->getProxy()->deleteElement(path);
-}
-
-basyx::object::object_map_t ConnectedMapProperty::getMap() const
-{
- auto map = this->getProxy()->readElementValue(IProperty::Path::Value).Get<basyx::object::object_map_t>();
- return map;
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedProperty.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedProperty.cpp
deleted file mode 100644
index 0b804de..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedProperty.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * ConnectedProperty.cpp
- *
- * Author: wendel
- */
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedProperty.h>
-#include <BaSyx/shared/anyTypeChecker.h>
-
-namespace basyx {
-namespace submodel {
-
-
-ConnectedProperty::ConnectedProperty(PropertyType type, std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy) :
- ConnectedDataElement(proxy),
- type(type)
-{}
-
-IProperty::PropertyType ConnectedProperty::getPropertyType() const
-{
- return this->type;
-}
-
-void ConnectedProperty::setId(const std::string & id)
-{
- this->setId(id);
-}
-
-std::string ConnectedProperty::getId() const
-{
- return this->getId();
-}
-
-basyx::object ConnectedProperty::retrieveObject() const
-{
- return this->getProxy()->readElementValue(IProperty::Path::Value).Get<basyx::object::object_map_t>().at(IProperty::Path::Value);
-}
-
-void ConnectedProperty::setValueId(const std::string & valueId)
-{}
-
-std::string ConnectedProperty::getValueId() const
-{
- return std::string();
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedReferenceElement.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedReferenceElement.cpp
deleted file mode 100644
index a3f0c65..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedReferenceElement.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * ConnectedReferenceElement.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedReferenceElement.h>
-
-namespace basyx {
-namespace submodel {
-
-ConnectedReferenceElement::ConnectedReferenceElement(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy) :
- ConnectedDataElement(proxy)
-{}
-
-void ConnectedReferenceElement::setValue(const IReference & ref)
-{
- //todo
- //this->setProxyValue(submodelelement::property::PropertyPaths::VALUE, ref);
-}
-
-std::shared_ptr<IReference> ConnectedReferenceElement::getValue() const
-{
- //todo
- return nullptr;// this->getProxyValue(submodelelement::property::PropertyPaths::VALUE);
-}
-
-}
-}
-
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedSingleProperty.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedSingleProperty.cpp
deleted file mode 100644
index 64166f1..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedSingleProperty.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * ConnectedSingleProperty.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedSingleProperty.h>
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-
-namespace basyx {
-namespace submodel {
-
-ConnectedSingleProperty::ConnectedSingleProperty(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy) :
- ConnectedProperty(PropertyType::Single, proxy)
-{}
-
-basyx::object ConnectedSingleProperty::get() const
-{
- return this->retrieveObject();
-}
-
-void ConnectedSingleProperty::set(const basyx::object & value)
-{
- this->setProxyValue(IProperty::Path::Value, value);
-}
-
-std::string ConnectedSingleProperty::getValueType() const
-{
- auto map = this->getProxy()->readElementValue("").Get<basyx::object::object_map_t>();
- return map.at(IProperty::Path::ValueType).Get<std::string>();
-}
-
-void basyx::submodel::ConnectedSingleProperty::setValueId(const std::string & valueId)
-{}
-
-std::string basyx::submodel::ConnectedSingleProperty::getValueId() const
-{
- return std::string();
-}
-
-IProperty::PropertyType basyx::submodel::ConnectedSingleProperty::getPropertyType() const
-{
- return PropertyType();
-}
-
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/blob/ConnectedBlob.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/blob/ConnectedBlob.cpp
deleted file mode 100644
index dca591e..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/blob/ConnectedBlob.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * ConnectedBlob.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/connected/submodelelement/property/blob/ConnectedBlob.h>
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-
-namespace basyx {
-namespace submodel {
-
-ConnectedBlob::ConnectedBlob(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy) :
- ConnectedDataElement(proxy)
-{}
-
-void ConnectedBlob::setValue(const std::string & bytes)
-{
- this->setProxyValue(IProperty::Path::Value, bytes);
-}
-
-const std::string & ConnectedBlob::getValue() const
-{
- return getProxy()->readElementValue(IProperty::Path::Value).GetStringContent();
-}
-
-void ConnectedBlob::setMimeType(const std::string & mimeType)
-{
- this->setProxyValue(IBlob::Path::MIMEType, mimeType);
-}
-
-const std::string & ConnectedBlob::getMimeType() const
-{
- return this->getProxyValue(IBlob::Path::MIMEType);
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/file/ConnectedFile.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/file/ConnectedFile.cpp
deleted file mode 100644
index 2502005..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/file/ConnectedFile.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * ConnectedFile.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/connected/submodelelement/property/file/ConnectedFile.h>
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-#include <BaSyx/submodel/api/submodelelement/property/blob/IBlob.h>
-
-namespace basyx {
-namespace submodel {
-
-ConnectedFile::ConnectedFile(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy) :
- ConnectedDataElement(proxy)
-{}
-
-void ConnectedFile::setValue(const std::string & value)
-{
- this->setProxyValue(IProperty::Path::Value, value);
-}
-
-const std::string & ConnectedFile::getValue() const
-{
- return this->getProxyValue(IProperty::Path::Value);
-}
-
-void ConnectedFile::setMimeType(const std::string & mimeType)
-{
- this->setProxyValue(IBlob::Path::MIMEType, mimeType);
-}
-
-const std::string & ConnectedFile::getMimeType() const
-{
- return this->getProxyValue(IBlob::Path::MIMEType);
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/enumerations/IdentifiableElements.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/enumerations/IdentifiableElements.cpp
index 295fb35..374072f 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/enumerations/IdentifiableElements.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/enumerations/IdentifiableElements.cpp
@@ -9,26 +9,12 @@
using enum_pair_t = std::pair<const char*, IdentifiableElements>;
-static const std::array<enum_pair_t, 18> string_to_enum =
+static const std::array<enum_pair_t, 4> string_to_enum =
{
- std::make_pair("AccessPermissionRule", IdentifiableElements::AccessPermissionRule),
- std::make_pair("AnnotatedRelationshipElemenBasicEvent", IdentifiableElements::AnnotatedRelationshipElemenBasicEvent),
- std::make_pair("Blob", IdentifiableElements::Blob),
- std::make_pair("Capability", IdentifiableElements::Capability),
- std::make_pair("ConceptDictionary", IdentifiableElements::ConceptDictionary),
- std::make_pair("DataElement", IdentifiableElements::DataElement),
- std::make_pair("Entity", IdentifiableElements::Entity),
- std::make_pair("Event", IdentifiableElements::Event),
- std::make_pair("File", IdentifiableElements::File),
- std::make_pair("MultiLanguageProperty", IdentifiableElements::MultiLanguageProperty),
- std::make_pair("Operation", IdentifiableElements::Operation),
- std::make_pair("Property", IdentifiableElements::Property),
- std::make_pair("Range", IdentifiableElements::Range),
- std::make_pair("ReferenceElement", IdentifiableElements::ReferenceElement),
- std::make_pair("RelationshipElement", IdentifiableElements::RelationshipElement),
- std::make_pair("SubmodelElement", IdentifiableElements::SubmodelElement),
- std::make_pair("SubmodelElementCollection", IdentifiableElements::SubmodelElementCollection),
- std::make_pair("View", IdentifiableElements::View),
+ std::make_pair("Asset", IdentifiableElements::Asset),
+ std::make_pair("AssetAdministrationShell", IdentifiableElements::AssetAdministrationShell),
+ std::make_pair("ConceptDescription", IdentifiableElements::ConceptDescription),
+ std::make_pair("Submodel", IdentifiableElements::Submodel),
};
IdentifiableElements IdentifiableElements_::from_string(const std::string & name)
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/enumerations/IdentifierType.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/enumerations/IdentifierType.cpp
index 0d1261f..a33dfc1 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/enumerations/IdentifierType.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/enumerations/IdentifierType.cpp
@@ -1,3 +1,5 @@
+#ifdef IDENT_TYPE
+
#include <BaSyx/submodel/enumerations/IdentifierType.h>
#include <array>
@@ -37,3 +39,4 @@
return pair->first;
}
+#endif
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/enumerations/KeyElements.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/enumerations/KeyElements.cpp
index 8871f43..14cdf84 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/enumerations/KeyElements.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/enumerations/KeyElements.cpp
@@ -9,7 +9,7 @@
using enum_pair_t = std::pair<const char*, KeyElements>;
-static const std::array<enum_pair_t, 26> string_to_enum =
+static const std::array<enum_pair_t, 27> string_to_enum =
{
std::make_pair("GlobalReference", KeyElements::GlobalReference),
std::make_pair("FragmentReference", KeyElements::FragmentReference),
@@ -25,6 +25,7 @@
std::make_pair("File", KeyElements::File),
std::make_pair("MultiLanguageProperty", KeyElements::MultiLanguageProperty),
std::make_pair("Operation", KeyElements::Operation),
+ std::make_pair("OperationVariable", KeyElements::OperationVariable),
std::make_pair("Property", KeyElements::Property),
std::make_pair("Range", KeyElements::Range),
std::make_pair("ReferenceElement", KeyElements::ReferenceElement),
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/SubModel.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/SubModel.cpp
deleted file mode 100644
index d7f0983..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/SubModel.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * SubModel.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/map/SubModel.h>
-#include <BaSyx/submodel/map/submodelelement/operation/Operation.h>
-#include <BaSyx/submodel/map/submodelelement/property/Property.h>
-
-namespace basyx {
-namespace submodel {
-
- SubModel::SubModel(
- const IHasSemantics& semantics,
- const IIdentifiable& identifiable,
- const IQualifiable& qualifiable,
- const IHasDataSpecification& specification,
- const IHasKind& hasKind)
- : vab::ElementMap {}
- , ModelType { ISubModel::Path::ModelType }
- , HasSemantics { semantics }
- , Identifiable { identifiable }
- , Qualifiable { qualifiable }
- , HasDataSpecification { specification }
- , HasKind { hasKind }
- {
- this->map.insertKey(ISubModel::Path::Operations, basyx::object::make_map());
- this->map.insertKey(ISubModel::Path::DataElements, basyx::object::make_map());
- this->map.insertKey(ISubModel::Path::Submodelelement, basyx::object::make_map());
- }
-
- //SubModel::SubModel(const basyx::object& object)
- // : vab::ElementMap { object }
- // , ModelType { ISubModel::Path::ModelType }
- //{
- // //todo: may assert if all sufficient parent classes are in object
- //}
-
- SubModel::SubModel()
- : SubModel {
- HasSemantics {},
- Identifiable {},
- Qualifiable {},
- HasDataSpecification {},
- HasKind {}
- }
- {
- }
-
- SubModel::SubModel(const ISubModel& submodel)
- : SubModel {
- HasSemantics { submodel.getSemanticId() },
- Identifiable { *submodel.getIdentification(), *submodel.getAdministration() },
- Qualifiable { submodel.getQualifier() },
- HasDataSpecification { submodel.getDataSpecificationReferences() },
- HasKind { submodel.getHasKindReference() }
- }
- {
- }
-
- void SubModel::setDataElements(const basyx::specificMap_t<IDataElement>& dataElements)
- {
- basyx::object map = basyx::object::make_map();
- for ( auto & elem : dataElements )
- {
- auto obj = DataElement{*elem.second}.getMap();
- map.insertKey(elem.first, obj, true);
- }
- this->map.insertKey(ISubModel::Path::DataElements, map, true);
- }
-
- void SubModel::setOperations(const basyx::specificMap_t<IOperation>& operations)
- {
- basyx::object map = basyx::object::make_map();
- for (auto& elem : operations) {
- auto obj = Operation { *elem.second }.getMap();
- map.insertKey(elem.first, obj, true);
- }
- this->map.insertKey(ISubModel::Path::Operations, map, true);
- }
-
- void SubModel::addSubModelElement(const std::shared_ptr<ISubmodelElement>& element)
- {
- //SubmodelElement element_obj { element };
- //this->map.getProperty(ISubModel::Path::Submodelelement).insertKey(element->getIdShort(), element_obj.getMap());
- }
-
- basyx::specificMap_t<IDataElement> SubModel::getDataElements() const
- {
- basyx::specificMap_t<IDataElement> specific_map;
- auto & obj_map = this->map.getProperty(ISubModel::Path::DataElements).Get<object::object_map_t&>();
- for (auto& elem : obj_map)
- {
- auto submodel_elem = std::make_shared<DataElement>(elem.second);
- specific_map.emplace(elem.first, submodel_elem);
- }
-
- return specific_map;
- }
-
- void SubModel::addOperation(const IOperation& operation)
- {
- auto operations = this->getMap().getProperty(ISubModel::Path::Operations);
- Operation operation_obj{ operation };
- operations.insertKey(operation.getIdShort(), operation_obj.getMap() );
- }
-
- void SubModel::addDataElement(const IDataElement& dataElement)
- {
- auto dataElements = this->getMap().getProperty(ISubModel::Path::DataElements);
- DataElement dataElement_obj{ dataElement };
- dataElements.insertKey(dataElement.getIdShort(), dataElement_obj.getMap());
- }
-
- basyx::specificMap_t<IOperation> SubModel::getOperations() const
- {
- basyx::specificMap_t<IOperation> specific_map;
- auto & obj_map = this->map.getProperty(ISubModel::Path::Operations).Get<object::object_map_t&>();
- for (auto& elem : obj_map)
- {
- auto submodel_elem = std::make_shared<Operation>(elem.second);
- specific_map.emplace(elem.first, submodel_elem);
- }
-
- return specific_map;
- }
-
- basyx::specificMap_t<ISubmodelElement> SubModel::getSubmodelElements() const
- {
- basyx::specificMap_t<ISubmodelElement> specific_map;
- auto & obj_map = this->map.getProperty(ISubModel::Path::Submodelelement).Get<object::object_map_t&>();
- for (auto& elem : obj_map)
- {
- auto submodel_elem = std::make_shared<SubmodelElement>(elem.second);
- specific_map.emplace(elem.first, submodel_elem);
- }
-
- return specific_map;
- }
-
-
-}
-}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/dataspecification/DataSpecification.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/dataspecification/DataSpecification.cpp
deleted file mode 100644
index 6cff6e3..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/dataspecification/DataSpecification.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * DataSpecification.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/map/dataspecification/DataSpecification.h>
-#include <BaSyx/submodel/map/dataspecification/DataSpecificationContent.h>
-
-namespace basyx {
-namespace submodel {
-
-DataSpecification::DataSpecification(basyx::object obj)
- : vab::ElementMap(obj)
-{}
-
-std::shared_ptr<IDataSpecificationContent> DataSpecification::getContent() const
-{
- return std::make_shared<DataSpecificationContent>(this->map.getProperty(IDataSpecification::Path::Content));
-}
-
-void DataSpecification::setContent(const std::shared_ptr<IDataSpecificationContent>& content)
-{
- this->map.insertKey(IDataSpecification::Path::Content, DataSpecificationContent(*content).getMap());
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/dataspecification/DataSpecificationContent.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/dataspecification/DataSpecificationContent.cpp
deleted file mode 100644
index 89217bc..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/dataspecification/DataSpecificationContent.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * DataSpecificationContent.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/map/dataspecification/DataSpecificationContent.h>
-
-namespace basyx {
-namespace submodel {
-
-DataSpecificationContent::DataSpecificationContent(const IDataSpecificationContent & other)
- : vab::ElementMap()
-{
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/dataspecification/DataSpecificationIEC61360.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/dataspecification/DataSpecificationIEC61360.cpp
deleted file mode 100644
index 6f85672..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/dataspecification/DataSpecificationIEC61360.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * DataSpecificationIEC61360.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/map/dataspecification/DataSpecificationIEC61360.h>
-#include <BaSyx/submodel/map/reference/Reference.h>
-#include <BaSyx/submodel/map/submodelelement/langstring/LangStringSet.h>
-
-namespace basyx {
-namespace submodel {
-
-DataSpecificationIEC61360::DataSpecificationIEC61360()
-{
- this->map.insertKey(IDataSpecificationIEC61360::Path::PreferredName, LangStringSet().getMap());
- this->map.insertKey(IDataSpecificationIEC61360::Path::ShortName, LangStringSet().getMap());
- this->map.insertKey(IDataSpecificationIEC61360::Path::Definition, LangStringSet().getMap());
-}
-
-std::shared_ptr<ILangStringSet> DataSpecificationIEC61360::PreferredName()
-{
- auto langStringObj = this->map.getProperty(IDataSpecificationIEC61360::Path::PreferredName);
- return std::make_shared<LangStringSet>(langStringObj);
-}
-
-std::shared_ptr<ILangStringSet> DataSpecificationIEC61360::ShortName()
-{
- auto langStringObj = this->map.getProperty(IDataSpecificationIEC61360::Path::ShortName);
- return std::make_shared<LangStringSet>(langStringObj);
-}
-
-std::string DataSpecificationIEC61360::getUnit() const
-{
- return this->map.getProperty(IDataSpecificationIEC61360::Path::Unit).GetStringContent();
-}
-
-std::shared_ptr<submodel::IReference> DataSpecificationIEC61360::getUnitId() const
-{
- return std::make_shared<submodel::Reference>(this->map.getProperty(IDataSpecificationIEC61360::Path::UnitId));
-}
-
-std::string DataSpecificationIEC61360::getSourceOfDefinition() const
-{
- return this->map.getProperty(IDataSpecificationIEC61360::Path::SourceOfDefinition).GetStringContent();
-}
-
-DataTypeIEC61360 DataSpecificationIEC61360::getDataType() const
-{
- const auto & dataTypeStr = this->map.getProperty(IDataSpecificationIEC61360::Path::DataType).GetStringContent();
- return util::from_string<DataTypeIEC61360>(dataTypeStr);
-}
-
-std::shared_ptr<ILangStringSet> DataSpecificationIEC61360::Definition()
-{
- auto langStringObj = this->map.getProperty(IDataSpecificationIEC61360::Path::Definition);
- return std::make_shared<LangStringSet>(langStringObj);
-}
-
-std::string DataSpecificationIEC61360::getValueFormat() const
-{
- return this->map.getProperty(IDataSpecificationIEC61360::Path::ValueFormat).GetStringContent();
-}
-
-basyx::object DataSpecificationIEC61360::getValueList() const
-{
- return this->map.getProperty(IDataSpecificationIEC61360::Path::ValueList).GetStringContent();
-}
-
-std::shared_ptr<submodel::IReference> DataSpecificationIEC61360::getValueId() const
-{
- return std::make_shared<submodel::Reference>(this->map.getProperty(IDataSpecificationIEC61360::Path::ValueId));
-}
-
-LevelType DataSpecificationIEC61360::getLevelType() const
-{
- return util::from_string<LevelType>(this->map.getProperty(IDataSpecificationIEC61360::Path::LevelType).GetStringContent());
-}
-
-void DataSpecificationIEC61360::setUnit(const std::string & unit)
-{
- this->map.insertKey(IDataSpecificationIEC61360::Path::Unit, unit);
-}
-
-void DataSpecificationIEC61360::setUnitId(const IReference & unitId)
-{
- this->map.insertKey(IDataSpecificationIEC61360::Path::UnitId, submodel::Reference(unitId).getMap());
-}
-
-void DataSpecificationIEC61360::setSourceOfDefinition(const std::string & sourceOfDefinition)
-{
- this->map.insertKey(IDataSpecificationIEC61360::Path::SourceOfDefinition, sourceOfDefinition);
-}
-
-void DataSpecificationIEC61360::setDataType(const std::string & dataType)
-{
- this->map.insertKey(IDataSpecificationIEC61360::Path::DataType, dataType);
-}
-
-void DataSpecificationIEC61360::setValueFormat(const std::string & valueFormat)
-{
- this->map.insertKey(IDataSpecificationIEC61360::Path::ValueFormat, valueFormat);
-}
-
-void DataSpecificationIEC61360::setValueList(const basyx::object & valueList)
-{
- this->map.insertKey(IDataSpecificationIEC61360::Path::ValueList, valueList);
-}
-
-void DataSpecificationIEC61360::setValueId(const submodel::IReference & valueId)
-{
- this->map.insertKey(IDataSpecificationIEC61360::Path::ValueId, submodel::Reference(valueId).getMap());
-}
-
-//void DataSpecificationIEC61360::setLevelType(const std::string & levelType)
-//{
-// this->map.insertKey(IDataSpecificationIEC61360::Path::LevelType, levelType);
-//}
-
-void DataSpecificationIEC61360::setLevelType(const LevelType & levelType)
-{
- this->map.insertKey(IDataSpecificationIEC61360::Path::LevelType, util::to_string(levelType), true);
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/identifier/Identifier.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/identifier/Identifier.cpp
deleted file mode 100644
index 174a2c9..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/identifier/Identifier.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Identifier.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/map/identifier/Identifier.h>
-#include <BaSyx/submodel/map/identifier/IdentifierType.h>
-
-namespace basyx {
-namespace submodel {
-
-Identifier::Identifier()
- : vab::ElementMap {}
-{
- this->map.insertKey(Path::Id, "");
- this->map.insertKey(Path::IdType, "");
-}
-
-Identifier::Identifier(const std::string & id, const std::string & idType)
- : vab::ElementMap {}
-{
- this->map.insertKey(Path::Id, id);
- this->map.insertKey(Path::IdType, idType);
-}
-
-Identifier::Identifier(basyx::object object)
- :vab::ElementMap {object}
-{}
-
-Identifier::Identifier(const std::shared_ptr<IIdentifier>& other)
- : Identifier {other->getId(), other->getIdType()}
-{}
-
-Identifier::Identifier(const IIdentifier & other)
- : Identifier {other.getId(), other.getIdType()}
-{}
-
-std::string Identifier::getIdType() const
-{
- return this->map.getProperty(Path::IdType).GetStringContent();
-}
-
-std::string Identifier::getId() const
-{
- return this->map.getProperty(Path::Id).GetStringContent();
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/modeltype/ModelType.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/modeltype/ModelType.cpp
deleted file mode 100644
index 507def8..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/modeltype/ModelType.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#include <BaSyx/submodel/map/modeltype/ModelType.h>
-
-basyx::submodel::ModelType::ModelType()
- : vab::ElementMap{}
-{
- this->map.insertKey(Path::Name, "");
- this->map.insertKey(Path::ModelType, basyx::object::make_map());
-}
-
-//basyx::submodel::ModelType::ModelType(basyx::object object)
-// : vab::ElementMap{object}
-//{
-//}
-
-basyx::submodel::ModelType::ModelType(const std::string & type)
- : vab::ElementMap{}
-{
- this->map.insertKey(Path::ModelType, basyx::object::make_map());
- this->map.getProperty(Path::ModelType).insertKey(Path::Name, type);
-};
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/parts/ConceptDescription.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/parts/ConceptDescription.cpp
deleted file mode 100644
index 5f943da..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/parts/ConceptDescription.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * ConceptDictionary.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/map/parts/ConceptDescription.h>
-
-#include <BaSyx/submodel/map/reference/Reference.h>
-
-using namespace basyx::submodel;
-
-namespace basyx {
-namespace submodel {
-
-ConceptDescription::ConceptDescription(basyx::object obj)
- : vab::ElementMap(obj)
-{}
-
-ConceptDescription::ConceptDescription()
- : vab::ElementMap()
- , submodel::ModelType(IConceptDescription::Path::ModelType)
-{}
-
-ConceptDescription::ConceptDescription(IConceptDescription & other)
- : vab::ElementMap()
- , submodel::ModelType(IConceptDescription::Path::ModelType)
-{
- this->setIsCaseOf(other.getIsCaseOf());
-}
-
-
-basyx::specificCollection_t<IReference> ConceptDescription::getIsCaseOf() const
-{
- auto description_objects = this->map.getProperty(IConceptDescription::Path::IsCaseOf).Get<basyx::object::object_list_t>();
- return vab::ElementMap::make_specific_collection<IReference, Reference>(description_objects);
-}
-
-void ConceptDescription::setIsCaseOf(const basyx::specificCollection_t<IReference>& references)
-{
- auto description_objects = vab::ElementMap::make_object_list<IReference, Reference>(references);
- this->map.insertKey(IConceptDescription::Path::IsCaseOf, description_objects);
-}
-
-}
-}
-
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/AdministrativeInformation.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/AdministrativeInformation.cpp
deleted file mode 100644
index 255d38c..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/AdministrativeInformation.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * AdministrativeInformation.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/map/qualifier/AdministrativeInformation.h>
-
-namespace basyx {
-namespace submodel {
-
-AdministrativeInformation::AdministrativeInformation()
- : HasDataSpecification{}
- , vab::ElementMap {}
-{
- this->map.insertKey(IAdministrativeInformation::Path::Version, "");
- this->map.insertKey(IAdministrativeInformation::Path::Revision, "");
-}
-
-AdministrativeInformation::AdministrativeInformation(const std::string & version, const std::string & revision)
- : HasDataSpecification{}
- , vab::ElementMap{}
-{
- this->map.insertKey(IAdministrativeInformation::Path::Version, version);
- this->map.insertKey(IAdministrativeInformation::Path::Revision, revision);
-}
-
-AdministrativeInformation::AdministrativeInformation(basyx::object obj)
- : vab::ElementMap{obj}
-{
-}
-
-AdministrativeInformation::AdministrativeInformation(const IAdministrativeInformation & other)
- : vab::ElementMap {}
-{
- this->setDataSpecificationReferences(other.getDataSpecificationReferences());
- this->setRevision(other.getRevision());
- this->setVersion(other.getVersion());
-}
-
-void AdministrativeInformation::setVersion(const std::string & version)
-{
- this->map.insertKey(IAdministrativeInformation::Path::Version, version, true);
-}
-
-void AdministrativeInformation::setRevision(const std::string & revision)
-{
- this->map.insertKey(IAdministrativeInformation::Path::Revision, revision, true);
-}
-
-std::string AdministrativeInformation::getVersion() const
-{
- return this->map.getProperty(IAdministrativeInformation::Path::Version).GetStringContent();
-}
-
-std::string AdministrativeInformation::getRevision() const
-{
- return this->map.getProperty(IAdministrativeInformation::Path::Revision).GetStringContent();
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/Description.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/Description.cpp
deleted file mode 100644
index 8a735e2..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/Description.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Description.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/map/qualifier/Description.h>
-
-
-namespace basyx {
-namespace submodel {
-
-Description::Description()
- : vab::ElementMap{}
-{
- this->map.insertKey(Path::Language, "");
- this->map.insertKey(Path::Text, "");
-};
-
-Description::Description(const std::string & language, const std::string & text)
- : vab::ElementMap{}
-{
- this->map.insertKey(Path::Language, language);
- this->map.insertKey(Path::Text, text);
-}
-
-Description::Description(basyx::object object)
- : vab::ElementMap{ object }
-{
-}
-
-std::string Description::getLanguage() const
-{
- return this->map.getProperty(Path::Language).GetStringContent();
-}
-
-std::string Description::getText() const
-{
- return this->map.getProperty(Path::Text).GetStringContent();
-}
-
-bool operator==(const Description & left, const Description & right)
-{
- return (left.getLanguage() == right.getLanguage()) and (left.getText() == right.getText());
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/HasDataSpecification.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/HasDataSpecification.cpp
deleted file mode 100644
index 3633fbc..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/HasDataSpecification.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * HasDataSpecification.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/map/qualifier/HasDataSpecification.h>
-
-#include <BaSyx/submodel/map/reference/Reference.h>
-
-namespace basyx {
-namespace submodel {
-
-HasDataSpecification::HasDataSpecification()
- : vab::ElementMap{}
-{
- this->map.insertKey(Path::HasDataSpecification, basyx::object::make_list<basyx::object>());
-}
-
-HasDataSpecification::HasDataSpecification(basyx::object & obj)
- : vab::ElementMap{obj}
-{
-
-}
-
-HasDataSpecification::HasDataSpecification(const basyx::specificCollection_t<IReference>& refs)
- : vab::ElementMap{}
-{
- this->setDataSpecificationReferences(refs);
-}
-
-HasDataSpecification::HasDataSpecification(const IHasDataSpecification & hasDataSpecification)
- : vab::ElementMap{}
-{
- this->setDataSpecificationReferences(hasDataSpecification.getDataSpecificationReferences());
-}
-
-basyx::specificCollection_t<IReference> HasDataSpecification::getDataSpecificationReferences() const
-{
- auto obj_list = this->map.getProperty(Path::HasDataSpecification).Get<basyx::object::object_list_t&>();
- return vab::ElementMap::make_specific_collection<IReference, Reference>(obj_list);
-}
-
-void HasDataSpecification::setDataSpecificationReferences(const basyx::specificCollection_t<IReference> & references)
-{
- auto list = basyx::object::make_list<basyx::object>();
-
- for (const auto & ref : references)
- {
- Reference reference{ ref->getKeys() };
- list.insert(reference.getMap());
- };
-
- this->map.insertKey(Path::HasDataSpecification, list, true);
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/HasKind.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/HasKind.cpp
deleted file mode 100644
index 84989da..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/HasKind.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * HasKind.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/map/qualifier/HasKind.h>
-
-using namespace basyx::submodel;
-
-HasKind::HasKind(Kind kind)
- : vab::ElementMap()
-{
- this->Init(kind);
-}
-
-void HasKind::Init(Kind kind)
-{
- this->map.insertKey(Path::Kind, util::to_string(kind));
-};
-
-HasKind::HasKind(basyx::object object)
- : vab::ElementMap(object)
-{
-}
-
-basyx::submodel::HasKind::HasKind(const IHasKind & other) :
- vab::ElementMap{}
-{
- this->setHasKindReference(other.getHasKindReference());
-}
-
-Kind HasKind::getHasKindReference() const
-{
- return util::from_string<Kind>(this->map.getProperty(Path::Kind).GetStringContent());
-}
-
-void HasKind::setHasKindReference(Kind kind)
-{
- this->map.insertKey(Path::Kind, util::to_string(kind), true);
-}
-
-static const std::string kind_to_string[] = {
- "NotSpecified",
- "Type",
- "Instance"
-};
-
-static const std::unordered_map<std::string, Kind> string_to_kind{
- { kind_to_string[static_cast<char>(Kind::Instance)] , Kind::Instance },
- { kind_to_string[static_cast<char>(Kind::Type)] , Kind::Type },
- { kind_to_string[static_cast<char>(Kind::NotSpecified)] , Kind::NotSpecified }
-};
-
-const std::string & util::to_string(Kind kind)
-{
- return kind_to_string[static_cast<char>(kind)];
-}
-
-template<>
-Kind util::from_string<Kind>(const std::string & str)
-{
- return string_to_kind.at(str);
-};
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/HasSemantics.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/HasSemantics.cpp
deleted file mode 100644
index e113237..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/HasSemantics.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * HasSemantics.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/map/qualifier/HasSemantics.h>
-#include <BaSyx/submodel/map/reference/Reference.h>
-
-namespace basyx {
-namespace submodel {
-
-
-HasSemantics::HasSemantics()
- : vab::ElementMap{}
-{
- this->map.insertKey(Path::SemanticId, Reference{}.getMap());
-}
-
-HasSemantics::HasSemantics(basyx::object object)
- : vab::ElementMap{object}
-{}
-
-HasSemantics::HasSemantics(const std::shared_ptr<IReference>& reference)
- : vab::ElementMap{}
-{
- this->setSemanticId(reference);
-}
-
-HasSemantics::HasSemantics(const IHasSemantics & semantics) :
- vab::ElementMap{}
-{
- this->setSemanticId(semantics.getSemanticId());
-}
-
-std::shared_ptr<IReference> HasSemantics::getSemanticId() const
-{
- return std::make_shared<Reference>(this->map.getProperty(Path::SemanticId));
-}
-
-void HasSemantics::setSemanticId(const std::shared_ptr<IReference> & reference)
-{
- Reference ref{ reference->getKeys() };
- this->map.insertKey(Path::SemanticId, ref.getMap(), true);
-}
-
-void HasSemantics::setSemanticId(const IReference & reference)
-{
- Reference ref{ reference.getKeys() };
- this->map.insertKey(Path::SemanticId, ref.getMap(), true);
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/Identifiable.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/Identifiable.cpp
deleted file mode 100644
index 405c4cd..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/Identifiable.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Identifiable.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/map/qualifier/Identifiable.h>
-
-#include <BaSyx/submodel/map/qualifier/AdministrativeInformation.h>
-#include <BaSyx/submodel/map/identifier/Identifier.h>
-
-namespace basyx {
-namespace submodel {
-
-
-Identifiable::Identifiable() :
- vab::ElementMap{},
- Referable{}
-{
- this->setIdentification(Identifier {"", ""});
- this->setAdministration(AdministrativeInformation {"", ""});
-}
-
-Identifiable::Identifiable(const basyx::object & obj) :
- vab::ElementMap{obj}
-{}
-
-Identifiable::Identifiable(const IIdentifiable & identifiable) :
- vab::ElementMap{},
- Referable{identifiable.getIdShort(), identifiable.getCategory(), identifiable.getDescription()}
-{
- this->setParent(*identifiable.getParent());
- this->setAdministration(*identifiable.getAdministration());
- this->setIdentification(*identifiable.getIdentification());
-}
-
-Identifiable::Identifiable(const IIdentifier & identifier, const IAdministrativeInformation & administration)
- : vab::ElementMap{}
- , Referable{}
-{
- this->setIdentification(identifier);
- this->setAdministration(administration);
-};
-
-Identifiable::Identifiable(
- const std::string & version,
- const std::string & revision,
- const std::string & idShort,
- const std::string & category,
- const Description & description,
- const std::string & idType,
- const std::string & id)
- : Referable{idShort, category, description}
-{
- this->setIdentification(Identifier{id, idType});
- this->setAdministration(AdministrativeInformation {version, revision});
-}
-
-std::shared_ptr<IAdministrativeInformation> Identifiable::getAdministration() const
-{
- return std::make_shared<AdministrativeInformation>(this->map.getProperty(IIdentifiable::Path::Administration));
-}
-
-std::shared_ptr<IIdentifier> Identifiable::getIdentification() const
-{
- return std::make_shared<Identifier>(this->map.getProperty(IIdentifiable::Path::Identification));
-}
-
-void Identifiable::setAdministration(const IAdministrativeInformation & administration)
-{
- this->insertMapElement(IIdentifiable::Path::Administration, AdministrativeInformation(administration));
-}
-
-void Identifiable::setIdentification(const IIdentifier & identification)
-{
- this->insertMapElement(IIdentifiable::Path::Identification, Identifier(identification));
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/Referable.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/Referable.cpp
deleted file mode 100644
index ec0675f..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/Referable.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Referable.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/map/qualifier/Referable.h>
-#include <BaSyx/submodel/map/reference/Reference.h>
-
-namespace basyx {
-namespace submodel {
-
-Referable::Referable()
- : vab::ElementMap{}
-{
- this->map.insertKey(Path::IdShort, "");
- this->map.insertKey(Path::Category, "");
- this->map.insertKey(Path::Description, basyx::object::make_map());
- this->map.insertKey(Path::Parent, Reference{}.getMap());
-}
-
-basyx::submodel::Referable::Referable(basyx::object & obj)
- : vab::ElementMap{ obj }
-{
- this->map.insertKey(Path::IdShort, "");
- this->map.insertKey(Path::Category, "");
- this->map.insertKey(Path::Description, Description{}.getMap());
- this->map.insertKey(Path::Parent, Reference{}.getMap());
-}
-
-Referable::Referable(const std::string & idShort, const std::string & category, const Description & description) :
- vab::ElementMap{}
-{
- this->map.insertKey(Path::IdShort, idShort, true);
- this->map.insertKey(Path::Category, category, true);
- this->map.insertKey(Path::Description, description.getMap(), true);
- this->map.insertKey(Path::Parent, Reference{}.getMap(), true);
-}
-
-Referable::Referable(const IReferable & other) :
- vab::ElementMap{}
-{
- this->setIdShort(other.getIdShort());
- this->setCategory(other.getCategory());
- this->setDescription(other.getDescription());
- this->setParent(*other.getParent());
-}
-
-std::string Referable::getIdShort() const
-{
- return this->map.getProperty(Path::IdShort).GetStringContent();
-}
-
-std::string Referable::getCategory() const
-{
- return this->map.getProperty(Path::Category).GetStringContent();
-}
-
-Description Referable::getDescription() const
-{
- return Description{ this->map.getProperty(Path::Description) };
-}
-
-std::shared_ptr<IReference> Referable::getParent() const
-{
- return std::make_shared<Reference>(this->map.getProperty(Path::Parent));
-}
-
-void Referable::setIdShort(const std::string & shortID)
-{
- this->map.insertKey(Path::IdShort, shortID, true);
-}
-
-void Referable::setCategory(const std::string & category)
-{
- this->map.insertKey(Path::Category, category, true);
-}
-
-void Referable::setDescription(const Description & description)
-{
- this->map.insertKey(Path::Description, description.getMap(), true);
-}
-
-void Referable::setParent(const IReference & parentReference)
-{
- this->insertMapElement(Path::Parent, Reference{parentReference});
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/Constraint.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/Constraint.cpp
deleted file mode 100644
index 3783173..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/Constraint.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Constraint.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/map/qualifier/qualifiable/Constraint.h>
-
-#include <BaSyx/submodel/map/modeltype/ModelType.h>
-
-namespace basyx {
-namespace submodel {
-
-Constraint::Constraint()
- : vab::ElementMap {ModelType(std::string(Path::ModelType)).getMap()}
-{}
-
-Constraint::Constraint(basyx::object object)
- : vab::ElementMap {object}
-{}
-
-Constraint::Constraint(const IConstraint & constraint)
- : vab::ElementMap {ModelType(std::string(Path::ModelType)).getMap()}
-{}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/Formula.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/Formula.cpp
deleted file mode 100644
index 2497dc6..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/Formula.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Formula.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/map/qualifier/qualifiable/Formula.h>
-#include <BaSyx/submodel/map/reference/Reference.h>
-#include <BaSyx/submodel/map/modeltype/ModelType.h>
-
-
-namespace basyx {
-namespace submodel {
-
-
-Formula::Formula() :
- vab::ElementMap{ModelType(std::string(IFormula::Path::Modeltype)).getMap()}
-{
- this->map.insertKey(IFormula::Path::Dependson, basyx::object::make_list<basyx::object>());
-}
-
-Formula::Formula(const basyx::specificCollection_t<IReference>& dependsOn) :
- vab::ElementMap{ModelType(std::string(IFormula::Path::Modeltype)).getMap()}
-{
- this->setDependsOn(dependsOn);
-}
-
-basyx::specificCollection_t<IReference> Formula::getDependsOn() const
-{
- auto & obj_list = this->map.getProperty(IFormula::Path::Dependson).Get<basyx::object::object_list_t&>();
- return vab::ElementMap::make_specific_collection<IReference, Reference>(obj_list);
-}
-
-void Formula::setDependsOn(const basyx::specificCollection_t<IReference>& dependsOn)
-{
- auto obj_list = vab::ElementMap::make_object_list<IReference, Reference>(dependsOn);
- this->map.insertKey(IFormula::Path::Dependson, obj_list, true);
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/Qualifiable.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/Qualifiable.cpp
deleted file mode 100644
index fd31d33..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/Qualifiable.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Qualifiable.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/map/qualifier/qualifiable/Qualifiable.h>
-
-#include <BaSyx/submodel/map/qualifier/qualifiable/Constraint.h>
-
-namespace basyx {
-namespace submodel {
-
-Qualifiable::Qualifiable()
- : vab::ElementMap{}
-{
- this->map.insertKey(Path::Constraints, basyx::object::make_list<basyx::object>());
-}
-
-Qualifiable::Qualifiable(const std::shared_ptr<IQualifiable> & other)
- : Qualifiable{other->getQualifier()}
-{}
-
-Qualifiable::Qualifiable(const IQualifiable & other)
- : vab::ElementMap{}
-{
- this->setQualifier(other.getQualifier());
-}
-
-Qualifiable::Qualifiable(basyx::object object)
- : vab::ElementMap{object}
-{
- this->map.insertKey(Path::Constraints, basyx::object::make_list<basyx::object>(), false);
-}
-
-Qualifiable::Qualifiable(const std::shared_ptr<IConstraint>& constraint)
- : vab::ElementMap{}
-{
- Constraint con{ *constraint };
- auto list = basyx::object::make_list<basyx::object>();
- list.insert(con.getMap());
- this->map.insertKey(Path::Constraints, list);
-}
-
-Qualifiable::Qualifiable(const basyx::specificCollection_t<IConstraint> & constraints)
- : vab::ElementMap{}
-{
- this->setQualifier(constraints);
-}
-
-basyx::specificCollection_t<IConstraint> Qualifiable::getQualifier() const
-{
- auto list = this->map.getProperty(Path::Constraints).Get<basyx::object::object_list_t>();
- return vab::ElementMap::make_specific_collection<IConstraint, Constraint>(list);
-}
-
-void Qualifiable::setQualifier(const basyx::specificCollection_t<IConstraint>& qualifiers)
-{
- auto list = vab::ElementMap::make_object_list<IConstraint, Constraint>(qualifiers);
- map.insertKey(Path::Constraints, list, true);
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/Qualifier.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/Qualifier.cpp
deleted file mode 100644
index e86280f..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/Qualifier.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Qualifier.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/map/qualifier/qualifiable/Qualifier.h>
-#include <BaSyx/submodel/map/reference/Reference.h>
-#include <BaSyx/submodel/map/modeltype/ModelType.h>
-
-namespace basyx {
-namespace submodel {
-
-Qualifier::Qualifier() :
- vab::ElementMap{ModelType{IQualifier::Path::Modeltype}}
-{
- this->setQualifierType("Type not specified");
-}
-
-Qualifier::Qualifier(
- const std::string & qualifierType,
- const basyx::object & qualifierValue,
- const IReference & valueId)
- : vab::ElementMap{ModelType{IQualifier::Path::Modeltype}}
-{
- this->setQualifierType(qualifierType);
- this->setQualifierValue(qualifierValue);
- this->setQualifierValueId(valueId);
-}
-
-std::string Qualifier::getQualifierType() const
-{
- return this->map.getProperty(IQualifier::Path::QualifierType).GetStringContent();
-}
-
-basyx::object Qualifier::getQualifierValue() const
-{
- return this->map.getProperty(IQualifier::Path::QualifierValue);
-}
-
-std::shared_ptr<IReference> Qualifier::getQualifierValueId() const
-{
- return std::make_shared<Reference>(this->map.getProperty(IQualifier::Path::QualifierValueID));
-}
-
-void Qualifier::setQualifierType(const std::string & qualifierType)
-{
- this->map.insertKey(IQualifier::Path::QualifierType, qualifierType, true);
-}
-
-void Qualifier::setQualifierValue(const basyx::object & qualifierValue)
-{
- this->map.insertKey(IQualifier::Path::QualifierValue, qualifierValue, true);
-}
-
-void Qualifier::setQualifierValueId(const IReference & valueId)
-{
- Reference reference{valueId};
- this->insertMapElement(IQualifier::Path::QualifierValueID, reference);
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/QualifierType.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/QualifierType.cpp
deleted file mode 100644
index 3f74a98..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/QualifierType.cpp
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * QualifierType.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/map/qualifier/qualifiable/QualifierType.h>
-
-namespace basyx {
-namespace submodel {
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/reference/Key.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/reference/Key.cpp
deleted file mode 100644
index eddf516..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/reference/Key.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Key.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/map/reference/Key.h>
-
-#include <BaSyx/shared/object.h>
-
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace submodel {
-
- constexpr char Key::KeyElements::ConceptDictionary[];
-
-
-Key::Key(const std::string & type, const bool & local, const std::string & value, const std::string & idType)
- : vab::ElementMap{}
-{
- this->setType(type);
- this->setLocal(local);
- this->setValue(value);
- this->setIdType(idType);
-}
-
-Key::Key(basyx::object obj)
- : vab::ElementMap(obj)
-{};
-
-std::string Key::getType() const
-{
- return map.getProperty(IKey::Path::Type).GetStringContent();
-}
-
-bool Key::isLocal() const
-{
- return map.getProperty(IKey::Path::Local).Get<bool>();
-}
-
-std::string Key::getValue() const
-{
- return map.getProperty(IKey::Path::Value).GetStringContent();
-}
-
-std::string Key::getidType() const
-{
- return map.getProperty(IKey::Path::IdType).GetStringContent();
-}
-
-void Key::setType(const std::string & type)
-{
- map.insertKey(IKey::Path::Type, type, true);
-}
-
-void Key::setLocal(const bool & local)
-{
- map.insertKey(IKey::Path::Local, local, true);
-}
-
-void Key::setValue(const std::string & value)
-{
- map.insertKey(IKey::Path::Value, value, true);
-}
-
-void Key::setIdType(const std::string & idType)
-{
- map.insertKey(IKey::Path::IdType, idType, true);
-}
-
-bool operator==(const IKey & left, const IKey & right)
-{
- return (left.getidType() == right.getidType()) and (left.getValue() == right.getValue()) and (left.getType() == right.getType()) and (left.isLocal() == right.isLocal());
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/reference/Reference.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/reference/Reference.cpp
deleted file mode 100644
index 1610ff3..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/reference/Reference.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Reference.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/map/reference/Reference.h>
-
-#include <BaSyx/submodel/map/reference/Key.h>
-
-namespace basyx {
-namespace submodel {
-
-Reference::Reference()
- : vab::ElementMap{}
-{
- this->setKeys(basyx::specificCollection_t<IKey>());
-}
-
-Reference::Reference(const basyx::specificCollection_t<IKey> & keys)
- : vab::ElementMap{}
-{
- this->setKeys(keys);
-}
-
-Reference::Reference(const std::initializer_list<Key> keys)
- : vab::ElementMap{}
-{
- auto list = basyx::object::make_list<basyx::object>();
-
- for (auto & key : keys)
- {
- list.insert(key.getMap());
- }
-
- map.insertKey(IReference::Path::Key, list, true);
-}
-
-Reference::Reference(const IReference & reference) :
- vab::ElementMap{}
-{
- this->setKeys(reference.getKeys());
-}
-
-const basyx::specificCollection_t<IKey> Reference::getKeys() const
-{
- auto & obj_list = this->map.getProperty(IReference::Path::Key).Get<basyx::object::object_list_t&>();
- basyx::specificCollection_t<IKey> keys;
-
- for (auto & obj : obj_list)
- {
- keys.emplace_back(std::make_shared<Key>(obj));
- };
-
- return keys;
-}
-
-void Reference::setKeys(const basyx::specificCollection_t<IKey>& keys)
-{
- auto list = basyx::object::make_list<basyx::object>();
-
- for (auto & key : keys)
- {
- Key newKey{
- key->getType(),
- key->isLocal(),
- key->getValue(),
- key->getidType()
- };
-
- list.insert(newKey.getMap());
- }
- map.insertKey(IReference::Path::Key, list, true);
-}
-
-Reference Reference::FromIdentifiable(const std::string & keyElementType, bool local, const IIdentifiable & identifiable)
-{
- Key key{ keyElementType, local, identifiable.getIdentification()->getId(), identifiable.getIdentification()->getIdType() };
- return Reference{ key };
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/DataElement.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/DataElement.cpp
deleted file mode 100644
index 3a2c46f..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/DataElement.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * DataElement.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/map/submodelelement/DataElement.h>
-
-namespace basyx {
-namespace submodel {
-
-DataElement::DataElement() :
- vab::ElementMap{},
- ModelType{IDataElement::Path::ModelType}
-{}
-
-DataElement::DataElement(basyx::object object) :
- vab::ElementMap{object},
- ModelType{ IDataElement::Path::ModelType }
-{}
-
-DataElement::DataElement(const IDataElement & other) :
- SubmodelElement{other},
- ModelType{ IDataElement::Path::ModelType }
-{}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/ReferenceElement.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/ReferenceElement.cpp
deleted file mode 100644
index 6c6250f..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/ReferenceElement.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * ReferenceElement.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/map/submodelelement/ReferenceElement.h>
-#include <BaSyx/submodel/map/reference/Reference.h>
-
-namespace basyx {
-namespace submodel {
-
-ReferenceElement::ReferenceElement() :
- vab::ElementMap{},
- ModelType{IReferenceElement::Path::Modeltype}
-{}
-
-ReferenceElement::ReferenceElement(const IReference & reference) :
- vab::ElementMap{},
- ModelType{IReferenceElement::Path::Modeltype}
-{
- this->setValue(reference);
-}
-
-ReferenceElement::ReferenceElement(const basyx::object & map) :
- vab::ElementMap{map}
-{}
-
-void ReferenceElement::setValue(const IReference & ref)
-{
- Reference reference {ref};
- this->insertMapElement(IProperty::Path::Value, reference);
-}
-
-std::shared_ptr<IReference> ReferenceElement::getValue() const
-{
- return std::make_shared<Reference>(this->map.getProperty(IProperty::Path::Value));
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/RelationshipElement.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/RelationshipElement.cpp
deleted file mode 100644
index e04fa81..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/RelationshipElement.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * RelationshipElement.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/map/submodelelement/RelationshipElement.h>
-#include <BaSyx/submodel/map/reference/Reference.h>
-
-namespace basyx {
-namespace submodel {
-
-RelationshipElement::RelationshipElement() :
- vab::ElementMap {},
- ModelType{IRelationshipElement::Path::ModelType}
-{}
-
-RelationshipElement::RelationshipElement(const IReference & first, const IReference & second) :
- vab::ElementMap{},
- ModelType {IRelationshipElement::Path::ModelType}
-{
- this->setFirst(first);
- this->setSecond(second);
-}
-
-void RelationshipElement::setFirst(const IReference& first)
-{
- Reference ref {first};
- this->insertMapElement(IRelationshipElement::Path::First, ref);
-}
-
-std::shared_ptr<IReference> RelationshipElement::getFirst() const
-{
- return std::make_shared<Reference>(this->map.getProperty(IRelationshipElement::Path::First));
-}
-
-void RelationshipElement::setSecond(const IReference& second)
-{
- Reference ref {second};
- this->insertMapElement(IRelationshipElement::Path::Second, ref);
-}
-
-std::shared_ptr<IReference> RelationshipElement::getSecond() const
-{
- return std::make_shared<Reference>(this->map.getProperty(IRelationshipElement::Path::Second));
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/SubmodelElement.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/SubmodelElement.cpp
deleted file mode 100644
index 1464883..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/SubmodelElement.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * SubmodelElement.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/map/submodelelement/SubmodelElement.h>
-
-namespace basyx {
-namespace submodel {
-
-
-SubmodelElement::SubmodelElement()
- : vab::ElementMap{}
- , ModelType(ISubmodelElement::Path::ModelType)
-{}
-
-
-SubmodelElement::SubmodelElement(const ISubmodelElement & abstractSubmodelElement)
- : vab::ElementMap{}
- , ModelType{ISubmodelElement::Path::ModelType}
- , HasDataSpecification{abstractSubmodelElement.getDataSpecificationReferences()}
- , HasKind{abstractSubmodelElement.getHasKindReference()}
- , HasSemantics{abstractSubmodelElement.getSemanticId()}
- , Qualifiable{abstractSubmodelElement.getQualifier()}
- , Referable{abstractSubmodelElement.getIdShort(), abstractSubmodelElement.getCategory(), abstractSubmodelElement.getDescription()}
-{}
-
-}
-}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/SubmodelElementCollection.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/SubmodelElementCollection.cpp
deleted file mode 100644
index 5ef72b6..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/SubmodelElementCollection.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * SubmodelElementCollection.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/map/submodelelement/SubmodelElementCollection.h>
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-#include <BaSyx/submodel/api/ISubModel.h>
-
-namespace basyx {
-namespace submodel {
-
-SubmodelElementCollection::SubmodelElementCollection() :
- vab::ElementMap{},
- ModelType{ISubmodelElementCollection::Path::ModelType}
-{}
-
-SubmodelElementCollection::SubmodelElementCollection(const basyx::specificCollection_t<ISubmodelElement>& value, const bool ordered, const bool allowDuplicates) :
- vab::ElementMap{},
- ModelType{ISubmodelElementCollection::Path::ModelType}
-{
- this->setValue(value);
- this->setOrdered(ordered);
- this->setAllowDuplicates(allowDuplicates);
-}
-
-void SubmodelElementCollection::setValue(const basyx::specificCollection_t<ISubmodelElement> & value)
-{
- //auto obj_list = vab::ElementMap::make_object_list<ISubmodelElement, SubmodelElement>(value);
- //this->map.insertKey(IProperty::Path::Value, obj_list);
-}
-
-basyx::specificCollection_t<ISubmodelElement> SubmodelElementCollection::getValue() const
-{
- basyx::specificCollection_t<ISubmodelElement> list;
- auto obj_list = this->map.getProperty(IProperty::Path::Value).Get<basyx::object::object_list_t>();
- for ( auto & elem : obj_list )
- {
- list.push_back(std::make_shared<SubmodelElement>(elem));
- }
- return list;
-}
-
-void SubmodelElementCollection::setOrdered(const bool & ordered)
-{
- this->map.insertKey(ISubmodelElementCollection::Path::Ordered, ordered, true);
-}
-
-bool SubmodelElementCollection::isOrdered() const
-{
- return this->map.getProperty(ISubmodelElementCollection::Path::Ordered).Get<bool>();
-}
-
-void SubmodelElementCollection::setAllowDuplicates(const bool & allowDuplicates)
-{
- this->map.insertKey(ISubmodelElementCollection::Path::AllowDuplicates, allowDuplicates, true);
-}
-
-bool SubmodelElementCollection::isAllowDuplicates() const
-{
- return this->map.getProperty(ISubmodelElementCollection::Path::AllowDuplicates).Get<bool>();
-}
-
-void SubmodelElementCollection::setElements(const basyx::specificMap_t<ISubmodelElement> & value)
-{
- basyx::object map = basyx::object::make_map();
- for ( auto & elem : value )
- {
- auto obj = SubmodelElement{*elem.second}.getMap();
- map.insertKey(elem.first, obj, true);
- }
- this->map.insertKey(ISubModel::Path::Submodelelement, map);
-}
-
-basyx::specificMap_t<ISubmodelElement> SubmodelElementCollection::getElements() const
-{
- basyx::specificMap_t<ISubmodelElement> specific_map;
- auto obj_map = this->map.getProperty(ISubModel::Path::Submodelelement).Get<object::object_map_t>();
- for ( auto & elem : obj_map )
- {
- auto submodel_elem = std::make_shared<SubmodelElement>(SubmodelElement{elem.second});
- specific_map.insert(std::pair<std::string, std::shared_ptr<ISubmodelElement>>(elem.first, submodel_elem));
- }
-
- return specific_map;
-}
-
-void SubmodelElementCollection::addSubmodelElement(const ISubmodelElement & element)
-{
-
-}
-
-
-
-}
-}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/entity/Entity.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/entity/Entity.cpp
deleted file mode 100644
index eb21e2d..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/entity/Entity.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-#include <BaSyx/submodel/map/submodelelement/entity/Entity.h>
-
-namespace basyx {
-namespace submodel {
- Entity::Entity(EntityType entityType)
- {
- this->map.insertKey(IEntity::Path::EntityType, static_cast<char>(entityType), true);
- }
-
- Entity::Entity(basyx::object object)
- : ElementMap{ object }
- {
- }
-
- Entity::Entity(const IEntity & entity)
- {
-
- }
-
- basyx::specificCollection_t<ISubmodelElement> basyx::submodel::Entity::getStatements()
- {
- return specificCollection_t<ISubmodelElement>();
- }
-
- EntityType Entity::getEntityType() const
- {
- return static_cast<EntityType>(this->map.getProperty(IEntity::Path::EntityType).Get<int>());
- }
-
- std::shared_ptr<IReference> Entity::getAsset() const
- {
- return std::shared_ptr<IReference>();
- }
-}
-}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/langstring/LangStringSet.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/langstring/LangStringSet.cpp
deleted file mode 100644
index 004fc40..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/langstring/LangStringSet.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-#include <BaSyx/submodel/map/submodelelement/langstring/LangStringSet.h>
-
-const std::string empty{};
-
-basyx::submodel::LangStringSet::LangStringSet()
- : vab::ElementMap{basyx::object::make_object_list()}
-{
-}
-
-basyx::submodel::LangStringSet::LangStringSet(std::initializer_list<std::pair<std::string, std::string>> il)
- : LangStringSet()
-{
- for (const auto & entry : il)
- this->addLangString(entry.first, entry.second);
-}
-
-const std::string & basyx::submodel::LangStringSet::getLangString(const std::string & languageCode) const
-{
- auto & objectSet = this->getMap().Get<basyx::object::object_list_t&>();
-
- for (auto & entry : objectSet)
- {
- auto & object = const_cast<basyx::object&>(entry);
- if (object.getProperty(Path::Language) == languageCode) {
- return object.getProperty(Path::Text).GetStringContent();
- }
- };
-
- return empty;
-}
-
-basyx::submodel::LangStringSet::langCodeSet_t basyx::submodel::LangStringSet::getLanguageCodes() const
-{
- auto & objectList = this->getMap().Get<basyx::object::object_list_t&>();
-
- std::remove_const<langCodeSet_t>::type ret;
- ret.reserve(objectList.size());
-
- for (auto & entry : objectList)
- {
- auto & object = const_cast<basyx::object&>(entry);
- ret.emplace_back( std::cref( object.getProperty(Path::Language).GetStringContent()) );
- };
-
- return ret;
-};
-
-void basyx::submodel::LangStringSet::addLangString(const std::string & languageCode, const std::string & langString)
-{
- auto langStringMap = basyx::object::make_map();
- langStringMap.insertKey( Path::Language, languageCode );
- langStringMap.insertKey( Path::Text, langString);
-
- this->map.insert(langStringMap);
-}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/operation/Operation.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/operation/Operation.cpp
deleted file mode 100644
index a7dac64..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/operation/Operation.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Operation.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/map/submodelelement/operation/Operation.h>
-#include <BaSyx/shared/object/obj_function.h>
-
-namespace basyx {
-namespace submodel {
-
-Operation::Operation()
- : vab::ElementMap{}
- , ModelType{Path::ModelType}
- , SubmodelElement{}
-{
- this->map.insertKey(Path::Input, basyx::object::make_list<basyx::object>());
- this->map.insertKey(Path::Invokable, basyx::object::make_null());
- this->map.insertKey(Path::Output, basyx::object::make_null());
-}
-
-Operation::Operation(const IOperation & other)
- : vab::ElementMap{}
- , ModelType{Path::ModelType}
- , SubmodelElement{other}
-{
- this->setParameterTypes(other.getParameterTypes());
- this->setReturnTypes(other.getReturnType());
- this->setInvocable(other.getInvocable());
-}
-
-Operation::Operation(const basyx::object & obj) :
- vab::ElementMap{obj}
- , SubmodelElement{}
-{}
-
-basyx::specificCollection_t<IOperationVariable> Operation::getParameterTypes() const
-{
- return basyx::specificCollection_t<IOperationVariable>();
-}
-
-std::shared_ptr<IOperationVariable> Operation::getReturnType() const
-{
- return std::shared_ptr<IOperationVariable>();
-}
-
-basyx::object Operation::getInvocable() const
-{
- return this->map.getProperty(Path::Invokable);
-}
-
-void Operation::setParameterTypes(const basyx::specificCollection_t<IOperationVariable>& parameterTypes)
-{
-}
-
-void Operation::setReturnTypes(const std::shared_ptr<IOperationVariable>& returnTypes)
-{
-}
-
-void Operation::setInvocable(basyx::object invocable)
-{
- this->map.insertKey(Path::Invokable, invocable, true);
-}
-
-basyx::object Operation::invoke(basyx::object & parameters) const
-{
- return basyx::object();
-}
-
-
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/operation/OperationVariable.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/operation/OperationVariable.cpp
deleted file mode 100644
index 44183a4..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/operation/OperationVariable.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * ModelType.cpp
- *
- * Author: wendel
- */
-
-#include <BaSyx/submodel/map/submodelelement/operation/OperationVariable.h>
-
-namespace basyx {
-namespace submodel {
-
-OperationVariable::OperationVariable()
- : ModelType(IOperationVariable::Path::ModelType)
- , vab::ElementMap{}
-{}
-
-OperationVariable::OperationVariable(basyx::object object)
- : vab::ElementMap{object}
-{}
-
-std::shared_ptr<ISubmodelElement> OperationVariable::getValue() const
-{
- return std::make_shared<SubmodelElement>(this->map.getProperty(IOperationVariable::Path::Value));
-}
-
-std::string OperationVariable::getType() const
-{
- return this->map.getProperty(Path::Type).GetStringContent();
-}
-
-void OperationVariable::setValue(const SubmodelElement & value)
-{
- this->map.insertKey(IOperationVariable::Path::Value, value.getMap(), true);
-}
-
-void OperationVariable::setValue(const ISubmodelElement & value)
-{
- auto map = SubmodelElement(value).getMap();
- this->map.insertKey(IOperationVariable::Path::Value, map, true);
-}
-
-void OperationVariable::setType(const std::string & string)
-{
- this->map.insertKey(Path::Type, string, true);
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/property/Blob.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/property/Blob.cpp
deleted file mode 100644
index 31308ff..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/property/Blob.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-#include <BaSyx/submodel/map/submodelelement/property/Blob.h>
-
-namespace basyx {
-namespace submodel {
-
-const std::string & Blob::getValue() const
-{
- return map.getProperty(Blob::Path::Value).Get<std::string&>();
-}
-
-const std::string & Blob::getMimeType() const
-{
- return map.getProperty(Blob::Path::MIMEType).Get<std::string&>();
-}
-
-void Blob::setValue(const std::string & bytes)
-{
- this->map.insertKey(Blob::Path::Value, bytes);
-}
-
-void Blob::setValue(const char * c, std::size_t length)
-{
-// TODO: basyx::object for blob types
-// this->map.insertKey(Blob::Path::Value, basyx::object::make_blob)
-}
-
-void Blob::setMimeType(const std::string & mimeType)
-{
- this->map.insertKey(IBlob::Path::MIMEType, mimeType, true);
-}
-
-
-}
-};
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/property/File.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/property/File.cpp
deleted file mode 100644
index d6508af..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/property/File.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-#include <BaSyx/submodel/map/submodelelement/property/File.h>
-
-namespace basyx {
-namespace submodel {
-
-const std::string & File::getValue() const
-{
- return map.getProperty(IFile::Path::Value).Get<std::string&>();
-}
-
-const std::string & File::getMimeType() const
-{
- return map.getProperty(IFile::Path::MIMEType).Get<std::string&>();
-}
-
-void File::setValue(const std::string & bytes)
-{
- this->map.insertKey(IFile::Path::Value, bytes);
-}
-
-void File::setMimeType(const std::string & mimeType)
-{
- this->map.insertKey(IFile::Path::MIMEType, mimeType, true);
-}
-
-
-}
-};
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/SubModel.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/SubModel.cpp
index 56c5f97..10166f9 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/SubModel.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/SubModel.cpp
@@ -4,12 +4,16 @@
using namespace basyx::submodel::api;
using namespace basyx::submodel::map;
+constexpr char SubModel::Path::SubmodelElements[];
+constexpr char SubModel::Path::SemanticId[];
+constexpr char SubModel::Path::Kind[];
+
SubModel::SubModel(const std::string & idShort, const simple::Identifier & identifier, ModelingKind kind)
: Identifiable(idShort, identifier)
{
- this->map.insertKey("submodelElements", this->elementContainer.getMap());
- this->map.insertKey("semanticId", semanticId.getMap());
- this->map.insertKey("kind", ModelingKind_::to_string(kind));
+ this->map.insertKey(Path::SubmodelElements, this->elementContainer.getMap());
+ this->map.insertKey(Path::SemanticId, semanticId.getMap());
+ this->map.insertKey(Path::Kind, ModelingKind_::to_string(kind));
};
IElementContainer<ISubmodelElement> & SubModel::submodelElements()
@@ -24,7 +28,7 @@
ModelingKind SubModel::getKind() const
{
- return ModelingKind_::from_string(this->map.getProperty("kind").GetStringContent());
+ return ModelingKind_::from_string(this->map.getProperty(Path::Kind).GetStringContent());
}
const IReference & SubModel::getSemanticId() const
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/aas/Asset.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/aas/Asset.cpp
index f66a447..b2f2c72 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/aas/Asset.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/aas/Asset.cpp
@@ -4,20 +4,24 @@
using namespace basyx::submodel::api;
using namespace basyx::submodel::map;
+constexpr char Asset::Path::Kind[];
+constexpr char Asset::Path::AssetIdentificationModelRef[];
+constexpr char Asset::Path::BillOfMaterialRef[];
+
Asset::Asset(const std::string & idShort, const simple::Identifier & identifier, AssetKind kind)
: Identifiable(idShort, identifier)
, billOfMaterialRef()
, assetIdentificationModelRef()
, vab::ElementMap()
{
- this->map.insertKey("kind", AssetKind_::to_string(kind));
- this->map.insertKey("assetIdentificationModelRef", assetIdentificationModelRef.getMap());
- this->map.insertKey("billOfMaterialRef", billOfMaterialRef.getMap());
+ this->map.insertKey(Path::Kind, AssetKind_::to_string(kind));
+ this->map.insertKey(Path::AssetIdentificationModelRef, assetIdentificationModelRef.getMap());
+ this->map.insertKey(Path::BillOfMaterialRef, billOfMaterialRef.getMap());
};
AssetKind Asset::getKind()
{
- return AssetKind_::from_string(this->map.getProperty("kind").Get<std::string&>());
+ return AssetKind_::from_string(this->map.getProperty(Path::Kind).Get<std::string&>());
};
IReference * const Asset::getAssetIdentificationModel()
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/aas/AssetAdministrationShell.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/aas/AssetAdministrationShell.cpp
index 279a4b4..a518a26 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/aas/AssetAdministrationShell.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/aas/AssetAdministrationShell.cpp
@@ -4,12 +4,17 @@
using namespace basyx::submodel::map;
using namespace basyx::submodel::api;
+constexpr char AssetAdministrationShell::Path::Submodels[];
+constexpr char AssetAdministrationShell::Path::Asset[];
+
AssetAdministrationShell::AssetAdministrationShell(const std::string & idShort, const simple::Identifier & identifier, const Asset & asset)
: Identifiable(idShort, identifier)
, asset(asset)
+ , submodels(this)
+ , conceptDictionary(this)
{
- this->map.insertKey("submodels", submodels.getMap());
- this->map.insertKey("asset", asset.getMap());
+ this->map.insertKey(Path::Submodels, submodels.getKeyMap());
+ this->map.insertKey(Path::Asset, asset.getMap());
};
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/constexpr.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/constexpr.cpp
new file mode 100644
index 0000000..f34285c
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/constexpr.cpp
@@ -0,0 +1,18 @@
+#include <BaSyx/submodel/map_v2/common/ModelType.h>
+#include <BaSyx/submodel/map_v2/common/ElementContainer.h>
+#include <BaSyx/submodel/map_v2/submodelelement/property/Property.h>
+#include <BaSyx/submodel/api_v2/submodelelement/property/XSDAnySimpleType.h>
+
+using namespace basyx::submodel::map;
+
+constexpr char ModelTypePath::Name[];
+constexpr char ModelTypePath::ModelType[];
+
+constexpr char ElementContainerPath::IdShort[];
+
+constexpr char PropertyPath::Value[];
+constexpr char PropertyPath::ValueType[];
+constexpr char PropertyPath::ValueId[];
+
+constexpr char basyx::xsd_types::xsd_type<basyx::submodel::simple::DateTime>::format[];
+constexpr char basyx::xsd_types::xsd_type<basyx::submodel::simple::Date>::format[];
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/constraint/Formula.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/constraint/Formula.cpp
index ca98424..dfcc510 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/constraint/Formula.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/constraint/Formula.cpp
@@ -5,15 +5,17 @@
using namespace basyx::submodel;
using namespace basyx::submodel::map;
+constexpr char Formula::Path::Dependencies[];
+
Formula::Formula()
{
- this->map.insertKey("dependencies", basyx::object::make_object_list());
+ this->map.insertKey(Path::Dependencies, basyx::object::make_object_list());
};
Formula::Formula(const std::vector<simple::Reference> & dependencies)
: Formula()
{
- auto & objectList = this->map.getProperty("dependencies").Get<basyx::object::object_list_t&>();
+ auto & objectList = this->map.getProperty(Path::Dependencies).Get<basyx::object::object_list_t&>();
for (const auto & dependency : dependencies)
{
@@ -32,7 +34,7 @@
{
std::vector<simple::Reference> dependencies;
- auto & objectList = this->map.getProperty("dependencies").Get<basyx::object::object_list_t&>();
+ auto & objectList = this->map.getProperty(Path::Dependencies).Get<basyx::object::object_list_t&>();
for (const auto & obj : objectList)
{
@@ -48,7 +50,7 @@
{
map::Reference ref{ reference };
- auto & objectList = this->map.getProperty("dependencies").Get<basyx::object::object_list_t&>();
+ auto & objectList = this->map.getProperty(Path::Dependencies).Get<basyx::object::object_list_t&>();
objectList.emplace_back(ref.getMap());
};
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/constraint/Qualifier.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/constraint/Qualifier.cpp
index 8a5f9ef..5815a65 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/constraint/Qualifier.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/constraint/Qualifier.cpp
@@ -5,12 +5,19 @@
using namespace basyx::submodel::api;
using namespace basyx::submodel::map;
+constexpr char Qualifier::Path::ValueDataType[];
+constexpr char Qualifier::Path::QualifierType[];
+constexpr char Qualifier::Path::ValueType[];
+constexpr char Qualifier::Path::SemanticId[];
+constexpr char Qualifier::Path::ValueId[];
+
+
Qualifier::Qualifier(const std::string & qualifierType, const std::string & valueType)
{
- this->map.insertKey("qualifierType", qualifierType);
- this->map.insertKey("valueType", valueType);
- this->map.insertKey("semanticId", this->semanticId.getMap());
- this->map.insertKey("valueId", this->valueId.getMap());
+ this->map.insertKey(Path::QualifierType, qualifierType);
+ this->map.insertKey(Path::ValueType, valueType);
+ this->map.insertKey(Path::SemanticId, this->semanticId.getMap());
+ this->map.insertKey(Path::ValueId, this->valueId.getMap());
};
Qualifier::Qualifier(const std::string & qualifierType,
@@ -19,11 +26,11 @@
const api::IReference & valueId)
: valueId(valueId)
{
- this->map.insertKey("valueDataType", valueDataType);
- this->map.insertKey("qualifierType", qualifierType);
- this->map.insertKey("valueType", valueType);
- this->map.insertKey("semanticId", semanticId.getMap());
- this->map.insertKey("valueId", this->valueId.getMap());
+ this->map.insertKey(Path::ValueDataType, valueDataType);
+ this->map.insertKey(Path::QualifierType, qualifierType);
+ this->map.insertKey(Path::ValueType, valueType);
+ this->map.insertKey(Path::SemanticId, semanticId.getMap());
+ this->map.insertKey(Path::ValueId, this->valueId.getMap());
};
Qualifier::Qualifier(const api::IQualifier & qualifier)
@@ -38,25 +45,25 @@
const std::string Qualifier::getQualifierType() const
{
- return this->map.getProperty("qualifierType").Get<std::string&>();
+ return this->map.getProperty(Path::QualifierType).Get<std::string&>();
};
const std::string Qualifier::getValueType() const
{
- return this->map.getProperty("valueType").Get<std::string&>();
+ return this->map.getProperty(Path::ValueType).Get<std::string&>();
};
const std::string * const Qualifier::getValueDataType() const
{
- if (!this->map.hasProperty("valueDataType"))
+ if (!this->map.hasProperty(Path::ValueDataType))
return nullptr;
- return &this->map.getProperty("valueDataType").Get<std::string&>();
+ return &this->map.getProperty(Path::ValueDataType).Get<std::string&>();
};
void Qualifier::setValueDataType(const std::string & valueDataType)
{
- this->map.insertKey("valueDataType", valueDataType);
+ this->map.insertKey(Path::ValueDataType, valueDataType);
};
const IReference * const Qualifier::getValueId() const
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/dataspecification/DataSpecification.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/dataspecification/DataSpecification.cpp
index ad73e2c..4587e1c 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/dataspecification/DataSpecification.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/dataspecification/DataSpecification.cpp
@@ -7,6 +7,8 @@
using namespace basyx::submodel::api;
+constexpr char DataSpecification::Path::DataSpecificationContent[];
+
DataSpecification::DataSpecification(const std::string & idShort, const simple::Identifier & identifier, std::unique_ptr<DataSpecificationContent> content)
: Identifiable(idShort, identifier)
, vab::ElementMap()
@@ -23,7 +25,7 @@
{
this->content = std::move(dataSpecificationContent);
auto element_map = dynamic_cast<vab::ElementMap*>(this->content.get());
- this->map.insertKey("dataSpecificationContent", element_map->getMap());
+ this->map.insertKey(Path::DataSpecificationContent, element_map->getMap());
}
api::IDataSpecificationContent& DataSpecification::getContent()
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/dataspecification/ValueList.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/dataspecification/ValueList.cpp
index 6ac067d..d667054 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/dataspecification/ValueList.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/dataspecification/ValueList.cpp
@@ -1,9 +1,13 @@
#include <BaSyx/submodel/map_v2/dataspecification/ValueList.h>
+
namespace basyx {
namespace submodel {
namespace map {
+constexpr char ValueList::Path::Value[];
+constexpr char ValueList::Path::ValueId[];
+
ValueList::ValueList()
: vab::ElementMap(basyx::object::make_object_list())
{}
@@ -15,8 +19,8 @@
void ValueList::addValueReferencePair(const simple::ValueReferencePair & valueRefPair)
{
object obj = object::make_map();
- obj.insertKey("value", valueRefPair.getValue());
- obj.insertKey("valueId", map::Reference(valueRefPair.getValueId()).getMap());
+ obj.insertKey(Path::Value, valueRefPair.getValue());
+ obj.insertKey(Path::ValueId, map::Reference(valueRefPair.getValueId()).getMap());
this->map.insert(obj);
}
@@ -25,8 +29,8 @@
std::vector<simple::ValueReferencePair> list;
for (auto & pair_obj : this->map.Get<object::object_list_t&>())
{
- std::string value = pair_obj.getProperty("value").GetStringContent();
- auto reference = simple::Reference(map::Reference(pair_obj.getProperty("valueId")));
+ std::string value = pair_obj.getProperty(Path::Value).GetStringContent();
+ auto reference = simple::Reference(map::Reference(pair_obj.getProperty(Path::ValueId)));
simple::ValueReferencePair pair(value, reference);
list.push_back(pair);
}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/parts/ConceptDictionary.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/parts/ConceptDictionary.cpp
index 2cb4a84..9dd734f 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/parts/ConceptDictionary.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/parts/ConceptDictionary.cpp
@@ -4,13 +4,16 @@
namespace basyx {
namespace submodel {
namespace map {
+
using namespace basyx::submodel::api;
+constexpr char ConceptDictionary::Path::ConceptDescriptions[];
+
ConceptDictionary::ConceptDictionary(const std::string & idShort)
: vab::ElementMap{}
, Referable(idShort)
{
- this->map.insertKey("ConceptDescriptions", this->concept_descriptions.getMap());
+ this->map.insertKey(Path::ConceptDescriptions, this->concept_descriptions.getMap());
}
const api::IElementContainer<api::IConceptDescription> & ConceptDictionary::getConceptDescriptions() const
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/parts/View.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/parts/View.cpp
index b973acc..431b9d9 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/parts/View.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/parts/View.cpp
@@ -3,12 +3,15 @@
using namespace basyx::submodel;
using namespace basyx::submodel::map;
-View::View(const std::string &idShort, const Referable *parent)
+constexpr char View::Path::ContainedElements[];
+constexpr char View::Path::SemanticId[];
+
+View::View(const std::string &idShort, Referable *parent)
: vab::ElementMap{}
, Referable(idShort, parent)
{
- this->map.insertKey("ContainedElements", this->contained_elements.getMap());
- this->map.insertKey("SemanticId", this->semanticId.getMap());
+ this->map.insertKey(Path::ContainedElements, this->contained_elements.getMap());
+ this->map.insertKey(Path::SemanticId, this->semanticId.getMap());
}
const api::IElementContainer<api::IReferable> & View::getContainedElements() const
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/AdministrativeInformation.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/AdministrativeInformation.cpp
new file mode 100644
index 0000000..5a35320
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/AdministrativeInformation.cpp
@@ -0,0 +1,62 @@
+#include <BaSyx/submodel/map_v2/qualifier/AdministrativeInformation.h>
+
+
+namespace basyx {
+namespace submodel {
+namespace map {
+
+using namespace basyx::submodel::api;
+
+constexpr char AdministrativeInformation::Path::Version[];
+constexpr char AdministrativeInformation::Path::Revision[];
+
+AdministrativeInformation::AdministrativeInformation()
+{}
+
+AdministrativeInformation::AdministrativeInformation(const std::string &version, const std::string &revision)
+{
+ this->map.insertKey(Path::Version, version);
+ this->map.insertKey(Path::Revision, revision);
+}
+
+void AdministrativeInformation::setVersion(const std::string &version)
+{
+ this->map.insertKey(Path::Version, version);
+}
+
+void AdministrativeInformation::setRevision(const std::string &revision)
+{
+ this->map.insertKey(Path::Revision, revision);
+}
+
+bool AdministrativeInformation::hasVersion() const
+{
+ return not this->map.getProperty(Path::Version).IsNull();
+}
+
+bool AdministrativeInformation::hasRevision() const
+{
+ return not this->map.getProperty(Path::Revision).IsNull();
+}
+
+const std::string * const AdministrativeInformation::getVersion() const
+{
+ auto version = this->map.getProperty(Path::Version);
+ if (version.IsNull())
+ return nullptr;
+
+ return &version.Get<std::string&>();
+}
+
+const std::string * const AdministrativeInformation::getRevision() const
+{
+ auto revision = this->map.getProperty(Path::Revision);
+ if (revision.IsNull())
+ return nullptr;
+
+ return &revision.Get<std::string&>();
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/HasDataSpecification.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/HasDataSpecification.cpp
index 8dc93bb..1f52305 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/HasDataSpecification.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/HasDataSpecification.cpp
@@ -7,11 +7,13 @@
using namespace basyx::submodel::api;
using namespace basyx::submodel::map;
+constexpr char HasDataSpecification::Path::DataSpecification[];
+
HasDataSpecification::HasDataSpecification()
: vab::ElementMap()
, dataSpecification()
{
- this->map.insertKey("dataSpecification", basyx::object::make_object_ref(&dataSpecification));
+ this->map.insertKey(Path::DataSpecification, this->dataSpecification);
}
void HasDataSpecification::addDataSpecification(const simple::Reference & reference)
@@ -34,4 +36,4 @@
};
return dataSpecs;
-}
\ No newline at end of file
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/Identifiable.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/Identifiable.cpp
index 6d7cab8..882f8ce 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/Identifiable.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/Identifiable.cpp
@@ -4,44 +4,47 @@
using namespace basyx::submodel::map;
using namespace basyx::submodel::api;
-struct IdentifierPath {
- static constexpr char IdType[] = "idType";
- static constexpr char Id[] = "id";
-};
-
-constexpr char IdentifierPath::IdType[];
-constexpr char IdentifierPath::Id[];
+constexpr char Identifiable::Path::IdType[];
+constexpr char Identifiable::Path::Id[];
+constexpr char Identifiable::Path::AdministrativeInformation[];
+constexpr char Identifiable::Path::Identifier[];
Identifiable::Identifiable(const std::string & idShort, const simple::Identifier & identifier)
: Referable(idShort)
, vab::ElementMap()
{
auto identifierMap = basyx::object::make_map();
- identifierMap.insertKey(IdentifierPath::Id, identifier.getId());
- identifierMap.insertKey(IdentifierPath::IdType, IdentifierType_::to_string(identifier.getIdType()));
- this->map.insertKey("identifier", identifierMap);
+ identifierMap.insertKey(Path::Id, identifier.getId());
+ identifierMap.insertKey(Path::IdType, IdentifierType_::to_string(identifier.getIdType()));
+ this->map.insertKey(Path::Identifier, identifierMap);
}
bool Identifiable::hasAdministrativeInformation() const noexcept
-{
- return this->administrativeInformation.exists();
+{
+ return not this->map.getProperty(Path::AdministrativeInformation).IsNull();
};
simple::Identifier Identifiable::getIdentification() const
{
- auto identifierMap = this->map.getProperty("identifier");
+ auto identifierMap = this->map.getProperty(Path::Identifier);
return simple::Identifier{
- IdentifierType_::from_string(identifierMap.getProperty(IdentifierPath::IdType).Get<std::string&>()),
- identifierMap.getProperty(IdentifierPath::Id).Get<std::string&>()
+ IdentifierType_::from_string(identifierMap.getProperty(Path::IdType).Get<std::string&>()),
+ identifierMap.getProperty(Path::Id).Get<std::string&>()
};
}
-const simple::AdministrativeInformation & Identifiable::getAdministrativeInformation() const
+const api::IAdministrativeInformation & Identifiable::getAdministrativeInformation() const
{
return this->administrativeInformation;
}
-simple::AdministrativeInformation & Identifiable::getAdministrativeInformation()
+api::IAdministrativeInformation & Identifiable::getAdministrativeInformation()
{
return this->administrativeInformation;
}
+
+void Identifiable::setAdministrativeInformation(const AdministrativeInformation &administrativeInformation)
+{
+ this->administrativeInformation = administrativeInformation;
+ this->map.insertKey(Path::AdministrativeInformation, this->administrativeInformation.getMap());
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/Qualifiable.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/Qualifiable.cpp
index 1aedb59..7c1c07e 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/Qualifiable.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/Qualifiable.cpp
@@ -7,16 +7,18 @@
using namespace basyx::submodel::api;
using namespace basyx::submodel::map;
+constexpr char Qualifiable::Path::Qualifier[];
+
Qualifiable::Qualifiable(const std::vector<simple::Formula> & formulas, const std::vector<simple::Qualifier> & qualifiers)
{
- this->map.insertKey("qualifier", basyx::object::make_object_list());
+ this->map.insertKey(Path::Qualifier, basyx::object::make_object_list());
};
void Qualifiable::addFormula(const api::IFormula & formula)
{
map::Formula f{ formula };
- auto & objectList = this->map.getProperty("qualifier").Get<basyx::object::object_list_t&>();
+ auto & objectList = this->map.getProperty(Path::Qualifier).Get<basyx::object::object_list_t&>();
objectList.emplace_back(f.getMap());
}
@@ -25,7 +27,7 @@
{
map::Qualifier q{ qualifier };
- auto & objectList = this->map.getProperty("qualifier").Get<basyx::object::object_list_t&>();
+ auto & objectList = this->map.getProperty(Path::Qualifier).Get<basyx::object::object_list_t&>();
objectList.emplace_back(q.getMap());
}
@@ -34,7 +36,7 @@
{
std::vector<simple::Formula> formulas;
- auto & objectList = this->map.getProperty("qualifier").Get<basyx::object::object_list_t&>();
+ auto & objectList = this->map.getProperty(Path::Qualifier).Get<basyx::object::object_list_t&>();
for (auto & object : objectList)
{
if(ModelType<ModelTypes::Constraint>(object).GetModelType() == ModelTypes::Formula)
@@ -51,7 +53,7 @@
{
std::vector<simple::Qualifier> qualifiers;
- auto & objectList = this->map.getProperty("qualifier").Get<basyx::object::object_list_t&>();
+ auto & objectList = this->map.getProperty(Path::Qualifier).Get<basyx::object::object_list_t&>();
for (auto & object : objectList)
{
if (ModelType<ModelTypes::Constraint>(object).GetModelType() == ModelTypes::Qualifier)
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/Referable.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/Referable.cpp
index 83de297..a85a21a 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/Referable.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/Referable.cpp
@@ -1,6 +1,7 @@
#include <BaSyx/submodel/map_v2/qualifier/Referable.h>
-#include <BaSyx/submodel/map_v2/reference/Reference.h>
+#include <BaSyx/submodel/simple/reference/Reference.h>
+using namespace basyx::submodel;
using namespace basyx::submodel::map;
using namespace basyx::submodel::api;
@@ -9,7 +10,7 @@
constexpr char Referable::Path::Description[];
constexpr char Referable::Path::Parent[];
-Referable::Referable(const std::string & idShort, const Referable * parent)
+Referable::Referable(const std::string & idShort, Referable * parent)
: parent(parent)
, vab::ElementMap(basyx::object::make_map())
{
@@ -51,7 +52,12 @@
this->map.insertKey(Path::Category, category);
}
-const IReferable * const Referable::getParent() const
+void Referable::setParent(IReferable * parent)
+{
+ this->parent = parent;
+};
+
+IReferable * Referable::getParent() const
{
return this->parent;
};
@@ -69,4 +75,23 @@
bool Referable::hasCategory() const noexcept
{
return this->map.hasProperty(Path::Category);
-};
\ No newline at end of file
+};
+
+simple::Reference Referable::getReference() const
+{
+ auto key = this->getKey();
+
+ if (this->getParent() == nullptr)
+ return simple::Reference(key);
+
+ auto reference = this->getParent()->getReference();
+
+ reference.addKey(key);
+
+ return reference;
+}
+
+simple::Key Referable::getKey(bool local) const
+{
+ return simple::Key(this->getKeyElementType(), local, this->getKeyType(), this->getIdShort());
+}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/reference/Reference.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/reference/Reference.cpp
index 818e94a..1a7de69 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/reference/Reference.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/reference/Reference.cpp
@@ -8,23 +8,16 @@
using namespace basyx::submodel;
using namespace basyx::submodel::map;
-struct KeyPath
-{
- static constexpr char IdType[] = "idType";
- static constexpr char Type[] = "type";
- static constexpr char Value[] = "value";
- static constexpr char Local[] = "local";
-};
-
-constexpr char KeyPath::IdType[];
-constexpr char KeyPath::Type[];
-constexpr char KeyPath::Value[];
-constexpr char KeyPath::Local[];
+constexpr char Reference::Path::IdType[];
+constexpr char Reference::Path::Type[];
+constexpr char Reference::Path::Value[];
+constexpr char Reference::Path::Local[];
+constexpr char Reference::Path::Keys[];
Reference::Reference()
: vab::ElementMap{}
{
- this->map.insertKey("keys", basyx::object::make_object_list());
+ this->map.insertKey(Path::Keys, basyx::object::make_object_list());
}
Reference::Reference(const simple::Key & key)
@@ -46,29 +39,29 @@
Reference::Reference(basyx::object &object)
- : Reference(keyMapList_to_keyList(object.getProperty("keys").Get<object::object_list_t&>()))
+ : Reference(keyMapList_to_keyList(object.getProperty(Path::Keys).Get<object::object_list_t&>()))
{}
std::vector<simple::Key> Reference::getKeys() const
{
- return this->keyMapList_to_keyList(this->map.getProperty("keys").Get<basyx::object::object_list_t&>());
+ return this->keyMapList_to_keyList(this->map.getProperty(Path::Keys).Get<basyx::object::object_list_t&>());
};
void Reference::addKey(const simple::Key & key)
{
basyx::object keyMap = basyx::object::make_map();
- keyMap.insertKey(KeyPath::IdType, KeyType_::to_string(key.getIdType()));
- keyMap.insertKey(KeyPath::Type, KeyElements_::to_string(key.getType()));
- keyMap.insertKey(KeyPath::Value, key.getValue());
- keyMap.insertKey(KeyPath::Local, key.isLocal());
- this->map.getProperty("keys").insert(keyMap);
+ keyMap.insertKey(Path::IdType, KeyType_::to_string(key.getIdType()));
+ keyMap.insertKey(Path::Type, KeyElements_::to_string(key.getType()));
+ keyMap.insertKey(Path::Value, key.getValue());
+ keyMap.insertKey(Path::Local, key.isLocal());
+ this->map.getProperty(Path::Keys).insert(keyMap);
}
Reference & Reference::operator=(const api::IReference & other)
{
- this->map.insertKey("keys", basyx::object::make_object_list());
+ this->map.insertKey(Path::Keys, basyx::object::make_object_list());
for (const auto & key : other.getKeys())
this->addKey(key);
@@ -79,17 +72,17 @@
bool Reference::empty() const
{
- return this->map.getProperty("keys").empty();
+ return this->map.getProperty(Path::Keys).empty();
}
simple::Key Reference::keyMap_to_key(basyx::object &keyMap)
{
return simple::Key
(
- KeyElements_::from_string(keyMap.getProperty(KeyPath::Type).Get<std::string&>()),
- keyMap.getProperty(KeyPath::Local).Get<bool>(),
- KeyType_::from_string(keyMap.getProperty(KeyPath::IdType).Get<std::string&>()),
- keyMap.getProperty(KeyPath::Value).Get<std::string&>()
+ KeyElements_::from_string(keyMap.getProperty(Path::Type).Get<std::string&>()),
+ keyMap.getProperty(Path::Local).Get<bool>(),
+ KeyType_::from_string(keyMap.getProperty(Path::IdType).Get<std::string&>()),
+ keyMap.getProperty(Path::Value).Get<std::string&>()
);
}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/SubmodelElement.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/SubmodelElement.cpp
index 60193e7..11441de 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/SubmodelElement.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/SubmodelElement.cpp
@@ -4,14 +4,17 @@
using namespace basyx::submodel::api;
using namespace basyx::submodel::map;
+constexpr char SubmodelElement::Path::Kind[];
+constexpr char SubmodelElement::Path::SemanticId[];
+
SubmodelElement::SubmodelElement(const std::string & idShort, ModelingKind kind)
: Referable(idShort, nullptr)
, HasDataSpecification()
, semanticId()
, vab::ElementMap{}
{
- this->map.insertKey("kind", ModelingKind_::to_string(kind));
- this->map.insertKey("semanticId", semanticId.getMap());
+ this->map.insertKey(Path::Kind, ModelingKind_::to_string(kind));
+ this->map.insertKey(Path::SemanticId, semanticId.getMap());
}
const api::IReference & SubmodelElement::getSemanticId() const
@@ -26,5 +29,5 @@
ModelingKind SubmodelElement::getKind() const
{
- return ModelingKind_::from_string(this->map.getProperty("kind").GetStringContent());
+ return ModelingKind_::from_string(this->map.getProperty(Path::Kind).GetStringContent());
}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/SubmodelElementFactory.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/SubmodelElementFactory.cpp
index fb53647..5585bbf 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/SubmodelElementFactory.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/SubmodelElementFactory.cpp
@@ -11,10 +11,12 @@
using namespace basyx::submodel::api;
using namespace basyx::submodel::map;
+constexpr char SubmodelElementFactory::Path::Value[];
+
std::unique_ptr<ISubmodelElement> SubmodelElementFactory::CreateProperty(const vab::ElementMap & elementMap)
{
auto object = elementMap.getMap();
- auto value = object.getProperty("value");
+ auto value = object.getProperty(Path::Value);
auto type = value.GetValueType();
switch (type)
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/operation/Operation.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/operation/Operation.cpp
index f4a1a51..105fe60 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/operation/Operation.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/operation/Operation.cpp
@@ -3,14 +3,20 @@
using namespace basyx::submodel::map;
using namespace basyx::submodel::api;
+constexpr char Operation::Path::Invokable[];
+constexpr char Operation::Path::InputVariable[];
+constexpr char Operation::Path::OutputVariable[];
+constexpr char Operation::Path::InoutputVariable[];
+
Operation::Operation(const std::string & idShort, basyx::object invokable)
: SubmodelElement(idShort)
, invokable(basyx::object::make_null())
{
this->invokable = invokable;
- this->map.insertKey("inputVariable", inputVariables.getMap());
- this->map.insertKey("outputVariable", outputVariables.getMap());
- this->map.insertKey("inoutputVariable", inOutVariables.getMap());
+ this->map.insertKey(Path::Invokable, this->invokable);
+ this->map.insertKey(Path::InputVariable, inputVariables.getMap());
+ this->map.insertKey(Path::OutputVariable, outputVariables.getMap());
+ this->map.insertKey(Path::InoutputVariable, inOutVariables.getMap());
};
IElementContainer<ISubmodelElement> & Operation::getInputVariables()
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/property/MultiLanguageProperty.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/property/MultiLanguageProperty.cpp
index d9d2fec..b2ee7f8 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/property/MultiLanguageProperty.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/property/MultiLanguageProperty.cpp
@@ -4,12 +4,16 @@
using namespace basyx::submodel::api;
using namespace basyx::submodel::map;
+constexpr char MultiLanguageProperty::Path::Value[];
+constexpr char MultiLanguageProperty::Path::ValueId[];
+constexpr char MultiLanguageProperty::Path::Kind[];
+
MultiLanguageProperty::MultiLanguageProperty(const std::string & idShort, ModelingKind kind)
: SubmodelElement(idShort, kind)
{
- this->map.insertKey("value", value.getMap());
- this->map.insertKey("valueId", valueId.getMap());
- this->map.insertKey("kind", ModelingKind_::to_string(kind));
+ this->map.insertKey(Path::Value, value.getMap());
+ this->map.insertKey(Path::ValueId, valueId.getMap());
+ this->map.insertKey(Path::Kind, ModelingKind_::to_string(kind));
};
api::ILangStringSet & MultiLanguageProperty::getValue()
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/property/ReferenceElement.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/property/ReferenceElement.cpp
index e4b0d09..d948553 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/property/ReferenceElement.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/property/ReferenceElement.cpp
@@ -4,11 +4,14 @@
using namespace basyx::submodel::api;
using namespace basyx::submodel::map;
+constexpr char ReferenceElement::Path::Value[];
+constexpr char ReferenceElement::Path::Kind[];
+
ReferenceElement::ReferenceElement(const std::string & idShort, ModelingKind kind)
: SubmodelElement(idShort, kind)
{
- this->map.insertKey("value", value.getMap());
- this->map.insertKey("kind", ModelingKind_::to_string(kind));
+ this->map.insertKey(Path::Value, value.getMap());
+ this->map.insertKey(Path::Kind, ModelingKind_::to_string(kind));
};
const api::IReference * const ReferenceElement::getValue() const
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/SubModel.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/SubModel.cpp
index fb0adef..9841050 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/SubModel.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/SubModel.cpp
@@ -50,11 +50,16 @@
return this->identifiable.getDescription();
}
-const IReferable * const SubModel::getParent() const
+IReferable * SubModel::getParent() const
{
return this->identifiable.getParent();
}
+void SubModel::setParent(IReferable * parent)
+{
+ return this->identifiable.setParent(parent);
+};
+
const AdministrativeInformation & SubModel::getAdministrativeInformation() const
{
return this->identifiable.getAdministrativeInformation();
@@ -115,3 +120,12 @@
return this->qualifiable.getQualifiers();
};
+simple::Reference SubModel::getReference() const
+{
+ return this->identifiable.getReference();
+};
+
+simple::Key SubModel::getKey(bool local) const
+{
+ return this->identifiable.getKey();
+};
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/aas/Asset.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/aas/Asset.cpp
index ab139d4..6cddc4b 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/aas/Asset.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/aas/Asset.cpp
@@ -82,11 +82,16 @@
return this->identifiable.getDescription();
}
-const api::IReferable * const Asset::getParent() const
+api::IReferable * Asset::getParent() const
{
return this->identifiable.getParent();
}
+void Asset::setParent(IReferable * parent)
+{
+ this->identifiable.setParent(parent);
+}
+
const AdministrativeInformation & Asset::getAdministrativeInformation() const
{
return this->identifiable.getAdministrativeInformation();
@@ -102,6 +107,17 @@
return this->identifiable.getIdentification();
}
+simple::Reference Asset::getReference() const
+{
+ return this->identifiable.getReference();
+};
+
+simple::Key Asset::getKey(bool local) const
+{
+ return this->identifiable.getKey();
+};
+
+
}
}
}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/aas/AssetAdministrationShell.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/aas/AssetAdministrationShell.cpp
index 687800e..ec9bed5 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/aas/AssetAdministrationShell.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/aas/AssetAdministrationShell.cpp
@@ -1,8 +1,10 @@
#include <BaSyx/submodel/simple/aas/AssetAdministrationShell.h>
#include <BaSyx/submodel/simple/reference/Reference.h>
+#include <BaSyx/submodel/enumerations/ModelTypes.h>
-using namespace basyx::submodel::simple;
+using namespace basyx::submodel;
using namespace basyx::submodel::api;
+using namespace basyx::submodel::simple;
AssetAdministrationShell::AssetAdministrationShell(const std::string & idShort, const Identifier & identifier, const Asset & asset)
: identifiable(idShort, identifier)
@@ -11,7 +13,6 @@
};
-
ElementContainer<IConceptDescription> & AssetAdministrationShell::getConceptDictionary()
{
return this->conceptDictionary;
@@ -63,17 +64,23 @@
return this->identifiable.getDescription();
}
-const IReferable * const AssetAdministrationShell::getParent() const
+IReferable * AssetAdministrationShell::getParent() const
{
return this->identifiable.getParent();
}
-const AdministrativeInformation & AssetAdministrationShell::getAdministrativeInformation() const
+void AssetAdministrationShell::setParent(IReferable * parent)
+{
+ this->identifiable.setParent(parent);
+}
+
+
+const api::IAdministrativeInformation & AssetAdministrationShell::getAdministrativeInformation() const
{
return this->identifiable.getAdministrativeInformation();
}
-AdministrativeInformation & AssetAdministrationShell::getAdministrativeInformation()
+api::IAdministrativeInformation & AssetAdministrationShell::getAdministrativeInformation()
{
return this->identifiable.getAdministrativeInformation();
}
@@ -98,3 +105,19 @@
{
return this->dataSpecification.getDataSpecificationReference();
}
+
+simple::Reference AssetAdministrationShell::getReference() const
+{
+ return this->identifiable.getReference();
+};
+
+
+ModelTypes AssetAdministrationShell::GetModelType() const
+{
+ return ModelTypes::AssetAdministrationShell;
+}
+
+simple::Key AssetAdministrationShell::getKey(bool local) const
+{
+ return this->identifiable.getKey();
+};
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/AnyURI.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/AnyURI.cpp
new file mode 100644
index 0000000..3c991c1
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/AnyURI.cpp
@@ -0,0 +1,24 @@
+#include <BaSyx/submodel/simple/common/xsd_types/AnyURI.h>
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+AnyURI::AnyURI(const std::string & uri)
+ : uri{uri}
+{}
+
+const std::string &AnyURI::getUri() const
+{
+ return this->uri;
+}
+
+void AnyURI::setURI(const std::string &uri)
+{
+ this->uri = uri;
+}
+
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/Date.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/Date.cpp
new file mode 100644
index 0000000..e77a195
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/Date.cpp
@@ -0,0 +1,24 @@
+#include <BaSyx/submodel/simple/common/xsd_types/Date.h>
+
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+Date::Date(const tm & date)
+ : date{date}
+{}
+
+const tm &Date::getDate() const
+{
+ return this->date;
+}
+
+void Date::setDate(const tm & date)
+{
+ this->date = date;
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/DateTime.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/DateTime.cpp
new file mode 100644
index 0000000..291c6aa
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/DateTime.cpp
@@ -0,0 +1,24 @@
+#include <BaSyx/submodel/simple/common/xsd_types/DateTime.h>
+#include <chrono>
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+DateTime::DateTime(const tm & time)
+ : time{time}
+{}
+
+const tm &DateTime::getTime() const
+{
+ return this->time;
+}
+
+void DateTime::setTime(const tm & time)
+{
+ this->time = time;
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/DayTimeDuration.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/DayTimeDuration.cpp
new file mode 100644
index 0000000..a62ef86
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/DayTimeDuration.cpp
@@ -0,0 +1,25 @@
+#include <BaSyx/submodel/simple/common/xsd_types/DayTimeDuration.h>
+#include <chrono>
+
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+DayTimeDuration::DayTimeDuration(const std::chrono::duration<long> & duration)
+ : duration_in_sec{duration}
+{}
+
+const std::chrono::duration<long> &DayTimeDuration::getDuration() const
+{
+ return this->duration_in_sec;
+}
+
+void DayTimeDuration::setDuration(const std::chrono::duration<long> & duration)
+{
+ this->duration_in_sec = duration;
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GDay.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GDay.cpp
new file mode 100644
index 0000000..1348725
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GDay.cpp
@@ -0,0 +1,39 @@
+#include <BaSyx/submodel/simple/common/xsd_types/GDay.h>
+
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+GDay::GDay(uint8_t day, const Timezone & timezone)
+ : timezone{timezone}
+{
+ this->setDay(day);
+}
+
+uint8_t GDay::getDay() const
+{
+ return this->day;
+}
+
+void GDay::setDay(uint8_t day)
+{
+ day %= 31;
+ if (day == 0)
+ day = 31;
+ this->day = day;
+}
+
+const Timezone &GDay::getTimezone() const
+{
+ return this->timezone;
+}
+
+void GDay::setTimezone(const Timezone &timezone)
+{
+ this->timezone = timezone;
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GMonth.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GMonth.cpp
new file mode 100644
index 0000000..27fc0d3
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GMonth.cpp
@@ -0,0 +1,40 @@
+#include <BaSyx/submodel/simple/common/xsd_types/GMonth.h>
+
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+GMonth::GMonth(uint8_t month, const Timezone &timezone)
+ : timezone{timezone}
+{
+ this->setMonth(month);
+}
+
+
+uint8_t GMonth::getMonth() const
+{
+ return this->month;
+}
+
+void GMonth::setMonth(uint8_t month)
+{
+ month %= 12;
+ if (month == 0)
+ month = 12;
+ this->month = month;
+}
+
+const Timezone &GMonth::getTimezone() const
+{
+ return this->timezone;
+}
+
+void GMonth::setTimezone(const Timezone &timezone)
+{
+ this->timezone = timezone;
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GMonthDay.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GMonthDay.cpp
new file mode 100644
index 0000000..30560da
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GMonthDay.cpp
@@ -0,0 +1,54 @@
+#include <BaSyx/submodel/simple/common/xsd_types/GMonthDay.h>
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+GMonthDay::GMonthDay(uint8_t month, uint8_t day, const Timezone & timezone)
+ : timezone{timezone}
+{
+ this->setMonth(month);
+ this->setDay(day);
+}
+
+uint8_t GMonthDay::getMonth() const
+{
+ return this->month;
+}
+
+void GMonthDay::setMonth(uint8_t month)
+{
+ month %= 12;
+ if (month == 0)
+ month = 12;
+ this->month = month;
+ // re-check day
+ this->setDay(this->day);
+}
+
+uint8_t GMonthDay::getDay() const
+{
+ return this->day;
+}
+
+void GMonthDay::setDay(uint8_t day)
+{
+ if (day > month_days[this->month - 1])
+ this->day = month_days[this->month - 1];
+ else
+ this->day = day;
+}
+
+const Timezone & GMonthDay::getTimezone() const
+{
+ return this->timezone;
+}
+
+void GMonthDay::setTimezone(const Timezone & timezone)
+{
+ this->timezone = timezone;
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GYear.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GYear.cpp
new file mode 100644
index 0000000..905dc37
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GYear.cpp
@@ -0,0 +1,35 @@
+#include <BaSyx/submodel/simple/common/xsd_types/GYear.h>
+
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+GYear::GYear(int year, const Timezone & timezone)
+ : year{year}
+ , timezone{timezone}
+{}
+
+int GYear::getYear() const
+{
+ return year;
+}
+
+void GYear::setYear(int year)
+{
+ this->year = this->year;
+}
+
+const Timezone & GYear::getTimezone() const
+{
+ return this->timezone;
+}
+
+void GYear::setTimezone(const Timezone & timezone)
+{
+ this->timezone = timezone;
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GYearMonth.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GYearMonth.cpp
new file mode 100644
index 0000000..3085f4d
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GYearMonth.cpp
@@ -0,0 +1,51 @@
+#include <BaSyx/submodel/simple/common/xsd_types/GYearMonth.h>
+
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+GYearMonth::GYearMonth(int year, uint8_t month, const Timezone & timezone)
+ : year{year}
+ , timezone{timezone}
+{
+ this->setMonth(month);
+}
+
+int GYearMonth::getYear() const
+{
+ return year;
+}
+
+void GYearMonth::setYear(int year)
+{
+ this->year = year;
+}
+
+uint8_t GYearMonth::getMonth() const
+{
+ return month;
+}
+
+void GYearMonth::setMonth(uint8_t month)
+{
+ //fit month in 1-12
+ month %= 13;
+ if (!month)
+ month = 12;
+ this->month = month;
+}
+
+const Timezone &GYearMonth::getTimezone() const
+{
+ return timezone;
+}
+
+void GYearMonth::setTimezone(const Timezone &timezone)
+{
+ this->timezone = timezone;
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/Time.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/Time.cpp
new file mode 100644
index 0000000..1ea8b94
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/Time.cpp
@@ -0,0 +1,66 @@
+#include <BaSyx/submodel/simple/common/xsd_types/Time.h>
+
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+Time::Time(uint8_t hours, uint8_t minutes, float seconds, const Timezone & timezone)
+ : timezone{timezone}
+{
+ this->setHours(hours);
+ this->setMinutes(minutes);
+ this->setSeconds(seconds);
+}
+
+uint8_t Time::getHours() const
+{
+ return this->hours;
+}
+
+void Time::setHours(uint8_t hours)
+{
+ this->hours = hours % 24;
+}
+
+uint8_t Time::getMinutes() const
+{
+ return this->minutes;
+}
+
+void Time::setMinutes(uint8_t minutes)
+{
+ this->minutes = minutes % 60;
+}
+
+float Time::getSeconds() const
+{
+ return this->seconds;
+}
+
+void Time::setSeconds(float seconds)
+{
+ if (seconds < 61)
+ {
+ this->seconds = seconds;
+ return;
+ }
+ int full_seconds = int(seconds);
+ seconds -= full_seconds;
+ full_seconds %= 60;
+ this->seconds += full_seconds;
+}
+
+const Timezone & Time::getTimezone() const
+{
+ return this->timezone;
+}
+
+void Time::setTimezone(const Timezone & timezone)
+{
+ this->timezone = timezone;
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/Timezone.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/Timezone.cpp
new file mode 100644
index 0000000..944711c
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/Timezone.cpp
@@ -0,0 +1,44 @@
+#include <BaSyx/submodel/simple/common/xsd_types/Timezone.h>
+
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+Timezone::Timezone()
+ : timezone{"Z"}
+{}
+
+Timezone::Timezone(const std::string & timezone)
+ : timezone{timezone}
+{}
+
+Timezone::Timezone(const char * timezone)
+ : timezone{timezone}
+{
+
+}
+
+const std::string &Timezone::getTimezone() const
+{
+ return this->timezone;
+}
+
+void Timezone::setTimezone(const std::string &timezone)
+{
+ this->timezone = timezone;
+}
+
+bool Timezone::isUTC() const
+{
+ return this->timezone.compare("Z");
+}
+
+Timezone::operator const std::string&() const
+{
+ return this->timezone;
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/YearMonthDuration.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/YearMonthDuration.cpp
new file mode 100644
index 0000000..e6dc713
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/YearMonthDuration.cpp
@@ -0,0 +1,43 @@
+#include <BaSyx/submodel/simple/common/xsd_types/YearMonthDuration.h>
+
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+YearMonthDuration::YearMonthDuration(int years, int months)
+{
+ this->setYears(years);
+ this->setMonths(months);
+}
+
+int YearMonthDuration::getYears() const
+{
+ return this->years;
+}
+
+int YearMonthDuration::getMonths() const
+{
+ return this->months;
+}
+
+void YearMonthDuration::setYears(const int & years)
+{
+ this->years = years;
+}
+
+void YearMonthDuration::setMonths(const int & months)
+{
+ this->years += months / 12;
+ if (months < 0)
+ {
+ this->months = 12 + (months % 12);
+ this->years -= 1;
+ }
+ else
+ this->months = months % 12;
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/dataspecification/DataSpecification.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/dataspecification/DataSpecification.cpp
index 3feff85..7a54e61 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/dataspecification/DataSpecification.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/dataspecification/DataSpecification.cpp
@@ -36,11 +36,16 @@
return this->ident.getDescription();
}
-const IReferable * const DataSpecification::getParent() const
+IReferable * DataSpecification::getParent() const
{
return this->ident.getParent();
}
+void DataSpecification::setParent(IReferable * parent)
+{
+ this->setParent(parent);
+}
+
const AdministrativeInformation & DataSpecification::getAdministrativeInformation() const
{
return this->ident.getAdministrativeInformation();
@@ -71,6 +76,11 @@
this->ident.setCategory(category);
}
+simple::Reference DataSpecification::getReference() const
+{
+ return this->ident.getReference();
+};
+
}
}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/parts/ConceptDescription.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/parts/ConceptDescription.cpp
index 8e231c8..5abbfb5 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/parts/ConceptDescription.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/parts/ConceptDescription.cpp
@@ -5,7 +5,7 @@
ConceptDescription::ConceptDescription(const std::string & idShort, const Identifier & identifier)
- : Identifiable{idShort, identifier}
+ : identifiable(idShort, identifier)
{}
const api::IElementContainer<api::IDataSpecification> & ConceptDescription::getEmbeddedDataSpecification() const
@@ -38,3 +38,64 @@
{
return this->dataSpec.getDataSpecificationReference();
}
+
+
+const std::string & ConceptDescription::getIdShort() const
+{
+ return this->identifiable.getIdShort();
+}
+
+const std::string * const ConceptDescription::getCategory() const
+{
+ return this->identifiable.getCategory();
+};
+
+void ConceptDescription::setCategory(const std::string & category)
+{
+ this->identifiable.setCategory(category);
+}
+
+LangStringSet & ConceptDescription::getDescription()
+{
+ return this->identifiable.getDescription();
+}
+
+const LangStringSet & ConceptDescription::getDescription() const
+{
+ return this->identifiable.getDescription();
+}
+
+api::IReferable * ConceptDescription::getParent() const
+{
+ return this->identifiable.getParent();
+}
+
+void ConceptDescription::setParent(api::IReferable * parent)
+{
+ this->identifiable.setParent(parent);
+}
+
+const AdministrativeInformation & ConceptDescription::getAdministrativeInformation() const
+{
+ return this->identifiable.getAdministrativeInformation();
+}
+
+AdministrativeInformation & ConceptDescription::getAdministrativeInformation()
+{
+ return this->identifiable.getAdministrativeInformation();
+}
+
+Identifier ConceptDescription::getIdentification() const
+{
+ return this->identifiable.getIdentification();
+}
+
+bool ConceptDescription::hasAdministrativeInformation() const
+{
+ return this->identifiable.hasAdministrativeInformation();
+};
+
+simple::Reference ConceptDescription::getReference() const
+{
+ return this->identifiable.getReference();
+};
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/parts/ConceptDictionary.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/parts/ConceptDictionary.cpp
index db4fd10..1d6c462 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/parts/ConceptDictionary.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/parts/ConceptDictionary.cpp
@@ -7,21 +7,61 @@
using namespace basyx::submodel::api;
ConceptDictionary::ConceptDictionary(const std::string & idShort)
- : conecpt_descriptions{}
- , Referable(idShort)
+ : conceptDescriptions()
+ , referable(idShort)
{}
const api::IElementContainer<api::IConceptDescription> & ConceptDictionary::getConceptDescriptions() const
{
- return this->conecpt_descriptions;
+ return this->conceptDescriptions;
}
void ConceptDictionary::addConceptDescription(std::unique_ptr<ConceptDescription> description)
{
- this->conecpt_descriptions.addElement(std::move(description));
+ this->conceptDescriptions.addElement(std::move(description));
}
+const std::string & ConceptDictionary::getIdShort() const
+{
+ return this->referable.getIdShort();
+}
+
+const std::string * const ConceptDictionary::getCategory() const
+{
+ return this->referable.getCategory();
+};
+
+void ConceptDictionary::setCategory(const std::string & category)
+{
+ this->referable.setCategory(category);
+}
+
+LangStringSet & ConceptDictionary::getDescription()
+{
+ return this->referable.getDescription();
+}
+
+const LangStringSet & ConceptDictionary::getDescription() const
+{
+ return this->referable.getDescription();
+}
+
+IReferable * ConceptDictionary::getParent() const
+{
+ return this->referable.getParent();
+}
+
+void ConceptDictionary::setParent(IReferable * parent)
+{
+ this->referable.setParent(parent);
+}
+
+simple::Reference ConceptDictionary::getReference() const
+{
+ return this->referable.getReference();
+};
+
}
}
-}
+}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/parts/View.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/parts/View.cpp
index 4968cb6..fb3720f 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/parts/View.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/parts/View.cpp
@@ -3,8 +3,9 @@
using namespace basyx::submodel;
using namespace basyx::submodel::simple;
-View::View(const std::string &idShort, const Referable *parent)
- : Referable(idShort, parent)
+View::View(const std::string &idShort, Referable * parent)
+ : referable(idShort, parent)
+ , dataSpec()
{}
const api::IElementContainer<api::IReferable> & View::getContainedElements() const
@@ -25,4 +26,55 @@
void View::setSemanticId(const api::IReference &reference)
{
this->semanticId = reference;
-}
\ No newline at end of file
+}
+
+void View::addDataSpecification(const simple::Reference & reference)
+{
+ this->dataSpec.addDataSpecification(reference);
+}
+
+const std::vector<simple::Reference> View::getDataSpecificationReference() const
+{
+ return this->dataSpec.getDataSpecificationReference();
+}
+
+const std::string & View::getIdShort() const
+{
+ return this->referable.getIdShort();
+}
+
+const std::string * const View::getCategory() const
+{
+ return this->referable.getCategory();
+};
+
+void View::setCategory(const std::string & category)
+{
+ this->referable.setCategory(category);
+};
+
+LangStringSet & View::getDescription()
+{
+ return this->referable.getDescription();
+}
+
+const LangStringSet & View::getDescription() const
+{
+ return this->referable.getDescription();
+}
+
+api::IReferable * View::getParent() const
+{
+ return this->referable.getParent();
+}
+
+void View::setParent(IReferable * parent)
+{
+ this->referable.setParent(parent);
+}
+
+simple::Reference View::getReference() const
+{
+ return this->referable.getReference();
+};
+
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/qualifier/AdministrativeInformation.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/qualifier/AdministrativeInformation.cpp
index e43f7f3..4b97bed 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/qualifier/AdministrativeInformation.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/qualifier/AdministrativeInformation.cpp
@@ -5,14 +5,17 @@
namespace simple {
AdministrativeInformation::AdministrativeInformation()
-{
-
-};
+{};
AdministrativeInformation::AdministrativeInformation(const std::string & version, const std::string & revision)
-{
+ : version{version}
+ , revision{revision}
+{};
-};
+AdministrativeInformation::AdministrativeInformation(const api::IAdministrativeInformation &other)
+ : revision{*other.getRevision()}
+ , version{*other.getVersion()}
+{}
void AdministrativeInformation::setVersion(const std::string & version)
{
@@ -24,24 +27,20 @@
this->revision = revision;
}
-std::string AdministrativeInformation::getVersion() const
+const std::string * const AdministrativeInformation::getVersion() const
{
- return version;
+ if (this->version.empty())
+ return nullptr;
+
+ return &this->version;
}
-std::string AdministrativeInformation::getRevision() const
+const std::string * const AdministrativeInformation::getRevision() const
{
- return revision;
-}
+ if (this->revision.empty())
+ return nullptr;
-void AdministrativeInformation::addDataSpecification(const Reference & reference)
-{
- this->hasDataSpecification.addDataSpecification(reference);
-}
-
-const std::vector<Reference> AdministrativeInformation::getDataSpecificationReference() const
-{
- return this->hasDataSpecification.getDataSpecificationReference();
+ return &this->revision;
}
}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/qualifier/Identifiable.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/qualifier/Identifiable.cpp
index cbbe16f..8ba4d7a 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/qualifier/Identifiable.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/qualifier/Identifiable.cpp
@@ -12,9 +12,7 @@
: Referable(other)
, identifier(other.getIdentification().getIdType(), other.getIdentification().getId())
, administrativeInformation(other.getAdministrativeInformation())
-{
-
-}
+{}
bool Identifiable::hasAdministrativeInformation() const noexcept
{
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/qualifier/Referable.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/qualifier/Referable.cpp
index bbfd956..ed52a8d 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/qualifier/Referable.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/qualifier/Referable.cpp
@@ -4,7 +4,7 @@
using namespace basyx::submodel::simple;
using namespace basyx::submodel::api;
-Referable::Referable(const std::string & idShort, const Referable * parent)
+Referable::Referable(const std::string & idShort, Referable * parent)
: idShort(idShort)
, parent(parent)
{}
@@ -49,11 +49,16 @@
this->category = category;
}
-const IReferable * const Referable::getParent() const
+IReferable * Referable::getParent() const
{
return this->parent;
};
+void Referable::setParent(IReferable * parent)
+{
+ this->parent = parent;
+};
+
bool Referable::hasParent() const noexcept
{
return this->parent != nullptr;
@@ -67,4 +72,28 @@
bool Referable::hasCategory() const noexcept
{
return !this->category.empty();
+}
+
+Reference Referable::getReference() const
+{
+ auto key = simple::Key(KeyElements::AssetAdministrationShell, true, KeyType::IdShort, this->getIdShort());
+
+ if (this->getParent() == nullptr)
+ return simple::Reference(key);
+
+ auto reference = this->getParent()->getReference();
+
+ reference.addKey(key);
+
+ return reference;
+}
+
+basyx::submodel::KeyElements Referable::getKeyElementType() const
+{
+ return basyx::submodel::KeyElements::Unknown;
+}
+
+basyx::submodel::simple::Key Referable::getKey(bool local) const
+{
+ return basyx::submodel::simple::Key(this->getKeyElementType(), local, this->getKeyType(), this->getIdShort());
}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/reference/Key.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/reference/Key.cpp
index 4888880..8e21b0e 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/reference/Key.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/reference/Key.cpp
@@ -41,6 +41,16 @@
&& this->value != other.value;
};
+bool Key::isModelKey() const noexcept
+{
+ return this->idType != basyx::submodel::KeyType::IdShort;
+};
+
+bool Key::isGlobalKey() const noexcept
+{
+ return this->type != basyx::submodel::KeyElements::GlobalReference;
+};
+
}
}
}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/reference/Reference.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/reference/Reference.cpp
index d3ede76..3f6ab96 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/reference/Reference.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/reference/Reference.cpp
@@ -32,14 +32,14 @@
{
};
-Reference Reference::FromIdentifiable(KeyElements keyElementType, const IIdentifiable & identifiable)
-{
- return Reference(
- Key(keyElementType,
- true,
- static_cast<KeyType>(identifiable.getIdentification().getIdType()),
- identifiable.getIdentification().getId()) );
-};
+//Reference Reference::FromIdentifiable(KeyElements keyElementType, const IIdentifiable & identifiable)
+//{
+// return Reference(
+// Key(keyElementType,
+// true,
+// static_cast<KeyType>(identifiable.getIdentification().getIdType()),
+// identifiable.getIdentification().getId()) );
+//};
std::vector<Key> Reference::getKeys() const
{
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/submodelelement/SubmodelElement.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/submodelelement/SubmodelElement.cpp
index 766d1f1..36cc77e 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/submodelelement/SubmodelElement.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/submodelelement/SubmodelElement.cpp
@@ -16,7 +16,7 @@
return this->semanticId;
};
-void SubmodelElement::setSemanticId(Reference semanticId)
+void SubmodelElement::setSemanticId(const api::IReference & semanticId)
{
this->semanticId = semanticId;
};
@@ -36,6 +36,11 @@
return this->referable.getIdShort();
}
+void SubmodelElement::setCategory(const std::string &category)
+{
+ this->referable.setCategory(category);
+}
+
const std::string * const SubmodelElement::getCategory() const
{
return this->referable.getCategory();
@@ -51,12 +56,52 @@
return this->referable.getDescription();
}
-const IReferable * const SubmodelElement::getParent() const
+IReferable * SubmodelElement::getParent() const
{
return this->referable.getParent();
}
+void SubmodelElement::setParent(IReferable * parent)
+{
+ this->setParent(parent);
+};
+
ModelingKind SubmodelElement::getKind() const
{
return this->kind;
-}
\ No newline at end of file
+}
+
+void SubmodelElement::addFormula(const api::IFormula &formula)
+{
+ this->qualifiable.addFormula(formula);
+}
+
+void SubmodelElement::addQualifier(const api::IQualifier &qualifier)
+{
+ this->qualifiable.addQualifier(qualifier);
+}
+
+std::vector<Qualifier> SubmodelElement::getQualifiers() const
+{
+ return this->qualifiable.getQualifiers();
+}
+
+std::vector<Formula> SubmodelElement::getFormulas() const
+{
+ return this->qualifiable.getFormulas();
+}
+
+ModelTypes SubmodelElement::GetModelType() const
+{
+ return this->modelType;
+}
+
+Key SubmodelElement::getKey(bool local) const
+{
+ return this->referable.getKey(local);
+}
+
+simple::Reference SubmodelElement::getReference() const
+{
+ return this->referable.getReference();
+}
diff --git a/sdks/c++/basys.sdk.cc/src/utility/CMakeLists.txt b/sdks/c++/basys.sdk.cc/src/utility/CMakeLists.txt
index 4227da3..2015252 100644
--- a/sdks/c++/basys.sdk.cc/src/utility/CMakeLists.txt
+++ b/sdks/c++/basys.sdk.cc/src/utility/CMakeLists.txt
@@ -15,8 +15,10 @@
set_target_properties(${BASYX_UTIL_LIB_SUFFIX} PROPERTIES SOVERSION ${BASYX_PACKAGE_VERSION_MAJOR})
set_target_properties(${BASYX_UTIL_LIB_SUFFIX} PROPERTIES PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_SHORTNAME}")
target_include_directories(${BASYX_UTIL_LIB_SUFFIX}
-INTERFACE ${CMAKE_INSTALL_PREFIX}/include
- ${CMAKE_INSTALL_PREFIX}/include/${PROJECT_SHORTNAME})
+ PUBLIC
+ $<BUILD_INTERFACE:${BASYX_INCLUDE_DIR}>
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>
+)
target_sources(${BASYX_UTIL_LIB_SUFFIX}
PRIVATE
@@ -41,7 +43,15 @@
add_library(basyx::util ALIAS ${BASYX_UTIL_LIB_SUFFIX})
add_library(${PROJECT_SHORTNAME}::${BASYX_UTIL_LIB_SUFFIX} ALIAS ${BASYX_UTIL_LIB_SUFFIX})
-diagnostics_print(${BASYX_UTIL_LIB_SUFFIX})
+if(BASYX_IS_SUBMODULE)
+ set_target_properties(${BASYX_UTIL_LIB_SUFFIX} PROPERTIES FOLDER BaSyx)
+endif()
+
+if(BASYX_VERBOSE_CMAKE_OUTPUT)
+ diagnostics_print(${BASYX_UTIL_LIB_SUFFIX})
+endif()
+
+build_source_group(${BASYX_UTIL_LIB_SUFFIX})
###############################################
### Install section ###
diff --git a/sdks/c++/basys.sdk.cc/src/vab/CMakeLists.txt b/sdks/c++/basys.sdk.cc/src/vab/CMakeLists.txt
index 549a9e0..a3fedf1 100644
--- a/sdks/c++/basys.sdk.cc/src/vab/CMakeLists.txt
+++ b/sdks/c++/basys.sdk.cc/src/vab/CMakeLists.txt
@@ -15,8 +15,10 @@
set_target_properties(${BASYX_VAB_LIB_SUFFIX} PROPERTIES SOVERSION ${BASYX_PACKAGE_VERSION_MAJOR})
set_target_properties(${BASYX_VAB_LIB_SUFFIX} PROPERTIES PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_SHORTNAME}")
target_include_directories(${BASYX_VAB_LIB_SUFFIX}
-INTERFACE ${CMAKE_INSTALL_PREFIX}/include
- ${CMAKE_INSTALL_PREFIX}/include/${PROJECT_SHORTNAME})
+ PUBLIC
+ $<BUILD_INTERFACE:${BASYX_INCLUDE_DIR}>
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>
+)
if(${BASYX_DEBUG_PRINT_FRAMES})
target_compile_definitions(${BASYX_VAB_LIB_SUFFIX} PUBLIC PRINT_FRAME)
@@ -68,7 +70,15 @@
add_library(basyx::vab ALIAS ${BASYX_VAB_LIB_SUFFIX})
add_library(${PROJECT_SHORTNAME}::${BASYX_VAB_LIB_SUFFIX} ALIAS ${BASYX_VAB_LIB_SUFFIX})
-diagnostics_print(${BASYX_VAB_LIB_SUFFIX})
+if(BASYX_IS_SUBMODULE)
+ set_target_properties(${BASYX_VAB_LIB_SUFFIX} PROPERTIES FOLDER BaSyx)
+endif()
+
+if(BASYX_VERBOSE_CMAKE_OUTPUT)
+ diagnostics_print(${BASYX_VAB_LIB_SUFFIX})
+endif()
+
+build_source_group(${BASYX_VAB_LIB_SUFFIX})
###############################################
### Install section ###
diff --git a/sdks/c++/basys.sdk.cc/src/vab/vab/backend/connector/native/BaSyxConnector.cpp b/sdks/c++/basys.sdk.cc/src/vab/vab/backend/connector/native/BaSyxConnector.cpp
index 8924014..1f4e891 100644
--- a/sdks/c++/basys.sdk.cc/src/vab/vab/backend/connector/native/BaSyxConnector.cpp
+++ b/sdks/c++/basys.sdk.cc/src/vab/vab/backend/connector/native/BaSyxConnector.cpp
@@ -54,10 +54,16 @@
return basyx::object::make_error(basyx::object::error::MalformedRequest, "invalid frame received");
};
- auto entityWrapper = nlohmann::json::parse(response_frame.getFirstValue());
+ auto firstField = response_frame.getFirstValue();
+ if (!firstField.empty())
+ {
+ auto entityWrapper = nlohmann::json::parse(response_frame.getFirstValue());
- auto value = basyx::vab::EntityWrapper::from_json(entityWrapper);
- return value;
+ auto value = basyx::vab::EntityWrapper::from_json(entityWrapper);
+ return value;
+ };
+
+ return basyx::object::make_null();
};
basyx::object NativeConnector::basysSet(std::string const& path, const basyx::object & newValue)
@@ -111,11 +117,11 @@
log.trace(" msg: 0x{0:x}", (std::size_t)msg);
log.trace(" size: {}", size);
- CoderTools::setInt32(msg, 0, size);
+ CoderTools::setInt32(msg, 0, static_cast<uint32_t>(size));
size += BASYX_FRAMESIZE_SIZE;
log.debug("Sending {} bytes.", size);
- int sent_bytes = this->socket.Send(basyx::net::make_buffer(msg, size));
+ auto sent_bytes = this->socket.Send(basyx::net::make_buffer(msg, size));
log.debug("Sent {} bytes.", sent_bytes);
if (sent_bytes < 0) {
@@ -130,7 +136,7 @@
log.trace(" data: 0x{0:x}", (std::size_t)data);
// recv(data, DEFAULT_BUFFER_LENGTH, 0);
- int recv_bytes = this->socket.Receive(basyx::net::make_buffer(data, default_buffer_length));
+ auto recv_bytes = this->socket.Receive(basyx::net::make_buffer(data, default_buffer_length));
log.debug("Received {} bytes.", recv_bytes);
diff --git a/sdks/c++/basys.sdk.cc/src/vab/vab/provider/VABModelProvider.cpp b/sdks/c++/basys.sdk.cc/src/vab/vab/provider/VABModelProvider.cpp
index 10b2a67..387db10 100644
--- a/sdks/c++/basys.sdk.cc/src/vab/vab/provider/VABModelProvider.cpp
+++ b/sdks/c++/basys.sdk.cc/src/vab/vab/provider/VABModelProvider.cpp
@@ -71,7 +71,7 @@
// Check empty paths
if (vabPath.isEmpty()) {
- // If path is empty, replace parenet element, but only if it doesn't exist
+ // If path is empty, replace parent element, but only if it does already exist
if (!elements.IsNull()) {
elements = newValue;
return basyx::object::error::None;
@@ -87,7 +87,7 @@
// Only write values, that already exist
auto thisElement = parentElement.getProperty(propertyName);
- if (!parentElement.IsNull()/* && !thisElement.IsNull()*/) {
+ if (!parentElement.IsNull() && !thisElement.IsError() ) {
parentElement.insertKey(propertyName, newValue, true);
return basyx::object::error::None;
}
@@ -150,7 +150,7 @@
core::VABPath vabPath{ path };
if (vabPath.isEmpty())
- return basyx::object::error::PropertyNotFound;
+ return basyx::object::error::MalformedRequest;
// Find parent & name of element
auto parentElement = this->getParentElement(path);
@@ -163,7 +163,8 @@
if (!childElement.IsNull()) {
//handler.DeleteValue(childElement, deletedValue);
- childElement.remove(deletedValue);
+ if (!childElement.remove(deletedValue))
+ return basyx::object::error::MalformedRequest;
return basyx::object::error::None;
}
}
diff --git a/sdks/c++/basys.sdk.cc/src/vab/vab/provider/native/frame/BaSyxNativeFrameProcessor.cpp b/sdks/c++/basys.sdk.cc/src/vab/vab/provider/native/frame/BaSyxNativeFrameProcessor.cpp
index 9667497..eb3c1f2 100644
--- a/sdks/c++/basys.sdk.cc/src/vab/vab/provider/native/frame/BaSyxNativeFrameProcessor.cpp
+++ b/sdks/c++/basys.sdk.cc/src/vab/vab/provider/native/frame/BaSyxNativeFrameProcessor.cpp
@@ -44,6 +44,8 @@
return processDelete(frame);
case BaSyxCommand::Invoke:
return processInvoke(frame);
+ default:
+ break;
}
return Frame{};
diff --git a/sdks/c++/basys.sdk.cc/tests/CMakeLists.txt b/sdks/c++/basys.sdk.cc/tests/CMakeLists.txt
index 07135d7..350df48 100644
--- a/sdks/c++/basys.sdk.cc/tests/CMakeLists.txt
+++ b/sdks/c++/basys.sdk.cc/tests/CMakeLists.txt
@@ -24,8 +24,8 @@
add_subdirectory(regression/util)
add_subdirectory(regression/vab)
-add_subdirectory(regression/aas)
add_subdirectory(regression/submodel)
+add_subdirectory(regression/controlcomponent)
### Integration tests ###
diff --git a/sdks/c++/basys.sdk.cc/tests/integration/cpp_test_connector/cpp_test_connector.cpp b/sdks/c++/basys.sdk.cc/tests/integration/cpp_test_connector/cpp_test_connector.cpp
index 0c838fe..0739dd7 100644
--- a/sdks/c++/basys.sdk.cc/tests/integration/cpp_test_connector/cpp_test_connector.cpp
+++ b/sdks/c++/basys.sdk.cc/tests/integration/cpp_test_connector/cpp_test_connector.cpp
@@ -89,44 +89,50 @@
};
#define HOST "127.0.0.1"
+#define PORT "8383"
-int test()
+std::string host(HOST);
+std::string port(PORT);
+
+int connector_run(const std::string & host, const std::string & port)
{
- //std::string host;
- //if (argc > 1)
- // host = argv[1];
- //else
- // host = HOST;
-
- std::string host = HOST;
-
- auto connector = util::make_unique<vab::connector::native::NativeConnector>(host, 7001);
+ auto connector = util::make_unique<vab::connector::native::NativeConnector>(host, port);
auto provider = ConnectedModelProvider(connector.get());
+ connector->basysInvoke("/reset", 0);
basyx::tests::regression::vab::snippet::MapRead::test(&provider);
+
+ connector->basysInvoke("/reset", 0);
basyx::tests::regression::vab::snippet::MapUpdate::test(&provider);
+
+ connector->basysInvoke("/reset", 0);
basyx::tests::regression::vab::snippet::MapCreateDelete::test(&provider);
+
+ connector->basysInvoke("/reset", 0);
basyx::tests::regression::vab::snippet::TestCollectionProperty::test(&provider);
+
+ connector->basysInvoke("/reset", 0);
basyx::tests::regression::vab::snippet::MapInvoke::test(&provider);
-
- //auto get = connector->basysGet("primitives/integer");
-
- //connector->basysSet("primitives/integer", 20);
-
- //auto get2 = connector->basysGet("primitives/integer");
-
- //auto inv = connector->basysInvoke("operations/complex", basyx::object::object_list_t{ 1,2 });
+
+ connector->basysInvoke("/reset", 0);
return 0;
};
TEST(Test_Case, Test)
{
- test();
+ connector_run(host, port);
};
-int main(int argc, char **argv) {
+int main(int argc, char **argv)
+{
+ if (argc > 1)
+ host = argv[1];
+
+ if (argc > 2)
+ port = argv[2];
+
// Init gtest framework
::testing::InitGoogleTest(&argc, argv);
diff --git a/sdks/c++/basys.sdk.cc/tests/integration/cpp_test_server/cpp_test_server.cpp b/sdks/c++/basys.sdk.cc/tests/integration/cpp_test_server/cpp_test_server.cpp
index fb95f67..b10494a 100644
--- a/sdks/c++/basys.sdk.cc/tests/integration/cpp_test_server/cpp_test_server.cpp
+++ b/sdks/c++/basys.sdk.cc/tests/integration/cpp_test_server/cpp_test_server.cpp
@@ -1,24 +1,42 @@
-#include <BaSyx/vab/provider/hashmap/VABHashmapProvider.h>
#include <BaSyx/server/TCPServer.h>
+#include <BaSyx/vab/provider/hashmap/VABHashmapProvider.h>
#include <vab/stub/elements/SimpleVABElement.h>
using namespace basyx;
-int main(int argc, char * argv[])
+class IntegrationTestModelProvider : public vab::provider::VABModelProvider {
+public:
+ void Reset()
+ {
+ this->elements = tests::support::make_simple_vab_element();
+ }
+
+ virtual basyx::object invokeOperation(const std::string& path, basyx::object parameters) override
+ {
+ log.info("[Integration] reset called");
+ if (path == "reset") {
+ Reset();
+ return basyx::object::make_null();
+ };
+
+ return VABModelProvider::invokeOperation(path, parameters);
+ };
+};
+
+int main(int argc, char* argv[])
{
- int port = 7001;
+ int port = 6000;
- if (argc > 1)
- port = std::atoi(argv[1]);
+ if (argc > 1)
+ port = std::atoi(argv[1]);
- vab::provider::VABModelProvider modelProvider{ tests::support::make_simple_vab_element() };
- server::TCPServer<vab::provider::VABModelProvider> tcpServer{ &modelProvider, port };
+ IntegrationTestModelProvider modelProvider;
+ modelProvider.Reset();
+ server::TCPServer<IntegrationTestModelProvider> tcpServer { &modelProvider, port };
+ while (true) {
+ tcpServer.update();
+ };
- while (true)
- {
- tcpServer.update();
- };
-
- return 0;
+ return 0;
};
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/controlcomponent/CMakeLists.txt b/sdks/c++/basys.sdk.cc/tests/regression/controlcomponent/CMakeLists.txt
new file mode 100644
index 0000000..f7b541d
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/tests/regression/controlcomponent/CMakeLists.txt
@@ -0,0 +1,20 @@
+#####################################################
+### tests_controlcomponent ###
+#####################################################
+
+cmake_minimum_required(VERSION 3.1.0)
+
+project(tests_controlcomponent)
+
+add_executable(${PROJECT_NAME})
+
+target_sources(${PROJECT_NAME}
+ PRIVATE
+ test_ControlComponent.cpp
+)
+
+target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR})
+target_link_libraries(${PROJECT_NAME} basyx::util basyx::shared lib::gtest basyx::vab tests::support basyx::controlcomponent tests::main)
+gtest_discover_tests(${PROJECT_NAME})
+
+diagnostics_print(${PROJECT_NAME})
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/controlcomponent/support/ControlComponentChangeListenerMock.hpp b/sdks/c++/basys.sdk.cc/tests/regression/controlcomponent/support/ControlComponentChangeListenerMock.hpp
new file mode 100644
index 0000000..ac54b44
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/tests/regression/controlcomponent/support/ControlComponentChangeListenerMock.hpp
@@ -0,0 +1,101 @@
+#ifndef BASYX_TESTING_SUPPORT_CONTROLCOMPONENT_CONTROLCOMPONENTCHANGELISTENER_MOCK_H_
+#define BASYX_TESTING_SUPPORT_CONTROLCOMPONENT_CONTROLCOMPONENTCHANGELISTENER_MOCK_H_
+
+#include <gtest/gtest.h>
+#include <BaSyx/controlcomponent/interfaces/IControlComponentChangeListener.h>
+
+using namespace basyx::controlcomponent;
+
+class ControlComponentChangeListenerMock : public IControlComponentChangeListener
+{
+public:
+ int unique_id = 0;
+
+ int call_counter_onVariableChange = 0;
+ int call_counter_onNewOccupier = 0;
+ int call_counter_onNewOccupationState = 0;
+ int call_counter_onLastOccupier = 0;
+ int call_counter_onChangedExecutionMode = 0;
+ int call_counter_onChangedExecutionState = 0;
+ int call_counter_onChangedOperationMode = 0;
+ int call_counter_onChangedWorkState = 0;
+ int call_counter_onChangedErrorState = 0;
+ int call_counter_onChangedPrevError = 0;
+ int call_counter_getUniqueID = 0;
+
+ ControlComponentChangeListenerMock(int id) : unique_id{id} {}
+ ControlComponentChangeListenerMock() {}
+
+ void onVariableChange(const std::string &varName, basyx::object newValue) override
+ {
+ call_counter_onVariableChange++;
+ }
+
+ void onNewOccupier(const std::string &occupierId) override
+ {
+ call_counter_onNewOccupier++;
+ }
+
+ void onNewOccupationState(basyx::controlcomponent::OccupationState state) override
+ {
+ call_counter_onNewOccupationState++;
+ }
+
+ void onLastOccupier(const std::string &lastOccupierId) override
+ {
+ call_counter_onLastOccupier++;
+ }
+
+ void onChangedExecutionMode(basyx::controlcomponent::ExecutionMode newExecutionMode) override
+ {
+ call_counter_onChangedExecutionMode++;
+ }
+
+ void onChangedExecutionState(basyx::controlcomponent::ExecutionState newExecutionState) override
+ {
+ call_counter_onChangedExecutionState++;
+ }
+
+ void onChangedOperationMode(const std::string &newOperationMode) override
+ {
+ call_counter_onChangedOperationMode++;
+ }
+
+ void onChangedWorkState(const std::string &newWorkState) override
+ {
+ call_counter_onChangedWorkState++;
+ }
+
+ void onChangedErrorState(const std::string &newWorkState) override
+ {
+ call_counter_onChangedErrorState++;
+ }
+
+ void onChangedPrevError(const std::string &newWorkState) override
+ {
+ call_counter_onChangedPrevError++;
+ }
+
+ int getUniqueID() override
+ {
+ call_counter_getUniqueID++;
+ return unique_id;
+ }
+
+ void reset()
+ {
+ call_counter_onVariableChange = 0;
+ call_counter_onNewOccupier = 0;
+ call_counter_onNewOccupationState = 0;
+ call_counter_onLastOccupier = 0;
+ call_counter_onChangedExecutionMode = 0;
+ call_counter_onChangedExecutionState = 0;
+ call_counter_onChangedOperationMode = 0;
+ call_counter_onChangedWorkState = 0;
+ call_counter_onChangedErrorState = 0;
+ call_counter_onChangedPrevError = 0;
+ call_counter_getUniqueID = 0;
+ }
+};
+
+#endif
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/controlcomponent/test_ControlComponent.cpp b/sdks/c++/basys.sdk.cc/tests/regression/controlcomponent/test_ControlComponent.cpp
new file mode 100644
index 0000000..ea1162e
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/tests/regression/controlcomponent/test_ControlComponent.cpp
@@ -0,0 +1,369 @@
+#include <gtest/gtest.h>
+
+#include <BaSyx/controlcomponent/map/ControlComponent.h>
+#include <BaSyx/controlcomponent/enumerations/ExecutionOrder.h>
+#include <BaSyx/controlcomponent/simple/ControlComponent.h>
+#include "support/ControlComponentChangeListenerMock.hpp"
+
+using namespace basyx::controlcomponent;
+
+using ImplTypes = ::testing::Types<
+ simple::ControlComponent,
+ map::ControlComponent
+>;
+
+template<class Impl>
+class ControlComponentTest: public ::testing::Test{
+protected:
+ std::unique_ptr<IControlComponent> control_component;
+ std::shared_ptr<ControlComponentChangeListenerMock> change_listener, change_listener_2;
+protected:
+ void SetUp() override
+ {
+ this->control_component = util::make_unique<Impl>();
+ this->change_listener = std::make_shared<ControlComponentChangeListenerMock>();
+ this->change_listener_2 = std::make_shared<ControlComponentChangeListenerMock>(2);
+
+ this->control_component->addControlComponentChangeListener(change_listener);
+ this->control_component->addControlComponentChangeListener(change_listener_2);
+ }
+
+ void TearDown() override
+ {
+ }
+};
+
+TYPED_TEST_CASE(ControlComponentTest, ImplTypes);
+
+TYPED_TEST(ControlComponentTest, TestListener)
+{
+ this->control_component->removeControlComponentChangeListener(this->change_listener);
+ // getUniqueID should have been called twice (see SetUp() above)
+ ASSERT_EQ(2, this->change_listener->call_counter_getUniqueID);
+
+ //only teh second change listener should have been notified
+ this->control_component->setLastOccupierID("");
+ ASSERT_EQ(0, this->change_listener->call_counter_onLastOccupier);
+ ASSERT_EQ(1, this->change_listener_2->call_counter_onLastOccupier);
+}
+
+TYPED_TEST(ControlComponentTest, TestAddClearOrder)
+{
+ //intially the list should be empty
+ const std::vector<std::string> & list = this->control_component->getOrderList();
+ ASSERT_EQ(list.size(), 0);
+
+ //add some orders
+ this->control_component->addOrder("order_1");
+ this->control_component->addOrder("order_2");
+
+ //check if they are in list
+ ASSERT_EQ(list.size(), 2);
+
+ //clear list
+ this->control_component->clearOrder();
+ ASSERT_EQ(list.size(), 0);
+}
+
+/*TEST_F(MapTest, TestPut)
+{
+ this->control_component->addControlComponentChangeListener(this->change_listener_2);
+
+ this->control_component->put("key", "test");
+ //key value pair should be in map
+ ASSERT_EQ("test", this->control_component->getMap().getProperty("key").GetStringContent());
+ //changeListeners onVariableChange should be called for each put
+ ASSERT_EQ(1, this->change_listener->call_counter_onVariableChange);
+ ASSERT_EQ(1, this->change_listener_2->call_counter_onVariableChange);
+ this->change_listener->reset();
+ this->change_listener_2->reset();
+
+ //If key cmd and value is a valid ExecutionOrder, ExecutionState should have changed
+ this->control_component->put("cmd", ExecutionOrder_::to_string(ExecutionOrder::reset));
+ ASSERT_EQ(1, this->change_listener->call_counter_onChangedExecutionState);
+ ASSERT_EQ(1, this->change_listener_2->call_counter_onChangedExecutionState);
+ ASSERT_EQ(ExecutionState::resetting ,this->control_component->getExecutionState());
+ this->change_listener->reset();
+ this->change_listener_2->reset();
+
+ //If key is localOverwrite occupier should be local
+ this->control_component->put(ControlComponentConstants_::to_string(ControlComponentConstants::localOverwrite), "test");
+ ASSERT_EQ(1, this->change_listener->call_counter_onNewOccupationState);
+ ASSERT_EQ(1, this->change_listener->call_counter_onNewOccupier);
+ ASSERT_EQ(ControlComponentConstants_::to_string(ControlComponentConstants::LOCAL), this->control_component->getOccupierID());
+ ASSERT_EQ(OccupationState::local, this->control_component->getOccupationState());
+
+ this->control_component->put(ControlComponentConstants_::to_string(ControlComponentConstants::localOverwriteFree), "test");
+ ASSERT_EQ("", this->control_component->getOccupierID());
+}*/
+
+TYPED_TEST(ControlComponentTest, TestOccupationState)
+{
+ OccupationState inital = this->control_component->getOccupationState();
+ ASSERT_EQ(OccupationState::free, inital);
+
+ this->control_component->setOccupationState(OccupationState::occupied);
+ OccupationState next = this->control_component->getOccupationState();
+ ASSERT_EQ(OccupationState::occupied, next);
+ ASSERT_EQ(1, this->change_listener->call_counter_onNewOccupationState);
+ ASSERT_EQ(1, this->change_listener_2->call_counter_onNewOccupationState);
+}
+
+TYPED_TEST(ControlComponentTest, TestOccupierId)
+{
+ std::string initial = this->control_component->getOccupierID();
+ ASSERT_EQ(initial, "");
+
+ this->control_component->setOccupierID("Some occupier");
+ std::string id = this->control_component->getOccupierID();
+ ASSERT_EQ("Some occupier", id);
+ ASSERT_EQ(1, this->change_listener->call_counter_onNewOccupier);
+ ASSERT_EQ(1, this->change_listener_2->call_counter_onNewOccupier);
+}
+
+TYPED_TEST(ControlComponentTest, TestLastOccupierId)
+{
+ std::string initial = this->control_component->getLastOccupierID();
+ ASSERT_EQ(initial, "");
+
+ this->control_component->setLastOccupierID("Some last occupier");
+ std::string id = this->control_component->getLastOccupierID();
+ ASSERT_EQ("Some last occupier", id);
+ ASSERT_EQ(1, this->change_listener->call_counter_onLastOccupier);
+ ASSERT_EQ(1, this->change_listener_2->call_counter_onLastOccupier);
+}
+
+TYPED_TEST(ControlComponentTest, TestExecutionMode)
+{
+ ExecutionMode initial = this->control_component->getExecutionMode();
+ ASSERT_EQ(initial, ExecutionMode::Auto);
+
+ this->control_component->setExecutionMode(ExecutionMode::Reserved);
+ ExecutionMode ex_mode = this->control_component->getExecutionMode();
+ ASSERT_EQ(ex_mode, ExecutionMode::Reserved);
+ ASSERT_EQ(1, this->change_listener->call_counter_onChangedExecutionMode);
+ ASSERT_EQ(1, this->change_listener_2->call_counter_onChangedExecutionMode);
+}
+
+TYPED_TEST(ControlComponentTest, TestExecutionState)
+{
+ ExecutionState initial = this->control_component->getExecutionState();
+ ASSERT_EQ(initial, ExecutionState::idle);
+
+ this->control_component->setExecutionState(ExecutionState::clearing);
+ ExecutionState ex_state = this->control_component->getExecutionState();
+ ASSERT_EQ(ex_state, ExecutionState::clearing);
+ ASSERT_EQ(1, this->change_listener->call_counter_onChangedExecutionState);
+ ASSERT_EQ(1, this->change_listener_2->call_counter_onChangedExecutionState);
+}
+
+TYPED_TEST(ControlComponentTest, TestOperationMode)
+{
+ std::string initial = this->control_component->getOperationMode();
+ ASSERT_EQ(initial, "");
+
+ this->control_component->setOperationMode("Special operation");
+ std::string op_mode = this->control_component->getOperationMode();
+ ASSERT_EQ(op_mode, "Special operation");
+ ASSERT_EQ(1, this->change_listener->call_counter_onChangedOperationMode);
+ ASSERT_EQ(1, this->change_listener_2->call_counter_onChangedOperationMode);
+}
+
+TYPED_TEST(ControlComponentTest, TestCommand)
+{
+ std::string initial = this->control_component->getCommand();
+ ASSERT_EQ(initial, "");
+
+ this->control_component->setCommand("Some command");
+ std::string command = this->control_component->getCommand();
+ ASSERT_EQ(command, "Some command");
+}
+
+TYPED_TEST(ControlComponentTest, TestLocalOverwrite)
+{
+ std::string initial = this->control_component->getLocalOverwrite();
+ ASSERT_EQ(initial, "");
+
+ this->control_component->setLocalOverwrite("Some overwrite");
+ std::string command = this->control_component->getLocalOverwrite();
+ ASSERT_EQ(command, "Some overwrite");
+}
+
+TYPED_TEST(ControlComponentTest, TestLocalOverwriteFree)
+{
+ std::string initial = this->control_component->getLocalOverwriteFree();
+ ASSERT_EQ(initial, "");
+
+ this->control_component->setLocalOverwriteFree("Some overwrite free");
+ std::string command = this->control_component->getLocalOverwriteFree();
+ ASSERT_EQ(command, "Some overwrite free");
+}
+
+TYPED_TEST(ControlComponentTest, TestServiceMap)
+{
+ basyx::object service_map = this->control_component->getServiceOperationMap();
+
+ service_map.getProperty(ControlComponentConstants_::to_string(ControlComponentConstants::semiauto)).invoke();
+ ExecutionMode ex_mode = this->control_component->getExecutionMode();
+ ASSERT_EQ(ex_mode, ExecutionMode::Semiauto);
+
+ service_map.getProperty(ControlComponentConstants_::to_string(ControlComponentConstants::start)).invoke();
+ ExecutionState ex_state = this->control_component->getExecutionState();
+ ASSERT_EQ(ex_state, ExecutionState::starting);
+
+ service_map.getProperty(ControlComponentConstants_::to_string(ControlComponentConstants::bstate)).invoke();
+ std::string op_mode = this->control_component->getOperationMode();
+ ASSERT_EQ(op_mode, "BSTATE");
+}
+
+TYPED_TEST(ControlComponentTest, TestFreeControlComponent)
+{
+ basyx::object service_map = this->control_component->getServiceOperationMap();
+
+ //set occupierID and last occupierID
+ this->control_component->setOccupierID("It's me");
+ this->control_component->setLastOccupierID("It's not anymore me");
+
+ // Try to free the controlcomponent
+ basyx::object who("It's me");
+ service_map.getProperty(ControlComponentConstants_::to_string(ControlComponentConstants::free)).invoke(who);
+ ASSERT_EQ(1, this->change_listener->call_counter_onNewOccupationState);
+ ASSERT_EQ(1, this->change_listener_2->call_counter_onNewOccupationState);
+
+ ASSERT_EQ("It's not anymore me", this->control_component->getOccupierID());
+ OccupationState oc_state = this->control_component->getOccupationState();
+ ASSERT_EQ(oc_state, OccupationState::occupied);
+
+ // Try to free controlcomponent without permission
+ service_map.getProperty(ControlComponentConstants_::to_string(ControlComponentConstants::free)).invoke(who);
+ //should not have changed
+ ASSERT_EQ("It's not anymore me", this->control_component->getOccupierID());
+ ASSERT_EQ(2, this->change_listener->call_counter_onNewOccupier);
+ ASSERT_EQ(2, this->change_listener_2->call_counter_onNewOccupier);
+
+ basyx::object has_permission("It's not anymore me");
+ service_map.getProperty(ControlComponentConstants_::to_string(ControlComponentConstants::free)).invoke(has_permission);
+ // should be empty now
+ ASSERT_EQ("", this->control_component->getOccupierID());
+ // ... and free
+ oc_state = this->control_component->getOccupationState();
+ ASSERT_EQ(oc_state, OccupationState::free);
+ ASSERT_EQ(3, this->change_listener->call_counter_onNewOccupier);
+ ASSERT_EQ(3, this->change_listener_2->call_counter_onNewOccupier);
+}
+
+TYPED_TEST(ControlComponentTest, TestOccupyControlComponent)
+{
+ basyx::object service_map = this->control_component->getServiceOperationMap();
+
+ basyx::object who("me");
+ service_map.getProperty(ControlComponentConstants_::to_string(ControlComponentConstants::occupy)).invoke(who);
+
+ // should be occupied by "me"
+ ASSERT_EQ(who.GetStringContent(), this->control_component->getOccupierID());
+ ASSERT_EQ(OccupationState::occupied, this->control_component->getOccupationState());
+ ASSERT_EQ(1, this->change_listener->call_counter_onNewOccupationState);
+ ASSERT_EQ(1, this->change_listener_2->call_counter_onNewOccupationState);
+
+ //If occupied, no one else should be able to occupy component
+ basyx::object not_permitted("Someone else");
+ service_map.getProperty(ControlComponentConstants_::to_string(ControlComponentConstants::occupy)).invoke();
+ ASSERT_EQ(who.GetStringContent(), this->control_component->getOccupierID());
+ ASSERT_EQ(OccupationState::occupied, this->control_component->getOccupationState());
+ ASSERT_EQ(1, this->change_listener->call_counter_onNewOccupier);
+ ASSERT_EQ(1, this->change_listener_2->call_counter_onNewOccupier);
+}
+
+TYPED_TEST(ControlComponentTest, TestPriorityOccupation)
+{
+ basyx::object service_map = this->control_component->getServiceOperationMap();
+
+ basyx::object who("me");
+ service_map.getProperty(ControlComponentConstants_::to_string(ControlComponentConstants::occupy)).invoke(who);
+ basyx::object priority_occupier("priority");
+ service_map.getProperty(ControlComponentConstants_::to_string(ControlComponentConstants::priority)).invoke(priority_occupier);
+
+ //Component should be in prioirity mode, last occupier "me" and actual occupier "priority"
+ ASSERT_EQ(OccupationState::priority, this->control_component->getOccupationState());
+ ASSERT_EQ("me", this->control_component->getLastOccupierID());
+ ASSERT_EQ("priority", this->control_component->getOccupierID());
+ ASSERT_EQ(2, this->change_listener->call_counter_onNewOccupier);
+ ASSERT_EQ(2, this->change_listener_2->call_counter_onNewOccupier);
+
+ //"me" should not be able to free component
+ service_map.getProperty(ControlComponentConstants_::to_string(ControlComponentConstants::free)).invoke(who);
+ ASSERT_EQ("priority", this->control_component->getOccupierID());
+ ASSERT_EQ(2, this->change_listener->call_counter_onNewOccupationState);
+ ASSERT_EQ(2, this->change_listener_2->call_counter_onNewOccupationState);
+
+ //but "prioirity" should be
+ service_map.getProperty(ControlComponentConstants_::to_string(ControlComponentConstants::free)).invoke(priority_occupier);
+ ASSERT_EQ("me", this->control_component->getOccupierID());
+ ASSERT_EQ(OccupationState::occupied, this->control_component->getOccupationState());
+ ASSERT_EQ(3, this->change_listener->call_counter_onNewOccupier);
+ ASSERT_EQ(3, this->change_listener_2->call_counter_onNewOccupier);
+}
+
+TYPED_TEST(ControlComponentTest, TestFinishState)
+{
+ // test transitions according to packml state machine
+ this->control_component->setExecutionState(ExecutionState::starting);
+ this->control_component->finishState();
+ ASSERT_EQ(ExecutionState::execute, this->control_component->getExecutionState());
+ ASSERT_EQ(2, this->change_listener->call_counter_onChangedExecutionState);
+
+ this->control_component->setExecutionState(ExecutionState::execute);
+ this->control_component->finishState();
+ ASSERT_EQ(ExecutionState::completing, this->control_component->getExecutionState());
+ ASSERT_EQ(4, this->change_listener->call_counter_onChangedExecutionState);
+
+ this->control_component->setExecutionState(ExecutionState::completing);
+ this->control_component->finishState();
+ ASSERT_EQ(ExecutionState::complete, this->control_component->getExecutionState());
+ ASSERT_EQ(6, this->change_listener->call_counter_onChangedExecutionState);
+
+ this->control_component->setExecutionState(ExecutionState::resetting);
+ this->control_component->finishState();
+ ASSERT_EQ(ExecutionState::idle, this->control_component->getExecutionState());
+ ASSERT_EQ(8, this->change_listener->call_counter_onChangedExecutionState);
+
+ this->control_component->setExecutionState(ExecutionState::holding);
+ this->control_component->finishState();
+ ASSERT_EQ(ExecutionState::held, this->control_component->getExecutionState());
+ ASSERT_EQ(10, this->change_listener->call_counter_onChangedExecutionState);
+
+ this->control_component->setExecutionState(ExecutionState::unholding);
+ this->control_component->finishState();
+ ASSERT_EQ(ExecutionState::execute, this->control_component->getExecutionState());
+ ASSERT_EQ(12, this->change_listener->call_counter_onChangedExecutionState);
+
+ this->control_component->setExecutionState(ExecutionState::suspending);
+ this->control_component->finishState();
+ ASSERT_EQ(ExecutionState::suspended, this->control_component->getExecutionState());
+ ASSERT_EQ(14, this->change_listener->call_counter_onChangedExecutionState);
+
+ this->control_component->setExecutionState(ExecutionState::unsuspending);
+ this->control_component->finishState();
+ ASSERT_EQ(ExecutionState::execute, this->control_component->getExecutionState());
+ ASSERT_EQ(16, this->change_listener->call_counter_onChangedExecutionState);
+
+ this->control_component->setExecutionState(ExecutionState::stopping);
+ this->control_component->finishState();
+ ASSERT_EQ(ExecutionState::stopped, this->control_component->getExecutionState());
+ ASSERT_EQ(18, this->change_listener->call_counter_onChangedExecutionState);
+
+ this->control_component->setExecutionState(ExecutionState::stopped);
+ this->control_component->finishState();
+ ASSERT_EQ(ExecutionState::idle, this->control_component->getExecutionState());
+ ASSERT_EQ(20, this->change_listener->call_counter_onChangedExecutionState);
+
+ this->control_component->setExecutionState(ExecutionState::aborting);
+ this->control_component->finishState();
+ ASSERT_EQ(ExecutionState::aborted, this->control_component->getExecutionState());
+ ASSERT_EQ(22, this->change_listener->call_counter_onChangedExecutionState);
+
+ this->control_component->setExecutionState(ExecutionState::clearing);
+ this->control_component->finishState();
+ ASSERT_EQ(ExecutionState::stopped, this->control_component->getExecutionState());
+ ASSERT_EQ(24, this->change_listener->call_counter_onChangedExecutionState);
+}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/submodel/CMakeLists.txt b/sdks/c++/basys.sdk.cc/tests/regression/submodel/CMakeLists.txt
index 3a23555..98b347c 100644
--- a/sdks/c++/basys.sdk.cc/tests/regression/submodel/CMakeLists.txt
+++ b/sdks/c++/basys.sdk.cc/tests/regression/submodel/CMakeLists.txt
@@ -11,8 +11,10 @@
target_sources(${PROJECT_NAME}
PRIVATE
api/common/test_ElementContainer.cpp
+ api/aas/test_AssetAdministrationShell.cpp
api/constraint/test_Formula.cpp
api/constraint/test_Qualifier.cpp
+ api/qualifier/test_AdministrativeInformation.cpp
api/qualifier/test_HasDataSpecification.cpp
api/qualifier/test_Identifiable.cpp
api/qualifier/test_Qualifiable.cpp
@@ -23,8 +25,11 @@
api/parts/test_ConceptDictionary.cpp
api/parts/test_ConceptDescription.cpp
api/parts/test_View.cpp
- map/common/test_ElementContainer.cpp
+ api/property/test_Property.cpp
api/common/test_LangStringSet.cpp
+ api/property/test_Property.cpp
+ api/test_Submodel.cpp
+ map_v2/common/test_ElementContainer.cpp
map_v2/dataspecification/test_DataSpecification.cpp
map_v2/dataspecification/test_DataSpecificationIEC61360.cpp
map_v2/identifier/test_Identifier.cpp
@@ -34,4 +39,4 @@
target_link_libraries(${PROJECT_NAME} basyx::util basyx::shared lib::gtest basyx::vab tests::support basyx::submodel tests::main)
gtest_discover_tests(${PROJECT_NAME})
-diagnostics_print(${PROJECT_NAME})
\ No newline at end of file
+diagnostics_print(${PROJECT_NAME})
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/aas/test_AssetAdministrationShell.cpp b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/aas/test_AssetAdministrationShell.cpp
new file mode 100644
index 0000000..23144ad
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/aas/test_AssetAdministrationShell.cpp
@@ -0,0 +1,51 @@
+#include <gtest/gtest.h>
+
+#include <BaSyx/submodel/api_v2/aas/IAssetAdministrationShell.h>
+#include <BaSyx/submodel/map_v2/aas/AssetAdministrationShell.h>
+#include <BaSyx/submodel/simple/aas/AssetAdministrationShell.h>
+
+#include <BaSyx/submodel/map_v2/SubModel.h>
+
+#include <BaSyx/util/util.h>
+
+using namespace basyx::submodel;
+
+using ImplTypes = ::testing::Types<
+ std::tuple<map::AssetAdministrationShell, map::Asset>,
+ std::tuple<simple::AssetAdministrationShell, simple::Asset>>;
+
+template<class Impl>
+class AssetAdministrationShellTest :public ::testing::Test {
+protected:
+ using impl_t = typename std::tuple_element<0, Impl>::type;
+ using asset_t = typename std::tuple_element<1, Impl>::type;
+
+ std::unique_ptr<api::IAssetAdministrationShell> aas;
+protected:
+ void SetUp() override
+ {
+ aas = util::make_unique<impl_t>("testAas",
+ simple::Identifier::Custom("testAas"),
+ asset_t{ "testAsset", simple::Identifier::Custom("testAsset") }
+ );
+ }
+
+ void TearDown() override
+ { }
+};
+
+TYPED_TEST_CASE(AssetAdministrationShellTest, ImplTypes);
+
+TYPED_TEST(AssetAdministrationShellTest, TestModelType)
+{
+ ASSERT_EQ(this->aas->GetModelType(), basyx::submodel::ModelTypes::AssetAdministrationShell);
+};
+
+TYPED_TEST(AssetAdministrationShellTest, TestAddSubmodel)
+{
+ auto submodel = this->aas->getSubmodels().template createElement<basyx::submodel::map::SubModel>("testSubmodel", simple::Identifier::Custom("testSubmodel"));
+
+ ASSERT_EQ(this->aas->getSubmodels().size(), 1);
+
+ return;
+};
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/common/test_ElementContainer.cpp b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/common/test_ElementContainer.cpp
index 10ba5be..abd197f 100644
--- a/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/common/test_ElementContainer.cpp
+++ b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/common/test_ElementContainer.cpp
@@ -52,6 +52,25 @@
ASSERT_EQ(propB->getValue(), 5);
};
+TYPED_TEST(ElementContainerTest, TestGetByIndex)
+{
+ auto prop = util::make_unique<Property<int>>("prop1");
+ prop->setValue(5);
+
+ auto prop2 = util::make_unique<Property<float>>("prop2");
+ prop2->setValue(10.0f);
+
+ this->elementContainer->addElement(std::move(prop));
+ this->elementContainer->addElement(std::move(prop2));
+ ASSERT_EQ(this->elementContainer->size(), 2);
+
+ auto submodelElement1 = this->elementContainer->getElement(0);
+ ASSERT_TRUE(submodelElement1->getIdShort() == "prop1" || submodelElement1->getIdShort() == "prop2");
+
+ auto submodelElement2 = this->elementContainer->getElement(0);
+ ASSERT_TRUE(submodelElement2->getIdShort() == "prop1" || submodelElement2->getIdShort() == "prop2");
+};
+
TYPED_TEST(ElementContainerTest, TestCreate)
{
auto prop = this->elementContainer->template createElement<Property<int>>("testProperty");
@@ -64,62 +83,3 @@
ASSERT_EQ(propB->getValue(), 5);
};
-/*********************************************************
- * Map implementation tests
- *********************************************************/
-
-class MapElementContainerTest : public ::testing::Test {
-protected:
- map::ElementContainer<ISubmodelElement> elementContainer;
-protected:
- void SetUp() override
- {
- }
-
- void TearDown() override
- {
- }
-};
-
-TEST_F(MapElementContainerTest, TestMapImplementationCreateDeleteAfterwards)
-{
- auto prop = this->elementContainer.createElement<Property<int>>("testProperty");
- ASSERT_EQ(this->elementContainer.size(), 1);
- prop->setValue(5);
-
- // Delete in map
- auto & objectList = this->elementContainer.getMap().Get<basyx::object::object_list_t&>();
- objectList.clear();
- ASSERT_EQ(this->elementContainer.size(), 0);
- auto prop_b = this->elementContainer.getElement("testProperty");
- ASSERT_EQ(prop_b, nullptr);
-};
-
-
-/*********************************************************
- * Simple implementation tests
- *********************************************************/
-class SimpleElementContainerTest : public ::testing::Test {
-protected:
- simple::ElementContainer<IReferable> elementContainer;
-protected:
- void SetUp() override
- {}
-
- void TearDown() override
- {}
-};
-
-TEST_F(SimpleElementContainerTest, TestSimpleImplementationCopy)
-{
-// std::unique_ptr<IReferable> ref = util::make_unique<simple::Referable>("testRef");
-// ref->setCategory("testCategory");
-// this->elementContainer.addElement(std::unique_ptr<IReferable>(ref.release()));
-// ASSERT_EQ(this->elementContainer.size(), 1);
-//
-// simple::ElementContainer<IReferable> elementContainer2(std::move(elementContainer));
-// auto prop2 = dynamic_cast<simple::Referable*>(elementContainer2.getElement("testRef"));
-// ASSERT_EQ(elementContainer2->size(), 1);
-// ASSERT_EQ(prop2->getCategory(), std::string("testCategory"));
-};
-
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/parts/test_ConceptDescription.cpp b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/parts/test_ConceptDescription.cpp
index 8b2546e..f3b2400 100644
--- a/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/parts/test_ConceptDescription.cpp
+++ b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/parts/test_ConceptDescription.cpp
@@ -8,61 +8,61 @@
using namespace basyx::submodel;
-using ImplTypes = ::testing::Types
-<
- std::tuple<map::ConceptDescription, map::Reference, map::DataSpecification>,
- std::tuple<simple::ConceptDescription, simple::Reference, simple::DataSpecification>
->;
+using ImplTypes = ::testing::Types<
+ std::tuple<map::ConceptDescription, map::Reference, map::DataSpecification>,
+ std::tuple<simple::ConceptDescription, simple::Reference, simple::DataSpecification>>;
-template<class Impl>
-class ConceptDescriptionTest :public ::testing::Test {
+template <class Impl>
+class ConceptDescriptionTest : public ::testing::Test {
protected:
- using impl_t = typename std::tuple_element<0, Impl>::type;
- using impl_ref_t = typename std::tuple_element<1, Impl>::type;
- using impl_dataSpec_t = typename std::tuple_element<2, Impl>::type;
+ using impl_t = typename std::tuple_element<0, Impl>::type;
+ using impl_ref_t = typename std::tuple_element<1, Impl>::type;
+ using impl_dataSpec_t = typename std::tuple_element<2, Impl>::type;
- std::unique_ptr<impl_t> conceptDescription;
- std::unique_ptr<impl_ref_t> testingReference;
- std::unique_ptr<impl_dataSpec_t> testingDataSpecification;
+ std::unique_ptr<impl_t> conceptDescription;
+ std::unique_ptr<impl_ref_t> testingReference;
+ std::unique_ptr<impl_dataSpec_t> testingDataSpecification;
+
protected:
- void SetUp() override
- {
- simple::Identifier id;
- conceptDescription = util::make_unique<impl_t>("test id", id);
- simple::Key key(KeyElements::Property, true, KeyType::IdShort, "test");
- testingReference = util::make_unique<impl_ref_t>(key);
- testingDataSpecification = util::make_unique<impl_dataSpec_t>("test data spec", id);
- }
+ void SetUp() override
+ {
+ simple::Identifier id;
+ conceptDescription = util::make_unique<impl_t>("test id", id);
+ simple::Key key(KeyElements::Property, true, KeyType::IdShort, "test");
+ testingReference = util::make_unique<impl_ref_t>(key);
+ testingDataSpecification = util::make_unique<impl_dataSpec_t>("test data spec", id);
+ }
- void TearDown() override
- { }
+ void TearDown() override
+ {
+ }
};
TYPED_TEST_CASE(ConceptDescriptionTest, ImplTypes);
TYPED_TEST(ConceptDescriptionTest, TestConstructor)
{
- auto & cases = this->conceptDescription->getIsCaseOf();
- auto & references = this->conceptDescription->getDataSpecificationReference();
+ auto& cases = this->conceptDescription->getIsCaseOf();
+ auto& references = this->conceptDescription->getDataSpecificationReference();
- ASSERT_EQ(references.size(), 0);
- ASSERT_EQ(cases.size(), 0);
+ ASSERT_EQ(references.size(), 0);
+ ASSERT_EQ(cases.size(), 0);
}
TYPED_TEST(ConceptDescriptionTest, TestAddIsCaseOf)
{
- this->conceptDescription->addIsCaseOf(std::move(this->testingReference));
+ this->conceptDescription->addIsCaseOf(std::move(this->testingReference));
- auto & references = this->conceptDescription->getIsCaseOf();
- auto keys = references.at(0)->getKeys();
- ASSERT_EQ(1, keys.size());
- ASSERT_EQ("test", keys.at(0).getValue());
+ auto& references = this->conceptDescription->getIsCaseOf();
+ auto keys = references.at(0)->getKeys();
+ ASSERT_EQ(1, keys.size());
+ ASSERT_EQ("test", keys.at(0).getValue());
}
TYPED_TEST(ConceptDescriptionTest, TestAddEmbeddedDataSpecification)
{
- this->conceptDescription->addEmbeddedDataSpecification(std::move(this->testingDataSpecification));
+ this->conceptDescription->addEmbeddedDataSpecification(std::move(this->testingDataSpecification));
- auto & references = this->conceptDescription->getEmbeddedDataSpecification();
- ASSERT_NE(references.getElement("test data spec"), nullptr);
-}
\ No newline at end of file
+ auto& references = this->conceptDescription->getEmbeddedDataSpecification();
+ ASSERT_NE(references.getElement("test data spec"), nullptr);
+}
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/parts/test_View.cpp b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/parts/test_View.cpp
index 0bdaf15..14f0c67 100644
--- a/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/parts/test_View.cpp
+++ b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/parts/test_View.cpp
@@ -25,12 +25,12 @@
protected:
void SetUp() override
{
- view = util::make_unique<impl_t>("TestView");
- referable = util::make_unique<impl_ref_t>("TestReferable");
+ view = util::make_unique<impl_t>("TestView");
+ referable = util::make_unique<impl_ref_t>("TestReferable");
}
void TearDown() override
- { }
+ {}
};
TYPED_TEST_CASE(ViewTest, ImplTypes);
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/property/test_Property.cpp b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/property/test_Property.cpp
new file mode 100644
index 0000000..34a7353
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/property/test_Property.cpp
@@ -0,0 +1,315 @@
+#include <gtest/gtest.h>
+#include <BaSyx/submodel/simple/submodelelement/property/Property.h>
+#include <BaSyx/submodel/map_v2/submodelelement/property/Property.h>
+#include <BaSyx/submodel/simple/common/xsd_types/AnyURI.h>
+
+using namespace basyx::submodel;
+
+// Implementations to run tests for
+using ImplTypes = ::testing::Types<
+ simple::Property<int>,
+ map::Property<int>
+>;
+
+template<class Impl>
+class PropertyTest :public ::testing::Test {
+protected:
+ using impl_t = Impl;
+protected:
+ std::unique_ptr<api::IProperty> property;
+protected:
+ void SetUp() override
+ {
+ std::string idShort("id test");
+ this->property = util::make_unique<Impl>(idShort);
+ }
+
+ void TearDown() override
+ {
+ }
+};
+
+TYPED_TEST_CASE(PropertyTest, ImplTypes);
+
+TYPED_TEST(PropertyTest, TestConstructor)
+{
+ ASSERT_EQ(this->property->getIdShort(), std::string("id test"));
+}
+
+TYPED_TEST(PropertyTest, TestValueType)
+{
+ this->property->setValueType("valueType test");
+ ASSERT_EQ(this->property->getValueType(), std::string("valueType test"));
+}
+
+TYPED_TEST(PropertyTest, TestObject)
+{
+ basyx::object o(123);
+ this->property->setObject(o);
+ ASSERT_EQ(this->property->getObject(), basyx::object(123));
+}
+
+TYPED_TEST(PropertyTest, TestValueID)
+{
+ simple::Key key(KeyElements::ConceptDictionary, false, KeyType::Custom, "test key");
+ std::unique_ptr<api::IReference> ref = util::make_unique<simple::Reference>(key);
+ this->property->setValueId(*ref);
+ ASSERT_EQ(this->property->getValueId()->getKeys().at(0), key);
+}
+
+TYPED_TEST(PropertyTest, TestGetKeyElementType)
+{
+ ASSERT_EQ(this->property->getKeyElementType(), KeyElements::Property);
+}
+
+TYPED_TEST(PropertyTest, TestAnyURI)
+{
+ map::Property<simple::AnyURI> map_uri_prop("id");
+ ASSERT_EQ(map_uri_prop.getValueType(), std::string("anyURI"));
+}
+
+TYPED_TEST(PropertyTest, TestSafeDateTime)
+{
+ map::Property<simple::DateTime> dateTime_property("test id");
+ std::string valueType = dateTime_property.getValueType();
+ ASSERT_EQ(valueType, std::string("dateTime"));
+
+ //Try to add a DateTime
+ time_t t = 1563002200;
+ tm time = *gmtime(&t);
+ simple::DateTime test_time(time);
+ dateTime_property.setValue(test_time);
+
+ auto dateTime_string = dateTime_property.getMap().getProperty(map::PropertyPath::Value).GetStringContent();
+ ASSERT_EQ(dateTime_string, std::string("2019-07-13T07:16:40Z"));
+ tm saved_time = dateTime_property.getValue().getTime();
+ ASSERT_EQ(mktime(&saved_time), mktime(&time));
+}
+
+TYPED_TEST(PropertyTest, TestSafeDate)
+{
+ map::Property<simple::Date> date_property("test id");
+ std::string valueType = date_property.getValueType();
+ ASSERT_EQ(valueType, std::string("date"));
+
+ //Try to add a Date
+ tm date;
+ //epoche starts at 1900
+ date.tm_year = 1986 - 1900;
+ //month count starts at 0
+ date.tm_mon = 5 - 1;
+ date.tm_mday = 6;
+ simple::Date test_date(date);
+ date_property.setValue(test_date);
+
+ auto dateTime_string = date_property.getMap().getProperty(map::PropertyPath::Value).GetStringContent();
+ ASSERT_EQ(dateTime_string, std::string("1986-05-06Z"));
+ tm saved_date = date_property.getValue().getDate();
+ ASSERT_EQ(saved_date.tm_year, date.tm_year);
+ ASSERT_EQ(saved_date.tm_mon, date.tm_mon);
+ ASSERT_EQ(saved_date.tm_mday, date.tm_mday);
+}
+
+TYPED_TEST(PropertyTest, TestSafeDayTimeDuration)
+{
+ map::Property<simple::DayTimeDuration> duration_property("test id");
+ ASSERT_EQ(duration_property.getValueType(), std::string("dayTimeDuration"));
+
+ std::vector<std::pair<long, std::string>> test_cases = {
+ {0, "P"},
+ {12312123, "P142D12H2M3S"},
+ {12268923, "P142D2M3S"},
+ {12312120, "P142D12H2M"},
+ {59, "P59S"},
+ {60, "P1M"},
+ {-1, "-P1S"},
+ {-12312123, "-P142D12H2M3S"}
+ };
+
+ for (auto pair : test_cases)
+ {
+ std::chrono::duration<long> test_duration{pair.first};
+ simple::DayTimeDuration duration{test_duration};
+ duration_property.setValue(duration);
+
+ auto dateTime_string = duration_property.getMap().getProperty(map::PropertyPath::Value).GetStringContent();
+ ASSERT_EQ(dateTime_string, std::string(pair.second));
+ ASSERT_EQ(duration_property.getValue().getDuration().count(), test_duration.count());
+ }
+}
+
+
+
+TYPED_TEST(PropertyTest, TestSafeYearMonthDuration)
+{
+ map::Property<simple::YearMonthDuration> duration_property("test id");
+ ASSERT_EQ(duration_property.getValueType(), std::string("yearMonthDuration"));
+
+ std::vector<std::tuple<int, int, int, int, std::string>> test_cases = {
+ {0, 0, 0, 0, "P"},
+ {99, 0, 99, 0, "P99Y"},
+ {0, 11, 0, 11, "P11M"},
+ {50, 100, 58, 4, "P58Y4M"},
+ {50, -100, 41, 8, "P41Y8M"},
+ {-50, 100, -42, 4, "-P42Y4M"}
+ };
+
+ for (auto tuple : test_cases)
+ {
+ simple::YearMonthDuration duration{std::get<0>(tuple), std::get<1>(tuple)};
+ duration_property.setValue(duration);
+
+ auto duration_string = duration_property.getMap().getProperty(map::PropertyPath::Value).GetStringContent();
+ ASSERT_EQ(duration_string, std::string(std::get<4>(tuple)));
+ ASSERT_EQ(duration_property.getValue().getYears(), std::get<2>(tuple));
+ ASSERT_EQ(duration_property.getValue().getMonths(), std::get<3>(tuple));
+ }
+}
+
+TYPED_TEST(PropertyTest, TestTime)
+{
+ map::Property<simple::Time> time_property("test id");
+ ASSERT_EQ(time_property.getValueType(), std::string("time"));
+
+ std::vector<std::tuple<uint8_t, uint8_t, float, std::string, std::string>> test_cases = {
+ {0, 0, 0, "Z", "00:00:00Z"},
+ {11, 12, 3, "+01:00", "11:12:03+01:00"},
+ {12, 34, 56.789, "-12:00", "12:34:56.789-12:00"},
+ {1, 2, 3.04, "Z", "01:02:03.04Z"}
+ };
+
+ for (auto tuple : test_cases)
+ {
+ simple::Time time{std::get<0>(tuple), std::get<1>(tuple), std::get<2>(tuple), std::get<3>(tuple)};
+ time_property.setValue(time);
+
+ auto xsd_str = time_property.getMap().getProperty(map::PropertyPath::Value).GetStringContent();
+ ASSERT_EQ(xsd_str, std::string(std::get<4>(tuple)));
+ ASSERT_EQ(time_property.getValue().getHours(), std::get<0>(tuple));
+ ASSERT_EQ(time_property.getValue().getMinutes(), std::get<1>(tuple));
+ ASSERT_EQ(time_property.getValue().getSeconds(), std::get<2>(tuple));
+ ASSERT_EQ(std::string{time_property.getValue().getTimezone()}, std::string(std::get<3>(tuple)));
+ }
+}
+
+TYPED_TEST(PropertyTest, TestGregorianYearMonth)
+{
+ map::Property<simple::GYearMonth> gregorianYearMonth_property("test id");
+ ASSERT_EQ(gregorianYearMonth_property.getValueType(), std::string("gYearMonth"));
+
+ std::vector<std::tuple<int, uint8_t, std::string, std::string>> test_cases = {
+ {0, 01, "Z", "0000-01Z"},
+ {11, 12, "+01:00", "0011-12+01:00"},
+ {2016, 1, "-12:00", "2016-01-12:00"},
+ {-1, 10, "Z", "-0001-10Z"},
+ {20202, 10, "Z", "20202-10Z"}
+ };
+
+ for (auto tuple : test_cases)
+ {
+ simple::GYearMonth yearMonth{std::get<0>(tuple), std::get<1>(tuple), std::get<2>(tuple)};
+ gregorianYearMonth_property.setValue(yearMonth);
+
+ auto xsd_str = gregorianYearMonth_property.getMap().getProperty(map::PropertyPath::Value).GetStringContent();
+ ASSERT_EQ(xsd_str, std::string(std::get<3>(tuple)));
+ ASSERT_EQ(gregorianYearMonth_property.getValue().getYear(), std::get<0>(tuple));
+ ASSERT_EQ(gregorianYearMonth_property.getValue().getMonth(), std::get<1>(tuple));
+ ASSERT_EQ(std::string{gregorianYearMonth_property.getValue().getTimezone()}, std::string(std::get<2>(tuple)));
+ }
+}
+
+TYPED_TEST(PropertyTest, TestGregorianYear)
+{
+ map::Property<simple::GYear> gregorianYear_property("test id");
+ ASSERT_EQ(gregorianYear_property.getValueType(), std::string("gYear"));
+
+ std::vector<std::tuple<int, std::string, std::string>> test_cases = {
+ {0, "Z", "0000Z"},
+ {11, "+01:00", "0011+01:00"},
+ {2016, "-12:00", "2016-12:00"},
+ {-1, "Z", "-0001Z"},
+ {-15445, "Z", "-15445Z"},
+ {20202, "Z", "20202Z"}
+ };
+
+ for (auto tuple : test_cases)
+ {
+ simple::GYear year{std::get<0>(tuple), std::get<1>(tuple)};
+ gregorianYear_property.setValue(year);
+
+ auto xsd_str = gregorianYear_property.getMap().getProperty(map::PropertyPath::Value).GetStringContent();
+ ASSERT_EQ(xsd_str, std::string(std::get<2>(tuple)));
+ ASSERT_EQ(gregorianYear_property.getValue().getYear(), std::get<0>(tuple));
+ ASSERT_EQ(std::string{gregorianYear_property.getValue().getTimezone()}, std::string(std::get<1>(tuple)));
+ }
+}
+
+TYPED_TEST(PropertyTest, TestGregorianMonthDay)
+{
+ map::Property<simple::GMonthDay> gregorianMonthDay_property("test id");
+ ASSERT_EQ(gregorianMonthDay_property.getValueType(), std::string("gMonthDay"));
+
+ std::vector<std::tuple<uint8_t, uint8_t, std::string, std::string, uint8_t, uint8_t>> test_cases = {
+ {1, 1, "Z", "--01-01Z", 1, 1},
+ {10, 31, "+01:00", "--10-31+01:00", 10, 31},
+ {13, 32, "-12:00", "--01-31-12:00", 1, 31},
+ };
+
+ for (auto tuple : test_cases)
+ {
+ simple::GMonthDay monthDay{std::get<0>(tuple), std::get<1>(tuple), std::get<2>(tuple)};
+ gregorianMonthDay_property.setValue(monthDay);
+
+ auto xsd_str = gregorianMonthDay_property.getMap().getProperty(map::PropertyPath::Value).GetStringContent();
+ ASSERT_EQ(xsd_str, std::string(std::get<3>(tuple)));
+ ASSERT_EQ(gregorianMonthDay_property.getValue().getMonth(), std::get<4>(tuple));
+ ASSERT_EQ(gregorianMonthDay_property.getValue().getDay(), std::get<5>(tuple));
+ ASSERT_EQ(std::string{gregorianMonthDay_property.getValue().getTimezone()}, std::string(std::get<2>(tuple)));
+ }
+}
+
+TYPED_TEST(PropertyTest, TestGregorianDay)
+{
+ map::Property<simple::GDay> gregorianDay_property("test id");
+ ASSERT_EQ(gregorianDay_property.getValueType(), std::string("gDay"));
+
+ std::vector<std::tuple<uint8_t, std::string, std::string, uint8_t>> test_cases = {
+ {1, "Z", "---01Z", 1},
+ {10, "+01:00", "---10+01:00", 10},
+ {32, "-12:00", "---01-12:00", 1},
+ };
+
+ for (auto tuple : test_cases)
+ {
+ simple::GDay day{std::get<0>(tuple), std::get<1>(tuple)};
+ gregorianDay_property.setValue(day);
+
+ auto xsd_str = gregorianDay_property.getMap().getProperty(map::PropertyPath::Value).GetStringContent();
+ ASSERT_EQ(xsd_str, std::string(std::get<2>(tuple)));
+ ASSERT_EQ(gregorianDay_property.getValue().getDay(), std::get<3>(tuple));
+ ASSERT_EQ(std::string{gregorianDay_property.getValue().getTimezone()}, std::string(std::get<1>(tuple)));
+ }
+}
+
+TYPED_TEST(PropertyTest, TestGregorianMonth)
+{
+ map::Property<simple::GMonth> gregorianMonth_property("test id");
+ ASSERT_EQ(gregorianMonth_property.getValueType(), std::string("gMonth"));
+
+ std::vector<std::tuple<uint8_t, std::string, std::string, uint8_t>> test_cases = {
+ {1, "Z", "--01Z", 1},
+ {10, "+01:00", "--10+01:00", 10},
+ {13, "-12:00", "--01-12:00", 1},
+ };
+
+ for (auto tuple : test_cases)
+ {
+ simple::GMonth month{std::get<0>(tuple), std::get<1>(tuple)};
+ gregorianMonth_property.setValue(month);
+
+ auto xsd_str = gregorianMonth_property.getMap().getProperty(map::PropertyPath::Value).GetStringContent();
+ ASSERT_EQ(xsd_str, std::string(std::get<2>(tuple)));
+ ASSERT_EQ(gregorianMonth_property.getValue().getMonth(), std::get<3>(tuple));
+ ASSERT_EQ(std::string{gregorianMonth_property.getValue().getTimezone()}, std::string(std::get<1>(tuple)));
+ }
+}
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/qualifier/test_AdministrativeInformation.cpp b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/qualifier/test_AdministrativeInformation.cpp
new file mode 100644
index 0000000..9603475
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/qualifier/test_AdministrativeInformation.cpp
@@ -0,0 +1,81 @@
+#include <gtest/gtest.h>
+#include <BaSyx/submodel/simple/qualifier/AdministrativeInformation.h>
+#include <BaSyx/submodel/map_v2/qualifier/AdministrativeInformation.h>
+
+using namespace basyx::submodel;
+
+// Implementations to run tests for
+using ImplTypes = ::testing::Types<
+ simple::AdministrativeInformation,
+ map::AdministrativeInformation
+>;
+
+template<class Impl>
+class AdministrativeInformationTest :public ::testing::Test {
+protected:
+ using impl_t = Impl;
+protected:
+ std::unique_ptr<api::IAdministrativeInformation> administrativeInformation;
+ std::unique_ptr<api::IAdministrativeInformation> administrativeInformationMembersSet;
+protected:
+ void SetUp() override
+ {
+ this->administrativeInformation = util::make_unique<Impl>();
+ this->administrativeInformationMembersSet = util::make_unique<Impl>("TestVersion", "TestRevision");
+ }
+
+ void TearDown() override
+ {
+ }
+};
+
+TYPED_TEST_CASE(AdministrativeInformationTest, ImplTypes);
+
+TYPED_TEST(AdministrativeInformationTest, TestConstructor)
+{
+ ASSERT_EQ(this->administrativeInformation->getRevision(), nullptr);
+ ASSERT_EQ(this->administrativeInformation->getVersion(), nullptr);
+}
+
+TYPED_TEST(AdministrativeInformationTest, TestStringConstructor)
+{
+ ASSERT_EQ(*this->administrativeInformationMembersSet->getVersion(), "TestVersion");
+ ASSERT_EQ(*this->administrativeInformationMembersSet->getRevision(), "TestRevision");
+}
+
+TYPED_TEST(AdministrativeInformationTest, TestSetVersion)
+{
+ ASSERT_EQ(this->administrativeInformation->getVersion(), nullptr);
+
+ this->administrativeInformation->setVersion("TestVersion");
+
+ ASSERT_EQ(*this->administrativeInformation->getVersion(), "TestVersion");
+}
+
+TYPED_TEST(AdministrativeInformationTest, TestSetRevision)
+{
+ ASSERT_EQ(this->administrativeInformation->getRevision(), nullptr);
+
+ this->administrativeInformation->setRevision("TestRevision");
+
+ ASSERT_EQ(*this->administrativeInformation->getRevision(), "TestRevision");
+}
+
+TYPED_TEST(AdministrativeInformationTest, TestHasVersion)
+{
+ ASSERT_FALSE(this->administrativeInformation->hasVersion());
+
+ this->administrativeInformation->setVersion("TestVersion");
+
+ ASSERT_TRUE(this->administrativeInformation->hasVersion());
+}
+
+TYPED_TEST(AdministrativeInformationTest, TestHasRevision)
+{
+ ASSERT_FALSE(this->administrativeInformation->hasRevision());
+
+ this->administrativeInformation->setRevision("TestRevision");
+
+ ASSERT_TRUE(this->administrativeInformation->hasRevision());
+}
+
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/qualifier/test_Identifiable.cpp b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/qualifier/test_Identifiable.cpp
index 4af3c94..520544c 100644
--- a/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/qualifier/test_Identifiable.cpp
+++ b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/qualifier/test_Identifiable.cpp
@@ -11,18 +11,25 @@
// Implementations to run tests for
using ImplTypes = ::testing::Types<
- simple::Identifiable,
- map::Identifiable
+ std::tuple<simple::Identifiable, simple::AdministrativeInformation>,
+ std::tuple<map::Identifiable, map::AdministrativeInformation>
>;
template<class Impl>
class IdentifiableTest :public ::testing::Test {
protected:
- std::unique_ptr<api::IIdentifiable> identifiable;
+ using impl_t = typename std::tuple_element<0, Impl>::type;
+ using impl_admin_info_t = typename std::tuple_element<1, Impl>::type;
+
+ std::unique_ptr<impl_t> identifiable;
+
+ impl_admin_info_t administrative_information;
+
protected:
void SetUp() override
{
- this->identifiable = util::make_unique<Impl>(idShort, simple::Identifier{ IdentifierType::Custom, "Test" });
+ this->identifiable = util::make_unique<impl_t>(idShort, simple::Identifier{ IdentifierType::Custom, "Test" });
+ this->administrative_information = impl_admin_info_t("test version", "test revision");
}
void TearDown() override
@@ -41,4 +48,14 @@
auto ident = this->identifiable->getIdentification();
ASSERT_EQ(ident.getId(), "Test" );
ASSERT_EQ(ident.getIdType(), IdentifierType::Custom );
+}
+
+TYPED_TEST(IdentifiableTest, TestSetAdministrativeInformation)
+{
+ ASSERT_FALSE(this->identifiable->hasAdministrativeInformation());
+
+ this->identifiable->setAdministrativeInformation(this->administrative_information);
+
+ ASSERT_TRUE(this->identifiable->hasAdministrativeInformation());
+ ASSERT_EQ(*this->identifiable->getAdministrativeInformation().getVersion(), std::string("test version"));
}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/test_Submodel.cpp b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/test_Submodel.cpp
new file mode 100644
index 0000000..b8b428f
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/test_Submodel.cpp
@@ -0,0 +1,88 @@
+#include <gtest/gtest.h>
+
+#include <BaSyx/submodel/map_v2/SubModel.h>
+#include <BaSyx/submodel/map_v2/aas/Asset.h>
+#include <BaSyx/submodel/map_v2/aas/AssetAdministrationShell.h>
+#include <BaSyx/submodel/simple/SubModel.h>
+#include <BaSyx/submodel/simple/aas/Asset.h>
+#include <BaSyx/submodel/simple/aas/AssetAdministrationShell.h>
+
+using namespace basyx::submodel;
+using namespace basyx::submodel::map;
+using namespace basyx::submodel::simple;
+
+// Implementations to run tests for
+struct map_types {
+ using submodel_t = map::SubModel;
+ using asset_t = map::Asset;
+ using aas_t = map::AssetAdministrationShell;
+};
+
+struct simple_types {
+ using submodel_t = simple::SubModel;
+ using asset_t = simple::Asset;
+ using aas_t = simple::AssetAdministrationShell;
+};
+
+using TestTypes = ::testing::Types<
+ map_types,
+ simple_types>;
+
+template <class Types>
+class SubmodelTest : public ::testing::Test {
+public:
+ using types = Types;
+
+protected:
+ std::unique_ptr<typename Types::submodel_t> subModel;
+
+protected:
+ void SetUp() override
+ {
+ }
+
+ void TearDown() override
+ {
+ }
+};
+
+TYPED_TEST_CASE(SubmodelTest, TestTypes);
+
+TYPED_TEST(SubmodelTest, TestSubmodelConstructor)
+{
+ using namespace basyx::submodel;
+
+
+ typename TypeParam::submodel_t submodel{ "test", { simple::Identifier { IdentifierType::Custom, "test" } } };
+};
+
+TYPED_TEST(SubmodelTest, TestSubmodelReferences)
+{
+ using aas_t = typename TypeParam::aas_t;
+ using asset_t = typename TypeParam::asset_t;
+ using submodel_t = typename TypeParam::submodel_t;
+
+ // Create asset
+ asset_t asset{
+ "asset", /* idShort */
+ simple::Identifier::Custom("asset") /* identifier */
+ };
+
+ // Create the asset administration shell and assign asset
+ aas_t aas{
+ "aas", /* idShort */
+ simple::Identifier::Custom("aas"), /* identifier */
+ asset
+ };
+
+
+ auto & submodels = aas.getSubmodels();
+ submodels.template createElement<submodel_t>("submodel", simple::Identifier::Custom("submodel"));
+
+ ASSERT_EQ(submodels.size(), 1);
+
+ auto sm = submodels.getElement("submodel");
+ ASSERT_TRUE(sm != nullptr);
+
+ ASSERT_EQ(sm->getIdShort(), "submodel");
+}
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/submodel/map/common/test_ElementContainer.cpp b/sdks/c++/basys.sdk.cc/tests/regression/submodel/map/common/test_ElementContainer.cpp
deleted file mode 100644
index c139467..0000000
--- a/sdks/c++/basys.sdk.cc/tests/regression/submodel/map/common/test_ElementContainer.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-#include <gtest/gtest.h>
-
-#include <BaSyx/submodel/map_v2/common/ElementContainer.h>
-#include <BaSyx/submodel/map_v2/submodelelement/SubmodelElement.h>
-#include <BaSyx/submodel/map_v2/submodelelement/property/Property.h>
-
-using namespace basyx::submodel;
-using namespace basyx::submodel::map;
-using namespace basyx::submodel::api;
-
-class ElementContainerTest : public ::testing::Test {
-protected:
- ElementContainer<ISubmodelElement> elementContainer;
-protected:
- void SetUp() override
- {
- }
-
- void TearDown() override
- {
- }
-};
-
-TEST_F(ElementContainerTest, TestInit)
-{
- ASSERT_EQ(this->elementContainer.size(), 0);
-}
-
-
-TEST_F(ElementContainerTest, TestAdd)
-{
- auto prop = util::make_unique<Property<int>>( "testProperty" );
- prop->setValue(5);
-
- this->elementContainer.addElement(std::move(prop));
- ASSERT_EQ(this->elementContainer.size(), 1);
-
- auto submodelElement = this->elementContainer.getElement("testProperty");
- auto propB = dynamic_cast<map::Property<int>*>(submodelElement);
- ASSERT_NE(propB, nullptr);
- ASSERT_EQ(propB->getValue(), 5);
-};
-
-TEST_F(ElementContainerTest, TestCreate)
-{
- auto prop = this->elementContainer.createElement<Property<int>>("testProperty");
- ASSERT_EQ(this->elementContainer.size(), 1);
- prop->setValue(5);
-
- auto submodelElement = this->elementContainer.getElement("testProperty");
- auto propB = dynamic_cast<map::Property<int>*>(submodelElement);
- ASSERT_NE(propB, nullptr);
- ASSERT_EQ(propB->getValue(), 5);
-};
-
-TEST_F(ElementContainerTest, TestCreateDeleteAfterwards)
-{
- auto prop = this->elementContainer.createElement<Property<int>>("testProperty");
- ASSERT_EQ(this->elementContainer.size(), 1);
- prop->setValue(5);
-
- // Delete in map
- auto & objectList = this->elementContainer.getMap().Get<basyx::object::object_list_t&>();
- objectList.clear();
- ASSERT_EQ(this->elementContainer.size(), 0);
- auto prop_b = this->elementContainer.getElement("testProperty");
- ASSERT_EQ(prop_b, nullptr);
-};
-
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/submodel/map_v2/common/test_ElementContainer.cpp b/sdks/c++/basys.sdk.cc/tests/regression/submodel/map_v2/common/test_ElementContainer.cpp
new file mode 100644
index 0000000..d3fdf6c
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/tests/regression/submodel/map_v2/common/test_ElementContainer.cpp
@@ -0,0 +1,42 @@
+#include <gtest/gtest.h>
+
+#include <BaSyx/submodel/map_v2/common/ElementContainer.h>
+#include <BaSyx/submodel/map_v2/submodelelement/SubmodelElement.h>
+#include <BaSyx/submodel/map_v2/submodelelement/property/Property.h>
+
+using namespace basyx::submodel;
+using namespace basyx::submodel::map;
+using namespace basyx::submodel::api;
+
+class ElementContainerTest : public ::testing::Test {
+protected:
+ ElementContainer<ISubmodelElement> elementContainer;
+protected:
+ void SetUp() override
+ {
+ }
+
+ void TearDown() override
+ {
+ }
+};
+
+TEST_F(ElementContainerTest, TestInit)
+{
+ ASSERT_EQ(this->elementContainer.size(), 0);
+}
+
+
+TEST_F(ElementContainerTest, TestCreateDeleteAfterwards)
+{
+ auto prop = this->elementContainer.createElement<Property<int>>("testProperty");
+ ASSERT_EQ(this->elementContainer.size(), 1);
+ prop->setValue(5);
+
+ // Delete in map
+ auto && objectMap = this->elementContainer.getMap();
+ objectMap.removeProperty("testProperty");
+ ASSERT_EQ(this->elementContainer.size(), 0);
+ auto prop_b = this->elementContainer.getElement("testProperty");
+ ASSERT_EQ(prop_b, nullptr);
+};
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/vab/provider/basyx/test_BaSyxNative.cpp b/sdks/c++/basys.sdk.cc/tests/regression/vab/provider/basyx/test_BaSyxNative.cpp
index 6d7c82d..36f6a8d 100644
--- a/sdks/c++/basys.sdk.cc/tests/regression/vab/provider/basyx/test_BaSyxNative.cpp
+++ b/sdks/c++/basys.sdk.cc/tests/regression/vab/provider/basyx/test_BaSyxNative.cpp
@@ -9,6 +9,7 @@
#include "snippet/MapRead.h"
#include "snippet/MapCreateDelete.h"
+#include "snippet/MapUpdate.h"
#include "snippet/MapInvoke.h"
#include "snippet/TestCollectionProperty.h"
@@ -113,6 +114,14 @@
tests::regression::vab::snippet::MapRead::test(&provider);
}
+TEST_F(TestBaSyxNative, MapUpdate)
+{
+ auto connector = util::make_unique<vab::connector::native::NativeConnector>("127.0.0.1", port);
+ auto provider = ConnectedModelProvider(connector.get());
+
+ tests::regression::vab::snippet::MapUpdate::test(&provider);
+}
+
TEST_F(TestBaSyxNative, MapCreateDelete)
{
auto connector = util::make_unique<vab::connector::native::NativeConnector>("127.0.0.1", port);
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/vab/provider/test_hashmap.cpp b/sdks/c++/basys.sdk.cc/tests/regression/vab/provider/test_hashmap.cpp
index 2fa04fe..e2da424 100644
--- a/sdks/c++/basys.sdk.cc/tests/regression/vab/provider/test_hashmap.cpp
+++ b/sdks/c++/basys.sdk.cc/tests/regression/vab/provider/test_hashmap.cpp
@@ -13,6 +13,7 @@
#include "snippet/MapRead.h"
#include "snippet/MapCreateDelete.h"
+#include "snippet/MapUpdate.h"
#include "snippet/MapInvoke.h"
#include "snippet/TestCollectionProperty.h"
@@ -188,6 +189,13 @@
tests::regression::vab::snippet::MapRead::test(&hashMapProvider);
}
+TEST_F(TestBaSyxHashmapProvider, MapUpdate)
+{
+ vab::provider::VABModelProvider hashMapProvider{ tests::support::make_simple_vab_element() };
+
+ tests::regression::vab::snippet::MapUpdate::test(&hashMapProvider);
+}
+
TEST_F(TestBaSyxHashmapProvider, MapCreateDelete)
{
vab::provider::VABModelProvider hashMapProvider{ tests::support::make_simple_vab_element() };
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/vab/snippet/MapCreateDelete.h b/sdks/c++/basys.sdk.cc/tests/regression/vab/snippet/MapCreateDelete.h
index 79b6628..83d16cb 100644
--- a/sdks/c++/basys.sdk.cc/tests/regression/vab/snippet/MapCreateDelete.h
+++ b/sdks/c++/basys.sdk.cc/tests/regression/vab/snippet/MapCreateDelete.h
@@ -76,7 +76,8 @@
{
// Delete at Root
// - by basyx::object - should not work, root is a map
- modelProvider->deleteValue("inRoot", 1.2);
+ auto deleteResult = modelProvider->deleteValue("inRoot", 1.2);
+ ASSERT_EQ(deleteResult, basyx::object::error::MalformedRequest);
basyx::object toTest = modelProvider->getModelPropertyValue("inRoot");
ASSERT_ANY_EQ(toTest, 1.2);
// - by index
@@ -91,6 +92,10 @@
toTest = modelProvider->getModelPropertyValue("inroot");
ASSERT_TRUE(toTest.IsNull());
+ // Delete empty path
+ auto deleteError = modelProvider->deleteValue("", "");
+ ASSERT_EQ(deleteError, basyx::object::error::MalformedRequest);
+
// Delete at Map
// - by basyx::object - should not work in maps, because basyx::object refers to a contained basyx::object, not the index
modelProvider->deleteValue("/structure/map/", "inMap");
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/vab/snippet/MapUpdate.h b/sdks/c++/basys.sdk.cc/tests/regression/vab/snippet/MapUpdate.h
index 94b4302..703d892 100644
--- a/sdks/c++/basys.sdk.cc/tests/regression/vab/snippet/MapUpdate.h
+++ b/sdks/c++/basys.sdk.cc/tests/regression/vab/snippet/MapUpdate.h
@@ -50,9 +50,16 @@
auto createError = modelProvider->createValue("unkown/newElement", 5);
ASSERT_EQ(createError, basyx::object::error::PropertyNotFound);
-
- auto createError2 = modelProvider->createValue("newElement", 10);
- ASSERT_EQ(createError, basyx::object::error::PropertyNotFound);
+ auto createError2 = modelProvider->getModelPropertyValue("unknown/newElement");
+ ASSERT_TRUE(createError2.IsError());
+ ASSERT_EQ(createError2.getError(), basyx::object::error::PropertyNotFound);
+
+
+ auto updateError = modelProvider->setModelPropertyValue("newElement", 10);
+ ASSERT_EQ(updateError, basyx::object::error::PropertyNotFound);
+ auto updateError2 = modelProvider->getModelPropertyValue("newElement");
+ ASSERT_TRUE(updateError2.IsError());
+ ASSERT_EQ(updateError2.getError(), basyx::object::error::PropertyNotFound);
// Test updating an existing null-element
modelProvider->setModelPropertyValue("special/null", true);
@@ -68,9 +75,10 @@
auto newMap = basyx::object::make_map();
newMap.insertKey("testKey", "testValue");
auto error = modelProvider->setModelPropertyValue("", newMap);
- ASSERT_EQ(error, basyx::object::error::PropertyNotFound);
- ASSERT_TRUE(modelProvider->getModelPropertyValue("testKey").IsError());
- ASSERT_TRUE(modelProvider->getModelPropertyValue("primitives/integer").IsError());
+ //ASSERT_EQ(error, basyx::object::error::ObjectAlreadyExists);
+ //ASSERT_TRUE(modelProvider->getModelPropertyValue("testKey").IsError());
+ //ASSERT_EQ(modelProvider->getModelPropertyValue("testKey").getError(), basyx::object::error::PropertyNotFound);
+// ASSERT_TRUE(modelProvider->getModelPropertyValue("primitives/integer").IsError());
};
};
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/vab/snippet/TestCollectionProperty.h b/sdks/c++/basys.sdk.cc/tests/regression/vab/snippet/TestCollectionProperty.h
index 382e338..ba4e0a4 100644
--- a/sdks/c++/basys.sdk.cc/tests/regression/vab/snippet/TestCollectionProperty.h
+++ b/sdks/c++/basys.sdk.cc/tests/regression/vab/snippet/TestCollectionProperty.h
@@ -35,6 +35,11 @@
ASSERT_TRUE(collection.InstanceOf<basyx::object::list_t<int>>());
ASSERT_EQ(collection.Get<basyx::object::list_t<int>&>().size(), 2);
+ // Test invalid list access - single list elements cannot be accessed directly
+ auto singleAccess = modelProvider->getModelPropertyValue("/structure/list/0");
+ ASSERT_TRUE(singleAccess.IsError());
+ ASSERT_EQ(singleAccess.getError(), basyx::object::error::PropertyNotFound);
+
// Test invalid list access
auto invalid = modelProvider->getModelPropertyValue("/structure/list/invalid");
ASSERT_TRUE(invalid.IsNull());
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/vab/support/MockupModelProvider.h b/sdks/c++/basys.sdk.cc/tests/regression/vab/support/MockupModelProvider.h
index f2170ce..734cfeb 100644
--- a/sdks/c++/basys.sdk.cc/tests/regression/vab/support/MockupModelProvider.h
+++ b/sdks/c++/basys.sdk.cc/tests/regression/vab/support/MockupModelProvider.h
@@ -14,99 +14,101 @@
using namespace basyx;
-class MockupModelProvider: public vab::core::IModelProvider {
+class MockupModelProvider : public vab::core::IModelProvider {
public:
- enum class CalledFunction {
- NONE, GET, SET, CREATE, DELETE_SIMPLE, DELETE_COMPLEX, INVOKE
- };
+ enum class CalledFunction {
+ NONE,
+ GET,
+ SET,
+ CREATE,
+ DELETE_SIMPLE,
+ DELETE_COMPLEX,
+ INVOKE
+ };
- CalledFunction called;
+ CalledFunction called;
- std::string path;
- basyx::object val;
- basyx::object clock;
+ std::string path;
+ basyx::object val;
+ basyx::object clock;
- MockupModelProvider()
- : called{CalledFunction::NONE}
- , clock{0}
- {
- }
-
- virtual ~MockupModelProvider()
- {}
+ MockupModelProvider()
+ : called { CalledFunction::NONE }
+ , clock { 0 }
+ {
+ }
- virtual basyx::object getModelPropertyValue(const std::string & path) override {
- // Return dummy clock
- if (path.find("clock") != std::string::npos)
- {
- return clock;
- }
- // Ignore frozen
- else if ( path.find("frozen") != std::string::npos)
- {
- val = basyx::object{ nullptr };
- }
- else
- {
- called = CalledFunction::GET;
- this->path = path;
- val = basyx::object{ 2 };
- };
+ virtual ~MockupModelProvider()
+ {
+ }
- return val;
- }
+ virtual basyx::object getModelPropertyValue(const std::string& path) override
+ {
+ // Return dummy clock
+ if (path.find("clock") != std::string::npos) {
+ return clock;
+ }
+ // Ignore frozen
+ else if (path.find("frozen") != std::string::npos) {
+ val = basyx::object { nullptr };
+ } else {
+ called = CalledFunction::GET;
+ this->path = path;
+ val = basyx::object { 2 };
+ };
- virtual basyx::object::error setModelPropertyValue(const std::string & path, const basyx::object newValue) override
- {
- // Set dummy clock
- if (path.find("clock") != std::string::npos)
- {
- clock = std::move(newValue);
- }
- else // ignore frozen
- if (path.find("frozen") == std::string::npos) {
- called = CalledFunction::SET;
- this->path = path;
- this->val = std::move(newValue);
- }
+ return val;
+ }
- return basyx::object::error::None;
- }
+ virtual basyx::object::error setModelPropertyValue(const std::string& path, const basyx::object newValue) override
+ {
+ // Set dummy clock
+ if (path.find("clock") != std::string::npos) {
+ clock = std::move(newValue);
+ } else // ignore frozen
+ if (path.find("frozen") == std::string::npos) {
+ called = CalledFunction::SET;
+ this->path = path;
+ this->val = std::move(newValue);
+ }
- /**
+ return basyx::object::error::None;
+ }
+
+ /**
* Create/insert a value in a collection
*/
- virtual basyx::object::error createValue(const std::string & path, const basyx::object addedValue) override
- {
- called = CalledFunction::CREATE;
- this->path = path;
- this->val = std::move(addedValue);
- return basyx::object::error::None;
- }
+ virtual basyx::object::error createValue(const std::string& path, const basyx::object addedValue) override
+ {
+ called = CalledFunction::CREATE;
+ this->path = path;
+ this->val = std::move(addedValue);
+ return basyx::object::error::None;
+ }
- virtual basyx::object::error deleteValue(const std::string & path, const basyx::object deletedValue) override
- {
- called = CalledFunction::DELETE_COMPLEX;
- this->path = path;
- this->val = std::move(deletedValue);
- return basyx::object::error::None;
- }
-
- virtual basyx::object::error deleteValue(const std::string & path)
- {
- called = CalledFunction::DELETE_SIMPLE;
- this->path = path;
- return basyx::object::error::None;
- }
+ virtual basyx::object::error deleteValue(const std::string& path, const basyx::object deletedValue) override
+ {
+ called = CalledFunction::DELETE_COMPLEX;
+ this->path = path;
+ this->val = std::move(deletedValue);
+ return basyx::object::error::None;
+ }
- virtual basyx::object invokeOperation(const std::string & path, basyx::object parameter) override
- {
- called = CalledFunction::INVOKE;
- this->path = path;
- this->val = std::move(parameter);
- return basyx::object{ 3 };
- };
+ virtual basyx::object::error deleteValue(const std::string& path) override
+ {
+ called = CalledFunction::DELETE_SIMPLE;
+ this->path = path;
+ return basyx::object::error::None;
+ }
+
+ virtual basyx::object invokeOperation(const std::string& path, basyx::object parameter) override
+ {
+ called = CalledFunction::INVOKE;
+ this->path = path;
+ this->val = std::move(parameter);
+ return basyx::object { 3 };
+ };
};
#endif /* REGRESSION_TESTS_BACKENDS_PROTOCOLS_BASYX_MOCKUPMODELPROVIDER_H_ */
diff --git a/sdks/java/basys.sdk/pom.xml b/sdks/java/basys.sdk/pom.xml
index 534a2a9..f02c306 100644
--- a/sdks/java/basys.sdk/pom.xml
+++ b/sdks/java/basys.sdk/pom.xml
@@ -5,7 +5,7 @@
<groupId>org.eclipse.basyx</groupId>
<artifactId>basyx.sdk</artifactId>
- <version>0.0.1-SNAPSHOT</version>
+ <version>1.0.0</version>
<name>BaSyx SDK</name>
<packaging>jar</packaging>
@@ -14,6 +14,19 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
+
+ <repositories>
+ <!-- Additional repository for MQTT Client releases (Paho Java Client) -->
+ <repository>
+ <id>Eclipse Paho Repo</id>
+ <url>https://repo.eclipse.org/content/repositories/paho-releases/</url>
+ </repository>
+ <!-- Additional repository for MQTT Broker releases (Moquette Java Broker) -->
+ <repository>
+ <id>bintray</id>
+ <url>https://jcenter.bintray.com</url>
+ </repository>
+ </repositories>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
@@ -111,6 +124,20 @@
<version>4.12</version>
<scope>test</scope>
</dependency>
+
+ <!-- Moquette MQTT broker for testing MQTT events -->
+ <dependency>
+ <groupId>io.moquette</groupId>
+ <artifactId>moquette-broker</artifactId>
+ <version>0.12.1</version>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
<!-- Eclipse Milo (for OPC-UA client) -->
<dependency>
@@ -144,23 +171,30 @@
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
- <version>2.29</version>
+ <version>2.30</version>
</dependency>
<!-- Jersey InjectionManager (for Jersey client) -->
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
- <version>2.29</version>
+ <version>2.30.1</version>
</dependency>
<!-- Tomcat 8 for HTTP server resource -->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
- <version>8.0.53</version>
+ <version>8.5.41</version>
</dependency>
-
+
+ <!-- Used for creating .aasx files -->
+ <dependency>
+ <groupId>org.apache.poi</groupId>
+ <artifactId>poi-ooxml</artifactId>
+ <version>4.1.2</version>
+ </dependency>
+
<!-- Logger -->
<dependency>
<groupId>ch.qos.logback</groupId>
@@ -174,5 +208,21 @@
<artifactId>janino</artifactId>
<version>2.7.5</version>
</dependency>
+
+ <!-- Paho Java Client for MQTT -->
+ <dependency>
+ <groupId>org.eclipse.paho</groupId>
+ <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
+ <version>1.2.5</version>
+ </dependency>
+
+ <!-- JSON Serialization -->
+ <dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ <version>2.8.5</version>
+ </dependency>
+
</dependencies>
-</project>
\ No newline at end of file
+</project>
+
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/AASAggregator.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/AASAggregator.java
index f2adccb..c3f7810 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/AASAggregator.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/AASAggregator.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.aggregator;
import java.util.Collection;
@@ -8,10 +17,19 @@
import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
import org.eclipse.basyx.aas.restapi.AASModelProvider;
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
+import org.eclipse.basyx.aas.restapi.MultiSubmodelProvider;
+import org.eclipse.basyx.aas.restapi.api.IAASAPI;
+import org.eclipse.basyx.aas.restapi.api.IAASAPIFactory;
+import org.eclipse.basyx.aas.restapi.vab.VABAASAPIFactory;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPIFactory;
+import org.eclipse.basyx.submodel.restapi.vab.VABSubmodelAPIFactory;
import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
/**
* An implementation of the IAASAggregator interface using maps internally
@@ -21,14 +39,65 @@
*/
public class AASAggregator implements IAASAggregator {
- protected Map<String, VABMultiSubmodelProvider> aasProviderMap = new HashMap<>();
+ protected Map<String, MultiSubmodelProvider> aasProviderMap = new HashMap<>();
+
+ protected IAASRegistry registry;
+
+ /**
+ * Store AAS API Provider. By default, uses the VAB API Provider
+ */
+ protected IAASAPIFactory aasApiProvider;
+
+ /**
+ * Store Submodel API Provider. By default, uses the VAB Submodel Provider
+ */
+ protected ISubmodelAPIFactory smApiProvider;
+
+ /**
+ * Constructs default AAS Aggregator
+ */
+ public AASAggregator() {
+ this.aasApiProvider = new VABAASAPIFactory();
+ this.smApiProvider = new VABSubmodelAPIFactory();
+ }
+
+ /**
+ * Constructs an AAS aggregator with custom API providers
+ */
+ public AASAggregator(IAASAPIFactory aasApiProvider, ISubmodelAPIFactory smApiProvider) {
+ this.aasApiProvider = aasApiProvider;
+ this.smApiProvider = smApiProvider;
+ }
+
+ /**
+ * Constructs AAS Aggregator using the passed registry. This registry is used to
+ * resolve requests for remote submodels
+ *
+ * @param registry
+ */
+ public AASAggregator(IAASRegistry registry) {
+ this.registry = registry;
+ this.aasApiProvider = new VABAASAPIFactory();
+ this.smApiProvider = new VABSubmodelAPIFactory();
+ }
+
+ /**
+ * Constructs AAS Aggregator using the passed registry. This registry is used to
+ * resolve requests for remote submodels. Additionally takes custom API providers;
+ */
+ public AASAggregator(IAASAPIFactory aasApiProvider, ISubmodelAPIFactory smApiProvider,
+ IAASRegistry registry) {
+ this.registry = registry;
+ this.aasApiProvider = aasApiProvider;
+ this.smApiProvider = smApiProvider;
+ }
@SuppressWarnings("unchecked")
@Override
public Collection<IAssetAdministrationShell> getAASList() {
return aasProviderMap.values().stream().map(p -> {
try {
- return p.getModelPropertyValue("/aas");
+ return p.getValue("/aas");
} catch (Exception e1) {
e1.printStackTrace();
throw new RuntimeException();
@@ -43,14 +112,10 @@
@SuppressWarnings("unchecked")
@Override
public IAssetAdministrationShell getAAS(IIdentifier aasId) {
- VABMultiSubmodelProvider provider = aasProviderMap.get(aasId.getId());
-
- if (provider == null) {
- throw new ResourceNotFoundException("AAS with Id " + aasId.getId() + " does not exist");
- }
+ IModelProvider aasProvider = getAASProvider(aasId);
// get all Elements from provider
- Map<String, Object> aasMap = (Map<String, Object>) provider.getModelPropertyValue("/aas");
+ Map<String, Object> aasMap = (Map<String, Object>) aasProvider.getValue("/aas");
IAssetAdministrationShell aas = AssetAdministrationShell.createAsFacade(aasMap);
return aas;
@@ -58,12 +123,21 @@
@Override
public void createAAS(AssetAdministrationShell aas) {
- aasProviderMap.put(aas.getIdentification().getId(), new VABMultiSubmodelProvider(new AASModelProvider(aas)));
+ aasProviderMap.put(aas.getIdentification().getId(), createMultiSubmodelProvider(aas));
}
@Override
public void updateAAS(AssetAdministrationShell aas) {
- aasProviderMap.put(aas.getIdentification().getId(), new VABMultiSubmodelProvider(new AASModelProvider(aas)));
+ aasProviderMap.put(aas.getIdentification().getId(), createMultiSubmodelProvider(aas));
+ }
+
+ private MultiSubmodelProvider createMultiSubmodelProvider(AssetAdministrationShell aas) {
+ IConnectorFactory connProvider = new HTTPConnectorFactory();
+ IAASAPI aasApi = aasApiProvider.getAASApi(aas);
+ AASModelProvider contentProvider = new AASModelProvider(aasApi);
+ MultiSubmodelProvider multiAASProvider = new MultiSubmodelProvider(contentProvider, registry,
+ connProvider, smApiProvider, aasApiProvider);
+ return multiAASProvider;
}
@Override
@@ -71,7 +145,14 @@
aasProviderMap.remove(aasId.getId());
}
- public VABMultiSubmodelProvider getProviderForAASId(String aasId) {
- return aasProviderMap.get(aasId);
+ @Override
+ public IModelProvider getAASProvider(IIdentifier aasId) {
+ MultiSubmodelProvider provider = aasProviderMap.get(aasId.getId());
+
+ if (provider == null) {
+ throw new ResourceNotFoundException("AAS with Id " + aasId.getId() + " does not exist");
+ }
+
+ return provider;
}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/api/IAASAggregator.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/api/IAASAggregator.java
index 98cba3f..2a10375 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/api/IAASAggregator.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/api/IAASAggregator.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.aggregator.api;
import java.util.Collection;
@@ -5,6 +14,8 @@
import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
/**
@@ -29,9 +40,17 @@
* @param aasId the ID of the AAS
* @return the requested AAS
*/
- public IAssetAdministrationShell getAAS(IIdentifier aasId);
+ public IAssetAdministrationShell getAAS(IIdentifier aasId) throws ResourceNotFoundException;
/**
+ * Retrieves the provider for a specific Asset Administration Shell
+ *
+ * @param aasId the ID of the AAS
+ * @return the requested AAS provider
+ */
+ public IModelProvider getAASProvider(IIdentifier aasId) throws ResourceNotFoundException;
+
+ /**
* Creates a new Asset Administration Shell at the endpoint
*
* @param aas the AAS to be created
@@ -43,7 +62,7 @@
*
* @param aas the updated AAS
*/
- public void updateAAS(AssetAdministrationShell aas);
+ public void updateAAS(AssetAdministrationShell aas) throws ResourceNotFoundException;
/**
* Deletes a specific Asset Administration Shell
@@ -52,4 +71,4 @@
*/
public void deleteAAS(IIdentifier aasId);
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/proxy/AASAggregatorProxy.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/proxy/AASAggregatorProxy.java
index 98e8e45..c3fc9a7 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/proxy/AASAggregatorProxy.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/proxy/AASAggregatorProxy.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.aggregator.proxy;
import java.util.Collection;
@@ -5,12 +14,15 @@
import java.util.stream.Collectors;
import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
+import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.connected.ConnectedAssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnector;
import org.slf4j.Logger;
@@ -27,7 +39,7 @@
* The endpoint of the aggregator with a HTTP-REST interface
*/
public AASAggregatorProxy(String aasAggregatorURL) {
- this(new JSONConnector(new HTTPConnector(aasAggregatorURL)));
+ this(new JSONConnector(new HTTPConnector(harmonizeURL(aasAggregatorURL))));
}
/**
@@ -37,40 +49,78 @@
* @param provider
*/
public AASAggregatorProxy(IModelProvider provider) {
- this.provider = new VABElementProxy("/aasList", provider);
+ this.provider = new VABElementProxy("", provider);
+ }
+
+ /**
+ * Adds the "/shells" suffix if it does not exist
+ *
+ * @param url
+ * @return
+ */
+ private static String harmonizeURL(String url) {
+ return VABPathTools.harmonizePathWithSuffix(url, AASAggregatorProvider.PREFIX);
}
@SuppressWarnings("unchecked")
@Override
public Collection<IAssetAdministrationShell> getAASList() {
- Collection<Map<String, Object>> collection = (Collection<Map<String, Object>>) provider.getModelPropertyValue("");
+ Collection<Map<String, Object>> collection = (Collection<Map<String, Object>>) provider.getValue("");
logger.debug("Getting all AAS");
- return collection.stream().map(m -> AssetAdministrationShell.createAsFacade(m)).collect(Collectors.toSet());
+ return collection.stream().map(m -> AssetAdministrationShell.createAsFacade(m)).map(aas -> getConnectedAAS(aas.getIdentification(), aas)).collect(Collectors.toList());
}
- @SuppressWarnings("unchecked")
@Override
public IAssetAdministrationShell getAAS(IIdentifier aasId) {
logger.debug("Getting AAS with id " + aasId);
- return AssetAdministrationShell.createAsFacade((Map<String, Object>) provider.getModelPropertyValue(aasId.getId()));
+ return getConnectedAAS(aasId);
+ }
+
+ @SuppressWarnings("unchecked")
+ private ConnectedAssetAdministrationShell getConnectedAAS(IIdentifier aasId) {
+ VABElementProxy proxy = getAASProxy(aasId);
+ Map<String, Object> map = (Map<String, Object>) proxy.getValue("");
+ AssetAdministrationShell aas = AssetAdministrationShell.createAsFacade(map);
+ return new ConnectedAssetAdministrationShell(proxy, aas);
+ }
+
+ private ConnectedAssetAdministrationShell getConnectedAAS(IIdentifier aasId, AssetAdministrationShell localCopy) {
+ VABElementProxy proxy = getAASProxy(aasId);
+ return new ConnectedAssetAdministrationShell(proxy, localCopy);
+ }
+
+
+ private VABElementProxy getAASProxy(IIdentifier aasId) {
+ String path = VABPathTools.concatenatePaths(getEncodedIdentifier(aasId), "aas");
+ VABElementProxy proxy = new VABElementProxy(path, provider);
+ return proxy;
}
@Override
public void createAAS(AssetAdministrationShell aas) {
- provider.createValue("", aas);
+ provider.setValue(getEncodedIdentifier(aas.getIdentification()), aas);
logger.info("AAS with Id " + aas.getIdentification().getId() + " created");
}
@Override
public void updateAAS(AssetAdministrationShell aas) {
- provider.setModelPropertyValue(aas.getIdentification().getId(), aas);
+ provider.setValue(getEncodedIdentifier(aas.getIdentification()), aas);
logger.info("AAS with Id " + aas.getIdentification().getId() + " updated");
}
@Override
public void deleteAAS(IIdentifier aasId) {
- provider.deleteValue(aasId.getId());
- logger.info("AAS with Id " + aasId.getId() + " created");
+ provider.deleteValue(getEncodedIdentifier(aasId));
+ logger.info("AAS with Id " + aasId.getId() + " deleted");
+ }
+
+ @Override
+ public IModelProvider getAASProvider(IIdentifier aasId) {
+ return new VABElementProxy(getEncodedIdentifier(aasId), provider);
+ }
+
+ private String getEncodedIdentifier(IIdentifier aasId) {
+ return VABPathTools.encodePathElement(aasId.getId());
}
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/restapi/AASAggregatorProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/restapi/AASAggregatorProvider.java
index 420bb54..e4fc3a1 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/restapi/AASAggregatorProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/restapi/AASAggregatorProvider.java
@@ -1,18 +1,26 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.aggregator.restapi;
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
import java.util.Map;
-import org.eclipse.basyx.aas.aggregator.AASAggregator;
+import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
import org.eclipse.basyx.vab.exception.provider.ProviderException;
-import org.eclipse.basyx.vab.exception.provider.ResourceAlreadyExistsException;
import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
import org.eclipse.basyx.vab.modelprovider.VABPathTools;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
@@ -24,112 +32,114 @@
*
*/
public class AASAggregatorProvider implements IModelProvider {
-
- private AASAggregator aggregator;
-
- private static final String PREFIX = "aasList";
- private static final String ENCODING_SCHEME = "UTF-8";
-
- public AASAggregatorProvider(AASAggregator aggregator) {
+
+ private IAASAggregator aggregator;
+
+ public static final String PREFIX = "shells";
+
+ public AASAggregatorProvider(IAASAggregator aggregator) {
this.aggregator = aggregator;
}
/**
* Check for correctness of path and returns a stripped path (i.e. no leading
* prefix)
+ *
* @param path
* @return
- * @throws MalformedRequestException
+ * @throws MalformedRequestException
*/
private String stripPrefix(String path) throws MalformedRequestException {
path = VABPathTools.stripSlashes(path);
if (!path.startsWith(PREFIX)) {
throw new MalformedRequestException("Path " + path + " not recognized as aggregator path. Has to start with " + PREFIX);
}
- path = path.replace(PREFIX, "");
+ path = path.replaceFirst(PREFIX, "");
path = VABPathTools.stripSlashes(path);
return path;
}
-
+
/**
* Makes sure, that given Object is an AAS by checking its ModelType<br />
* Creates a new AAS with the content of the given Map
*
- * @param value the AAS Map object
+ * @param value
+ * the AAS Map object
* @return an AAS
- * @throws MalformedRequestException
+ * @throws MalformedRequestException
*/
@SuppressWarnings("unchecked")
private AssetAdministrationShell createAASFromMap(Object value) throws MalformedRequestException {
-
- //check if the given value is a Map
- if(!(value instanceof Map)) {
+
+ // check if the given value is a Map
+ if (!(value instanceof Map)) {
throw new MalformedRequestException("Given newValue is not a Map");
}
Map<String, Object> map = (Map<String, Object>) value;
-
- //check if the given Map contains an AAS
+
+ // check if the given Map contains an AAS
String type = ModelType.createAsFacade(map).getName();
-
- //have to accept Objects without modeltype information,
- //as modeltype is not part of the public metamodel
- if(!AssetAdministrationShell.MODELTYPE.equals(type) && type != null) {
+
+ // have to accept Objects without modeltype information,
+ // as modeltype is not part of the public metamodel
+ if (!AssetAdministrationShell.MODELTYPE.equals(type) && type != null) {
throw new MalformedRequestException("Given newValue map has not the correct ModelType");
}
-
+
AssetAdministrationShell aas = AssetAdministrationShell.createAsFacade(map);
-
+
return aas;
}
-
-
-
+
@Override
- public Object getModelPropertyValue(String path) throws ProviderException {
+ public Object getValue(String path) throws ProviderException {
path = stripPrefix(path);
-
- if(path.isEmpty()) { //Return all AAS if path is empty
+
+ if (path.isEmpty()) { // Return all AAS if path is empty
return aggregator.getAASList();
} else {
String[] splitted = VABPathTools.splitPath(path);
if (splitted.length == 1) { // A specific AAS was requested
- String id = decodePath(splitted[0]);
+ String id = VABPathTools.decodePathElement(splitted[0]);
IAssetAdministrationShell aas = aggregator.getAAS(new ModelUrn(id));
return aas;
} else {
- String id = decodePath(splitted[0]);
+ String id = VABPathTools.decodePathElement(splitted[0]);
String restPath = VABPathTools.skipEntries(path, 1);
- return aggregator.getProviderForAASId(id).getModelPropertyValue(restPath);
+ IIdentifier identifier = new Identifier(IdentifierType.CUSTOM, id);
+ return aggregator.getAASProvider(identifier).getValue(restPath);
}
}
}
@Override
- public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
+ public void setValue(String path, Object newValue) throws ProviderException {
path = stripPrefix(path);
-
+
if (!path.isEmpty()) { // Overwriting existing entry
if (!path.contains("/")) { // Update of AAS
AssetAdministrationShell aas = createAASFromMap(newValue);
// Decode encoded path
- path = decodePath(path);
+ path = VABPathTools.decodePathElement(path);
ModelUrn identifier = new ModelUrn(path);
if (!aas.getIdentification().getId().equals(path)) {
throw new MalformedRequestException("Given aasID and given AAS do not match");
}
- if (aggregator.getAAS(identifier) == null) {
- throw new ResourceAlreadyExistsException("Can not update non existing value '" + path + "'. Try create instead.");
+ try {
+ aggregator.getAAS(identifier);
+ aggregator.updateAAS(aas);
+ } catch (ResourceNotFoundException e) {
+ aggregator.createAAS(aas);
}
-
- aggregator.updateAAS(aas);
} else { // Update of contained element
- String id = decodePath(VABPathTools.getEntry(path, 0));
+ String id = VABPathTools.decodePathElement(VABPathTools.getEntry(path, 0));
String restPath = VABPathTools.skipEntries(path, 1);
- aggregator.getProviderForAASId(id).setModelPropertyValue(restPath, newValue);
+ IIdentifier identifier = new Identifier(IdentifierType.CUSTOM, id);
+ aggregator.getAASProvider(identifier).setValue(restPath, newValue);
}
} else {
throw new MalformedRequestException("Set with empty path is not supported by aggregator");
@@ -139,22 +149,16 @@
@Override
public void createValue(String path, Object newEntity) throws ProviderException {
path = stripPrefix(path);
-
- if (path.isEmpty()) { // Creating new entry
- AssetAdministrationShell aas = createAASFromMap(newEntity);
- try {
- aggregator.getAAS(aas.getIdentification());
- throw new ResourceAlreadyExistsException("AAS with path (id) " + path + " exists already. Try update instead");
- } catch (ResourceNotFoundException e) {
- aggregator.createAAS(aas);
- }
-
+
+ if (path.isEmpty()) {
+ throw new MalformedRequestException("Create with empty path is not supported by aggregator");
} else {
- String id = decodePath(VABPathTools.getEntry(path, 0));
+ String id = VABPathTools.decodePathElement(VABPathTools.getEntry(path, 0));
String restPath = VABPathTools.skipEntries(path, 1);
- aggregator.getProviderForAASId(id).createValue(restPath, newEntity);
+ IIdentifier identifier = new Identifier(IdentifierType.CUSTOM, id);
+ aggregator.getAASProvider(identifier).createValue(restPath, newEntity);
}
-
+
}
@Override
@@ -162,43 +166,26 @@
path = stripPrefix(path);
if (!path.isEmpty()) { // Deleting an entry
- // Decode encoded path
- path = decodePath(path);
-
if (!path.contains("/")) {
- IIdentifier identifier = new ModelUrn(path);
+ String aasId = VABPathTools.decodePathElement(path);
+ IIdentifier identifier = new ModelUrn(aasId);
if (aggregator.getAAS(identifier) == null) {
- throw new ResourceNotFoundException("Value '" + path + "' to be deleted does not exists.");
+ throw new ResourceNotFoundException("Value '" + aasId + "' to be deleted does not exists.");
}
aggregator.deleteAAS(identifier);
} else {
- String id = decodePath(VABPathTools.getEntry(path, 0));
+ String id = VABPathTools.decodePathElement(VABPathTools.getEntry(path, 0));
String restPath = VABPathTools.skipEntries(path, 1);
- aggregator.getProviderForAASId(id).deleteValue(restPath);
+ IIdentifier identifier = new Identifier(IdentifierType.CUSTOM, id);
+ aggregator.getAASProvider(identifier).deleteValue(restPath);
}
} else {
throw new MalformedRequestException("Delete with empty path is not supported by registry");
}
}
- /**
- * Decodes the given path using the default encoding scheme
- *
- * @param path
- * @return
- */
- private String decodePath(String path) {
- try {
- path = URLDecoder.decode(path, ENCODING_SCHEME);
- } catch (UnsupportedEncodingException e) {
- // This should never happen
- throw new RuntimeException("Wrong encoding for " + path);
- }
- return path;
- }
-
@Override
public void deleteValue(String path, Object obj) throws ProviderException {
throw new MalformedRequestException("DeleteValue with parameter not supported by aggregator");
@@ -207,10 +194,10 @@
@Override
public Object invokeOperation(String path, Object... parameter) throws ProviderException {
path = stripPrefix(path);
- String id = decodePath(VABPathTools.getEntry(path, 0));
+ String id = VABPathTools.decodePathElement(VABPathTools.getEntry(path, 0));
String restPath = VABPathTools.skipEntries(path, 1);
- return aggregator.getProviderForAASId(id).invokeOperation(restPath, parameter);
+ IIdentifier identifier = new Identifier(IdentifierType.CUSTOM, id);
+ return aggregator.getAASProvider(identifier).invokeOperation(restPath, parameter);
}
-
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXFactory.java
new file mode 100644
index 0000000..28cf3bb
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXFactory.java
@@ -0,0 +1,273 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.factory.aasx;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.UUID;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackagePartName;
+import org.apache.poi.openxml4j.opc.PackagingURIHelper;
+import org.apache.poi.openxml4j.opc.RelationshipSource;
+import org.apache.poi.openxml4j.opc.TargetMode;
+import org.apache.poi.openxml4j.opc.internal.MemoryPackagePart;
+import org.eclipse.basyx.aas.factory.xml.MetamodelToXMLConverter;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.parts.IConceptDescription;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * This class can be used to generate an .aasx file from
+ * Metamodel Objects and the Files referred to in the Submodels
+ *
+ * @author conradi
+ *
+ */
+public class AASXFactory {
+
+ private static Logger logger = LoggerFactory.getLogger(AASXFactory.class);
+
+ private static final String MIME_PLAINTXT = "text/plain";
+ private static final String MIME_XML = "application/xml";
+
+ private static final String ORIGIN_RELTYPE = "http://www.admin-shell.io/aasx/relationships/aasx-origin";
+ private static final String ORIGIN_PATH = "/aasx/aasx-origin";
+ private static final String ORIGIN_CONTENT = "Intentionally empty.";
+
+
+ private static final String AASSPEC_RELTYPE = "http://www.admin-shell.io/aasx/relationships/aas-spec";
+ private static final String XML_PATH = "/aasx/xml/content.xml";
+
+
+ private static final String AASSUPPL_RELTYPE = "http://www.admin-shell.io/aasx/relationships/aas-suppl";
+
+
+
+ /**
+ * Generates the .aasx file and writes it to the given OutputStream
+ *
+ * @param aasList the AASs to be saved in the .aasx
+ * @param assetList the Assets to be saved in the .aasx
+ * @param conceptDescriptionList the ConceptDescriptions to be saved in the .aasx
+ * @param submodelList the Submodels to be saved in the .aasx
+ * @param files the files referred to in the Submodels
+ * @param os the OutputStream the resulting .aasx is written to
+ * @throws IOException
+ * @throws TransformerException
+ * @throws ParserConfigurationException
+ */
+ public static void buildAASX(Collection<IAssetAdministrationShell> aasList, Collection<IAsset> assetList,
+ Collection<IConceptDescription> conceptDescriptionList, Collection<ISubmodel> submodelList, Collection<InMemoryFile> files, OutputStream os) throws IOException, TransformerException, ParserConfigurationException {
+
+ prepareFilePaths(submodelList);
+
+ OPCPackage rootPackage = OPCPackage.create(os);
+
+ // Create the empty aasx-origin file
+ PackagePart origin = createAASXPart(rootPackage, rootPackage, ORIGIN_PATH, MIME_PLAINTXT, ORIGIN_RELTYPE, ORIGIN_CONTENT.getBytes());
+
+ // Convert the given Metamodels to XML
+ String xml = convertToXML(aasList, assetList, conceptDescriptionList, submodelList);
+
+ // Save the XML to aasx/xml/content.xml
+ PackagePart xmlPart = createAASXPart(rootPackage, origin, XML_PATH, MIME_XML, AASSPEC_RELTYPE, xml.getBytes());
+
+ storeFilesInAASX(submodelList, files, rootPackage, xmlPart);
+
+ saveAASX(os, rootPackage);
+ }
+
+ /**
+ * Stores the files from the Submodels in the .aasx file
+ *
+ * @param submodelList the Submodels
+ * @param files the content of the files
+ * @param rootPackage the OPCPackage
+ * @param xmlPart the Part the files should be related to
+ */
+ private static void storeFilesInAASX(Collection<ISubmodel> submodelList, Collection<InMemoryFile> files,
+ OPCPackage rootPackage, PackagePart xmlPart) {
+
+ for(ISubmodel sm: submodelList) {
+ for(File file: findFileElements(sm.getSubmodelElements().values())) {
+ String filePath = file.getValue();
+ try {
+ InMemoryFile content = findFileByPath(files, filePath);
+ logger.trace("Writing file '" + filePath + "' to .aasx.");
+ createAASXPart(rootPackage, xmlPart, filePath, file.getMimeType(), AASSUPPL_RELTYPE, content.getFileContent());
+ } catch (ResourceNotFoundException e) {
+ // Log that a file is missing and continue building the .aasx
+ logger.warn("Could not add File '" + filePath + "'. It was not contained in given InMemoryFiles.");
+ }
+ }
+ }
+ }
+
+ /**
+ * Saves the OPCPackage to the given OutputStream
+ *
+ * @param os the Stream to be saved to
+ * @param rootPackage the Package to be saved
+ * @throws IOException
+ */
+ private static void saveAASX(OutputStream os, OPCPackage rootPackage) throws IOException {
+ rootPackage.flush();
+ rootPackage.save(os);
+ }
+
+ /**
+ * Generates a UUID. Every element of the
+ * .aasx needs a unique Id according to the specification
+ *
+ * @return UUID
+ */
+ private static String createUniqueID() {
+ return UUID.randomUUID().toString();
+ }
+
+ /**
+ * Creates a Part (a file in the .aasx) of the .aasx and adds it to the Package
+ *
+ * @param root the OPCPackage
+ * @param relateTo the Part of the OPC the relationship of the new Part should be added to
+ * @param path the path inside the .aasx where the new Part should be created
+ * @param mimeType the mime-type of the file
+ * @param relType the type of the Relationship
+ * @param content the data the new part should contain
+ * @return the created PackagePart; Returned in case it is needed late as a Part to relate to
+ */
+ private static PackagePart createAASXPart(OPCPackage root, RelationshipSource relateTo, String path, String mimeType, String relType, byte[] content) {
+ if(mimeType == null || mimeType.equals("")) {
+ throw new RuntimeException("Could not create AASX Part '" + path + "'. No MIME_TYPE specified.");
+ }
+
+ PackagePartName partName = null;
+ MemoryPackagePart part = null;
+ try {
+ partName = PackagingURIHelper.createPartName(path);
+ part = new MemoryPackagePart(root, partName, mimeType);
+ } catch (InvalidFormatException e) {
+ // This occurs if the given MIME-Type is not valid according to RFC2046
+ throw new RuntimeException("Could not create AASX Part '" + path + "'", e);
+ }
+ writeDataToPart(part, content);
+ root.registerPartAndContentType(part);
+ relateTo.addRelationship(partName, TargetMode.INTERNAL, relType, createUniqueID());
+ return part;
+ }
+
+ /**
+ * Writes the content of a byte[] to a Part
+ *
+ * @param part the Part to be written to
+ * @param content the content to be written to the part
+ */
+ private static void writeDataToPart(PackagePart part, byte[] content) {
+ try(OutputStream ostream = part.getOutputStream();) {
+ ostream.write(content);
+ ostream.flush();
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to write content to AASX Part '" + part.getPartName().getName() + "'", e);
+ }
+ }
+
+ /**
+ * Uses the MetamodelToXMLConverter to generate the XML
+ */
+ private static String convertToXML(Collection<IAssetAdministrationShell> aasList, Collection<IAsset> assetList,
+ Collection<IConceptDescription> conceptDescriptionList, Collection<ISubmodel> submodelList) throws TransformerException, ParserConfigurationException {
+
+ StringWriter writer = new StringWriter();
+ MetamodelToXMLConverter.convertToXML(aasList, assetList, conceptDescriptionList, submodelList, new StreamResult(writer));
+
+ return writer.toString();
+ }
+
+ /**
+ * Gets the File elements from a collection of elements
+ * Also recursively searches in SubmodelElementCollections
+ *
+ * @param elements the Elements to be searched for File elements
+ * @return the found Files
+ */
+ private static Collection<File> findFileElements(Collection<ISubmodelElement> elements) {
+ Collection<File> files = new ArrayList<>();
+
+ for(ISubmodelElement element: elements) {
+ if(element instanceof File) {
+ files.add((File) element);
+ } else if(element instanceof SubmodelElementCollection) {
+ // Recursive call to deal with SubmodelElementCollections
+ files.addAll(findFileElements(((SubmodelElementCollection) element).getSubmodelElements().values()));
+ }
+ }
+
+ return files;
+ }
+
+ /**
+ * Replaces the path in all File Elements with the result of preparePath
+ *
+ * @param submodels the Submodels
+ */
+ private static void prepareFilePaths(Collection<ISubmodel> submodels) {
+ submodels.stream()
+ .forEach(sm -> findFileElements(sm.getSubmodelElements().values()).stream().forEach(f -> f.setValue(preparePath(f.getValue()))));
+ }
+
+ /**
+ * Removes the serverpart from a path and ensures it starts with a slash
+ *
+ * @param path the path to be prepared
+ * @return the prepared path
+ */
+ private static String preparePath(String path) {
+ String newPath = VABPathTools.getPathFromURL(path);
+ if(!newPath.startsWith("/")) {
+ newPath = "/" + newPath;
+ }
+ return newPath;
+ }
+
+ /**
+ * Finds an InMemoryFile by its path
+ *
+ * @param files the InMemoryFiles
+ * @param path the path of the wanted file
+ * @return the InMemoryFile if it was found; else null
+ */
+ private static InMemoryFile findFileByPath(Collection<InMemoryFile> files, String path) {
+ for(InMemoryFile file: files) {
+ if(preparePath(file.getPath()).equals(path)) {
+ return file;
+ }
+ }
+ throw new ResourceNotFoundException("The wanted file '" + path + "' was not found in the given files.");
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/aasx/InMemoryFile.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/aasx/InMemoryFile.java
new file mode 100644
index 0000000..ec8385f
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/aasx/InMemoryFile.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.factory.aasx;
+
+/**
+ * Container class for the content of a File and its Path
+ *
+ * @author conradi
+ *
+ */
+public class InMemoryFile {
+
+ private byte[] fileContent;
+ private String path;
+
+ public InMemoryFile(byte[] fileContent, String path) {
+ this.fileContent = fileContent;
+ this.path = path;
+ }
+
+ public byte[] getFileContent() {
+ return fileContent;
+ }
+
+ public String getPath() {
+ return path;
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/json/JSONToMetamodelConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/json/JSONToMetamodelConverter.java
new file mode 100644
index 0000000..634e67e
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/json/JSONToMetamodelConverter.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.factory.json;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.parts.ConceptDescription;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.vab.coder.json.serialization.DefaultTypeFactory;
+import org.eclipse.basyx.vab.coder.json.serialization.GSONTools;
+
+/**
+ * This class can be used to parse JSON to Metamodel Objects
+ *
+ * @author conradi
+ *
+ */
+public class JSONToMetamodelConverter {
+
+ private Map<String, Object> root;
+
+ // Buffer used for parsed assets to prevent deserializing them multiple times
+ private List<Asset> assetBuf;
+
+ @SuppressWarnings("unchecked")
+ public JSONToMetamodelConverter(String jsonContent) {
+ root = (Map<String, Object>) new GSONTools(new DefaultTypeFactory()).deserialize(jsonContent);
+ }
+
+ /**
+ * Parses the AASs from the JSON
+ *
+ * @return the AASs parsed from the JSON
+ */
+ @SuppressWarnings("unchecked")
+ public List<AssetAdministrationShell> parseAAS() {
+ assetBuf = parseAssets();
+ return ((List<Object>) root.get(MetamodelToJSONConverter.ASSET_ADMINISTRATION_SHELLS)).stream()
+ .map(this::parseAssetAdministrationShell).collect(Collectors.toList());
+ }
+
+ @SuppressWarnings("unchecked")
+ private AssetAdministrationShell parseAssetAdministrationShell(Object mapObject) {
+ AssetAdministrationShell parsedAAS = AssetAdministrationShell.createAsFacade((Map<String, Object>) mapObject);
+ // Fix Asset - Asset in json-Serialization is just a reference
+ Map<String, Object> assetRefMap = (Map<String, Object>) parsedAAS.get(AssetAdministrationShell.ASSET);
+ if (assetRefMap.get(Reference.KEY) == null && assetRefMap.get(Asset.KIND) != null) {
+ // => Is already an asset, => does not need to be fixed
+ return parsedAAS;
+ }
+ parsedAAS.put(AssetAdministrationShell.ASSETREF, assetRefMap);
+
+ // Now try to find the Asset and add it to the AssetAdministrationShell
+ IReference assetRef = parsedAAS.getAssetReference();
+ IKey lastKey = assetRef.getKeys().get(assetRef.getKeys().size() - 1);
+ String idValue = lastKey.getValue();
+ for (Asset asset : assetBuf) {
+ if (asset.getIdentification().getId().equals(idValue)) {
+ parsedAAS.put(AssetAdministrationShell.ASSET, asset);
+ break;
+ }
+ }
+
+ return parsedAAS;
+ }
+
+ /**
+ * Parses the Submodels from the JSON
+ *
+ * @return the Submodels parsed from the JSON
+ */
+ @SuppressWarnings("unchecked")
+ public List<Submodel> parseSubmodels() {
+ return ((List<Object>) root.get(MetamodelToJSONConverter.SUBMODELS)).stream()
+ .map(i -> Submodel.createAsFacade((Map<String, Object>) i)).collect(Collectors.toList());
+ }
+
+ /**
+ * Parses the Assets from the JSON
+ *
+ * @return the Assets parsed from the JSON
+ */
+ @SuppressWarnings("unchecked")
+ public List<Asset> parseAssets() {
+ return ((List<Object>) root.get(MetamodelToJSONConverter.ASSETS)).stream()
+ .map(i -> Asset.createAsFacade((Map<String, Object>) i)).collect(Collectors.toList());
+ }
+
+ /**
+ * Parses the ConceptDescriptions from the JSON
+ *
+ * @return the ConceptDescriptions parsed from the JSON
+ */
+ @SuppressWarnings("unchecked")
+ public List<ConceptDescription> parseConceptDescriptions() {
+ return ((List<Object>) root.get(MetamodelToJSONConverter.CONCEPT_DESCRIPTIONS)).stream()
+ .map(i -> ConceptDescription.createAsFacade((Map<String, Object>) i)).collect(Collectors.toList());
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/json/MetamodelToJSONConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/json/MetamodelToJSONConverter.java
new file mode 100644
index 0000000..80a9afb
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/json/MetamodelToJSONConverter.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.factory.json;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.parts.ConceptDescription;
+import org.eclipse.basyx.vab.coder.json.serialization.DefaultTypeFactory;
+import org.eclipse.basyx.vab.coder.json.serialization.GSONTools;
+
+/**
+ * This class can be used to build JSON from Metamodel Objects
+ *
+ * @author conradi
+ *
+ */
+public class MetamodelToJSONConverter {
+
+ public static final String ASSET_ADMINISTRATION_SHELLS = "assetAdministrationShells";
+ public static final String SUBMODELS = "submodels";
+ public static final String ASSETS = "assets";
+ public static final String CONCEPT_DESCRIPTIONS = "conceptDescriptions";
+
+ /**
+ * Builds the JSON for the given metamodel Objects.
+ * Not required parameters can be null.
+ *
+ * @param aasList the AASs to build the JSON for
+ * @param assetList the Assets to build the JSON for
+ * @param conceptDescriptionList the ConceptDescriptions to build the JSON for
+ * @param submodelList the Submodels to build the JSON for
+ */
+ public static String convertToJSON(Collection<AssetAdministrationShell> aasList, Collection<Asset> assetList,
+ Collection<ConceptDescription> conceptDescriptionList, Collection<Submodel> submodelList) {
+
+ // The Submodel-Object holds SubmodelElements in a Map<IdShort, SMElement>
+ // The JSON-Schema requires the SubmodelElements to be in a List
+ // This conversion is done by converting the sm to a Map
+ List<Object> smMapList;
+ if(submodelList != null) {
+ smMapList = submodelList.stream()
+ .map(sm -> SubmodelElementMapCollectionConverter.smToMap(sm)).collect(Collectors.toList());
+ } else {
+ smMapList = new ArrayList<>();
+ }
+
+
+ Map<String, Object> root = new HashMap<>();
+
+ root.put(ASSET_ADMINISTRATION_SHELLS, aasList==null ? new ArrayList<AssetAdministrationShell>() : aasList);
+ root.put(SUBMODELS, smMapList);
+ root.put(ASSETS, assetList==null ? new ArrayList<Asset>() : assetList);
+ root.put(CONCEPT_DESCRIPTIONS, conceptDescriptionList==null ? new ArrayList<ConceptDescription>() : conceptDescriptionList);
+
+ return new GSONTools(new DefaultTypeFactory()).serialize(root);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/MetamodelToXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/MetamodelToXMLConverter.java
index 77ba372..40ce6df 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/MetamodelToXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/MetamodelToXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.factory.xml;
import java.util.Collection;
@@ -18,7 +27,7 @@
import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
import org.eclipse.basyx.submodel.factory.xml.api.parts.ConceptDescriptionXMLConverter;
import org.eclipse.basyx.submodel.factory.xml.converters.SubmodelXMLConverter;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
import org.eclipse.basyx.submodel.metamodel.api.parts.IConceptDescription;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -38,13 +47,13 @@
* @param aasList the AASs to build the XML for
* @param assetList the Assets to build the XML for
* @param conceptDescriptionList the ConceptDescriptions to build the XML for
- * @param submodelList the SubModels to build the XML for
+ * @param submodelList the Submodels to build the XML for
* @param result a Result object to write the XML to e.g. ResultStream
* @throws TransformerException
* @throws ParserConfigurationException
*/
public static void convertToXML(Collection<IAssetAdministrationShell> aasList, Collection<IAsset> assetList,
- Collection<IConceptDescription> conceptDescriptionList, Collection<ISubModel> submodelList, Result result)
+ Collection<IConceptDescription> conceptDescriptionList, Collection<ISubmodel> submodelList, Result result)
throws TransformerException, ParserConfigurationException {
DocumentBuilderFactory documentFactory = DocumentBuilderFactory.newInstance();
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/XMLToMetamodelConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/XMLToMetamodelConverter.java
index fb8e500..fbd3af1 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/XMLToMetamodelConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/XMLToMetamodelConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.factory.xml;
import java.io.IOException;
@@ -13,7 +22,7 @@
import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
import org.eclipse.basyx.submodel.factory.xml.api.parts.ConceptDescriptionXMLConverter;
import org.eclipse.basyx.submodel.factory.xml.converters.SubmodelXMLConverter;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
import org.eclipse.basyx.submodel.metamodel.api.parts.IConceptDescription;
import org.eclipse.basyx.vab.factory.xml.XmlParser;
import org.xml.sax.SAXException;
@@ -80,15 +89,15 @@
/**
- * Parses the SubModels form the XML
+ * Parses the Submodels form the XML
*
- * @return the SubModels parsed form the XML
+ * @return the Submodels parsed form the XML
* @throws ParserConfigurationException
* @throws SAXException
* @throws IOException
*/
@SuppressWarnings("unchecked")
- public List<ISubModel> parseSubmodels() {
+ public List<ISubmodel> parseSubmodels() {
Map<String, Object> xmlSubmodels = (Map<String, Object>) root.get(SubmodelXMLConverter.SUBMODELS);
return SubmodelXMLConverter.parseSubmodels(xmlSubmodels);
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/api/parts/AssetXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/api/parts/AssetXMLConverter.java
index 269a452..c152b15 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/api/parts/AssetXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/api/parts/AssetXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.factory.xml.api.parts;
import java.util.ArrayList;
@@ -5,17 +14,22 @@
import java.util.List;
import java.util.Map;
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
import org.eclipse.basyx.submodel.factory.xml.XMLHelper;
import org.eclipse.basyx.submodel.factory.xml.converters.qualifier.HasDataSpecificationXMLConverter;
import org.eclipse.basyx.submodel.factory.xml.converters.qualifier.IdentifiableXMLConverter;
-import org.eclipse.basyx.submodel.factory.xml.converters.qualifier.haskind.HasKindXMLConverter;
import org.eclipse.basyx.submodel.factory.xml.converters.reference.ReferenceXMLConverter;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+import com.google.common.base.Strings;
+
/**
* Handles the conversion between IAsset objects and the XML tag <aas:assets> in both directions
*
@@ -43,9 +57,9 @@
for (Map<String, Object> xmlAsset : xmlAssets) {
Asset asset = new Asset();
- IdentifiableXMLConverter.populateIdentifiable(xmlAsset, asset);
- HasDataSpecificationXMLConverter.populateHasDataSpecification(xmlAsset, asset);
- HasKindXMLConverter.populateHasKind(xmlAsset, asset);
+ IdentifiableXMLConverter.populateIdentifiable(xmlAsset, Identifiable.createAsFacadeNonStrict(asset, KeyElements.ASSET));
+ HasDataSpecificationXMLConverter.populateHasDataSpecification(xmlAsset, HasDataSpecification.createAsFacade(asset));
+ asset.setAssetKind(parseAssetKind(xmlAsset));
if(xmlAsset.containsKey(ASSET_IDENTIFICATION_MODEL_REF)) {
asset.setAssetIdentificationModel(parseAssetIdentificationModelRef(xmlAsset));
@@ -69,6 +83,22 @@
return ReferenceXMLConverter.parseReference(semanticIDObj);
}
+
+ /**
+ * Parses <aas:akind> and gets the correct AssetKind from it
+ *
+ * @param xmlObject a Map containing the XML tag <aas:kind>
+ * @return the parsed AssetKind or null if none was present
+ */
+ private static AssetKind parseAssetKind(Map<String, Object> xmlObject) {
+ String assetKindValue = XMLHelper.getString(xmlObject.get(ASSET_KIND));
+ if (!Strings.isNullOrEmpty(assetKindValue)) {
+ return AssetKind.fromString(assetKindValue);
+ } else {
+ throw new RuntimeException("Necessary value 'AssetKind' was not found for one of the Assets in the XML file.");
+ }
+ }
+
/**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/api/parts/ViewXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/api/parts/ViewXMLConverter.java
index 8202449..f6827c4 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/api/parts/ViewXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/api/parts/ViewXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.factory.xml.api.parts;
import java.util.ArrayList;
@@ -15,6 +24,10 @@
import org.eclipse.basyx.submodel.factory.xml.converters.qualifier.ReferableXMLConverter;
import org.eclipse.basyx.submodel.factory.xml.converters.reference.ReferenceXMLConverter;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -51,9 +64,9 @@
for(Map<String, Object> xmlView: xmlViewList) {
View view = new View();
- ReferableXMLConverter.populateReferable(xmlView, view);
- HasSemanticsXMLConverter.populateHasSemantics(xmlView, view);
- HasDataSpecificationXMLConverter.populateHasDataSpecification(xmlView, view);
+ ReferableXMLConverter.populateReferable(xmlView, Referable.createAsFacadeNonStrict(view, KeyElements.VIEW));
+ HasSemanticsXMLConverter.populateHasSemantics(xmlView, HasSemantics.createAsFacade(view));
+ HasDataSpecificationXMLConverter.populateHasDataSpecification(xmlView, HasDataSpecification.createAsFacade(view));
Map<String, Object> xmlContainedElementsObject = ((Map<String, Object>) xmlView.get(CONTAINED_ELEMENTS));
Map<String, Object> xmlContainedElementObject = (Map<String, Object>) xmlContainedElementsObject.get(CONTAINED_ELEMENT_REF);
@@ -119,4 +132,4 @@
xmlView.appendChild(xmlContainedElements);
}
}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/converters/AssetAdministrationShellXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/converters/AssetAdministrationShellXMLConverter.java
index 79ad580..7d95a57 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/converters/AssetAdministrationShellXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/converters/AssetAdministrationShellXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.factory.xml.converters;
import java.util.ArrayList;
@@ -22,6 +31,9 @@
import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -62,8 +74,8 @@
for(Map<String, Object> xmlAAS: xmlAASs) {
AssetAdministrationShell adminShell = new AssetAdministrationShell();
- IdentifiableXMLConverter.populateIdentifiable(xmlAAS, adminShell);
- HasDataSpecificationXMLConverter.populateHasDataSpecification(xmlAAS, adminShell);
+ IdentifiableXMLConverter.populateIdentifiable(xmlAAS, Identifiable.createAsFacadeNonStrict(adminShell, KeyElements.ASSETADMINISTRATIONSHELL));
+ HasDataSpecificationXMLConverter.populateHasDataSpecification(xmlAAS, HasDataSpecification.createAsFacade(adminShell));
Collection<IView> views = ViewXMLConverter.parseViews(xmlAAS);
Collection<IConceptDictionary> conceptDictionary = parseConceptDictionaries(xmlAAS, conceptDescriptions);
@@ -133,7 +145,7 @@
List<Map<String, Object>> xmlConceptDictionaryList = XMLHelper.getList(xmlConceptDictionaries.get(CONCEPT_DICTIONARY));
for (Map<String, Object> xmlConceptDictionary : xmlConceptDictionaryList) {
ConceptDictionary conceptDictionary = new ConceptDictionary();
- ReferableXMLConverter.populateReferable(xmlConceptDictionary, conceptDictionary);
+ ReferableXMLConverter.populateReferable(xmlConceptDictionary, Referable.createAsFacadeNonStrict(conceptDictionary, KeyElements.CONCEPTDICTIONARY));
Map<String, Object> xmlConceptDescriptionRefs = (Map<String, Object>) xmlConceptDictionary.get(CONCEPT_DESCRIPTION_REFS);
HashSet<IReference> referenceSet = new HashSet<>();
@@ -305,4 +317,4 @@
return conceptDicts;
}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/manager/ConnectedAssetAdministrationShellManager.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/manager/ConnectedAssetAdministrationShellManager.java
index 2b95057..aeae53b 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/manager/ConnectedAssetAdministrationShellManager.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/manager/ConnectedAssetAdministrationShellManager.java
@@ -10,24 +10,26 @@
import java.util.Map;
import org.eclipse.basyx.aas.aggregator.proxy.AASAggregatorProxy;
+import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
import org.eclipse.basyx.aas.manager.api.IAssetAdministrationShellManager;
import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.connected.ConnectedAssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.submodel.metamodel.connected.ConnectedSubModel;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.connected.ConnectedSubmodel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
import org.eclipse.basyx.vab.exception.FeatureNotImplementedException;
import org.eclipse.basyx.vab.factory.java.ModelProxyFactory;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
import org.eclipse.basyx.vab.modelprovider.VABPathTools;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-import org.eclipse.basyx.vab.protocol.api.IConnectorProvider;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
/**
* Implement a AAS manager backend that communicates via HTTP/REST<br />
@@ -38,8 +40,8 @@
*/
public class ConnectedAssetAdministrationShellManager implements IAssetAdministrationShellManager {
- protected IAASRegistryService aasDirectory;
- protected IConnectorProvider connectorProvider;
+ protected IAASRegistry aasDirectory;
+ protected IConnectorFactory connectorFactory;
protected ModelProxyFactory proxyFactory;
/**
@@ -47,75 +49,59 @@
*
* @param directory
*/
- public ConnectedAssetAdministrationShellManager(IAASRegistryService directory) {
- this(directory, new HTTPConnectorProvider());
+ public ConnectedAssetAdministrationShellManager(IAASRegistry directory) {
+ this(directory, new HTTPConnectorFactory());
}
/**
* @param networkDirectoryService
* @param providerProvider
*/
- public ConnectedAssetAdministrationShellManager(IAASRegistryService directory,
- IConnectorProvider provider) {
+ public ConnectedAssetAdministrationShellManager(IAASRegistry directory,
+ IConnectorFactory provider) {
this.aasDirectory = directory;
- this.connectorProvider = provider;
+ this.connectorFactory = provider;
this.proxyFactory = new ModelProxyFactory(provider);
}
@Override
- public ISubModel retrieveSubModel(IIdentifier aasId, IIdentifier smId) {
- // look up AAS descriptor in the registry
- AASDescriptor aasDescriptor = aasDirectory.lookupAAS(aasId);
-
- // Get submodel descriptor from the aas descriptor
- SubmodelDescriptor smDescriptor = aasDescriptor.getSubModelDescriptorFromIdentifierId(smId.getId());
+ public ISubmodel retrieveSubmodel(IIdentifier aasId, IIdentifier smId) {
+ // look up SM descriptor in the registry
+ SubmodelDescriptor smDescriptor = aasDirectory.lookupSubmodel(aasId, smId);
// get address of the submodel descriptor
String addr = smDescriptor.getFirstEndpoint();
// Return a new VABElementProxy
- return new ConnectedSubModel(proxyFactory.createProxy(addr));
+ return new ConnectedSubmodel(proxyFactory.createProxy(addr));
}
@Override
- public ConnectedAssetAdministrationShell retrieveAAS(IIdentifier aasId) throws Exception {
+ public ConnectedAssetAdministrationShell retrieveAAS(IIdentifier aasId) {
VABElementProxy proxy = getAASProxyFromId(aasId);
- return new ConnectedAssetAdministrationShell(proxy, this);
+ return new ConnectedAssetAdministrationShell(proxy);
}
@Override
- public Map<String, ISubModel> retrieveSubmodels(IIdentifier aasId) {
+ public Map<String, ISubmodel> retrieveSubmodels(IIdentifier aasId) {
AASDescriptor aasDesc = aasDirectory.lookupAAS(aasId);
- Collection<SubmodelDescriptor> smDescriptors = aasDesc.getSubModelDescriptors();
- Map<String, ISubModel> submodels = new HashMap<>();
+ Collection<SubmodelDescriptor> smDescriptors = aasDesc.getSubmodelDescriptors();
+ Map<String, ISubmodel> submodels = new HashMap<>();
for (SubmodelDescriptor smDesc : smDescriptors) {
String smEndpoint = smDesc.getFirstEndpoint();
String smIdShort = smDesc.getIdShort();
VABElementProxy smProxy = proxyFactory.createProxy(smEndpoint);
- ConnectedSubModel connectedSM = new ConnectedSubModel(smProxy);
+ ConnectedSubmodel connectedSM = new ConnectedSubmodel(smProxy);
submodels.put(smIdShort, connectedSM);
}
return submodels;
}
- @Override
- public void createAAS(AssetAdministrationShell aas, IIdentifier aasId, String endpoint) {
- IModelProvider provider = connectorProvider.getConnector(endpoint);
- AASAggregatorProxy proxy = new AASAggregatorProxy(provider);
- proxy.createAAS(aas);
- try {
- String combinedEndpoint = VABPathTools.concatenatePaths(endpoint, "aasList", URLEncoder.encode(aas.getIdentification().getId(), "UTF-8"), "aas");
- aasDirectory.register(new AASDescriptor(aas, combinedEndpoint));
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException("Encoding failed. This should never happen");
- }
- }
-
private VABElementProxy getAASProxyFromId(IIdentifier aasId) {
// Lookup AAS descriptor
AASDescriptor aasDescriptor = aasDirectory.lookupAAS(aasId);
- // Get AAD address from AAS descriptor
+ // Get AAS address from AAS descriptor
String addr = aasDescriptor.getFirstEndpoint();
// Return a new VABElementProxy
@@ -128,19 +114,32 @@
}
@Override
- public void deleteAAS(String id) throws Exception {
- throw new FeatureNotImplementedException();
+ public void deleteAAS(IIdentifier id) {
+ // Lookup AAS descriptor
+ AASDescriptor aasDescriptor = aasDirectory.lookupAAS(id);
+
+ // Get AAS address from AAS descriptor
+ String addr = aasDescriptor.getFirstEndpoint();
+
+ // Address ends in "/aas", has to be stripped for removal
+ addr = VABPathTools.stripSlashes(addr);
+ addr = addr.substring(0, addr.length() - "/aas".length());
+
+ // Delete from server
+ proxyFactory.createProxy(addr).deleteValue("");
+
+ // Delete from Registry
+ aasDirectory.delete(id);
+
+ // TODO: How to handle submodels -> Lifecycle needs to be clarified
}
@Override
- public void createSubModel(IIdentifier aasId, SubModel submodel) {
+ public void createSubmodel(IIdentifier aasId, Submodel submodel) {
// Push the SM to the server using the ConnectedAAS
- try {
- retrieveAAS(aasId).addSubModel(submodel);
- } catch (Exception e) {
- throw new RuntimeException("Could not create Submodel on server", e);
- }
+
+ retrieveAAS(aasId).addSubmodel(submodel);
// Lookup AAS descriptor
AASDescriptor aasDescriptor = aasDirectory.lookupAAS(aasId);
@@ -149,7 +148,34 @@
String addr = aasDescriptor.getFirstEndpoint();
// Register the SM
- String smEndpoint = VABPathTools.concatenatePaths(addr, AssetAdministrationShell.SUBMODELS, submodel.getIdShort());
+ String smEndpoint = VABPathTools.concatenatePaths(addr, AssetAdministrationShell.SUBMODELS, submodel.getIdShort(), SubmodelProvider.SUBMODEL);
aasDirectory.register(aasId, new SubmodelDescriptor(submodel, smEndpoint));
}
+
+ @Override
+ public void deleteSubmodel(IIdentifier aasId, IIdentifier submodelId) {
+ IAssetAdministrationShell shell = retrieveAAS(aasId);
+ shell.removeSubmodel(submodelId);
+
+ aasDirectory.delete(aasId, submodelId);
+ }
+
+ @Override
+ public void createAAS(AssetAdministrationShell aas, String endpoint) {
+ endpoint = VABPathTools.stripSlashes(endpoint);
+ if (!endpoint.endsWith(AASAggregatorProvider.PREFIX)) {
+ endpoint += "/" + AASAggregatorProvider.PREFIX;
+ }
+
+ IModelProvider provider = connectorFactory.getConnector(endpoint);
+ AASAggregatorProxy proxy = new AASAggregatorProxy(provider);
+ proxy.createAAS(aas);
+ try {
+
+ String combinedEndpoint = VABPathTools.concatenatePaths(endpoint, URLEncoder.encode(aas.getIdentification().getId(), "UTF-8"), "aas");
+ aasDirectory.register(new AASDescriptor(aas, combinedEndpoint));
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("Encoding failed. This should never happen");
+ }
+ }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/manager/api/IAssetAdministrationShellManager.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/manager/api/IAssetAdministrationShellManager.java
index 3877084..cc6420a 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/manager/api/IAssetAdministrationShellManager.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/manager/api/IAssetAdministrationShellManager.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.manager.api;
import java.util.Collection;
@@ -5,9 +14,9 @@
import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
@@ -29,28 +38,40 @@
public Collection<IAssetAdministrationShell> retrieveAASAll();
/**
- * Creates an AAS on a remote server.
+ * Creates an AAS on a remote server
+ *
+ * @param aas
+ * @param aasId
+ * @param endpoint
*/
- void createAAS(AssetAdministrationShell aas, IIdentifier aasId, String endpoint);
-
+ void createAAS(AssetAdministrationShell aas, String endpoint);
+
/**
* Unlink an AAS from the system
*/
- void deleteAAS(String id) throws Exception;
+ void deleteAAS(IIdentifier id) throws Exception;
/**
* Retrieves a submodel
*/
- ISubModel retrieveSubModel(IIdentifier aasId, IIdentifier subModelId);
+ ISubmodel retrieveSubmodel(IIdentifier aasId, IIdentifier subModelId);
/**
* Creates a submodel on a remote server. Assumes that the AAS is already
* registered in the directory
*/
- void createSubModel(IIdentifier aasId, SubModel submodel);
+ void createSubmodel(IIdentifier aasId, Submodel submodel);
+
+ /**
+ * Deletes a submodel on a remote server and removes its registry entry
+ *
+ * @param aasId
+ * @param submodelId
+ */
+ void deleteSubmodel(IIdentifier aasId, IIdentifier submodelId);
/**
* Retrieves all submodels in a specific AAS
*/
- Map<String, ISubModel> retrieveSubmodels(IIdentifier aasId);
+ Map<String, ISubmodel> retrieveSubmodels(IIdentifier aasId);
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/IAasEnv.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/IAasEnv.java
new file mode 100644
index 0000000..06115aa
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/IAasEnv.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.metamodel.api;
+
+import java.util.Collection;
+
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.parts.IConceptDescription;
+
+public interface IAasEnv {
+
+ Collection<IAsset> getAssets();
+
+ Collection<IAssetAdministrationShell> getAssetAdministrationShells();
+
+ Collection<ISubmodel> getSubmodels();
+
+ Collection<IConceptDescription> getConceptDescriptions();
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/IAssetAdministrationShell.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/IAssetAdministrationShell.java
index 3514971..46710c7 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/IAssetAdministrationShell.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/IAssetAdministrationShell.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.metamodel.api;
import java.util.Collection;
@@ -8,11 +17,12 @@
import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
import org.eclipse.basyx.aas.metamodel.api.security.ISecurity;
import org.eclipse.basyx.submodel.metamodel.api.IElement;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
import org.eclipse.basyx.submodel.metamodel.api.qualifier.IHasDataSpecification;
import org.eclipse.basyx.submodel.metamodel.api.qualifier.IIdentifiable;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
/**
* Asset Administration Shell (AAS) interface
@@ -25,9 +35,9 @@
/**
* Return all registered submodels of this AAS
*
- * @return
+ * @return IdShort -> ISubmodel
*/
- public Map<String, ISubModel> getSubModels();
+ public Map<String, ISubmodel> getSubmodels();
/**
* Return the references to all registered submodels
@@ -37,12 +47,26 @@
public Collection<IReference> getSubmodelReferences();
/**
- * Add a sub model to the AAS
+ * Add a submodel to the AAS
*
* @param subModel
* The added sub model
*/
- public void addSubModel(SubModel subModel);
+ public void addSubmodel(Submodel subModel);
+
+ /**
+ * Removes a submodel from the AAS
+ *
+ * @param id
+ */
+ public void removeSubmodel(IIdentifier id);
+
+ /**
+ * Gets a submodel from the AAS
+ *
+ * @param id
+ */
+ public ISubmodel getSubmodel(IIdentifier id);
/**
* Gets the definition of the security relevant aspects of the AAS.
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/IConceptDictionary.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/IConceptDictionary.java
index cf76055..217d510 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/IConceptDictionary.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/IConceptDictionary.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.metamodel.api.parts;
import java.util.Collection;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/IView.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/IView.java
index ea951f1..9ec0cd0 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/IView.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/IView.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.metamodel.api.parts;
import java.util.Collection;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/asset/AssetKind.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/asset/AssetKind.java
index 5028960..31b2030 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/asset/AssetKind.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/asset/AssetKind.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.metamodel.api.parts.asset;
import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnum;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/asset/IAsset.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/asset/IAsset.java
index b7b729c..a9af5ed 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/asset/IAsset.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/asset/IAsset.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.metamodel.api.parts.asset;
import org.eclipse.basyx.submodel.metamodel.api.qualifier.IHasDataSpecification;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/policypoints/IAccessControlPolicyPoints.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/policypoints/IAccessControlPolicyPoints.java
index c804dfd..248188f 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/policypoints/IAccessControlPolicyPoints.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/policypoints/IAccessControlPolicyPoints.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.metamodel.api.policypoints;
/**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/security/ICertificate.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/security/ICertificate.java
index 5113e5d..8ac3316 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/security/ICertificate.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/security/ICertificate.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.metamodel.api.security;
/**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/security/ISecurity.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/security/ISecurity.java
index 8fba5b4..60abcbf 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/security/ISecurity.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/security/ISecurity.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.metamodel.api.security;
import org.eclipse.basyx.aas.metamodel.api.policypoints.IAccessControlPolicyPoints;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/connected/ConnectedAssetAdministrationShell.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/connected/ConnectedAssetAdministrationShell.java
index 59eaa58..a804400 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/connected/ConnectedAssetAdministrationShell.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/connected/ConnectedAssetAdministrationShell.java
@@ -1,10 +1,20 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.metamodel.connected;
import java.util.Collection;
+import java.util.HashMap;
import java.util.Map;
+import java.util.Optional;
import java.util.stream.Collectors;
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.api.parts.IConceptDictionary;
import org.eclipse.basyx.aas.metamodel.api.parts.IView;
@@ -15,43 +25,52 @@
import org.eclipse.basyx.aas.metamodel.map.parts.ConceptDictionary;
import org.eclipse.basyx.aas.metamodel.map.parts.View;
import org.eclipse.basyx.aas.metamodel.map.security.Security;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IEmbeddedDataSpecification;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
import org.eclipse.basyx.submodel.metamodel.api.qualifier.IAdministrativeInformation;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.connected.ConnectedElement;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.connected.ConnectedSubmodel;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
import org.eclipse.basyx.submodel.metamodel.map.reference.ReferenceHelper;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
/**
* "Connected" implementation of IAssetAdministrationShell
*
- * @author rajashek, Zai Zhang
+ * @author rajashek, Zai Zhang, schnicke
*
*/
public class ConnectedAssetAdministrationShell extends ConnectedElement implements IAssetAdministrationShell {
-
- ConnectedAssetAdministrationShellManager manager;
+ /**
+ * Constructor creating a ConnectedAAS pointing to the AAS represented by proxy
+ *
+ * @param proxy
+ */
+ public ConnectedAssetAdministrationShell(VABElementProxy proxy) {
+ super(proxy);
+ }
/**
* Constructor creating a ConnectedAAS pointing to the AAS represented by proxy
- * and path
+ * and an already cached local copy
*
- * @param path
* @param proxy
- * @param manager
+ * @param localCopy
*/
- public ConnectedAssetAdministrationShell(VABElementProxy proxy, ConnectedAssetAdministrationShellManager manager) {
+ public ConnectedAssetAdministrationShell(VABElementProxy proxy, AssetAdministrationShell localCopy) {
super(proxy);
- this.manager = manager;
}
/**
@@ -118,15 +137,28 @@
return set.stream().map(ConceptDictionary::createAsFacade).collect(Collectors.toSet());
}
+ @SuppressWarnings("unchecked")
@Override
- public Map<String, ISubModel> getSubModels() {
- return manager.retrieveSubmodels(getIdentification());
+ public Map<String, ISubmodel> getSubmodels() {
+ Collection<Map<String, Object>> submodelCollection = (Collection<Map<String, Object>>) getProxy().getValue(AssetAdministrationShell.SUBMODELS);
+
+ Map<String, ISubmodel> ret = new HashMap<>();
+
+ for (Map<String, Object> m : submodelCollection) {
+ Submodel sm = Submodel.createAsFacade(m);
+ String path = VABPathTools.concatenatePaths(AssetAdministrationShell.SUBMODELS, sm.getIdShort(), SubmodelProvider.SUBMODEL);
+ ret.put(sm.getIdShort(), new ConnectedSubmodel(getProxy().getDeepProxy(path), sm));
+ }
+
+ return ret;
}
@Override
- public void addSubModel(SubModel subModel) {
+ public void addSubmodel(Submodel subModel) {
subModel.setParent(getReference());
- getProxy().createValue("/submodels", subModel);
+ Map<String, Object> convertedMap = SubmodelElementMapCollectionConverter.smToMap(subModel);
+ String accessPath = VABPathTools.concatenatePaths(AssetAdministrationShell.SUBMODELS, subModel.getIdShort());
+ getProxy().setValue(accessPath, convertedMap);
}
@Override
@@ -169,4 +201,32 @@
public IReference getReference() {
return Identifiable.createAsFacade(getElem(), getKeyElement()).getReference();
}
+
+ /**
+ * Returns a local copy of the AAS, i.e. a snapshot of the current state. <br>
+ * No changes of this copy are reflected in the remote AAS
+ *
+ * @return the local copy
+ */
+ public AssetAdministrationShell getLocalCopy() {
+ return AssetAdministrationShell.createAsFacade(getElem());
+ }
+
+ @Override
+ public void removeSubmodel(IIdentifier id) {
+ ISubmodel sm = getSubmodel(id);
+
+ String path = VABPathTools.concatenatePaths(AssetAdministrationShell.SUBMODELS, sm.getIdShort());
+ getProxy().deleteValue(path);
+ }
+
+ @Override
+ public ISubmodel getSubmodel(IIdentifier id) {
+ // FIXME: Change this when AAS API supports Submodel retrieval by Identifier
+ Optional<ISubmodel> op = getSubmodels().values().stream().filter(sm -> sm.getIdentification().getId().equals(id.getId())).findFirst();
+ if (!op.isPresent()) {
+ throw new ResourceNotFoundException("AAS " + getIdentification() + " does not have a submodel with id " + id);
+ }
+ return op.get();
+ }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/exception/MetamodelConstructionException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/exception/MetamodelConstructionException.java
new file mode 100644
index 0000000..42ede92
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/exception/MetamodelConstructionException.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.metamodel.exception;
+
+import java.util.Map;
+
+/**
+ * This class is used to throw exception when
+ * metamodel's createAsFacade from map does not work
+ * due to absence of mandatory fields
+ *
+ * @author haque
+ *
+ */
+public class MetamodelConstructionException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+
+ public MetamodelConstructionException(Class<?> clazz , Map<String, Object> map) {
+ super("Could not construct meta model element " + clazz.getName() + ". Passed argument was " + map.toString());
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/AasEnv.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/AasEnv.java
new file mode 100644
index 0000000..3cf7b51
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/AasEnv.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.metamodel.map;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.api.IAasEnv;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.parts.IConceptDescription;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
+import org.eclipse.basyx.submodel.metamodel.map.parts.ConceptDescription;
+import org.eclipse.basyx.vab.model.VABModelMap;
+
+/**
+ * AasEnv class
+ *
+ * @author gordt
+ */
+
+public class AasEnv extends VABModelMap<Object> implements IAasEnv {
+
+ public static final String ASSETS = "assets";
+ public static final String ASSETADMINISTRATIONSHELLS = "assetAdministrationShells";
+ public static final String SUBMODELS = "submodels";
+ public static final String CONCEPTDESCRIPTIONS = "conceptDescriptions";
+ public static final String MODELTYPE = "AasEnv";
+
+
+ public AasEnv() {
+ // Add model type
+ putAll(new ModelType(MODELTYPE));
+ }
+
+ /**
+ * Creates a AssetAdministrationShell object from a map
+ *
+ * @param obj
+ * a AssetAdministrationShell object as raw map
+ * @return a AssetAdministrationShell object, that behaves like a facade for the
+ * given map
+ */
+ @SuppressWarnings("unchecked")
+ public static AasEnv createAsFacade(Map<String, Object> map) {
+ if (map == null) {
+ return null;
+ }
+
+ AasEnv ret = new AasEnv();
+
+ Collection<IAsset> assetsTarget = new LinkedList<>();
+ if (map.get(ASSETS) != null && map.get(ASSETS) instanceof Collection) {
+ Collection<Map<String, Object>> objectMapCollection = (Collection<Map<String, Object>>) map.get(ASSETS);
+ for(Map<String, Object> objectMap : objectMapCollection) {
+ assetsTarget.add(Asset.createAsFacade(objectMap));
+ }
+ }
+ ret.put(ASSETS, assetsTarget);
+
+ Collection<IAssetAdministrationShell> aasTarget = new LinkedList<>();
+ if (map.get(ASSETADMINISTRATIONSHELLS) != null && map.get(ASSETADMINISTRATIONSHELLS) instanceof Collection) {
+ Collection<Map<String, Object>> objectMapCollection = (Collection<Map<String, Object>>) map.get(ASSETADMINISTRATIONSHELLS);
+ for(Map<String, Object> objectMap : objectMapCollection) {
+ aasTarget.add(AssetAdministrationShell.createAsFacade(objectMap));
+ }
+ }
+ ret.put(ASSETADMINISTRATIONSHELLS, aasTarget);
+
+ Collection<ISubmodel> submodelsTarget = new LinkedList<>();
+ if (map.get(SUBMODELS) != null && map.get(SUBMODELS) instanceof Collection) {
+ Collection<Map<String, Object>> objectMapCollection = (Collection<Map<String, Object>>) map.get(SUBMODELS);
+ for(Map<String, Object> objectMap : objectMapCollection) {
+ submodelsTarget.add(Submodel.createAsFacade(objectMap));
+ }
+ }
+ ret.put(SUBMODELS, submodelsTarget);
+
+ Collection<IConceptDescription> conceptDescriptionsTarget = new LinkedList<>();
+ if (map.get(CONCEPTDESCRIPTIONS) != null && map.get(CONCEPTDESCRIPTIONS) instanceof Collection) {
+ Collection<Map<String, Object>> objectMapCollection = (Collection<Map<String, Object>>) map.get(CONCEPTDESCRIPTIONS);
+ for(Map<String, Object> objectMap : objectMapCollection) {
+ conceptDescriptionsTarget.add(ConceptDescription.createAsFacade(objectMap));
+ }
+ }
+ ret.put(CONCEPTDESCRIPTIONS, conceptDescriptionsTarget);
+
+ return ret;
+ }
+
+
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Collection<IAsset> getAssets() {
+ List<IAsset> internal = (List<IAsset>) get(ASSETS);
+ List<IAsset> result = new ArrayList<IAsset>(internal.size());
+ result.addAll(internal);
+ return result;
+ }
+
+ public void setAssets(Collection<IAsset> assets) {
+ put(ASSETS, assets);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Collection<IAssetAdministrationShell> getAssetAdministrationShells() {
+ List<IAssetAdministrationShell> internal = (List<IAssetAdministrationShell>) get(ASSETADMINISTRATIONSHELLS);
+ List<IAssetAdministrationShell> result = new ArrayList<IAssetAdministrationShell>(internal.size());
+ result.addAll(internal);
+ return result;
+ }
+
+ public void setAssetAdministrationShells(Collection<IAssetAdministrationShell> assetAdministrationShells) {
+ put(ASSETADMINISTRATIONSHELLS, assetAdministrationShells);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Collection<ISubmodel> getSubmodels() {
+ List<ISubmodel> internal = (List<ISubmodel>) get(SUBMODELS);
+ List<ISubmodel> result = new ArrayList<ISubmodel>(internal.size());
+ result.addAll(internal);
+ return result;
+ }
+
+ public void setSubmodels(Collection<ISubmodel> submodels) {
+ put(SUBMODELS, submodels);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Collection<IConceptDescription> getConceptDescriptions() {
+ List<IConceptDescription> internal = (List<IConceptDescription>) get(CONCEPTDESCRIPTIONS);
+ List<IConceptDescription> result = new ArrayList<IConceptDescription>(internal.size());
+ result.addAll(internal);
+ return result;
+ }
+
+ public void setConceptDescriptions(Collection<IConceptDescription> conceptDescriptions) {
+ put(CONCEPTDESCRIPTIONS, conceptDescriptions);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/AssetAdministrationShell.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/AssetAdministrationShell.java
index 0ca5f88..969592e 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/AssetAdministrationShell.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/AssetAdministrationShell.java
@@ -1,11 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.metamodel.map;
-import java.util.Arrays;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashMap;
import java.util.HashSet;
-import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@@ -14,11 +21,12 @@
import org.eclipse.basyx.aas.metamodel.api.parts.IView;
import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
import org.eclipse.basyx.aas.metamodel.api.security.ISecurity;
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
import org.eclipse.basyx.aas.metamodel.map.parts.ConceptDictionary;
import org.eclipse.basyx.aas.metamodel.map.parts.View;
import org.eclipse.basyx.aas.metamodel.map.security.Security;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IEmbeddedDataSpecification;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
@@ -26,7 +34,7 @@
import org.eclipse.basyx.submodel.metamodel.api.qualifier.IAdministrativeInformation;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.AdministrativeInformation;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
@@ -35,6 +43,7 @@
import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
import org.eclipse.basyx.submodel.metamodel.map.reference.ReferenceHelper;
+import org.eclipse.basyx.vab.exception.FeatureNotImplementedException;
import org.eclipse.basyx.vab.model.VABModelMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -60,18 +69,29 @@
public static final String CONCEPTDICTIONARY = "conceptDictionary";
public static final String TYPE = "type";
public static final String ADDRESS = "address";
- public static final String ENDPOINTS = "endpoints";
- public static final String MODELTYPE = "AssetAdministationShell";
+ public static final String MODELTYPE = "AssetAdministrationShell";
/**
* Constructor
*/
public AssetAdministrationShell() {
- this(null, null, new Asset(), new HashSet<SubModel>(), new HashSet<IConceptDictionary>(), new HashSet<IView>());
+ this(null, null, new Asset(), new HashSet<Submodel>(), new HashSet<IConceptDictionary>(), new HashSet<IView>());
+ }
+
+ /**
+ * Constructor accepting only mandatory attributes
+ * @param idShort
+ * @param identification
+ * @param asset
+ */
+ public AssetAdministrationShell(String idShort, IIdentifier identification, Asset asset) {
+ this(null, null, asset, new HashSet<Submodel>(), new HashSet<IConceptDictionary>(), new HashSet<IView>());
+ setIdentification(identification);
+ setIdShort(idShort);
}
public AssetAdministrationShell(Reference derivedFrom, Security security, Asset asset,
- Collection<SubModel> submodels, Collection<IConceptDictionary> dictionaries, Collection<IView> views) {
+ Collection<Submodel> submodels, Collection<IConceptDictionary> dictionaries, Collection<IView> views) {
// Add model type
putAll(new ModelType(MODELTYPE));
@@ -85,7 +105,7 @@
setSecurity(security);
setDerivedFrom(derivedFrom);
setAsset(asset);
- setSubModels(submodels);
+ setSubmodels(submodels);
setViews(views);
setConceptDictionary(dictionaries);
@@ -103,30 +123,30 @@
if (map == null) {
return null;
}
+
+ if (!isValid(map)) {
+ throw new MetamodelConstructionException(AssetAdministrationShell.class, map);
+ }
+
+ if (!map.containsKey(SUBMODELS)) {
+ map.put(SUBMODELS, new ArrayList<>());
+ }
AssetAdministrationShell ret = new AssetAdministrationShell();
ret.setMap(map);
- return ret;
+ return ret;
}
-
+
/**
- * Sets the endpoint of the AAS
- *
- * @param endpoint
- * is expected to end with "/aas"
- * @param endpointType
+ * Check whether all mandatory elements for the metamodel
+ * exist in a map
+ * @return true/false
*/
- public void setEndpoint(String endpoint, String endpointType) {
- HashMap<String, String> endpointWrapper = new HashMap<String, String>();
- endpointWrapper.put(TYPE, endpointType);
- endpointWrapper.put(ADDRESS, endpoint);
-
- put(ENDPOINTS, Arrays.asList(endpointWrapper));
- }
-
@SuppressWarnings("unchecked")
- public List<HashMap<String, String>> getEndpoints() {
- return (List<HashMap<String, String>>) get(ENDPOINTS);
+ public static boolean isValid(Map<String, Object> map) {
+ return Identifiable.isValid(map) &&
+ map.containsKey(AssetAdministrationShell.ASSET) &&
+ Asset.isValid((Map<String, Object>)map.get(AssetAdministrationShell.ASSET));
}
@Override
@@ -148,7 +168,7 @@
}
public void setIdentification(IdentifierType idType, String id) {
- Identifiable.createAsFacade(this, getKeyElement()).setIdentification(idType, id);
+ Identifiable.createAsFacadeNonStrict(this, getKeyElement()).setIdentification(idType, id);
}
@Override
@@ -170,7 +190,7 @@
}
public void setIdShort(String id) {
- Referable.createAsFacade(this, getKeyElement()).setIdShort(id);
+ Referable.createAsFacadeNonStrict(this, getKeyElement()).setIdShort(id);
}
public void setSecurity(ISecurity security) {
@@ -214,7 +234,7 @@
}
@SuppressWarnings("unchecked")
- public void setSubModels(Collection<SubModel> submodels) {
+ public void setSubmodels(Collection<Submodel> submodels) {
setSubmodelParent(submodels);
// Clear submodel references and add new keys
@@ -246,8 +266,8 @@
}
@Override
- public Map<String, ISubModel> getSubModels() {
- throw new RuntimeException("getSubModels on local copy is not supported");
+ public Map<String, ISubmodel> getSubmodels() {
+ throw new RuntimeException("getSubmodels on local copy is not supported");
}
@Override
@@ -283,12 +303,19 @@
}
@Override
- public void addSubModel(SubModel submodel) {
+ public void addSubmodel(Submodel submodel) {
logger.trace("adding Submodel", submodel.getIdentification().getId());
setSubmodelParent(Collections.singletonList(submodel));
addSubmodelReferences(submodel);
}
+
+ @Override
+ public void removeSubmodel(IIdentifier id) {
+ // Currently not implemented since future of Submodel References in AAS is not clear
+ throw new FeatureNotImplementedException();
+ }
+
/**
* Allows addition of a concept description to the concept dictionary
*
@@ -298,7 +325,7 @@
public void addConceptDescription(IConceptDescription description) {
Collection<IConceptDictionary> dictionaries = (Collection<IConceptDictionary>) get(AssetAdministrationShell.CONCEPTDICTIONARY);
if (dictionaries.isEmpty()) {
- dictionaries.add(new ConceptDictionary());
+ dictionaries.add(new ConceptDictionary("defaultConceptDictionary"));
}
ConceptDictionary dictionary = (ConceptDictionary) dictionaries.iterator().next();
dictionary.addConceptDescription(description);
@@ -319,22 +346,22 @@
smReferences.add(reference);
}
- private void addSubmodelReferences(SubModel submodel) {
+ private void addSubmodelReferences(Submodel submodel) {
addSubmodelReference(submodel.getReference());
}
-
+
private KeyElements getKeyElement() {
return KeyElements.ASSETADMINISTRATIONSHELL;
}
/**
- * Set reference of current AAS to each SubModel of a collection
+ * Set reference of current AAS to each Submodel of a collection
* as a parent reference
*
* @param submodels collection of Submodels
*/
- private void setSubmodelParent(Collection<SubModel> submodels) {
- for (SubModel submodel : submodels) {
+ private void setSubmodelParent(Collection<Submodel> submodels) {
+ for (Submodel submodel : submodels) {
submodel.setParent(getReference());
}
}
@@ -342,4 +369,10 @@
public IReference getReference() {
return Identifiable.createAsFacade(this, getKeyElement()).getReference();
}
+
+ @Override
+ public ISubmodel getSubmodel(IIdentifier id) {
+ throw new RuntimeException("getSubmodel on local copy is not supported");
+ }
+
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/AASDescriptor.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/AASDescriptor.java
index cdd617e..ed3f8e1 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/AASDescriptor.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/AASDescriptor.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.metamodel.map.descriptor;
import java.util.Collection;
@@ -14,6 +23,7 @@
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
/**
* AAS descriptor class
@@ -22,7 +32,7 @@
*
*/
public class AASDescriptor extends ModelDescriptor {
- public static final String MODELTYPE = "AASDescriptor";
+ public static final String MODELTYPE = "AssetAdministrationShellDescriptor";
public static final String ASSET = "asset";
/**
@@ -30,6 +40,10 @@
*/
public AASDescriptor(Map<String, Object> map) {
super(map);
+ validate(map);
+
+ // Set map again
+ putAll(map);
}
protected AASDescriptor() {
@@ -96,6 +110,7 @@
// Add new sub model descriptor to list
submodelDescriptors.add(desc);
+ put(AssetAdministrationShell.SUBMODELS, submodelDescriptors);
// Enable method chaining
return this;
@@ -103,7 +118,18 @@
@SuppressWarnings("unchecked")
public void removeSubmodelDescriptor(String idShort) {
- Optional<SubmodelDescriptor> toRemove = getSubModelDescriptors().stream().filter(x -> x.getIdShort().equals(idShort)).findAny();
+ Optional<SubmodelDescriptor> toRemove = getSubmodelDescriptors().stream().filter(x -> x.getIdShort().equals(idShort)).findAny();
+
+ // TODO: Exception in else case
+ if (toRemove.isPresent()) {
+ // Don't use getSubmodelDescriptors here since it returns a copy
+ ((Collection<Object>) get(AssetAdministrationShell.SUBMODELS)).remove(toRemove.get());
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void removeSubmodelDescriptor(IIdentifier id) {
+ Optional<SubmodelDescriptor> toRemove = getSubmodelDescriptors().stream().filter(x -> x.getIdentifier().getId().equals(id.getId())).findAny();
// TODO: Exception in else case
if (toRemove.isPresent()) {
@@ -120,7 +146,7 @@
* @return
*/
@SuppressWarnings("unchecked")
- public SubmodelDescriptor getSubModelDescriptorFromIdentifierId(String subModelId) {
+ public SubmodelDescriptor getSubmodelDescriptorFromIdentifierId(String subModelId) {
// Sub model descriptors are stored in a list
Collection<Map<String, Object>> smDescriptorMaps = (Collection<Map<String, Object>>) get(
AssetAdministrationShell.SUBMODELS);
@@ -145,14 +171,14 @@
* @return
*/
public SubmodelDescriptor getSubmodelDescriptorFromIdShort(String idShort) {
- return getSubModelDescriptors().stream().filter(x -> x.getIdShort().equals(idShort)).findAny().orElse(null); // TODO: Exception
+ return getSubmodelDescriptors().stream().filter(x -> x.getIdShort().equals(idShort)).findAny().orElse(null); // TODO: Exception
}
/**
* Get a specific sub model descriptor from a ModelUrn
*/
- public SubmodelDescriptor getSubModelDescriptor(ModelUrn submodelUrn) {
- return getSubModelDescriptorFromIdentifierId(submodelUrn.getURN());
+ public SubmodelDescriptor getSubmodelDescriptor(ModelUrn submodelUrn) {
+ return getSubmodelDescriptorFromIdentifierId(submodelUrn.getURN());
}
/**
@@ -161,7 +187,7 @@
* @return
*/
@SuppressWarnings("unchecked")
- public Collection<SubmodelDescriptor> getSubModelDescriptors() {
+ public Collection<SubmodelDescriptor> getSubmodelDescriptors() {
Collection<Map<String, Object>> descriptors = (Collection<Map<String, Object>>) get(AssetAdministrationShell.SUBMODELS);
return descriptors.stream().map(SubmodelDescriptor::new).collect(Collectors.toSet());
}
@@ -179,5 +205,15 @@
Map<String, Object> assetModel = (Map<String, Object>) get(ASSET);
return Asset.createAsFacade(assetModel);
}
+
+ @Override
+ public void validate(Map<String, Object> map) {
+ super.validate(map);
+ if (!map.containsKey(AssetAdministrationShell.SUBMODELS)) {
+ map.put(AssetAdministrationShell.SUBMODELS, new HashSet<>());
+ } else if (map.containsKey(AssetAdministrationShell.SUBMODELS) && !(map.get(AssetAdministrationShell.SUBMODELS) instanceof Collection<?>)) {
+ throw new MalformedRequestException("Passed entry for " + AssetAdministrationShell.SUBMODELS + " is not a list of submodelDescriptors!");
+ }
+ }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/CustomId.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/CustomId.java
new file mode 100644
index 0000000..7c0b29e
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/CustomId.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.metamodel.map.descriptor;
+
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+
+/**
+ * CustomId identifier
+ *
+ * @author schnicke
+ *
+ */
+public class CustomId extends Identifier {
+
+ /**
+ * Creates a new Identifier with IdentifierType == IdentifierType.CUSTOM
+ *
+ * @param id
+ */
+ public CustomId(String id) {
+ super(IdentifierType.CUSTOM, id);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/ModelDescriptor.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/ModelDescriptor.java
index ed3e562..8dc0b62 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/ModelDescriptor.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/ModelDescriptor.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.metamodel.map.descriptor;
import java.util.ArrayList;
@@ -12,6 +21,7 @@
import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
import org.eclipse.basyx.vab.model.VABModelMap;
/**
@@ -24,6 +34,7 @@
*
*/
public abstract class ModelDescriptor extends VABModelMap<Object> {
+ public static final String ENDPOINTS = "endpoints";
protected ModelDescriptor() {
putAll(new ModelType(getModelType()));
@@ -55,7 +66,7 @@
HashMap<String, String> endpointWrapper = new HashMap<>();
endpointWrapper.put(AssetAdministrationShell.TYPE, "http");
endpointWrapper.put(AssetAdministrationShell.ADDRESS, httpEndpoint);
- put(AssetAdministrationShell.ENDPOINTS, Arrays.asList(endpointWrapper));
+ put(ENDPOINTS, Arrays.asList(endpointWrapper));
}
/**
@@ -77,7 +88,7 @@
*/
@SuppressWarnings("unchecked")
public String getFirstEndpoint() {
- Object e = get(AssetAdministrationShell.ENDPOINTS);
+ Object e = get(ENDPOINTS);
// Extract String from endpoint for set or list representations of the endpoint wrappers
if (e instanceof Collection<?>) {
Collection<Map<?, ?>> endpoints = (Collection<Map<?, ?>>) e;
@@ -97,7 +108,7 @@
*/
@SuppressWarnings("unchecked")
public Collection<Map<String, Object>> getEndpoints() {
- Object endpoints = get(AssetAdministrationShell.ENDPOINTS);
+ Object endpoints = get(ENDPOINTS);
// Extract String from endpoint for set or list representations of the endpoint wrappers
if (endpoints instanceof Collection<?>) {
return (Collection<Map<String, Object>>) endpoints;
@@ -105,6 +116,20 @@
return new ArrayList<>();
}
}
+
+ /**
+ * Validates a model descriptor by checking whether
+ * idShort, identification and endpoints key is present in the given map
+ * @param map
+ */
+ protected void validate(Map<String, Object> map) {
+ if (!map.containsKey(Referable.IDSHORT) || !(map.get(Referable.IDSHORT) instanceof String))
+ throw new MalformedRequestException(getModelType() + " is missing idShort entry");
+ if (!map.containsKey(Identifiable.IDENTIFICATION) || !(map.get(Identifiable.IDENTIFICATION) instanceof Map<?, ?>))
+ throw new MalformedRequestException(getModelType() + " is missing identification entry");
+ if (!map.containsKey(ENDPOINTS) || !(map.get(ENDPOINTS) instanceof Collection<?>))
+ throw new MalformedRequestException(getModelType() + " is missing endpoints entry");
+ }
protected abstract String getModelType();
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/ModelUrn.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/ModelUrn.java
index a89bc23..81f0433 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/ModelUrn.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/ModelUrn.java
@@ -1,10 +1,19 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.metamodel.map.descriptor;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -14,23 +23,20 @@
* @author kuhn
*
*/
-public class ModelUrn implements IIdentifier {
+public class ModelUrn extends Identifier {
private static Logger logger = LoggerFactory.getLogger(ModelUrn.class);
-
- /**
- * URN string
- */
- protected String urnString = null;
-
-
+ private ModelUrn() {
+ setIdType(IdentifierType.IRI);
+ }
/**
* Constructor that accepts a single, raw URN
*/
public ModelUrn(String rawURN) {
- urnString = rawURN;
+ this();
+ setId(rawURN);
}
@@ -38,6 +44,7 @@
* Constructor that build a URN
*/
public ModelUrn(String legalEntity, String subUnit, String subModel, String version, String revision, String elementId, String elementInstance) {
+ this();
// Goal is: urn:<legalEntity>:<subUnit>:<subModel>:<version>:<revision>:<elementID>#<elementInstance>
StringBuffer urnBuilder = new StringBuffer();
@@ -54,7 +61,7 @@
if (elementInstance != null) urnBuilder.append("#"+elementInstance);
// Build URN
- urnString = urnBuilder.toString();
+ setId(urnBuilder.toString());
}
@@ -63,7 +70,7 @@
* Get URN as string
*/
public String getURN() {
- return urnString;
+ return getId();
}
@@ -73,7 +80,7 @@
public String getEncodedURN() {
try {
// Try to encode urn string
- return URLEncoder.encode(urnString, "UTF-8");
+ return URLEncoder.encode(getId(), "UTF-8");
} catch (UnsupportedEncodingException e) {
// Catch block
logger.error("Exception in getEncodedURN", e);
@@ -86,44 +93,7 @@
*/
public ModelUrn append(String suffix) {
// Append suffix
- return new ModelUrn(urnString + suffix);
- }
-
- /**
- * A ModelUrn is a unique identifier and is a specialization of an URI
- */
- @Override
- public IdentifierType getIdType() {
- return IdentifierType.IRI;
- }
-
- /**
- * A ModelUrn is a unique identifier => the urn is the id
- */
- @Override
- public String getId() {
- return getURN();
- }
-
- /**
- * HashCode method - required to be able to use this class as hashmap key
- */
- @Override
- public int hashCode() {
- return urnString.hashCode();
- }
-
-
- /**
- * Check equality - required to be able to use this class as hashmap key
- */
- @Override
- public boolean equals(Object obj) {
- // Type check
- if (!(obj instanceof ModelUrn)) return false;
-
- // Check values
- return urnString.equals(((ModelUrn) obj).urnString);
+ return new ModelUrn(getId() + suffix);
}
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/SubmodelDescriptor.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/SubmodelDescriptor.java
index 2149eda..2ccb817 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/SubmodelDescriptor.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/SubmodelDescriptor.java
@@ -1,11 +1,23 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.metamodel.map.descriptor;
import java.util.Map;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.IHasSemantics;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
@@ -16,7 +28,7 @@
* @author kuhn
*
*/
-public class SubmodelDescriptor extends ModelDescriptor {
+public class SubmodelDescriptor extends ModelDescriptor implements IHasSemantics {
public static final String MODELTYPE = "SubmodelDescriptor";
@@ -25,13 +37,14 @@
*/
public SubmodelDescriptor(Map<String, Object> map) {
super(map);
+ validate(map);
}
/**
* Create a new aas descriptor with minimal information based on an existing
* submodel.
*/
- public SubmodelDescriptor(ISubModel sm, String httpEndpoint) {
+ public SubmodelDescriptor(ISubmodel sm, String httpEndpoint) {
// Create descriptor with minimal information (id and idShort)
this(sm.getIdShort(), sm.getIdentification(), httpEndpoint);
@@ -42,7 +55,7 @@
* Create a new descriptor with minimal information
*/
public SubmodelDescriptor(String idShort, IIdentifier id, String httpEndpoint) {
- super(idShort, id, httpEndpoint);
+ super(idShort, id, harmonizeEndpoint(httpEndpoint));
// Add model type
putAll(new ModelType(MODELTYPE));
@@ -52,5 +65,23 @@
protected String getModelType() {
return MODELTYPE;
}
+
+ private static String harmonizeEndpoint(String endpoint) {
+ if (!endpoint.endsWith("/submodel")) {
+ return endpoint + "/submodel";
+ } else {
+ return endpoint;
+ }
+ }
+
+ @Override
+ public IReference getSemanticId() {
+ return HasSemantics.createAsFacade(this).getSemanticId();
+ }
+
+ public void setSemanticId(Reference ref) {
+ HasSemantics.createAsFacade(this).setSemanticId(ref);
+ }
+
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/Asset.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/Asset.java
index 6c2f8d5..c62365b 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/Asset.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/Asset.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.metamodel.map.parts;
import java.util.Collection;
@@ -5,6 +14,7 @@
import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IEmbeddedDataSpecification;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
@@ -49,8 +59,20 @@
putAll(new Identifiable());
// Default values
- put(ASSETIDENTIFICATIONMODEL, null);
- put(KIND, null);
+ setAssetKind(AssetKind.INSTANCE);
+ }
+
+ /**
+ * Constructor accepting only mandatory attributes
+ * @param idShort
+ * @param identification
+ * @param kind
+ */
+ public Asset(String idShort, IIdentifier identification, AssetKind kind) {
+ this();
+ setIdentification(identification);
+ setIdShort(idShort);
+ setAssetKind(kind);
}
/**
@@ -76,10 +98,25 @@
if (map == null) {
return null;
}
+
+ if (!isValid(map)) {
+ throw new MetamodelConstructionException(Asset.class, map);
+ }
+
Asset ret = new Asset();
ret.setMap(map);
return ret;
}
+
+ /**
+ * Check whether all mandatory elements for the metamodel
+ * exist in a map
+ * @return true/false
+ */
+ public static boolean isValid(Map<String, Object> map) {
+ return Identifiable.isValid(map) &&
+ map.containsKey(Asset.KIND);
+ }
@Override
public Collection<IReference> getDataSpecificationReferences() {
@@ -122,8 +159,12 @@
Identifiable.createAsFacade(this, getKeyElement()).setAdministration(information);
}
+ public void setIdentification(IIdentifier id) {
+ setIdentification(id.getIdType(), id.getId());
+ }
+
public void setIdentification(IdentifierType idType, String id) {
- Identifiable.createAsFacade(this, getKeyElement()).setIdentification(idType, id);
+ Identifiable.createAsFacadeNonStrict(this, getKeyElement()).setIdentification(idType, id);
}
@Override
@@ -156,7 +197,7 @@
}
public void setIdShort(String idShort) {
- Referable.createAsFacade(this, getKeyElement()).setIdShort(idShort);
+ Referable.createAsFacadeNonStrict(this, getKeyElement()).setIdShort(idShort);
}
public void setCategory(String category) {
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/ConceptDictionary.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/ConceptDictionary.java
index 53e3ed5..b418b99 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/ConceptDictionary.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/ConceptDictionary.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.metamodel.map.parts;
import java.util.ArrayList;
@@ -5,6 +14,7 @@
import java.util.Map;
import org.eclipse.basyx.aas.metamodel.api.parts.IConceptDictionary;
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
import org.eclipse.basyx.submodel.metamodel.api.parts.IConceptDescription;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
@@ -32,10 +42,18 @@
* Constructor
*/
public ConceptDictionary() {
- putAll(new Referable());
put(CONCEPTDESCRIPTION, new ArrayList<IReference>());
put(CONCEPTDESCRIPTIONS, new ArrayList<IConceptDescription>());
}
+
+ /**
+ * Constructor accepting only mandatory attribute
+ * @param idShort
+ */
+ public ConceptDictionary(String idShort) {
+ this();
+ setIdShort(idShort);
+ }
public ConceptDictionary(Collection<IReference> ref) {
putAll(new Referable());
@@ -55,11 +73,24 @@
if (map == null) {
return null;
}
-
+
+ if (!isValid(map)) {
+ throw new MetamodelConstructionException(ConceptDictionary.class, map);
+ }
+
ConceptDictionary ret = new ConceptDictionary();
ret.setMap(map);
return ret;
}
+
+ /**
+ * Check whether all mandatory elements for the metamodel
+ * exist in a map
+ * @return true/false
+ */
+ public static boolean isValid(Map<String, Object> map) {
+ return Referable.isValid(map);
+ }
@Override
public String getIdShort() {
@@ -82,7 +113,7 @@
}
public void setIdShort(String idShort) {
- Referable.createAsFacade(this, getKeyElement()).setIdShort(idShort);
+ Referable.createAsFacadeNonStrict(this, getKeyElement()).setIdShort(idShort);
}
public void setCategory(String category) {
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/View.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/View.java
index 7bb740a..8b80b01 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/View.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/View.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.metamodel.map.parts;
import java.util.Collection;
@@ -6,6 +15,7 @@
import java.util.Set;
import org.eclipse.basyx.aas.metamodel.api.parts.IView;
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IEmbeddedDataSpecification;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
@@ -38,13 +48,20 @@
putAll(new ModelType(MODELTYPE));
// Add qualifiers
- putAll(new HasSemantics());
putAll(new HasDataSpecification());
- putAll(new Referable());
// Default values
put(CONTAINEDELEMENT, new HashSet<Reference>());
}
+
+ /**
+ * Constructor accepting only mandatory attribute
+ * @param idShort
+ */
+ public View(String idShort) {
+ this();
+ setIdShort(idShort);
+ }
/**
*
@@ -67,11 +84,24 @@
if (map == null) {
return null;
}
-
+
+ if (!isValid(map)) {
+ throw new MetamodelConstructionException(View.class, map);
+ }
+
View ret = new View();
ret.setMap(map);
return ret;
}
+
+ /**
+ * Check whether all mandatory elements for the metamodel
+ * exist in a map
+ * @return true/false
+ */
+ public static boolean isValid(Map<String, Object> map) {
+ return Referable.isValid(map);
+ }
public void setContainedElement(Collection<IReference> references) {
put(View.CONTAINEDELEMENT, references);
@@ -88,7 +118,7 @@
}
public void setSemanticId(IReference ref) {
- HasSemantics.createAsFacade(this).setSemanticID(ref);
+ HasSemantics.createAsFacade(this).setSemanticId(ref);
}
@@ -131,7 +161,7 @@
}
public void setIdShort(String idShort) {
- Referable.createAsFacade(this, getKeyElement()).setIdShort(idShort);
+ Referable.createAsFacadeNonStrict(this, getKeyElement()).setIdShort(idShort);
}
public void setCategory(String category) {
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/AccessControlPolicyPoints.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/AccessControlPolicyPoints.java
index ec0480b..30e71fe 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/AccessControlPolicyPoints.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/AccessControlPolicyPoints.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.metamodel.map.policypoints;
import java.util.Map;
@@ -20,14 +29,7 @@
/**
* Constructor
*/
- public AccessControlPolicyPoints() {
- // Default values
- put(POLICYADMINISTRATIONPOINT, null);
- put(POLICYDECISIONPOINT, null);
- put(POLICYENFORECEMENTPOINT, null);
-
- put(POLICYINFORMATIONPOINTS, null);
- }
+ public AccessControlPolicyPoints() {}
/**
* Creates a DataSpecificationIEC61360 object from a map
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyAdministrationPoint.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyAdministrationPoint.java
index bbe2f24..8495d8b 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyAdministrationPoint.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyAdministrationPoint.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.metamodel.map.policypoints;
/**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyDecisionPoint.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyDecisionPoint.java
index 33a8994..824f657 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyDecisionPoint.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyDecisionPoint.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.metamodel.map.policypoints;
/**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyEnforcementPoint.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyEnforcementPoint.java
index eaacae3..158c7b9 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyEnforcementPoint.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyEnforcementPoint.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.metamodel.map.policypoints;
/**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyInformationPoints.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyInformationPoints.java
index 19dcd5b..908ff56 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyInformationPoints.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyInformationPoints.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.metamodel.map.policypoints;
/**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/security/Security.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/security/Security.java
index 01feb38..32ff7f9 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/security/Security.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/security/Security.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.metamodel.map.security;
import java.util.Map;
@@ -23,11 +32,7 @@
/**
* Constructor
*/
- public Security() {
- // Default values
- put(ACCESSCONTROLPOLICYPOINTS, null);
- put(CERTIFICATE, null);
- }
+ public Security() {}
/**
* Creates a Security object from a map
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/api/IAASRegistry.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/api/IAASRegistry.java
new file mode 100644
index 0000000..2173b06
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/api/IAASRegistry.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.registration.api;
+
+import java.util.List;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+
+
+
+
+/**
+ * BaSys registry interface
+ *
+ * @author kuhn
+ *
+ */
+public interface IAASRegistry {
+
+ /**
+ * Register AAS descriptor in registry, delete old registration
+ */
+ public void register(AASDescriptor deviceAASDescriptor) throws ProviderException;
+
+ /**
+ * Register SM descriptor in registry, delete old registration
+ */
+ public void register(IIdentifier aas, SubmodelDescriptor smDescriptor) throws ProviderException;
+
+ /**
+ * Delete AAS descriptor from registry
+ */
+ public void delete(IIdentifier aasId) throws ProviderException;
+
+ /**
+ * Delete SM descriptor from registry
+ */
+ public void delete(IIdentifier aasId, IIdentifier smId) throws ProviderException;
+
+ /**
+ * Lookup AAS
+ */
+ public AASDescriptor lookupAAS(IIdentifier aasId) throws ProviderException;
+
+ /**
+ * Retrieve all registered AAS
+ *
+ * @return
+ */
+ public List<AASDescriptor> lookupAll() throws ProviderException;
+
+ /**
+ * Retrieves all SubmodelDescriptors of submodels of an AAS
+ *
+ * @param aasId
+ * of the AAS
+ * @return list of SubmodelDescriptors
+ * @throws ProviderException
+ */
+ public List<SubmodelDescriptor> lookupSubmodels(IIdentifier aasId) throws ProviderException;
+
+ /**
+ * Retrieves the SubmodelDescriptor of a specific submodel of an AAS
+ *
+ * @param aasId
+ * of the AAS
+ * @param smId
+ * of the Submodel
+ * @return the SubmodelDescriptor
+ * @throws ProviderException
+ */
+ public SubmodelDescriptor lookupSubmodel(IIdentifier aasId, IIdentifier smId) throws ProviderException;
+
+}
+
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/api/IAASRegistryService.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/api/IAASRegistryService.java
deleted file mode 100644
index 2dc8ede..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/api/IAASRegistryService.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package org.eclipse.basyx.aas.registration.api;
-
-import java.util.List;
-
-import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.vab.exception.provider.ProviderException;
-
-
-
-
-/**
- * BaSys registry interface
- *
- * @author kuhn
- *
- */
-public interface IAASRegistryService {
-
- /**
- * Register AAS descriptor in registry, delete old registration
- */
- public void register(AASDescriptor deviceAASDescriptor) throws ProviderException;
-
- /**
- * Register SM descriptor in registry, delete old registration
- */
- public void register(IIdentifier aas, SubmodelDescriptor smDescriptor) throws ProviderException;
-
- /**
- * Delete AAS descriptor from registry
- */
- public void delete(IIdentifier aasId) throws ProviderException;
-
- /**
- * Delete SM descriptor from registry
- */
- public void delete(IIdentifier aasId, String smIdShort) throws ProviderException;
-
- /**
- * Lookup AAS
- */
- public AASDescriptor lookupAAS(IIdentifier aasId) throws ProviderException;
-
- /**
- * Retrieve all registered AAS
- *
- * @return
- */
- public List<AASDescriptor> lookupAll() throws ProviderException;
-}
-
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/AASRegistry.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/AASRegistry.java
new file mode 100644
index 0000000..021d654
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/AASRegistry.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.registration.memory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implements a generic AAS registry that makes use of a given handler.
+ */
+public class AASRegistry implements IAASRegistry {
+ private static Logger logger = LoggerFactory.getLogger(AASRegistry.class);
+ protected IRegistryHandler handler;
+
+ public AASRegistry(IRegistryHandler handler) {
+ this.handler = handler;
+ }
+
+ @Override
+ public void register(AASDescriptor aasDescriptor) {
+ IIdentifier aasIdentifier = aasDescriptor.getIdentifier();
+ if (handler.contains(aasIdentifier)) {
+ handler.update(aasDescriptor);
+ } else {
+ handler.insert(aasDescriptor);
+ }
+ logger.debug("Registered " + aasIdentifier.getId());
+ }
+
+ @Override
+ public void delete(IIdentifier aasIdentifier) {
+ String aasId = aasIdentifier.getId();
+ if (!handler.contains(aasIdentifier)) {
+ throw new ResourceNotFoundException(
+ "Could not delete key for AAS " + aasId + " since it does not exist");
+ } else {
+ handler.remove(aasIdentifier);
+ logger.debug("Removed " + aasId);
+ }
+ }
+
+ @Override
+ public AASDescriptor lookupAAS(IIdentifier aasIdentifier) {
+ String aasId = aasIdentifier.getId();
+ if (!handler.contains(aasIdentifier)) {
+ throw new ResourceNotFoundException(
+ "Could not look up descriptor for AAS " + aasId + " since it does not exist");
+ }
+ return handler.get(aasIdentifier);
+ }
+
+ @Override
+ public List<AASDescriptor> lookupAll() {
+ logger.debug("Looking up all AAS");
+ return handler.getAll();
+ }
+
+ @Override
+ public void register(IIdentifier aas, SubmodelDescriptor smDescriptor) {
+ try {
+ delete(aas, smDescriptor.getIdentifier());
+ } catch (ResourceNotFoundException e) {
+ // Doesn't matter
+ }
+
+ AASDescriptor descriptor = handler.get(aas);
+ if(descriptor == null) {
+ throw new ResourceNotFoundException(
+ "Could not add submodel descriptor for AAS " + aas.getId() + " since the AAS does not exist");
+ }
+
+ descriptor.addSubmodelDescriptor(smDescriptor);
+ handler.update(descriptor);
+ logger.debug("Registered submodel " + smDescriptor.getIdShort() + " for AAS " + aas.getId());
+ }
+
+ @Override
+ public void delete(IIdentifier aasId, IIdentifier smId) {
+ String smIdString = smId.getId();
+ AASDescriptor desc = handler.get(aasId);
+ if (desc == null) {
+ throw new ResourceNotFoundException(
+ "Could not delete submodel descriptor for AAS " + aasId.getId() + " since the AAS does not exist");
+ }
+ if (desc.getSubmodelDescriptorFromIdentifierId(smIdString) == null) {
+ throw new ResourceNotFoundException(
+ "Could not delete submodel descriptor for AAS " + aasId.getId() + " since the SM does not exist");
+ }
+
+ desc.removeSubmodelDescriptor(smId);
+ handler.update(desc);
+ logger.debug("Deleted submodel " + smIdString + " from AAS " + aasId.getId());
+ }
+
+ @Override
+ public List<SubmodelDescriptor> lookupSubmodels(IIdentifier aasId) throws ProviderException {
+ AASDescriptor desc = handler.get(aasId);
+ if (desc == null) {
+ throw new ResourceNotFoundException("Could not look up submodels for AAS " + aasId + " since it does not exist");
+ }
+
+ return new ArrayList<>(desc.getSubmodelDescriptors());
+ }
+
+ @Override
+ public SubmodelDescriptor lookupSubmodel(IIdentifier aasId, IIdentifier smId) throws ProviderException {
+ AASDescriptor desc = handler.get(aasId);
+ if (desc == null) {
+ throw new ResourceNotFoundException("Could not look up descriptor for SM " + smId + " of AAS " + aasId + " since the AAS does not exist");
+ }
+ SubmodelDescriptor smDesc = desc.getSubmodelDescriptorFromIdentifierId(smId.getId());
+ if (smDesc == null) {
+ throw new ResourceNotFoundException("Could not look up descriptor for SM " + smId + " of AAS " + aasId + " since the SM does not exist");
+ }
+ return smDesc;
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/IRegistryHandler.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/IRegistryHandler.java
new file mode 100644
index 0000000..d0c723f
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/IRegistryHandler.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.registration.memory;
+
+import java.util.List;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+/**
+ * An interface for a registry handler for different types of registry datasources.
+ *
+ * @author espen
+ *
+ */
+public interface IRegistryHandler {
+ /**
+ * Queries the registry datasource to check, if an entry with the given identifier exists.
+ *
+ * @param id The asset- or AAS-identifier that will be checked
+ * @return True, if an entry with the given identifier exists
+ */
+ public boolean contains(IIdentifier id);
+
+ /**
+ * Removes an entry with a given identifier from the registry datasource
+ *
+ * @param id The asset- or AAS-identifier that will be removed
+ */
+ public void remove(IIdentifier id);
+
+ /**
+ * Inserts a new descriptor into the registry datasource.
+ *
+ * @param descriptor The descriptor that will be inserted.
+ */
+ public void insert(AASDescriptor descriptor);
+
+ /**
+ * Updates a given descriptor. It is assumed that an entry with the same AAS id already exists in the registry
+ * datasource.
+ *
+ * @param descriptor The descriptor that will be inserted.
+ */
+ public void update(AASDescriptor descriptor);
+
+ /**
+ * Queries the registry datasource for a entry with the given identifier.
+ *
+ * @param id The asset- or AAS-identifier for which the descriptor should be retrieved.
+ * @return The found descriptor from the registry datasource matching the id.
+ */
+ public AASDescriptor get(IIdentifier id);
+
+ /**
+ * Returns a list of all descriptors contained in the registry datasource.
+ *
+ * @return The list of AASDescriptors.
+ */
+ public List<AASDescriptor> getAll();
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/InMemoryRegistry.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/InMemoryRegistry.java
index 54c5046..a1d5625 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/InMemoryRegistry.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/InMemoryRegistry.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.registration.memory;
import java.util.HashMap;
@@ -9,12 +18,12 @@
* @author espen
*
*/
-public class InMemoryRegistry extends MapRegistry {
+public class InMemoryRegistry extends AASRegistry {
/**
* Default constructor based on HashMaps
*/
public InMemoryRegistry() {
- super(new HashMap<>());
+ super(new MapRegistryHandler(new HashMap<>()));
}
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/MapRegistry.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/MapRegistry.java
deleted file mode 100644
index cccea83..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/MapRegistry.java
+++ /dev/null
@@ -1,132 +0,0 @@
-package org.eclipse.basyx.aas.registration.memory;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Implements a preconfigured registry based on the Map interface
- */
-public class MapRegistry implements IAASRegistryService {
- protected Map<String, AASDescriptor> descriptorMap;
-
- Logger logger = LoggerFactory.getLogger(MapRegistry.class);
-
- /**
- * Constructor that takes a reference to a map as a base for the registry
- * entries
- */
- public MapRegistry(Map<String, AASDescriptor> rootMap) {
- descriptorMap = rootMap;
- }
-
- @Override
- public void register(AASDescriptor aasDescriptor) {
- String aasId = aasDescriptor.getIdentifier().getId();
-
- // Get the Asset identifier from the descriptor
- IAsset asset = aasDescriptor.getAsset();
-
- if (descriptorMap.containsKey(aasId)) {
- descriptorMap.remove(aasId);
- }
-
- // If asset identifier exists, delete the existing mapping,
- // and add the new mapping
- if (asset != null) {
- IIdentifier assetIdentifier = asset.getIdentification();
- if (descriptorMap.containsKey(assetIdentifier.getId())) {
- descriptorMap.remove(assetIdentifier.getId());
- }
- descriptorMap.put(assetIdentifier.getId(), aasDescriptor);
- }
-
-
- descriptorMap.put(aasId, aasDescriptor);
- logger.debug("Registered " + aasId);
- }
-
- @Override
- public void delete(IIdentifier aasIdentifier) {
- String aasId = aasIdentifier.getId();
- if (!descriptorMap.containsKey(aasId)) {
- throw new ResourceNotFoundException("Could not delete key for AAS " + aasId + " since it does not exist");
- } else {
- AASDescriptor aasDescriptor = lookupAAS(aasIdentifier);
- descriptorMap.remove(aasId);
-
- // Get the identifier of the asset
- IAsset asset = aasDescriptor.getAsset();
- // Delete the Mapping of asset-id to the AAS if exists
- if (asset != null) {
- descriptorMap.remove(asset.getIdentification().getId());
- }
-
- logger.debug("Removed " + aasId);
- }
- }
-
- @Override
- public AASDescriptor lookupAAS(IIdentifier aasIdentifier) {
- String aasId = aasIdentifier.getId();
- if (!descriptorMap.containsKey(aasId)) {
- throw new ResourceNotFoundException("Could not look up descriptor for AAS " + aasId + " since it does not exist");
- }
- return descriptorMap.get(aasIdentifier.getId());
- }
-
-
- @Override
- public List<AASDescriptor> lookupAll() {
- logger.debug("Looking up all AAS");
- // duplicate entries should be filtered
- return new ArrayList<>(new HashSet<>(descriptorMap.values()));
- }
-
- @Override
- public void register(IIdentifier aas, SubmodelDescriptor smDescriptor) {
-
-
- try {
- delete(aas, smDescriptor.getIdShort());
- } catch (ResourceNotFoundException e) {
- // Doesn't matter
- }
-
- AASDescriptor descriptor = descriptorMap.get(aas.getId());
- descriptor.addSubmodelDescriptor(smDescriptor);
- // Do not assume that the returned descriptor is referenced in the base map
- descriptorMap.put(aas.getId(), descriptor);
- logger.debug("Registered submodel " + smDescriptor.getIdShort() + " for AAS " + aas.getId());
- }
-
- @Override
- public void delete(IIdentifier aasId, String smIdShort) {
- AASDescriptor desc = descriptorMap.get(aasId.getId());
- if (desc == null) {
- throw new ResourceNotFoundException("Could not delete submodel descriptor for AAS " + aasId + " since the AAS does not exist");
- }
-
- if (desc.getSubmodelDescriptorFromIdShort(smIdShort) == null) {
- throw new ResourceNotFoundException("Could not delete submodel descriptor for AAS " + aasId + " since the SM does not exist");
- }
-
- desc.removeSubmodelDescriptor(smIdShort);
- // Do not assume that the returned descriptor is referenced in the base map
- descriptorMap.put(aasId.getId(), desc);
-
- logger.debug("Deleted submodel " + smIdShort + " from AAS " + aasId.getId());
-
- }
-
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/MapRegistryHandler.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/MapRegistryHandler.java
new file mode 100644
index 0000000..cccb80b
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/MapRegistryHandler.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.registration.memory;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+/**
+ * Implements a preconfigured registry based on the Map interface
+ */
+public class MapRegistryHandler implements IRegistryHandler {
+ protected Map<String, AASDescriptor> descriptorMap;
+
+ /**
+ * Constructor that takes a reference to a map as a base for the registry
+ * entries
+ */
+ public MapRegistryHandler(Map<String, AASDescriptor> rootMap) {
+ descriptorMap = rootMap;
+ }
+
+ @Override
+ public boolean contains(IIdentifier id) {
+ return descriptorMap.containsKey(id.getId());
+ }
+
+ @Override
+ public void remove(IIdentifier id) {
+ AASDescriptor removed = descriptorMap.remove(id.getId());
+
+ IIdentifier aasId = removed.getIdentifier();
+ if (!aasId.getId().equals(id.getId())) {
+ // id is an assetId => also remove the aasId-mapping
+ descriptorMap.remove(aasId.getId());
+ } else {
+ IAsset asset = removed.getAsset();
+ if (asset != null) {
+ IIdentifier assetId = asset.getIdentification();
+ descriptorMap.remove(assetId.getId());
+ }
+ }
+ }
+
+ @Override
+ public void insert(AASDescriptor descriptor) {
+ // insert with descriptor id
+ String id = descriptor.getIdentifier().getId();
+ descriptorMap.put(id, descriptor);
+
+ // insert with asset id if present
+ IAsset asset = descriptor.getAsset();
+ if (asset != null) {
+ String assetId = asset.getIdentification().getId();
+ descriptorMap.put(assetId, descriptor);
+ }
+ }
+
+ @Override
+ public void update(AASDescriptor descriptor) {
+ insert(descriptor); // has no semantic difference for hashmaps
+ }
+
+ @Override
+ public AASDescriptor get(IIdentifier id) {
+ return descriptorMap.get(id.getId());
+ }
+
+ @Override
+ public List<AASDescriptor> getAll() {
+ return new ArrayList<>(new HashSet<>(descriptorMap.values()));
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/proxy/AASRegistryProxy.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/proxy/AASRegistryProxy.java
index a84b403..c5c5380 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/proxy/AASRegistryProxy.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/proxy/AASRegistryProxy.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.registration.proxy;
import java.io.UnsupportedEncodingException;
@@ -9,16 +18,16 @@
import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
-import org.eclipse.basyx.aas.registration.restapi.DirectoryModelProvider;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.restapi.AASRegistryModelProvider;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
-import org.eclipse.basyx.vab.directory.proxy.VABDirectoryProxy;
import org.eclipse.basyx.vab.exception.provider.ProviderException;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
import org.eclipse.basyx.vab.modelprovider.VABPathTools;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnector;
+import org.eclipse.basyx.vab.registry.proxy.VABRegistryProxy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -27,10 +36,10 @@
/**
* Local proxy class that hides HTTP calls to BaSys registry
*
- * @author kuhn
+ * @author kuhn, schnicke
*
*/
-public class AASRegistryProxy extends VABDirectoryProxy implements IAASRegistryService {
+public class AASRegistryProxy extends VABRegistryProxy implements IAASRegistry {
private static Logger logger = LoggerFactory.getLogger(AASRegistryProxy.class);
@@ -41,7 +50,20 @@
* The endpoint of the registry with a HTTP-REST interface
*/
public AASRegistryProxy(String registryUrl) {
- this(new JSONConnector(new HTTPConnector(registryUrl)));
+ this(new JSONConnector(new HTTPConnector(harmonizeURL(registryUrl))));
+ }
+
+ /**
+ * Removes prefix if it exists since it will be readded at a later stage
+ *
+ * @param url
+ * @return
+ */
+ private static String harmonizeURL(String url) {
+ if (url.endsWith(AASRegistryModelProvider.PREFIX)) {
+ url = url.substring(0, url.length() - AASRegistryModelProvider.PREFIX.length());
+ }
+ return url;
}
/**
@@ -55,7 +77,7 @@
}
private static VABElementProxy createProxy(IModelProvider provider) {
- return new VABElementProxy(DirectoryModelProvider.PREFIX, provider);
+ return new VABElementProxy(AASRegistryModelProvider.PREFIX, provider);
}
/**
@@ -69,7 +91,7 @@
// Typically, VAB SET should not create new entries. Nevertheless, the registry
// API is defined to do it.
- provider.setModelPropertyValue(encodedId, deviceAASDescriptor);
+ provider.setValue(encodedId, deviceAASDescriptor);
} catch (Exception e) {
if (e instanceof ProviderException) {
throw (ProviderException) e;
@@ -98,7 +120,7 @@
@Override @SuppressWarnings("unchecked")
public AASDescriptor lookupAAS(IIdentifier aasIdentifier) throws ProviderException {
try {
- Object result = provider.getModelPropertyValue(URLEncoder.encode(aasIdentifier.getId(), "UTF-8"));
+ Object result = provider.getValue(URLEncoder.encode(aasIdentifier.getId(), "UTF-8"));
return new AASDescriptor((Map<String, Object>) result);
} catch (Exception e) {
if (e instanceof ProviderException) {
@@ -113,7 +135,7 @@
@Override
public List<AASDescriptor> lookupAll() throws ProviderException {
try {
- Object result = provider.getModelPropertyValue("");
+ Object result = provider.getValue("");
Collection<?> descriptors = (Collection<?>) result;
return descriptors.stream().map(x -> new AASDescriptor((Map<String, Object>) x)).collect(Collectors.toList());
} catch (Exception e) {
@@ -130,7 +152,7 @@
try {
// Typically, VAB SET should not create new entries. Nevertheless, the registry
// API is defined to do it.
- provider.setModelPropertyValue(VABPathTools.concatenatePaths(buildSubmodelPath(aas), smDescriptor.getIdShort()), smDescriptor);
+ provider.setValue(VABPathTools.concatenatePaths(buildSubmodelPath(aas), URLEncoder.encode(smDescriptor.getIdentifier().getId(), "UTF-8")), smDescriptor);
} catch (Exception e) {
if (e instanceof ProviderException) {
throw (ProviderException) e;
@@ -141,9 +163,9 @@
}
@Override
- public void delete(IIdentifier aasId, String smIdShort) throws ProviderException {
+ public void delete(IIdentifier aasId, IIdentifier smId) throws ProviderException {
try {
- provider.deleteValue(VABPathTools.concatenatePaths(buildSubmodelPath(aasId), URLEncoder.encode(smIdShort, "UTF-8")));
+ provider.deleteValue(VABPathTools.concatenatePaths(buildSubmodelPath(aasId), URLEncoder.encode(smId.getId(), "UTF-8")));
} catch (Exception e) {
if (e instanceof ProviderException) {
throw (ProviderException) e;
@@ -156,7 +178,38 @@
private String buildSubmodelPath(IIdentifier aas) throws ProviderException {
// Encode id to handle usage of reserved symbols, e.g. /
String encodedAASId = VABPathTools.encodePathElement(aas.getId());
- return VABPathTools.concatenatePaths(encodedAASId, DirectoryModelProvider.SUBMODELS);
+ return VABPathTools.concatenatePaths(encodedAASId, AASRegistryModelProvider.SUBMODELS);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public List<SubmodelDescriptor> lookupSubmodels(IIdentifier aasId) throws ProviderException {
+ try {
+ Object result = provider.getValue(VABPathTools.concatenatePaths(buildSubmodelPath(aasId)));
+ Collection<?> descriptors = (Collection<?>) result;
+ return descriptors.stream().map(x -> new SubmodelDescriptor((Map<String, Object>) x)).collect(Collectors.toList());
+ } catch (Exception e) {
+ if (e instanceof ProviderException) {
+ throw (ProviderException) e;
+ } else {
+ throw new ProviderException(e);
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public SubmodelDescriptor lookupSubmodel(IIdentifier aasId, IIdentifier smId) throws ProviderException {
+ try {
+ Object result = provider.getValue(VABPathTools.concatenatePaths(buildSubmodelPath(aasId), URLEncoder.encode(smId.getId(), "UTF-8")));
+ return new SubmodelDescriptor((Map<String, Object>) result);
+ } catch (Exception e) {
+ if (e instanceof ProviderException) {
+ throw (ProviderException) e;
+ } else {
+ throw new ProviderException(e);
+ }
+ }
}
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/restapi/AASRegistryModelProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/restapi/AASRegistryModelProvider.java
new file mode 100644
index 0000000..be780dc
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/restapi/AASRegistryModelProvider.java
@@ -0,0 +1,328 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.registration.restapi;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+
+/**
+ * Connects an arbitrary IRegistryService implementation to the VAB
+ *
+ * @author schnicke, conradi
+ *
+ */
+public class AASRegistryModelProvider implements IModelProvider {
+
+ IAASRegistry registry;
+
+ public static final String PREFIX = "api/v1/registry";
+ public static final String SUBMODELS = "submodels";
+
+ public AASRegistryModelProvider(IAASRegistry registry) {
+ this.registry = registry;
+ }
+
+ public AASRegistryModelProvider() {
+ this(new InMemoryRegistry());
+ }
+
+ /**
+ * Check for correctness of path and returns a stripped path (i.e. no leading
+ * prefix)
+ *
+ * @param path
+ * @return
+ * @throws MalformedRequestException if path does not start with PERFIX "api/v1/registry"
+ */
+ private String stripPrefix(String path) throws MalformedRequestException {
+ path = VABPathTools.stripSlashes(path);
+ if (!path.startsWith(PREFIX)) {
+ throw new MalformedRequestException("Path " + path + " not recognized as registry path. Has to start with " + PREFIX);
+ }
+ path = path.replaceFirst(PREFIX, "");
+ path = VABPathTools.stripSlashes(path);
+ return path;
+ }
+
+ /**
+ * Splits a path and checks, that first element is not "submodels" and that the second one, if exists, is "submodels"
+ *
+ * @param path the path to be splitted
+ * @return Array of path elements
+ * @throws MalformedRequestException if path is not valid
+ */
+ private String[] splitPath(String path) throws MalformedRequestException {
+
+ if(path.isEmpty()) {
+ return new String[0];
+ }
+
+ String[] splitted = path.split("/");
+
+ //Assumes "submodels" is not a valid AASId
+ if(splitted[0].equals(SUBMODELS)) {
+ throw new MalformedRequestException("Path must not start with " + SUBMODELS);
+ }
+
+ //If path contains more than one element, the second one has to be "submodels"
+ if(splitted.length > 1 && !splitted[1].equals(SUBMODELS)) {
+ throw new MalformedRequestException("Second path element must be (if present): " + SUBMODELS);
+ }
+
+ return splitted;
+ }
+
+ private String[] preparePath(String path) throws MalformedRequestException {
+ path = stripPrefix(path);
+
+ String[] splitted = splitPath(path);
+
+ try {
+ for (int i = 0; i < splitted.length; i++) {
+ splitted[i] = URLDecoder.decode(splitted[i], "UTF-8");
+ }
+ return splitted;
+ } catch (UnsupportedEncodingException e) {
+ //Malformed request because of unsupported encoding
+ throw new MalformedRequestException("Path has to be encoded as UTF-8 string.");
+ }
+ }
+
+ /**
+ * Checks if a given Object is a Map and checks if it has the correct modelType
+ *
+ * @param expectedModelType the modelType the Object is expected to have
+ * @param value the Object to be checked and casted
+ * @return the object casted to a Map
+ * @throws MalformedRequestException
+ */
+ @SuppressWarnings("unchecked")
+ private Map<String, Object> checkModelType(String expectedModelType, Object value) throws MalformedRequestException {
+ //check if the given value is a Map
+ if(!(value instanceof Map)) {
+ throw new MalformedRequestException("Given newValue is not a Map");
+ }
+
+ Map<String, Object> map = (Map<String, Object>) value;
+
+ //check if the given Map contains an AAS
+ String type = ModelType.createAsFacade(map).getName();
+
+ //have to accept Objects without modeltype information,
+ //as modeltype is not part of the public metamodel
+ if(!expectedModelType.equals(type) && type != null) {
+ throw new MalformedRequestException("Given newValue map has not the correct ModelType");
+ }
+
+ return map;
+ }
+
+ /**
+ * Makes sure, that given Object is an AASDescriptor by checking its ModelType<br />
+ * Creates a new AASDescriptor with the content of the given Map
+ *
+ * @param value the AAS Map object
+ * @return an AAS
+ * @throws MalformedRequestException
+ */
+ private AASDescriptor createAASDescriptorFromMap(Object value) throws MalformedRequestException {
+ Map<String, Object> map = checkModelType(AASDescriptor.MODELTYPE, value);
+ AASDescriptor aasDescriptor = new AASDescriptor(map);
+ return aasDescriptor;
+ }
+
+ /**
+ * Makes sure, that given Object is an SubmodelDescriptor by checking its ModelType<br />
+ * Creates a new SubmodelDescriptor with the content of the given Map
+ *
+ * @param value the AAS Map object
+ * @return an AAS
+ * @throws MalformedRequestException
+ */
+ private SubmodelDescriptor createSMDescriptorFromMap(Object value) throws MalformedRequestException {
+ Map<String, Object> map = checkModelType(SubmodelDescriptor.MODELTYPE, value);
+ SubmodelDescriptor smDescriptor = new SubmodelDescriptor(map);
+ return smDescriptor;
+ }
+
+ @Override
+ public Object getValue(String path) throws ProviderException {
+ String[] splitted = preparePath(path);
+
+ //Path is empty, request for all AASDescriptors
+ if (splitted.length == 0) {
+ return registry.lookupAll();
+ } else {
+
+ //Given path consists only of an AAS Id
+ if(splitted.length == 1) {
+ AASDescriptor descriptor = registry.lookupAAS(new ModelUrn(splitted[0]));
+
+ //Throw an Exception if the requested AAS does not exist
+ if(descriptor == null) {
+ throw new ResourceNotFoundException("Specified AASid '" + splitted[0] + "' does not exist.");
+ }
+ return descriptor;
+
+ //Given path consists of an AAS Id and "/submodels"
+ //Request for all SubmodelDescriptors of given AAS
+ } else if(splitted.length == 2) {
+ return getSmDescriptorsFromAAS(new ModelUrn(splitted[0]));
+
+ //Given path consists of an AAS Id and "/submodels/" and a SubmodelId
+ //Request for the SubmodelDescriptor of given AAS with given id
+ } else if(splitted.length == 3) {
+ SubmodelDescriptor smDescriptor = getSmDescriptorFromAAS(new ModelUrn(splitted[0]), splitted[2]);
+ if(smDescriptor == null) {
+ throw new ResourceNotFoundException("Specified SubmodelId '" + splitted[2] + "' does not exist in AAS '" + splitted[0] + "'.");
+ }
+ return smDescriptor;
+ }
+
+ //path has more than three elements and is therefore invalid
+ throw new MalformedRequestException("Given path '" + path + "' contains more than three path elements and is therefore invalid.");
+ }
+ }
+
+ @Override
+ public void setValue(String path, Object newValue) throws ProviderException {
+ String[] splitted = preparePath(path);
+
+ if (splitted.length > 0) { // Overwriting existing entry
+ //if path contains more or less than an aasID after the prefix
+
+ // Decode encoded path
+ ModelUrn identifier = new ModelUrn(splitted[0]);
+
+ if (splitted.length == 1) {
+ // Typically, VAB SET should not create new entries. Nevertheless, the registry
+ // API is defined to do it.
+ AASDescriptor desc = createAASDescriptorFromMap(newValue);
+
+ // Ensure the passed identifier is equals the
+ String descId = desc.getIdentifier().getId();
+ String urlId = splitted[0];
+ if (descId.equals(urlId)) {
+ registry.register(desc);
+ } else {
+ throw new MalformedRequestException("The Identifier " + descId + " in the descriptor does not match the URL with id " + urlId);
+ }
+ } else if (splitted.length == 3) {
+ SubmodelDescriptor smDesc = createSMDescriptorFromMap(newValue);
+ registry.register(identifier, smDesc);
+ } else {
+ throw new MalformedRequestException("Unknown path " + path);
+ }
+ } else {
+ throw new MalformedRequestException("Set with empty path is not supported by registry");
+ }
+ }
+
+ @Override
+ public void createValue(String path, Object newEntity) throws ProviderException {
+ throw new MalformedRequestException("Create (POST) on a registry is not supported. Please, use put");
+ }
+
+ @Override
+ public void deleteValue(String path) throws ProviderException {
+ String[] splitted = preparePath(path);
+
+ if (splitted.length == 1) { //delete an aas
+
+ ModelUrn aasId = new ModelUrn(splitted[0]);
+
+ //aas to be deleted does not exist
+ if(registry.lookupAAS(aasId) == null) {
+ throw new ResourceNotFoundException("AAS '" + splitted[0] + "' to be deleted does not exist.");
+ }
+
+ registry.delete(aasId);
+
+ } else if(splitted.length == 3) { //delete a submodel
+ ModelUrn aasId = new ModelUrn(splitted[0]);
+ String smId = splitted[2];
+ // a submodel with this Id does not exist in given aas
+ // getSmDescriptorFromAAS also checks if aas exists
+ SubmodelDescriptor smDesc = getSmDescriptorFromAAS(aasId, smId);
+ if (smDesc == null) {
+ throw new ResourceNotFoundException("A Submodel with id '" + smId + "' does not exist in aas '" + splitted[0] + "'.");
+ }
+
+ registry.delete(aasId, smDesc.getIdentifier());
+ } else {
+ throw new MalformedRequestException("Delete with empty path is not supported by registry");
+ }
+ }
+
+ @Override
+ public void deleteValue(String path, Object obj) throws ProviderException {
+ throw new MalformedRequestException("DeleteValue with parameter not supported by registry");
+ }
+
+ @Override
+ public Object invokeOperation(String path, Object... parameter) throws ProviderException {
+ throw new MalformedRequestException("Invoke not supported by registry");
+ }
+
+ /**
+ * Gets all SubmodelDescriptor objects form an aas.
+ * Throws RuntimeException if aas does not exist.
+ *
+ * @param id id of the aas
+ * @return Set of contained SubmodelDescriptor objects
+ * @throws ResourceNotFoundException if the AAS does not exist
+ */
+ private Collection<SubmodelDescriptor> getSmDescriptorsFromAAS(IIdentifier id) throws ResourceNotFoundException {
+ AASDescriptor aasDescriptor = registry.lookupAAS(id);
+ if(aasDescriptor == null) {
+ throw new ResourceNotFoundException("Specified AASid '" + id.getId() + "' does not exist.");
+ }
+ return aasDescriptor.getSubmodelDescriptors();
+ }
+
+ /**
+ * Gets a specific SubmodelDescriptor form an aas.
+ * Throws RuntimeException if aas does not exist.
+ *
+ * @param aasId id of the aas
+ * @param smId id of the submodel
+ * @return the SubmodelDescriptor with the given id
+ * @throws ResourceNotFoundException if aasId does not exist
+ */
+ private SubmodelDescriptor getSmDescriptorFromAAS(IIdentifier aasId, String smId)
+ throws ResourceNotFoundException {
+ AASDescriptor aasDescriptor = registry.lookupAAS(aasId);
+ if(aasDescriptor == null) {
+ throw new ResourceNotFoundException("Specified AASId '" + aasId.getId() + "' does not exist.");
+ }
+
+ SubmodelDescriptor smDescriptor = aasDescriptor.getSubmodelDescriptorFromIdentifierId(smId);
+ if (smDescriptor == null) {
+ throw new ResourceNotFoundException("Specified SMId '" + smId + "' for AAS " + aasId.getId() + " does not exist.");
+ }
+ return smDescriptor;
+ }
+
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/restapi/DirectoryModelProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/restapi/DirectoryModelProvider.java
deleted file mode 100644
index f2072d0..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/restapi/DirectoryModelProvider.java
+++ /dev/null
@@ -1,347 +0,0 @@
-package org.eclipse.basyx.aas.registration.restapi;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
-import java.util.Collection;
-import java.util.Map;
-
-import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
-import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
-import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
-import org.eclipse.basyx.vab.exception.provider.ProviderException;
-import org.eclipse.basyx.vab.exception.provider.ResourceAlreadyExistsException;
-import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
-import org.eclipse.basyx.vab.modelprovider.VABPathTools;
-import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-
-/**
- * Connects an arbitrary IRegistryService implementation to the VAB
- *
- * @author schnicke, conradi
- *
- */
-public class DirectoryModelProvider implements IModelProvider {
-
- IAASRegistryService registry;
-
- public static final String PREFIX = "api/v1/registry";
- public static final String SUBMODELS = "submodels";
-
- public DirectoryModelProvider(IAASRegistryService registry) {
- this.registry = registry;
- }
-
- public DirectoryModelProvider() {
- this(new InMemoryRegistry());
- }
-
- /**
- * Check for correctness of path and returns a stripped path (i.e. no leading
- * prefix)
- *
- * @param path
- * @return
- * @throws MalformedRequestException if path does not start with PERFIX "api/v1/registry"
- */
- private String stripPrefix(String path) throws MalformedRequestException {
- path = VABPathTools.stripSlashes(path);
- if (!path.startsWith(PREFIX)) {
- throw new MalformedRequestException("Path " + path + " not recognized as registry path. Has to start with " + PREFIX);
- }
- path = path.replaceFirst(PREFIX, "");
- path = VABPathTools.stripSlashes(path);
- return path;
- }
-
- /**
- * Splits a path and checks, that first element is not "submodels" and that the second one, if exists, is "submodels"
- *
- * @param path the path to be splitted
- * @return Array of path elements
- * @throws MalformedRequestException if path is not valid
- */
- private String[] splitPath(String path) throws MalformedRequestException {
-
- if(path.isEmpty()) {
- return new String[0];
- }
-
- String[] splitted = path.split("/");
-
- //Assumes "submodels" is not a valid AASId
- if(splitted[0].equals(SUBMODELS)) {
- throw new MalformedRequestException("Path must not start with " + SUBMODELS);
- }
-
- //If path contains more than one element, the second one has to be "submodels"
- if(splitted.length > 1 && !splitted[1].equals(SUBMODELS)) {
- throw new MalformedRequestException("Second path element must be (if present): " + SUBMODELS);
- }
-
- return splitted;
- }
-
- private String[] preparePath(String path) throws MalformedRequestException {
- path = stripPrefix(path);
-
- String[] splitted = splitPath(path);
-
- try {
- for (int i = 0; i < splitted.length; i++) {
- splitted[i] = URLDecoder.decode(splitted[i], "UTF-8");
- }
- return splitted;
- } catch (UnsupportedEncodingException e) {
- //Malformed request because of unsupported encoding
- throw new MalformedRequestException("Path has to be encoded as UTF-8 string.");
- }
- }
-
- /**
- * Checks if a given Object is a Map and checks if it has the correct modelType
- *
- * @param expectedModelType the modelType the Object is expected to have
- * @param value the Object to be checked and casted
- * @return the object casted to a Map
- * @throws MalformedRequestException
- */
- @SuppressWarnings("unchecked")
- private Map<String, Object> checkModelType(String expectedModelType, Object value) throws MalformedRequestException {
- //check if the given value is a Map
- if(!(value instanceof Map)) {
- throw new MalformedRequestException("Given newValue is not a Map");
- }
-
- Map<String, Object> map = (Map<String, Object>) value;
-
- //check if the given Map contains an AAS
- String type = ModelType.createAsFacade(map).getName();
-
- //have to accept Objects without modeltype information,
- //as modeltype is not part of the public metamodel
- if(!expectedModelType.equals(type) && type != null) {
- throw new MalformedRequestException("Given newValue map has not the correct ModelType");
- }
-
- return map;
- }
-
- /**
- * Makes sure, that given Object is an AASDescriptor by checking its ModelType<br />
- * Creates a new AASDescriptor with the content of the given Map
- *
- * @param value the AAS Map object
- * @return an AAS
- * @throws MalformedRequestException
- */
- private AASDescriptor createAASDescriptorFromMap(Object value) throws MalformedRequestException {
- Map<String, Object> map = checkModelType(AASDescriptor.MODELTYPE, value);
- AASDescriptor aasDescriptor = new AASDescriptor(map);
- return aasDescriptor;
- }
-
- /**
- * Makes sure, that given Object is an SubmodelDescriptor by checking its ModelType<br />
- * Creates a new SubmodelDescriptor with the content of the given Map
- *
- * @param value the AAS Map object
- * @return an AAS
- * @throws MalformedRequestException
- */
- private SubmodelDescriptor createSMDescriptorFromMap(Object value) throws MalformedRequestException {
- Map<String, Object> map = checkModelType(SubmodelDescriptor.MODELTYPE, value);
- SubmodelDescriptor smDescriptor = new SubmodelDescriptor(map);
- return smDescriptor;
- }
-
- @Override
- public Object getModelPropertyValue(String path) throws ProviderException {
- String[] splitted = preparePath(path);
-
- //Path is empty, request for all AASDescriptors
- if (splitted.length == 0) {
- return registry.lookupAll();
- } else {
-
- //Given path consists only of an AAS Id
- if(splitted.length == 1) {
- AASDescriptor descriptor = registry.lookupAAS(new ModelUrn(splitted[0]));
-
- //Throw an Exception if the requested AAS does not exist
- if(descriptor == null) {
- throw new ResourceNotFoundException("Specified AASid '" + splitted[0] + "' does not exist.");
- }
- return descriptor;
-
- //Given path consists of an AAS Id and "/submodels"
- //Request for all SubmodelDescriptors of given AAS
- } else if(splitted.length == 2) {
- return getSmDescriptorsFromAAS(new ModelUrn(splitted[0]));
-
- //Given path consists of an AAS Id and "/submodels/" and a SubmodelId
- //Request for the SubmodelDescriptor of given AAS with given id
- } else if(splitted.length == 3) {
- SubmodelDescriptor smDescriptor = getSmDescriptorFromAAS(new ModelUrn(splitted[0]), splitted[2]);
- if(smDescriptor == null) {
- throw new ResourceNotFoundException("Specified SubmodelId '" + splitted[2] + "' does not exist in AAS '" + splitted[0] + "'.");
- }
- return smDescriptor;
- }
-
- //path has more than three elements and is therefore invalid
- throw new MalformedRequestException("Given path '" + path + "' contains more than three path elements and is therefore invalid.");
- }
- }
-
- @Override
- public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
- String[] splitted = preparePath(path);
-
- if (splitted.length > 0) { // Overwriting existing entry
- //if path contains more or less than an aasID after the prefix
-
- // Decode encoded path
- ModelUrn identifier = new ModelUrn(splitted[0]);
-
- if (splitted.length == 1) {
- // Typically, VAB SET should not create new entries. Nevertheless, the registry
- // API is defined to do it.
- registry.register(createAASDescriptorFromMap(newValue));
- } else if (splitted.length == 3) {
- SubmodelDescriptor smDesc = createSMDescriptorFromMap(newValue);
- registry.register(identifier, smDesc);
- } else {
- throw new MalformedRequestException("Unknown path " + path);
- }
- } else {
- throw new MalformedRequestException("Set with empty path is not supported by registry");
- }
- }
-
- @Override
- public void createValue(String path, Object newEntity) throws ProviderException {
- String[] splitted = preparePath(path);
-
- // Creating new entry
- if (splitted.length == 0) {
-
- AASDescriptor aas = createAASDescriptorFromMap(newEntity);
-
- // Check if resource does already exist
- try {
- registry.lookupAAS(aas.getIdentifier());
- throw new ResourceAlreadyExistsException("AAS with Id '" +
- aas.getIdentifier().getId() + "' already exists. Try update instead.");
- } catch (ResourceNotFoundException e) {
- registry.register(aas);
- }
-
- // Creating new submodel entry for existing aas
- } else if (splitted.length == 2) {
- ModelUrn aasId = retrieveModelURN(splitted[0]);
-
- SubmodelDescriptor smDescriptor = createSMDescriptorFromMap(newEntity);
-
- //a submodel with this Id already exists in given aas
- //getSmDescriptorFromAAS also checks if aas exists
- try {
- getSmDescriptorFromAAS(aasId, smDescriptor.getIdShort());
- throw new ResourceAlreadyExistsException("A Submodel with id '" + smDescriptor.getIdShort() +
- "' already exists in aas '" + splitted[0] + "'. Try update instead.");
- } catch (ResourceNotFoundException e) {
- registry.register(aasId, smDescriptor);
- }
- } else {
- throw new MalformedRequestException("Create was called with an unsupported path: " + path);
- }
- }
-
- private ModelUrn retrieveModelURN(String str) {
- return new ModelUrn(str);
- }
-
- @Override
- public void deleteValue(String path) throws ProviderException {
- String[] splitted = preparePath(path);
-
- if (splitted.length == 1) { //delete an aas
-
- ModelUrn aasId = new ModelUrn(splitted[0]);
-
- //aas to be deleted does not exist
- if(registry.lookupAAS(aasId) == null) {
- throw new ResourceNotFoundException("AAS '" + splitted[0] + "' to be deleted does not exist.");
- }
-
- registry.delete(aasId);
-
- } else if(splitted.length == 3) { //delete a submodel
- ModelUrn aasId = new ModelUrn(splitted[0]);
- String smId = splitted[2];
- // a submodel with this Id does not exist in given aas
- // getSmDescriptorFromAAS also checks if aas exists
- if (getSmDescriptorFromAAS(aasId, smId) == null) {
- throw new ResourceNotFoundException("A Submodel with id '" + smId + "' does not exist in aas '" + splitted[0] + "'.");
- }
-
- registry.delete(aasId, smId);
- } else {
- throw new MalformedRequestException("Delete with empty path is not supported by registry");
- }
- }
-
- @Override
- public void deleteValue(String path, Object obj) throws ProviderException {
- throw new MalformedRequestException("DeleteValue with parameter not supported by registry");
- }
-
- @Override
- public Object invokeOperation(String path, Object... parameter) throws ProviderException {
- throw new MalformedRequestException("Invoke not supported by registry");
- }
-
- /**
- * Gets all SubmodelDescriptor objects form an aas.
- * Throws RuntimeException if aas does not exist.
- *
- * @param id id of the aas
- * @return Set of contained SubmodelDescriptor objects
- * @throws ResourceNotFoundException if the AAS does not exist
- */
- private Collection<SubmodelDescriptor> getSmDescriptorsFromAAS(IIdentifier id) throws ResourceNotFoundException {
- AASDescriptor aasDescriptor = registry.lookupAAS(id);
- if(aasDescriptor == null) {
- throw new ResourceNotFoundException("Specified AASid '" + id.getId() + "' does not exist.");
- }
- return aasDescriptor.getSubModelDescriptors();
- }
-
- /**
- * Gets a specific SubmodelDescriptor form an aas.
- * Throws RuntimeException if aas does not exist.
- *
- * @param aasId id of the aas
- * @param smId id of the submodel
- * @return the SubmodelDescriptor with the given id
- * @throws ResourceNotFoundException if aasId does not exist
- */
- private SubmodelDescriptor getSmDescriptorFromAAS(IIdentifier aasId, String smId)
- throws ResourceNotFoundException {
- AASDescriptor aasDescriptor = registry.lookupAAS(aasId);
- if(aasDescriptor == null) {
- throw new ResourceNotFoundException("Specified AASId '" + aasId.getId() + "' does not exist.");
- }
-
- SubmodelDescriptor smDescriptor = aasDescriptor.getSubmodelDescriptorFromIdShort(smId);
- if (smDescriptor == null) {
- throw new ResourceNotFoundException("Specified SMId '" + smId + "' for AAS " + aasId.getId() + " does not exist.");
- }
- return smDescriptor;
- }
-
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/AASModelProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/AASModelProvider.java
index d4ea4f8..47b07bc 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/AASModelProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/AASModelProvider.java
@@ -1,10 +1,20 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.restapi;
import java.util.Map;
import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
import org.eclipse.basyx.aas.restapi.api.IAASAPI;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.aas.restapi.vab.VABAASAPI;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
import org.eclipse.basyx.vab.exception.provider.NotAnInvokableException;
import org.eclipse.basyx.vab.exception.provider.ProviderException;
@@ -13,8 +23,8 @@
import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
/**
- * Model provider explicitely meant to implement the access to the AAS object. This excludes access to the submodels,
- * that are wrapped into their own provider.
+ * Model provider explicitely meant to implement the access to the AAS object.
+ * This excludes access to the submodels, that are wrapped into their own provider.
*
* @author espen
*
@@ -24,7 +34,8 @@
private IAASAPI aasApi;
/**
- * Constructor based on the model provider containing the AAS model
+ * Constructor based on the model provider containing the AAS model. This is based
+ * on the default AAS API
*/
public AASModelProvider(IModelProvider modelProvider) {
aasApi = new VABAASAPI(modelProvider);
@@ -47,7 +58,7 @@
}
@Override
- public Object getModelPropertyValue(String path) throws ProviderException {
+ public Object getValue(String path) throws ProviderException {
path = preparePath(path);
if (path.isEmpty()) {
return aasApi.getAAS();
@@ -57,7 +68,7 @@
}
@Override
- public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
+ public void setValue(String path, Object newValue) throws ProviderException {
throw new MalformedRequestException("For an AAS, Set is not supported");
}
@@ -67,7 +78,9 @@
path = preparePath(path);
if (path.equals("submodels")) {
Map<String, Object> smMap = (Map<String, Object>) newEntity;
- SubModel sm = SubModel.createAsFacade(smMap);
+ Submodel sm = Submodel.createAsFacade(smMap);
+ // It is allowed to overwrite existing submodels
+ aasApi.removeSubmodel(sm.getIdentification().getId());
aasApi.addSubmodel(sm.getReference());
} else {
throw new MalformedRequestException("Path " + path + " is not supported");
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/MultiAASProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/MultiAASProvider.java
deleted file mode 100644
index 2ae86be..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/MultiAASProvider.java
+++ /dev/null
@@ -1,159 +0,0 @@
-package org.eclipse.basyx.aas.restapi;
-
-import java.util.HashMap;
-
-import org.eclipse.basyx.vab.exception.provider.ProviderException;
-import org.eclipse.basyx.vab.modelprovider.VABPathTools;
-import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-
-/**
- * Provider, that redirects requests for different Asset Administration Shells.
- * e.g. aas1 refers to the AAS with id "aas1".
- *
- * @author espen
- *
- */
-public class MultiAASProvider implements IModelProvider {
- protected HashMap<String, VABMultiSubmodelProvider> aas_providers;
-
- public MultiAASProvider() {
- aas_providers = new HashMap<>();
- }
-
- /**
- * Adds an Asset Administration Shell to this provider. The AAS will be
- * accessible via *id
- *
- * @param aasIdShort
- * The id of the added Asset Administration Shell.
- * @param modelProvider
- * The provider that contains the Asset Administration Shell.
- */
- public void addMultiSubmodelProvider(String aasIdShort, VABMultiSubmodelProvider modelProvider) {
- aas_providers.put(aasIdShort, modelProvider);
- }
-
- /**
- * Removes all connected Asset Administration Shells from this provider
- */
- public void clear() {
- aas_providers.clear();
- }
-
- @Override
- public Object getModelPropertyValue(String path) throws ProviderException {
- String aasId = getId(path);
- if (aasId != null) {
- VABMultiSubmodelProvider provider = aas_providers.get(aasId);
- if (provider == null) {
- return null;
- }
- String subPath = getSubPath(path, aasId);
- return provider.getModelPropertyValue(subPath);
- }
- return null;
- }
-
- @Override
- public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
- String aasId = getId(path);
- if (aasId != null) {
- VABMultiSubmodelProvider provider = aas_providers.get(aasId);
- if (provider == null) {
- return;
- }
- String subPath = getSubPath(path, aasId);
- provider.setModelPropertyValue(subPath, newValue);
- }
- }
-
- @Override
- public void createValue(String path, Object newEntity) throws ProviderException {
- String aasId = getId(path);
- if (aasId != null) {
- VABMultiSubmodelProvider provider = aas_providers.get(aasId);
- if (provider == null) {
- return;
- }
- String subPath = getSubPath(path, aasId);
- provider.createValue(subPath, newEntity);
- }
- }
-
- @Override
- public void deleteValue(String path) throws ProviderException {
- String aasId = getId(path);
- if (aasId != null) {
- VABMultiSubmodelProvider provider = aas_providers.get(aasId);
- if (provider == null) {
- return;
- }
- String subPath = getSubPath(path, aasId);
- provider.deleteValue(subPath);
- }
- }
-
- @Override
- public void deleteValue(String path, Object obj) throws ProviderException {
- String aasId = getId(path);
- if (aasId != null) {
- VABMultiSubmodelProvider provider = aas_providers.get(aasId);
- if (provider == null) {
- return;
- }
- String subPath = getSubPath(path, aasId);
- provider.deleteValue(subPath, obj);
- }
- }
-
- @Override
- public Object invokeOperation(String path, Object... parameter) throws ProviderException {
- String aasId = getId(path);
- if (aasId != null) {
- VABMultiSubmodelProvider provider = aas_providers.get(aasId);
- if (provider == null) {
- return null;
- }
- String subPath = getSubPath(path, aasId);
- return provider.invokeOperation(subPath, parameter);
- }
- return null;
- }
-
- /**
- * Returns the requested aas id from a given VAB path. E.g. returns "aas1", if
- * the path is aas1/aas/
- *
- * @param path
- * The requested VAB path
- * @return The id of the requested Asset Administration Shell. Returns null, if
- * the path is invalid or does not contain an AAS id.
- */
- private String getId(String path) {
- if (path == null) {
- return null;
- }
-
- String[] elements = VABPathTools.splitPath(path);
- if (elements.length >= 1) {
- String aasId = elements[0];
- return aasId;
- } else {
- return null;
- }
- }
-
- /**
- * Returns the sub path in the context of a given AAS id. E.g. returns
- * "/aas/submodels", if the path is aas1/aas/submodels/
- *
- * @param path
- * The requested VAB path
- * @param aasId
- * The id of the requested Asset Administration Shell
- * @return The remaining sub-path, when removing the id from the VAB path
- */
- private String getSubPath(String path, String aasId) {
- return path.substring(aasId.length());
- }
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/MultiSubmodelProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/MultiSubmodelProvider.java
new file mode 100644
index 0000000..e2b4483
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/MultiSubmodelProvider.java
@@ -0,0 +1,527 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.restapi;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.restapi.api.IAASAPI;
+import org.eclipse.basyx.aas.restapi.api.IAASAPIFactory;
+import org.eclipse.basyx.aas.restapi.vab.VABAASAPIFactory;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
+import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI;
+import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPIFactory;
+import org.eclipse.basyx.submodel.restapi.vab.VABSubmodelAPIFactory;
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
+
+/**
+ * Provider class that implements the AssetAdministrationShellServices <br />
+ * This provider supports operations on multiple sub models that are selected by
+ * path<br />
+ * <br />
+ * Supported API:<br />
+ * - getModelPropertyValue<br />
+ * /aas Returns the Asset Administration Shell<br />
+ * /aas/submodels Retrieves all Submodels from the current Asset Administration
+ * Shell<br />
+ * /aas/submodels/{subModelId} Retrieves a specific Submodel from a specific
+ * Asset Administration Shell<br />
+ * /aas/submodels/{subModelId}/properties Retrieves all Properties from the
+ * current Submodel<br />
+ * /aas/submodels/{subModelId}/operations Retrieves all Operations from the
+ * current Submodel<br />
+ * /aas/submodels/{subModelId}/events Retrieves all Events from the current
+ * Submodel<br />
+ * /aas/submodels/{subModelId}/properties/{propertyId} Retrieves a specific
+ * property from the AAS's Submodel<br />
+ * /aas/submodels/{subModelId}/operations/{operationId} Retrieves a specific
+ * Operation from the AAS's Submodel<br />
+ * /aas/submodels/{subModelId}/events/{eventId} Retrieves a specific event from
+ * the AAS's submodel
+ * <br /><br />
+ * - createValue <br />
+ * /aas/submodels Adds a new Submodel to an existing Asset Administration Shell
+ * <br /><br />
+ * /aas/submodels/{subModelId}/properties Adds a new property to the AAS's
+ * submodel <br />
+ * /aas/submodels/{subModelId}/operations Adds a new operation to the AAS's
+ * submodel <br />
+ * /aas/submodels/{subModelId}/events Adds a new event to the AAS's submodel
+ * <br /><br />
+ * - invokeOperation<br />
+ * /aas/submodels/{subModelId}/operations/{operationId} Invokes a specific
+ * operation from the AAS' submodel with a list of input parameters
+ * <br /><br />
+ * - deleteValue<br />
+ * /aas/submodels/{subModelId} Deletes a specific Submodel from a specific Asset
+ * Administration Shell <br />
+ * /aas/submodels/{subModelId}/properties/{propertyId} Deletes a specific
+ * Property from the AAS's Submodel<br />
+ * /aas/submodels/{subModelId}/operations/{operationId} Deletes a specific
+ * Operation from the AAS's Submodel<br />
+ * /aas/submodels/{subModelId}/events/{eventId} Deletes a specific event from
+ * the AAS's submodel
+ * <br /><br />
+ * - setModelPropertyValue<br />
+ * /aas/submodels/{subModelId}/properties/{propertyId} Sets the value of the
+ * AAS's Submodel's Property
+ *
+ *
+ * @author kuhn, pschorn
+ *
+ */
+public class MultiSubmodelProvider implements IModelProvider {
+
+ /**
+ * Store aas providers
+ */
+ protected AASModelProvider aas_provider = null;
+
+ /**
+ * Store aasId
+ */
+ protected IIdentifier aasId = null;
+
+ /**
+ * Store submodel providers
+ */
+ protected Map<String, SubmodelProvider> submodel_providers = new HashMap<>();
+
+ /**
+ * Store AAS Registry
+ */
+ protected IAASRegistry registry = null;
+
+ /**
+ * Store HTTP Connector
+ */
+ protected IConnectorFactory connectorFactory = null;
+
+ /**
+ * Store AAS API Provider. By default, uses the VAB API Provider
+ */
+ protected IAASAPIFactory aasApiProvider;
+
+ /**
+ * Store Submodel API Provider. By default, uses the VAB Submodel Provider
+ */
+ protected ISubmodelAPIFactory smApiProvider;
+
+ /**
+ * Constructor with empty default aas and default VAB APIs
+ */
+ public MultiSubmodelProvider() {
+ this.aasApiProvider = new VABAASAPIFactory();
+ this.smApiProvider = new VABSubmodelAPIFactory();
+ IAASAPI aasApi = aasApiProvider.getAASApi(new AssetAdministrationShell());
+ setAssetAdministrationShell(new AASModelProvider(aasApi));
+ }
+
+ /**
+ * Constructor for using custom APIs
+ */
+ public MultiSubmodelProvider(AASModelProvider contentProvider, IAASAPIFactory aasApiProvider,
+ ISubmodelAPIFactory smApiProvider) {
+ this.aasApiProvider = aasApiProvider;
+ this.smApiProvider = smApiProvider;
+ setAssetAdministrationShell(contentProvider);
+ }
+
+ /**
+ * Constructor that accepts an AAS
+ */
+ public MultiSubmodelProvider(AASModelProvider contentProvider) {
+ this.aasApiProvider = new VABAASAPIFactory();
+ this.smApiProvider = new VABSubmodelAPIFactory();
+ // Store content provider
+ setAssetAdministrationShell(contentProvider);
+ }
+
+ /**
+ * Constructor that accepts Submodel
+ */
+ public MultiSubmodelProvider(SubmodelProvider contentProvider) {
+ this();
+ // Store content provider
+ addSubmodel(contentProvider);
+ }
+
+ /**
+ * Constructor that accepts a registry and a connection provider
+ * @param registry
+ * @param provider
+ */
+ public MultiSubmodelProvider(IAASRegistry registry, IConnectorFactory provider) {
+ this();
+ this.registry = registry;
+ this.connectorFactory = provider;
+ }
+
+ /**
+ * Constructor that accepts a registry, a connection provider and API providers
+ */
+ public MultiSubmodelProvider(AASModelProvider contentProvider, IAASRegistry registry,
+ IConnectorFactory connectorFactory, ISubmodelAPIFactory smApiProvider, IAASAPIFactory aasApiProvider) {
+ this(contentProvider, aasApiProvider, smApiProvider);
+ this.registry = registry;
+ this.connectorFactory = connectorFactory;
+ }
+
+ /**
+ * Constructor that accepts a aas provider, a registry and a connection provider
+ *
+ * @param contentProvider
+ * @param registry
+ * @param provider
+ */
+ public MultiSubmodelProvider(AASModelProvider contentProvider, IAASRegistry registry, HTTPConnectorFactory provider) {
+ this(contentProvider);
+ this.registry = registry;
+ this.connectorFactory = provider;
+ }
+
+ /**
+ * Set an AAS for this provider
+ *
+ * @param elementId
+ * Element ID
+ * @param modelContentProvider
+ * Model content provider
+ */
+ @SuppressWarnings("unchecked")
+ public void setAssetAdministrationShell(AASModelProvider modelContentProvider) {
+ // Add model provider
+ aas_provider = modelContentProvider;
+ aasId = AssetAdministrationShell.createAsFacade((Map<String, Object>) modelContentProvider.getValue("")).getIdentification();
+ }
+
+ @SuppressWarnings("unchecked")
+ public void addSubmodel(SubmodelProvider modelContentProvider) {
+ Submodel sm = Submodel.createAsFacade((Map<String, Object>) modelContentProvider.getValue("/"));
+ addSubmodel(sm, modelContentProvider);
+ }
+
+ @SuppressWarnings("unchecked")
+ private void createSubmodel(Object newSM) throws ProviderException {
+ // Adds a new submodel to the registered AAS
+ Submodel sm = Submodel.createAsFacade((Map<String, Object>) newSM);
+
+ ISubmodelAPI smApi = smApiProvider.getSubmodelAPI(sm);
+ addSubmodel(sm, new SubmodelProvider(smApi));
+ }
+
+ private void addSubmodel(Submodel sm, SubmodelProvider modelContentProvider) {
+ String smIdShort = sm.getIdShort();
+ submodel_providers.put(smIdShort, modelContentProvider);
+ aas_provider.createValue("/submodels", sm);
+ }
+
+ /**
+ * Remove a provider
+ *
+ * @param elementId
+ * Element ID
+ */
+ public void removeProvider(String elementId) {
+ // Remove model provider
+ submodel_providers.remove(elementId);
+ }
+
+ /**
+ * Get the value of an element
+ */
+ @Override
+ public Object getValue(String path) throws ProviderException {
+ VABPathTools.checkPathForNull(path);
+ path = VABPathTools.stripSlashes(path);
+ String[] pathElements = VABPathTools.splitPath(path);
+ if (pathElements.length > 0 && pathElements[0].equals("aas")) {
+ if (pathElements.length == 1) {
+ return aas_provider.getValue("");
+ }
+ if (pathElements[1].equals(AssetAdministrationShell.SUBMODELS)) {
+ if (pathElements.length == 2) {
+ return retrieveSubmodels();
+ } else {
+ IModelProvider provider = submodel_providers.get(pathElements[2]);
+
+ if (provider == null) {
+ // Get a model provider for the submodel in the registry
+ provider = getModelProvider(pathElements[2]);
+ }
+
+ // - Retrieve submodel or property value
+ return provider.getValue(VABPathTools.buildPath(pathElements, 4));
+ }
+ } else {
+ // Handle access to AAS
+ return aas_provider.getValue(VABPathTools.buildPath(pathElements, 1));
+ }
+ } else {
+ return new MalformedRequestException("The request " + path + " is not allowed for this endpoint");
+ }
+ }
+
+ /**
+ * Retrieves all submodels of the AAS. If there's a registry, remote Submodels
+ * will also be retrieved.
+ *
+ * @return
+ * @throws ProviderException
+ */
+ @SuppressWarnings("unchecked")
+ private Object retrieveSubmodels() throws ProviderException {
+ // Make a list and return all local submodels
+ Collection<Submodel> submodels = new HashSet<>();
+ for (IModelProvider submodel : submodel_providers.values()) {
+ submodels.add(Submodel.createAsFacade((Map<String, Object>) submodel.getValue("")));
+ }
+
+ // Check for remote submodels
+ if (registry != null) {
+ AASDescriptor desc = registry.lookupAAS(aasId);
+
+ // Get the address of the AAS e.g. http://localhost:8080
+ // This address should be equal to the address of this server
+ String aasEndpoint = desc.getFirstEndpoint();
+ String aasServerURL = getServerURL(aasEndpoint);
+
+ List<String> localIds = submodels.stream().map(sm -> sm.getIdentification().getId()).collect(Collectors.toList());
+ List<IIdentifier> missingIds = desc.getSubmodelDescriptors().stream().map(d -> d.getIdentifier()).
+ filter(id -> !localIds.contains(id.getId())).collect(Collectors.toList());
+
+ if(!missingIds.isEmpty()) {
+ List<String> missingEndpoints = missingIds.stream().map(id -> desc.getSubmodelDescriptorFromIdentifierId(id.getId()))
+ .map(smDesc -> smDesc.getFirstEndpoint()).collect(Collectors.toList());
+
+ // Check if any of the missing Submodels have the same address as the AAS.
+ // This would mean, that the Submodel should be present on the same
+ // server of the AAS but is not
+
+ // If this error would not be caught here an endless loop would develop
+ // as the registry would be asked for this Submodel and then it would be requested
+ // from this server again, which would ask the registry about it again
+
+ // Such a situation might originate from a deleted but not unregistered Submodel
+ // or from a manually registered but never pushed Submodel
+ for(String missingEndpoint: missingEndpoints) {
+ if(getServerURL(missingEndpoint).equals(aasServerURL)) {
+ throw new ResourceNotFoundException("The Submodel at Endpoint '" + missingEndpoint +
+ "' does not exist on this server. It seems to be registered but not actually present.");
+ }
+ }
+
+ List<Submodel> remoteSms = missingEndpoints.stream().map(endpoint -> connectorFactory.getConnector(endpoint)).
+ map(p -> (Map<String, Object>) p.getValue("")).map(m -> Submodel.createAsFacade(m)).collect(Collectors.toList());
+ submodels.addAll(remoteSms);
+ }
+ }
+
+ return submodels;
+ }
+
+ /**
+ * Change a model property value
+ */
+ @Override
+ public void setValue(String path, Object newValue) throws ProviderException {
+ VABPathTools.checkPathForNull(path);
+ path = VABPathTools.stripSlashes(path);
+ // Split path
+ String[] pathElements = VABPathTools.splitPath(path);
+ String propertyPath = VABPathTools.buildPath(pathElements, 3);
+ // - Ignore first 2 elements, as it is "/aas/submodels" --> 'aas','submodels'
+
+ if (path.equals("aas")) {
+ createAssetAdministrationShell(newValue);
+ } else if (!path.startsWith("aas/submodels")) {
+ throw new MalformedRequestException("Access to MultiSubmodelProvider always has to start with \"aas/submodels\", was " + path);
+ } else if (propertyPath.isEmpty()) {
+ createSubmodel(newValue);
+ } else {
+ IModelProvider provider;
+ if (isSubmodelLocal(pathElements[2])) {
+ provider = submodel_providers.get(pathElements[2]);
+ } else {
+ // Get a model provider for the submodel in the registry
+ provider = getModelProvider(pathElements[2]);
+ }
+ provider.setValue(propertyPath, newValue);
+ }
+ }
+
+ @Override
+ public void createValue(String path, Object newValue) throws ProviderException {
+ throw new MalformedRequestException("Create is not supported by VABMultiSubmodelProvider. Path was: " + path);
+ }
+
+
+ @SuppressWarnings("unchecked")
+ private void createAssetAdministrationShell(Object newAAS) {
+ Map<String, Object> aas = (Map<String, Object>) newAAS;
+ AssetAdministrationShell shell = AssetAdministrationShell.createAsFacade(aas);
+ IAASAPI aasApi = aasApiProvider.getAASApi(shell);
+ aas_provider = new AASModelProvider(aasApi);
+ }
+
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void deleteValue(String path) throws ProviderException {
+ VABPathTools.checkPathForNull(path);
+ path = VABPathTools.stripSlashes(path);
+ String[] pathElements = VABPathTools.splitPath(path);
+ String propertyPath = VABPathTools.buildPath(pathElements, 3);
+ // - Ignore first 2 elements, as it is "/aas/submodels" --> 'aas','submodels'
+ if (pathElements.length == 3) {
+ // Delete Submodel from registered AAS
+ String smIdShort = pathElements[2];
+ if (!isSubmodelLocal(smIdShort)) {
+ return;
+ }
+
+ // Delete submodel reference from aas
+ // TODO: This is a hack until the API is further clarified
+ Submodel sm = Submodel.createAsFacade((Map<String, Object>) submodel_providers.get(smIdShort).getValue("/"));
+ aas_provider.deleteValue("aas/submodels/" + sm.getIdentification().getId());
+
+ // Remove submodel provider
+ submodel_providers.remove(smIdShort);
+ } else if (propertyPath.length() > 0) {
+ IModelProvider provider;
+ if (isSubmodelLocal(pathElements[2])) {
+ provider = submodel_providers.get(pathElements[2]);
+ } else {
+ // Get a model provider for the submodel in the registry
+ provider = getModelProvider(pathElements[2]);
+ }
+
+ provider.deleteValue(propertyPath);
+ }
+ }
+
+ @Override
+ public void deleteValue(String path, Object obj) throws ProviderException {
+ throw new MalformedRequestException("DeleteValue with a parameter is not supported. Path was: " + path);
+ }
+
+ @Override
+ public Object invokeOperation(String path, Object... parameter) throws ProviderException {
+ VABPathTools.checkPathForNull(path);
+ path = VABPathTools.stripSlashes(path);
+ String[] pathElements = VABPathTools.splitPath(path);
+ String operationPath = VABPathTools.buildPath(pathElements, 3);
+ // - Ignore first 2 elements, as it is "/aas/submodels" --> 'aas','submodels'
+ // - Invoke provider and return result
+ IModelProvider provider;
+ if (isSubmodelLocal(pathElements[2])) {
+ provider = submodel_providers.get(pathElements[2]);
+ } else {
+ // Get a model provider for the submodel in the registry
+ provider = getModelProvider(pathElements[2]);
+ }
+
+ return provider.invokeOperation(operationPath, parameter);
+ }
+
+ /**
+ * Check whether the given submodel exists in submodel provider
+ * @param key to search the submodel
+ * @return boolean true/false
+ */
+ private boolean isSubmodelLocal(String submodelId) {
+ return submodel_providers.containsKey(submodelId);
+ }
+
+ /**
+ * Check whether a registry exists
+ * @return boolean true/false
+ */
+ private boolean doesRegistryExist() {
+ return this.registry != null;
+ }
+
+ /**
+ * Get submodel descriptor from the registry
+ * @param submodelId to search the submodel
+ * @return a specifi submodel descriptor
+ */
+ private SubmodelDescriptor getSubmodelDescriptorFromRegistry(String submodelIdShort) {
+ AASDescriptor aasDescriptor = registry.lookupAAS(aasId);
+ SubmodelDescriptor desc = aasDescriptor.getSubmodelDescriptorFromIdShort(submodelIdShort);
+ if(desc == null) {
+ throw new ResourceNotFoundException("Could not resolve Submodel with idShort " + submodelIdShort + " for AAS " + aasId);
+ }
+ return desc;
+ }
+
+ /**
+ * Get a model provider from a submodel descriptor
+ * @param submodelDescriptor
+ * @return a model provider
+ */
+ private IModelProvider getModelProvider(SubmodelDescriptor submodelDescriptor) {
+ String endpoint = submodelDescriptor.getFirstEndpoint();
+
+ // Remove "/submodel" since it will be readded later
+ endpoint = endpoint.substring(0, endpoint.length() - SubmodelProvider.SUBMODEL.length() - 1);
+
+ return connectorFactory.getConnector(endpoint);
+ }
+
+ /**
+ * Get a model provider from a submodel id
+ * @param submodelId to select a specific submodel
+ * @throws ResourceNotFoundException if no registry is found
+ * @return a model provider
+ */
+ private IModelProvider getModelProvider(String submodelId) {
+ if (!doesRegistryExist()) {
+ throw new ResourceNotFoundException("Submodel with id " + submodelId + " cannot be resolved locally, but no registry is passed");
+ }
+
+ SubmodelDescriptor submodelDescriptor = getSubmodelDescriptorFromRegistry(submodelId);
+ return getModelProvider(submodelDescriptor);
+ }
+
+ /**
+ * Gets the server URL of a given endpoint.
+ * e.g. http://localhost:1234/x/y/z/aas/submodels/Sm1IdShort would return
+ * http://localhost:1234/x/y/z
+ *
+ * @param endpoint
+ * @return the server URL part of the given endpoint
+ */
+ public static String getServerURL(String endpoint) {
+ int endServerURL = endpoint.indexOf("/aas");
+ // if indexOf returned -1 ("/aas" not present in String)
+ // return the whole given path
+ if(endServerURL < 0) {
+ return endpoint;
+ }
+ return endpoint.substring(0, endServerURL);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/VABAASAPI.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/VABAASAPI.java
deleted file mode 100644
index 49f4bc2..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/VABAASAPI.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package org.eclipse.basyx.aas.restapi;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.aas.restapi.api.IAASAPI;
-import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
-import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
-import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
-import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-
-/**
- * Implements the AAS API by mapping it to the VAB
- *
- * @author schnicke
- *
- */
-public class VABAASAPI implements IAASAPI {
-
- // The VAB model provider containing the model this API implementation is based
- // on
- private IModelProvider provider;
-
- /**
- * Creates a VABAASAPI that wraps an IModelProvider
- *
- * @param modelProvider
- * providing the AAS
- */
- public VABAASAPI(IModelProvider provider) {
- super();
- this.provider = provider;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public IAssetAdministrationShell getAAS() {
- // For access on the container property root, return the whole model
- Map<String, Object> map = (Map<String, Object>) provider.getModelPropertyValue("");
- return AssetAdministrationShell.createAsFacade(map);
- }
-
- @Override
- public void addSubmodel(IReference submodel) {
- provider.createValue(AssetAdministrationShell.SUBMODELS, submodel);
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public void removeSubmodel(String id) {
- Collection<Map<String, Object>> smReferences = (Collection<Map<String, Object>>) provider.getModelPropertyValue(AssetAdministrationShell.SUBMODELS);
- // Reference to submodel could be either by idShort (=> local) or directly via
- // its identifier
- for (Iterator<Map<String, Object>> iterator = smReferences.iterator(); iterator.hasNext();) {
- Map<String, Object> smRefMap = iterator.next();
- IReference ref = Reference.createAsFacade(smRefMap);
- List<IKey> keys = ref.getKeys();
- IKey lastKey = keys.get(keys.size() - 1);
- String idValue = lastKey.getValue();
- // remove this reference, if the last key points to the submodel
- if (idValue.equals(id)) {
- provider.deleteValue(AssetAdministrationShell.SUBMODELS, ref);
- break;
- }
- }
- }
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/VABMultiSubmodelProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/VABMultiSubmodelProvider.java
deleted file mode 100644
index c4a401a..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/VABMultiSubmodelProvider.java
+++ /dev/null
@@ -1,286 +0,0 @@
-package org.eclipse.basyx.aas.restapi;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
-import org.eclipse.basyx.vab.exception.provider.ProviderException;
-import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
-import org.eclipse.basyx.vab.modelprovider.VABPathTools;
-import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-
-/**
- * Provider class that implements the AssetAdministrationShellServices <br />
- * This provider supports operations on multiple sub models that are selected by
- * path<br />
- * <br />
- * Supported API:<br />
- * - getModelPropertyValue<br />
- * /aas Returns the Asset Administration Shell<br />
- * /aas/submodels Retrieves all SubModels from the current Asset Administration
- * Shell<br />
- * /aas/submodels/{subModelId} Retrieves a specific SubModel from a specific
- * Asset Administration Shell<br />
- * /aas/submodels/{subModelId}/properties Retrieves all Properties from the
- * current SubModel<br />
- * /aas/submodels/{subModelId}/operations Retrieves all Operations from the
- * current SubModel<br />
- * /aas/submodels/{subModelId}/events Retrieves all Events from the current
- * SubModel<br />
- * /aas/submodels/{subModelId}/properties/{propertyId} Retrieves a specific
- * property from the AAS's SubModel<br />
- * /aas/submodels/{subModelId}/operations/{operationId} Retrieves a specific
- * Operation from the AAS's SubModel<br />
- * /aas/submodels/{subModelId}/events/{eventId} Retrieves a specific event from
- * the AAS's submodel
- * <br /><br />
- * - createValue <br />
- * /aas/submodels Adds a new SubModel to an existing Asset Administration Shell
- * <br /><br />
- * /aas/submodels/{subModelId}/properties Adds a new property to the AAS's
- * submodel <br />
- * /aas/submodels/{subModelId}/operations Adds a new operation to the AAS's
- * submodel <br />
- * /aas/submodels/{subModelId}/events Adds a new event to the AAS's submodel
- * <br /><br />
- * - invokeOperation<br />
- * /aas/submodels/{subModelId}/operations/{operationId} Invokes a specific
- * operation from the AAS' submodel with a list of input parameters
- * <br /><br />
- * - deleteValue<br />
- * /aas/submodels/{subModelId} Deletes a specific SubModel from a specific Asset
- * Administration Shell <br />
- * /aas/submodels/{subModelId}/properties/{propertyId} Deletes a specific
- * Property from the AAS's SubModel<br />
- * /aas/submodels/{subModelId}/operations/{operationId} Deletes a specific
- * Operation from the AAS's SubModel<br />
- * /aas/submodels/{subModelId}/events/{eventId} Deletes a specific event from
- * the AAS's submodel
- * <br /><br />
- * - setModelPropertyValue<br />
- * /aas/submodels/{subModelId}/properties/{propertyId} Sets the value of the
- * AAS's SubModel's Property
- *
- *
- * @author kuhn, pschorn
- *
- */
-public class VABMultiSubmodelProvider implements IModelProvider {
-
- /**
- * Store aas providers
- */
- protected AASModelProvider aas_provider = null;
-
- /**
- * Store submodel providers
- */
- protected Map<String, SubModelProvider> submodel_providers = new HashMap<>();
-
- /**
- * Constructor
- */
- public VABMultiSubmodelProvider() {
- this(new AASModelProvider(new AssetAdministrationShell()));
- }
-
- /**
- * Constructor that accepts an AAS
- */
- public VABMultiSubmodelProvider(AASModelProvider contentProvider) {
- // Store content provider
- setAssetAdministrationShell(contentProvider);
- }
-
- /**
- * Constructor that accepts Submodel
- */
- public VABMultiSubmodelProvider(String smID, SubModelProvider contentProvider) {
- this();
- // Store content provider
- addSubmodel(smID, contentProvider);
- }
-
- /**
- * Set an AAS for this provider
- *
- * @param elementId
- * Element ID
- * @param modelContentProvider
- * Model content provider
- */
- public void setAssetAdministrationShell(AASModelProvider modelContentProvider) {
- // Add model provider
- aas_provider = modelContentProvider;
- }
-
- /**
- * Add a Submodel to the provider
- *
- * @param elementId
- * Element ID
- * @param modelContentProvider
- * Model content provider
- */
- @SuppressWarnings("unchecked")
- public void addSubmodel(String elementId, SubModelProvider modelContentProvider) {
- // Add model provider
- submodel_providers.put(elementId, modelContentProvider);
-
- SubModel sm = SubModel.createAsFacade((Map<String, Object>) modelContentProvider.getModelPropertyValue("/"));
-
- // Adds a new submodel to the registered AAS
- aas_provider.createValue("/submodels", sm);
- }
-
- /**
- * Remove a provider
- *
- * @param elementId
- * Element ID
- */
- public void removeProvider(String elementId) {
- // Remove model provider
- submodel_providers.remove(elementId);
- }
-
- /**
- * Get the value of an element
- */
- @Override
- public Object getModelPropertyValue(String path) throws ProviderException {
- VABPathTools.checkPathForNull(path);
- String[] pathElements = VABPathTools.splitPath(path);
- if (pathElements.length == 0) { // e.g. "/"
- return null;
- } else if (pathElements[0].equals("aas")) {
- if (pathElements.length == 1) {
- return aas_provider.getModelPropertyValue("");
- }
- if (pathElements[1].equals(AssetAdministrationShell.SUBMODELS)) {
- if (pathElements.length == 2) {
- // Make a list and return all submodels
- Collection<Object> submodels = new HashSet<>();
- for (IModelProvider submodel : submodel_providers.values()) {
- submodels.add(submodel.getModelPropertyValue(""));
- }
- return submodels;
- } else {
- IModelProvider hashmapProvider = submodel_providers.get(pathElements[2]);
-
- if(hashmapProvider == null) {
- throw new ResourceNotFoundException("Submodel with id " + pathElements[2] + " does not exist");
- }
-
- // - Retrieve submodel or property value
- return hashmapProvider.getModelPropertyValue(VABPathTools.buildPath(pathElements, 3));
- }
- } else {
- // Handle access to AAS
- return aas_provider.getModelPropertyValue(VABPathTools.buildPath(pathElements, 1));
- }
- } else {
- return null;
- }
- }
-
- /**
- * Change a model property value
- */
- @Override
- public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
- VABPathTools.checkPathForNull(path);
- // Split path
- String[] pathElements = VABPathTools.splitPath(path);
- String propertyPath = VABPathTools.buildPath(pathElements, 3);
- // - Ignore first 2 elements, as it is "/aas/submodels" --> 'aas','submodels'
- submodel_providers.get(pathElements[2]).setModelPropertyValue(propertyPath, newValue);
- }
-
- @Override
- public void createValue(String path, Object newValue) throws ProviderException {
- VABPathTools.checkPathForNull(path);
- String[] pathElements = VABPathTools.splitPath(path);
- if (pathElements.length >= 1 && pathElements[0].equals("aas")) {
- if (pathElements.length == 1) {
- createAssetAdministrationShell(newValue);
- } else if (pathElements[1].equals(AssetAdministrationShell.SUBMODELS)) {
- if (pathElements.length == 2) {
- createSubModel(newValue);
- } else {
- String propertyPath = VABPathTools.buildPath(pathElements, 3);
- createSubModelProperty(pathElements[2], propertyPath, newValue);
- }
- }
- }
- }
-
- private void createSubModelProperty(String smId, String propertyPath, Object newProperty) throws ProviderException {
- SubModelProvider subModelProvider = submodel_providers.get(smId);
- subModelProvider.createValue(propertyPath, newProperty);
- }
-
- @SuppressWarnings("unchecked")
- private void createAssetAdministrationShell(Object newAAS) {
- Map<String, Object> aas = (Map<String, Object>) newAAS;
- aas_provider = new AASModelProvider(AssetAdministrationShell.createAsFacade(aas));
- }
-
- @SuppressWarnings("unchecked")
- private void createSubModel(Object newSM) throws ProviderException {
- // Adds a new submodel to the registered AAS
- SubModel sm = SubModel.createAsFacade((Map<String, Object>) newSM);
-
- addSubmodel(sm.getIdShort(), new SubModelProvider(sm));
- }
-
-
- @SuppressWarnings("unchecked")
- @Override
- public void deleteValue(String path) throws ProviderException {
- VABPathTools.checkPathForNull(path);
- String[] pathElements = VABPathTools.splitPath(path);
- String propertyPath = VABPathTools.buildPath(pathElements, 3);
- // - Ignore first 2 elements, as it is "/aas/submodels" --> 'aas','submodels'
- if (pathElements.length == 3) {
- // Delete Submodel from registered AAS
- String smIdShort = pathElements[2];
- if (!submodel_providers.containsKey(smIdShort)) {
- return;
- }
-
- // Delete submodel reference from aas
- // TODO: This is a hack until the API is further clarified
- SubModel sm = SubModel.createAsFacade((Map<String, Object>) submodel_providers.get(smIdShort).getModelPropertyValue("/"));
- aas_provider.deleteValue("aas/submodels/" + sm.getIdentification().getId());
-
- // Remove submodel provider
- submodel_providers.remove(smIdShort);
- } else if (propertyPath.length() > 0) {
- submodel_providers.get(pathElements[2]).deleteValue(propertyPath);
- }
- }
-
- @Override
- public void deleteValue(String path, Object obj) throws ProviderException {
- VABPathTools.checkPathForNull(path);
- String[] pathElements = VABPathTools.splitPath(path);
- String propertyPath = VABPathTools.buildPath(pathElements, 3);
- // - Ignore first 2 elements, as it is "/aas/submodels" --> 'aas','submodels'
- submodel_providers.get(pathElements[2]).deleteValue(propertyPath, obj);
- }
-
- @Override
- public Object invokeOperation(String path, Object... parameter) throws ProviderException {
- VABPathTools.checkPathForNull(path);
- String[] pathElements = VABPathTools.splitPath(path);
- String operationPath = VABPathTools.buildPath(pathElements, 3);
- // - Ignore first 2 elements, as it is "/aas/submodels" --> 'aas','submodels'
- // - Invoke provider and return result
- return submodel_providers.get(pathElements[2]).invokeOperation(operationPath, parameter);
- }
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/api/IAASAPI.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/api/IAASAPI.java
index fbd03a9..96498fb 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/api/IAASAPI.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/api/IAASAPI.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.aas.restapi.api;
import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/api/IAASAPIFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/api/IAASAPIFactory.java
new file mode 100644
index 0000000..430a077
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/api/IAASAPIFactory.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.restapi.api;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+
+/**
+ * Interface for providing an AAS API
+ *
+ * @author espen
+ *
+ */
+public interface IAASAPIFactory {
+ /**
+ * Return a constructed AAS API based on a raw model provider
+ *
+ * @return
+ */
+ public IAASAPI getAASApi(AssetAdministrationShell aas);
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/vab/VABAASAPI.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/vab/VABAASAPI.java
new file mode 100644
index 0000000..d6e0437
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/vab/VABAASAPI.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.restapi.vab;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.restapi.api.IAASAPI;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+
+/**
+ * Implements the AAS API by mapping it to the VAB
+ *
+ * @author schnicke
+ *
+ */
+public class VABAASAPI implements IAASAPI {
+
+ // The VAB model provider containing the model this API implementation is based
+ // on
+ private IModelProvider provider;
+
+ /**
+ * Creates a VABAASAPI that wraps an IModelProvider
+ *
+ * @param modelProvider
+ * providing the AAS
+ */
+ public VABAASAPI(IModelProvider provider) {
+ super();
+ this.provider = provider;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public IAssetAdministrationShell getAAS() {
+ // For access on the container property root, return the whole model
+ Map<String, Object> map = (Map<String, Object>) provider.getValue("");
+ return AssetAdministrationShell.createAsFacade(map);
+ }
+
+ @Override
+ public void addSubmodel(IReference submodel) {
+ provider.createValue(AssetAdministrationShell.SUBMODELS, submodel);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void removeSubmodel(String id) {
+ Collection<Map<String, Object>> smReferences = (Collection<Map<String, Object>>) provider.getValue(AssetAdministrationShell.SUBMODELS);
+ // Reference to submodel could be either by idShort (=> local) or directly via
+ // its identifier
+ for (Iterator<Map<String, Object>> iterator = smReferences.iterator(); iterator.hasNext();) {
+ Map<String, Object> smRefMap = iterator.next();
+ IReference ref = Reference.createAsFacade(smRefMap);
+ List<IKey> keys = ref.getKeys();
+ IKey lastKey = keys.get(keys.size() - 1);
+ String idValue = lastKey.getValue();
+ // remove this reference, if the last key points to the submodel
+ if (idValue.equals(id)) {
+ provider.deleteValue(AssetAdministrationShell.SUBMODELS, ref);
+ break;
+ }
+ }
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/vab/VABAASAPIFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/vab/VABAASAPIFactory.java
new file mode 100644
index 0000000..c125080
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/vab/VABAASAPIFactory.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.restapi.vab;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.restapi.api.IAASAPI;
+import org.eclipse.basyx.aas.restapi.api.IAASAPIFactory;
+import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
+
+/**
+ * AAS API provider that provides the default VAB AAS API
+ *
+ * @author espen
+ */
+public class VABAASAPIFactory implements IAASAPIFactory {
+ @Override
+ public IAASAPI getAASApi(AssetAdministrationShell aas) {
+ return new VABAASAPI(new VABLambdaProvider(aas));
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/mqtt/MqttAASAggregator.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/mqtt/MqttAASAggregator.java
new file mode 100644
index 0000000..bc8ca22
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/mqtt/MqttAASAggregator.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.extensions.aas.aggregator.mqtt;
+
+import java.util.Collection;
+
+import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.extensions.shared.mqtt.MqttEventService;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.paho.client.mqttv3.MqttClient;
+import org.eclipse.paho.client.mqttv3.MqttException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implementation variant for the AASAggregator that triggers MQTT events for
+ * different operations on the aggregator. Has to be based on a backend
+ * implementation of the IAASAggregator to forward its method calls.
+ *
+ * @author haque
+ *
+ */
+public class MqttAASAggregator extends MqttEventService implements IAASAggregator {
+ private static Logger logger = LoggerFactory.getLogger(MqttAASAggregator.class);
+
+ // List of topics
+ public static final String TOPIC_CREATEAAS = "BaSyxAggregator_createdAAS";
+ public static final String TOPIC_DELETEAAS = "BaSyxAggregator_deletedAAS";
+ public static final String TOPIC_UPDATEAAS = "BaSyxAggregator_updatedAAS";
+
+ // The underlying AASAggregator
+ protected IAASAggregator observedAASAggregator;
+
+ /**
+ * Constructor for adding this MQTT extension on top of an AASAggregator
+ *
+ * @param observedRegistryService the underlying AAS Aggregator
+ * @param serverEndpoint endpoint of mqtt broker
+ * @param clientId unique client identifier
+ * @throws MqttException
+ */
+ public MqttAASAggregator(IAASAggregator observedAASAggregator, String serverEndpoint, String clientId) throws MqttException {
+ super(serverEndpoint, clientId);
+ logger.info("Create new MQTT AAS Aggregator for endpoint " + serverEndpoint);
+ this.observedAASAggregator = observedAASAggregator;
+ }
+
+ /**
+ * Constructor for adding this MQTT extension on top of an AASAggregator
+ *
+ * @param observedRegistryService the underlying AAS Aggregator
+ * @param serverEndpoint endpoint of mqtt broker
+ * @param clientId unique client identifier
+ * @param user username for authentication with broker
+ * @param pw password for authentication with broker
+ * @throws MqttException
+ */
+ public MqttAASAggregator(IAASAggregator observedAASAggregator, String serverEndpoint, String clientId, String user, char[] pw)
+ throws MqttException {
+ super(serverEndpoint, clientId, user, pw);
+ logger.info("Create new MQTT AAS Aggregator for endpoint " + serverEndpoint);
+ this.observedAASAggregator = observedAASAggregator;
+ }
+
+ /**
+ * Constructor for adding this MQTT extension on top of an AASAggregator
+ *
+ * @param observedRegistryService the underlying AAS Aggregator
+ * @param client already configured client
+ * @throws MqttException
+ */
+ public MqttAASAggregator(IAASAggregator observedAASAggregator, MqttClient client) throws MqttException {
+ super(client);
+ logger.info("Create new MQTT AAS Aggregator for endpoint " + client.getServerURI());
+ this.observedAASAggregator = observedAASAggregator;
+ }
+
+ @Override
+ public Collection<IAssetAdministrationShell> getAASList() {
+ return this.observedAASAggregator.getAASList();
+ }
+
+ @Override
+ public IAssetAdministrationShell getAAS(IIdentifier aasId) throws ResourceNotFoundException {
+ return this.observedAASAggregator.getAAS(aasId);
+ }
+
+ @Override
+ public IModelProvider getAASProvider(IIdentifier aasId) throws ResourceNotFoundException {
+ return this.observedAASAggregator.getAASProvider(aasId);
+ }
+
+ @Override
+ public void createAAS(AssetAdministrationShell aas) {
+ this.observedAASAggregator.createAAS(aas);
+ sendMqttMessage(TOPIC_CREATEAAS, aas.getIdentification().getId());
+
+ }
+
+ @Override
+ public void updateAAS(AssetAdministrationShell aas) throws ResourceNotFoundException {
+ this.observedAASAggregator.updateAAS(aas);
+ sendMqttMessage(TOPIC_UPDATEAAS, aas.getIdentification().getId());
+
+ }
+
+ @Override
+ public void deleteAAS(IIdentifier aasId) {
+ this.observedAASAggregator.deleteAAS(aasId);
+ sendMqttMessage(TOPIC_DELETEAAS, aasId.getId());
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/IAASTaggedDirectory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/IAASTaggedDirectory.java
index c4ee5b4..795f6a9 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/IAASTaggedDirectory.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/IAASTaggedDirectory.java
@@ -1,8 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.extensions.aas.directory.tagged.api;
import java.util.Set;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
/**
* A tagged directory is a registry that allows to register AAS and associate
@@ -11,7 +20,7 @@
* @author schnicke
*
*/
-public interface IAASTaggedDirectory extends IAASRegistryService {
+public interface IAASTaggedDirectory extends IAASRegistry {
public void register(TaggedAASDescriptor descriptor);
/**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/TaggedAASDescriptor.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/TaggedAASDescriptor.java
index 6c836f2..beae4f2 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/TaggedAASDescriptor.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/TaggedAASDescriptor.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.extensions.aas.directory.tagged.api;
import java.util.Collection;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/map/MapTaggedDirectory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/map/MapTaggedDirectory.java
index 47bd26f..403cfba 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/map/MapTaggedDirectory.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/map/MapTaggedDirectory.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.extensions.aas.directory.tagged.map;
import java.util.HashSet;
@@ -7,7 +16,8 @@
import java.util.stream.Collectors;
import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
-import org.eclipse.basyx.aas.registration.memory.MapRegistry;
+import org.eclipse.basyx.aas.registration.memory.AASRegistry;
+import org.eclipse.basyx.aas.registration.memory.MapRegistryHandler;
import org.eclipse.basyx.extensions.aas.directory.tagged.api.IAASTaggedDirectory;
import org.eclipse.basyx.extensions.aas.directory.tagged.api.TaggedAASDescriptor;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
@@ -19,8 +29,7 @@
* @author schnicke
*
*/
-public class MapTaggedDirectory extends MapRegistry implements IAASTaggedDirectory {
-
+public class MapTaggedDirectory extends AASRegistry implements IAASTaggedDirectory {
private Map<String, Set<TaggedAASDescriptor>> tagMap;
/**
@@ -31,7 +40,7 @@
* @param tagMap
*/
public MapTaggedDirectory(Map<String, AASDescriptor> rootMap, Map<String, Set<TaggedAASDescriptor>> tagMap) {
- super(rootMap);
+ super(new MapRegistryHandler(rootMap));
this.tagMap = tagMap;
}
@@ -72,7 +81,7 @@
@Override
public void delete(IIdentifier aasIdentifier) {
// Let MapRegistry take care of the registry part and only manage the tags
- AASDescriptor desc = descriptorMap.get(aasIdentifier.getId());
+ AASDescriptor desc = super.lookupAAS(aasIdentifier);
super.delete(aasIdentifier);
if (desc instanceof TaggedAASDescriptor) {
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/proxy/TaggedDirectoryProxy.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/proxy/TaggedDirectoryProxy.java
index 4ddb6cd..293b0c5 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/proxy/TaggedDirectoryProxy.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/proxy/TaggedDirectoryProxy.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.extensions.aas.directory.tagged.proxy;
import java.util.Collection;
@@ -53,7 +62,7 @@
@SuppressWarnings("unchecked")
private Set<TaggedAASDescriptor> performTagRequest(String tagList) {
- Collection<Map<String, Object>> desc = (Collection<Map<String, Object>>) taggedProvider.getModelPropertyValue(TaggedDirectoryProvider.API_ACCESS + tagList);
+ Collection<Map<String, Object>> desc = (Collection<Map<String, Object>>) taggedProvider.getValue(TaggedDirectoryProvider.API_ACCESS + tagList);
return desc.stream().map(m -> TaggedAASDescriptor.createAsFacade(m)).collect(Collectors.toSet());
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/restapi/TaggedDirectoryProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/restapi/TaggedDirectoryProvider.java
index b1238c9..c6d251e 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/restapi/TaggedDirectoryProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/restapi/TaggedDirectoryProvider.java
@@ -1,18 +1,28 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.extensions.aas.directory.tagged.restapi;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
+import java.util.regex.Pattern;
import java.util.stream.Collectors;
-import org.eclipse.basyx.aas.registration.restapi.DirectoryModelProvider;
+import org.eclipse.basyx.aas.registration.restapi.AASRegistryModelProvider;
import org.eclipse.basyx.extensions.aas.directory.tagged.api.TaggedAASDescriptor;
import org.eclipse.basyx.extensions.aas.directory.tagged.map.MapTaggedDirectory;
import org.eclipse.basyx.vab.exception.provider.ProviderException;
import org.eclipse.basyx.vab.modelprovider.VABPathTools;
-public class TaggedDirectoryProvider extends DirectoryModelProvider {
+public class TaggedDirectoryProvider extends AASRegistryModelProvider {
private MapTaggedDirectory directory;
public static final String PREFIX = "api/v1/directory";
public static final String API_ACCESS = "?tags=";
@@ -27,12 +37,12 @@
}
@Override
- public Object getModelPropertyValue(String path) throws ProviderException {
+ public Object getValue(String path) throws ProviderException {
path = VABPathTools.stripSlashes(path);
if (path.startsWith(PREFIX)) {
return directory.lookupTags(extractTags(path));
} else {
- return super.getModelPropertyValue(path);
+ return super.getValue(path);
}
}
@@ -49,10 +59,10 @@
private Set<String> extractTags(String path) {
path = VABPathTools.stripSlashes(path);
- path = path.replace(PREFIX, "");
+ path = path.replaceFirst(PREFIX, "");
// Paths now does only contain ?tags=a,b,c
- path = path.replace(API_ACCESS, "");
+ path = path.replaceFirst(Pattern.quote(API_ACCESS), "");
return Arrays.stream(path.split(",")).collect(Collectors.toSet());
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/registration/mqtt/MqttAASRegistryService.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/registration/mqtt/MqttAASRegistryService.java
new file mode 100644
index 0000000..4181c5e
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/registration/mqtt/MqttAASRegistryService.java
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.extensions.aas.registration.mqtt;
+
+import java.util.List;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.extensions.shared.mqtt.MqttEventService;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.paho.client.mqttv3.MqttClient;
+import org.eclipse.paho.client.mqttv3.MqttException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implementation variant for the AASRegistryService that triggers MQTT events for
+ * different operations on the registry. Has to be based on a backend
+ * implementation of the IAASRegistryService to forward its method calls.
+ *
+ * @author haque
+ *
+ */
+public class MqttAASRegistryService extends MqttEventService implements IAASRegistry {
+ private static Logger logger = LoggerFactory.getLogger(MqttAASRegistryService.class);
+
+ // List of topics
+ public static final String TOPIC_REGISTERAAS = "BaSyxRegistry_registeredAAS";
+ public static final String TOPIC_REGISTERSUBMODEL = "BaSyxRegistry_registeredSubmodel";
+ public static final String TOPIC_DELETEAAS = "BaSyxRegistry_deletedAAS";
+ public static final String TOPIC_DELETESUBMODEL = "BaSyxRegistry_deletedSubmodel";
+
+ // The underlying AASRegistryService
+ protected IAASRegistry observedRegistryService;
+
+ /**
+ * Constructor for adding this MQTT extension on top of an AASRegistryService
+ *
+ * @param observedRegistryService the underlying registry service
+ * @param serverEndpoint endpoint of mqtt broker
+ * @param clientId unique client identifier
+ * @throws MqttException
+ */
+ public MqttAASRegistryService(IAASRegistry observedRegistryService, String serverEndpoint, String clientId) throws MqttException {
+ super(serverEndpoint, clientId);
+ logger.info("Create new MQTT AAS Registry Service for endpoint " + serverEndpoint);
+ this.observedRegistryService = observedRegistryService;
+ }
+
+ /**
+ * Constructor for adding this MQTT extension on top of an AASRegistryService
+ *
+ * @param observedRegistryService the underlying registry service
+ * @param serverEndpoint endpoint of mqtt broker
+ * @param clientId unique client identifier
+ * @param user username for authentication with broker
+ * @param pw password for authentication with broker
+ * @throws MqttException
+ */
+ public MqttAASRegistryService(IAASRegistry observedRegistryService, String serverEndpoint, String clientId, String user, char[] pw)
+ throws MqttException {
+ super(serverEndpoint, clientId, user, pw);
+ logger.info("Create new MQTT AAS Registry Service for endpoint " + serverEndpoint);
+ this.observedRegistryService = observedRegistryService;
+ }
+
+ /**
+ * Constructor for adding this MQTT extension on top of an AASRegistryService
+ *
+ * @param observedRegistryService the underlying registry service
+ * @param client already configured client
+ * @throws MqttException
+ */
+ public MqttAASRegistryService(IAASRegistry observedRegistryService, MqttClient client) throws MqttException {
+ super(client);
+ logger.info("Create new MQTT AAS Registry Service for endpoint " + client.getServerURI());
+ this.observedRegistryService = observedRegistryService;
+ }
+
+
+ @Override
+ public void register(AASDescriptor deviceAASDescriptor) throws ProviderException {
+ this.observedRegistryService.register(deviceAASDescriptor);
+ sendMqttMessage(TOPIC_REGISTERAAS, deviceAASDescriptor.getIdentifier().getId());
+ }
+
+ @Override
+ public void register(IIdentifier aas, SubmodelDescriptor smDescriptor) throws ProviderException {
+ this.observedRegistryService.register(aas, smDescriptor);
+ sendMqttMessage(TOPIC_REGISTERSUBMODEL, concatAasSmId(aas, smDescriptor.getIdentifier()));
+ }
+
+ @Override
+ public void delete(IIdentifier aasId) throws ProviderException {
+ this.observedRegistryService.delete(aasId);
+ sendMqttMessage(TOPIC_DELETEAAS, aasId.getId());
+ }
+
+ @Override
+ public void delete(IIdentifier aasId, IIdentifier smId) throws ProviderException {
+ this.observedRegistryService.delete(aasId, smId);
+ sendMqttMessage(TOPIC_DELETESUBMODEL, concatAasSmId(aasId, smId));
+ }
+
+ @Override
+ public AASDescriptor lookupAAS(IIdentifier aasId) throws ProviderException {
+ return this.observedRegistryService.lookupAAS(aasId);
+ }
+
+ @Override
+ public List<AASDescriptor> lookupAll() throws ProviderException {
+ return this.observedRegistryService.lookupAll();
+ }
+
+ @Override
+ public List<SubmodelDescriptor> lookupSubmodels(IIdentifier aasId) throws ProviderException {
+ return this.observedRegistryService.lookupSubmodels(aasId);
+ }
+
+ @Override
+ public SubmodelDescriptor lookupSubmodel(IIdentifier aasId, IIdentifier smId) throws ProviderException {
+ return this.observedRegistryService.lookupSubmodel(aasId, smId);
+ }
+
+ public static String concatAasSmId(IIdentifier aasId, IIdentifier smId) {
+ return "(" + aasId.getId() + "," + smId.getId() + ")";
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/shared/mqtt/MqttEventService.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/shared/mqtt/MqttEventService.java
new file mode 100644
index 0000000..f71ef77
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/shared/mqtt/MqttEventService.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.extensions.shared.mqtt;
+
+import org.eclipse.paho.client.mqttv3.MqttClient;
+import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
+import org.eclipse.paho.client.mqttv3.MqttException;
+import org.eclipse.paho.client.mqttv3.MqttMessage;
+import org.eclipse.paho.client.mqttv3.MqttPersistenceException;
+import org.eclipse.paho.client.mqttv3.persist.MqttDefaultFilePersistence;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implementation of common parts of MQTT event propagation services.
+ * Extend this class to make a service MQTT extendable
+ *
+ * @author haque
+ *
+ */
+public class MqttEventService {
+ private static Logger logger = LoggerFactory.getLogger(MqttEventService.class);
+
+ // The MQTTClient
+ protected MqttClient mqttClient;
+
+ // QoS for MQTT messages (1, 2 or 3).
+ protected int qos = 1;
+
+ /**
+ * Constructor for creating an MqttClient (no authentication)
+ * @param serverEndpoint
+ * @param clientId
+ * @throws MqttException
+ */
+ public MqttEventService(String serverEndpoint, String clientId) throws MqttException {
+ this.mqttClient = new MqttClient(serverEndpoint, clientId, new MqttDefaultFilePersistence());
+ mqttClient.connect();
+ }
+
+ /**
+ * Constructor for creating an MqttClient with authentication
+ * @param serverEndpoint
+ * @param clientId
+ * @param user
+ * @param pw
+ * @throws MqttException
+ */
+ public MqttEventService(String serverEndpoint, String clientId, String user, char[] pw)
+ throws MqttException {
+ this.mqttClient = new MqttClient(serverEndpoint, clientId, new MqttDefaultFilePersistence());
+ MqttConnectOptions options = new MqttConnectOptions();
+ options.setUserName(user);
+ options.setPassword(pw);
+ mqttClient.connect(options);
+ }
+
+ /**
+ * Constructor for creating an MqttClient with existing client
+ * @param client
+ * @throws MqttException
+ */
+ public MqttEventService(MqttClient client) throws MqttException {
+ this.mqttClient = client;
+ mqttClient.connect();
+ }
+
+ /**
+ * Sets the QoS for MQTT messages
+ *
+ * @param qos
+ */
+ public void setQoS(int qos) {
+ if (qos >= 0 && qos <= 3) {
+ this.qos = qos;
+ } else {
+ throw new IllegalArgumentException("Invalid QoS: " + qos);
+ }
+ }
+
+ /**
+ * Gets the QoS for MQTT messages
+ *
+ * @param qos
+ */
+ public int getQoS() {
+ return this.qos;
+ }
+
+ /**
+ * Sends MQTT message to connected broker
+ * @param topic in which the message will be published
+ * @param payload the actual message
+ */
+ protected void sendMqttMessage(String topic, String payload) {
+ MqttMessage msg = new MqttMessage(payload.getBytes());
+ if (this.qos != 1) {
+ msg.setQos(this.qos);
+ }
+ try {
+ logger.debug("Send MQTT message to " + topic + ": " + payload);
+ mqttClient.publish(topic, msg);
+ } catch (MqttPersistenceException e) {
+ logger.error("Could not persist mqtt message", e);
+ } catch (MqttException e) {
+ logger.error("Could not send mqtt message", e);
+ }
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/submodel/mqtt/MqttSubmodelAPI.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/submodel/mqtt/MqttSubmodelAPI.java
new file mode 100644
index 0000000..fdf33e9
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/submodel/mqtt/MqttSubmodelAPI.java
@@ -0,0 +1,231 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.extensions.submodel.mqtt;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.basyx.extensions.shared.mqtt.MqttEventService;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
+import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.paho.client.mqttv3.MqttClient;
+import org.eclipse.paho.client.mqttv3.MqttException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implementation variant for the SubmodelAPI that triggers MQTT events for
+ * different CRUD operations on the submodel. Has to be based on a backend
+ * implementation of the ISubmodelAPI to forward its method calls.
+ *
+ * @author espen
+ *
+ */
+public class MqttSubmodelAPI extends MqttEventService implements ISubmodelAPI {
+ private static Logger logger = LoggerFactory.getLogger(MqttSubmodelAPI.class);
+
+ // List of topics
+ public static final String TOPIC_CREATESUBMODEL = "BaSyxSubmodel_createdSubmodel";
+ public static final String TOPIC_ADDELEMENT = "BaSyxSubmodel_addedSubmodelElement";
+ public static final String TOPIC_DELETEELEMENT = "BaSyxSubmodel_removedSubmodelElement";
+ public static final String TOPIC_UPDATEELEMENT = "BaSyxSubmodel_updatedSubmodelElement";
+
+ // The underlying SubmodelAPI
+ protected ISubmodelAPI observedAPI;
+
+ // Submodel Element whitelist for filtering
+ protected boolean useWhitelist = false;
+ protected Set<String> whitelist = new HashSet<>();
+
+ /**
+ * Constructor for adding this MQTT extension on top of another SubmodelAPI
+ *
+ * @param observedAPI The underlying submodelAPI
+ * @throws MqttException
+ */
+ public MqttSubmodelAPI(ISubmodelAPI observedAPI, String serverEndpoint, String clientId) throws MqttException {
+ super(serverEndpoint, clientId);
+ logger.info("Create new MQTT submodel for endpoint " + serverEndpoint);
+ this.observedAPI = observedAPI;
+ sendMqttMessage(TOPIC_CREATESUBMODEL, observedAPI.getSubmodel().getIdentification().getId());
+ }
+
+ /**
+ * Constructor for adding this MQTT extension on top of another SubmodelAPI
+ *
+ * @param observedAPI The underlying submodelAPI
+ * @throws MqttException
+ */
+ public MqttSubmodelAPI(ISubmodelAPI observedAPI, String serverEndpoint, String clientId, String user, char[] pw)
+ throws MqttException {
+ super(serverEndpoint, clientId, user, pw);
+ logger.info("Create new MQTT submodel for endpoint " + serverEndpoint);
+ this.observedAPI = observedAPI;
+ sendMqttMessage(TOPIC_CREATESUBMODEL, observedAPI.getSubmodel().getIdentification().getId());
+ }
+
+ /**
+ * Constructor for adding this MQTT extension on top of another SubmodelAPI.
+ *
+ * @param observedAPI The underlying submodelAPI
+ * @param client An already connected mqtt client
+ * @throws MqttException
+ */
+ public MqttSubmodelAPI(ISubmodelAPI observedAPI, MqttClient client) throws MqttException {
+ super(client);
+ this.observedAPI = observedAPI;
+ sendMqttMessage(TOPIC_CREATESUBMODEL, observedAPI.getSubmodel().getIdentification().getId());
+ }
+
+ /**
+ * Adds a submodel element to the filter whitelist. Can also be a path for nested submodel elements.
+ *
+ * @param element
+ */
+ public void observeSubmodelElement(String shortId) {
+ whitelist.add(VABPathTools.stripSlashes(shortId));
+ }
+
+ /**
+ * Sets a new filter whitelist.
+ *
+ * @param element
+ */
+ public void setWhitelist(Set<String> shortIds) {
+ this.whitelist.clear();
+ for (String entry : shortIds) {
+ this.whitelist.add(VABPathTools.stripSlashes(entry));
+ }
+ }
+
+ /**
+ * Disables the submodel element filter whitelist
+ *
+ * @param element
+ */
+ public void disableWhitelist() {
+ useWhitelist = false;
+ }
+
+ /**
+ * Enables the submodel element filter whitelist
+ *
+ * @param element
+ */
+ public void enableWhitelist() {
+ useWhitelist = true;
+ }
+
+ @Override
+ public ISubmodel getSubmodel() {
+ return observedAPI.getSubmodel();
+ }
+
+ @Override
+ public void addSubmodelElement(ISubmodelElement elem) {
+ observedAPI.addSubmodelElement(elem);
+ if (filter(elem.getIdShort())) {
+ sendMqttMessage(TOPIC_ADDELEMENT, getCombinedMessage(getAASId(), getSubmodelId(), elem.getIdShort()));
+ }
+ }
+
+ @Override
+ public void addSubmodelElement(String idShortPath, ISubmodelElement elem) {
+ observedAPI.addSubmodelElement(idShortPath, elem);
+ if (filter(idShortPath)) {
+ sendMqttMessage(TOPIC_ADDELEMENT, getCombinedMessage(getAASId(), getSubmodelId(), idShortPath));
+ }
+ }
+
+ @Override
+ public ISubmodelElement getSubmodelElement(String idShortPath) {
+ return observedAPI.getSubmodelElement(idShortPath);
+ }
+
+ @Override
+ public void deleteSubmodelElement(String idShortPath) {
+ observedAPI.deleteSubmodelElement(idShortPath);
+ if (filter(idShortPath)) {
+ sendMqttMessage(TOPIC_DELETEELEMENT, getCombinedMessage(getAASId(), getSubmodelId(), idShortPath));
+ }
+ }
+
+ @Override
+ public Collection<IOperation> getOperations() {
+ return observedAPI.getOperations();
+ }
+
+ @Override
+ public Collection<ISubmodelElement> getSubmodelElements() {
+ return observedAPI.getSubmodelElements();
+ }
+
+ @Override
+ public void updateSubmodelElement(String idShortPath, Object newValue) {
+ observedAPI.updateSubmodelElement(idShortPath, newValue);
+ if (filter(idShortPath)) {
+ sendMqttMessage(TOPIC_UPDATEELEMENT, getCombinedMessage(getAASId(), getSubmodelId(), idShortPath));
+ }
+ }
+
+ @Override
+ public Object getSubmodelElementValue(String idShortPath) {
+ return observedAPI.getSubmodelElementValue(idShortPath);
+ }
+
+ @Override
+ public Object invokeOperation(String idShortPath, Object... params) {
+ return observedAPI.invokeOperation(idShortPath, params);
+ }
+
+ @Override
+ public Object invokeAsync(String idShortPath, Object... params) {
+ return observedAPI.invokeAsync(idShortPath, params);
+ }
+
+ @Override
+ public Object getOperationResult(String idShort, String requestId) {
+ return observedAPI.getOperationResult(idShort, requestId);
+ }
+
+ public static String getCombinedMessage(String aasId, String submodelId, String elementPart) {
+ elementPart = VABPathTools.stripSlashes(elementPart);
+ return "(" + aasId + "," + submodelId + "," + elementPart + ")";
+ }
+
+ private boolean filter(String idShort) {
+ idShort = VABPathTools.stripSlashes(idShort);
+ return !useWhitelist || whitelist.contains(idShort);
+ }
+
+ private String getSubmodelId() {
+ ISubmodel submodel = getSubmodel();
+ return submodel.getIdentification().getId();
+ }
+
+ private String getAASId() {
+ ISubmodel submodel = getSubmodel();
+ IReference parentReference = submodel.getParent();
+ if (parentReference != null) {
+ List<IKey> keys = parentReference.getKeys();
+ if (keys != null && keys.size() > 0) {
+ return keys.get(0).getValue();
+ }
+ }
+ return null;
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/XMLHelper.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/XMLHelper.java
index e724425..9967865 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/XMLHelper.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/XMLHelper.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.factory.xml;
import java.util.ArrayList;
@@ -45,4 +54,4 @@
public static String getString(Object object) {
return object instanceof String ? ((String) object).trim() : "";
}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/api/dataspecification/DataSpecificationIEC61360XMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/api/dataspecification/DataSpecificationIEC61360XMLConverter.java
index 855a8ba..f3f52b0 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/api/dataspecification/DataSpecificationIEC61360XMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/api/dataspecification/DataSpecificationIEC61360XMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.factory.xml.api.dataspecification;
import java.util.ArrayList;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/api/parts/ConceptDescriptionXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/api/parts/ConceptDescriptionXMLConverter.java
index 07532b9..a46f9db 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/api/parts/ConceptDescriptionXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/api/parts/ConceptDescriptionXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.factory.xml.api.parts;
import java.util.ArrayList;
@@ -12,7 +21,10 @@
import org.eclipse.basyx.submodel.factory.xml.converters.reference.ReferenceXMLConverter;
import org.eclipse.basyx.submodel.metamodel.api.parts.IConceptDescription;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.map.parts.ConceptDescription;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -44,8 +56,8 @@
for (Map<String, Object> xmlConceptDescription : xmlConceptDescriptionList) {
ConceptDescription conceptDescription = new ConceptDescription();
- IdentifiableXMLConverter.populateIdentifiable(xmlConceptDescription, conceptDescription);
- HasDataSpecificationXMLConverter.populateHasDataSpecification(xmlConceptDescription, conceptDescription);
+ IdentifiableXMLConverter.populateIdentifiable(xmlConceptDescription, Identifiable.createAsFacadeNonStrict(conceptDescription, KeyElements.CONCEPTDESCRIPTION));
+ HasDataSpecificationXMLConverter.populateHasDataSpecification(xmlConceptDescription, HasDataSpecification.createAsFacade(conceptDescription));
Collection<Reference> handleIsCaseOf = parseIsCaseOfRefs(xmlConceptDescription);
conceptDescription.setIsCaseOf(handleIsCaseOf);
@@ -120,4 +132,4 @@
xmlConceptDescription.appendChild(xmlIsCaseOf);
}
}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/SubmodelXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/SubmodelXMLConverter.java
index 8ca4c19..9347f8e 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/SubmodelXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/SubmodelXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.factory.xml.converters;
import java.util.ArrayList;
@@ -12,14 +21,20 @@
import org.eclipse.basyx.submodel.factory.xml.converters.qualifier.haskind.HasKindXMLConverter;
import org.eclipse.basyx.submodel.factory.xml.converters.qualifier.qualifiable.QualifiableXMLConverter;
import org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.SubmodelElementXMLConverter;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.haskind.HasKind;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifiable;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
- * Handles the conversion between ISubModel objects and the XML tag <aas:submodels> in both directions
+ * Handles the conversion between ISubmodel objects and the XML tag <aas:submodels> in both directions
*
* @author conradi
*
@@ -30,28 +45,28 @@
public static final String SUBMODEL = "aas:submodel";
/**
- * Parses <aas:submodels> and builds the SubModel objects from it
+ * Parses <aas:submodels> and builds the Submodel objects from it
*
* @param xmlObject a Map containing the content of the XML tag <aas:submodels>
- * @return a List of ISubModel objects parsed form the given XML Map
+ * @return a List of ISubmodel objects parsed form the given XML Map
*/
- public static List<ISubModel> parseSubmodels(Map<String, Object> xmlObject) {
+ public static List<ISubmodel> parseSubmodels(Map<String, Object> xmlObject) {
List<Map<String, Object>> xmlSubmodels = XMLHelper.getList(xmlObject.get(SUBMODEL));
- List<ISubModel> submodels = new ArrayList<>();
+ List<ISubmodel> submodels = new ArrayList<>();
for (Map<String, Object> xmlSubmodel : xmlSubmodels) {
- SubModel submodel = new SubModel();
+ Submodel submodel = new Submodel();
- IdentifiableXMLConverter.populateIdentifiable(xmlSubmodel, submodel);
- HasSemanticsXMLConverter.populateHasSemantics(xmlSubmodel, submodel);
- HasDataSpecificationXMLConverter.populateHasDataSpecification(xmlSubmodel, submodel);
- QualifiableXMLConverter.populateQualifiable(xmlSubmodel, submodel);
- HasKindXMLConverter.populateHasKind(xmlSubmodel, submodel);
+ IdentifiableXMLConverter.populateIdentifiable(xmlSubmodel, Identifiable.createAsFacadeNonStrict(submodel, KeyElements.SUBMODEL));
+ HasSemanticsXMLConverter.populateHasSemantics(xmlSubmodel, HasSemantics.createAsFacade(submodel));
+ HasDataSpecificationXMLConverter.populateHasDataSpecification(xmlSubmodel, HasDataSpecification.createAsFacade(submodel));
+ QualifiableXMLConverter.populateQualifiable(xmlSubmodel, Qualifiable.createAsFacade(submodel));
+ HasKindXMLConverter.populateHasKind(xmlSubmodel, HasKind.createAsFacade(submodel));
List<ISubmodelElement> submodelElements = SubmodelElementXMLConverter.parseSubmodelElements(xmlSubmodel);
for (ISubmodelElement submdoElement : submodelElements) {
- submodel.addSubModelElement(submdoElement);
+ submodel.addSubmodelElement(submdoElement);
}
submodels.add(submodel);
@@ -63,17 +78,17 @@
/**
- * Builds <aas:submodels> from a given Collection of ISubModel objects
+ * Builds <aas:submodels> from a given Collection of ISubmodel objects
*
* @param document the XML document
- * @param subModels a Collection of ISubModel objects to build the XML for
- * @return the <aas:submodels> XML tag for the given ISubModel objects
+ * @param subModels a Collection of ISubmodel objects to build the XML for
+ * @return the <aas:submodels> XML tag for the given ISubmodel objects
*/
- public static Element buildSubmodelsXML(Document document, Collection<ISubModel> subModels) {
+ public static Element buildSubmodelsXML(Document document, Collection<ISubmodel> subModels) {
Element root = document.createElement(SUBMODELS);
List<Element> xmlSubmodelList = new ArrayList<>();
- for(ISubModel subModel: subModels) {
+ for(ISubmodel subModel: subModels) {
Element subModelRoot = document.createElement(SUBMODEL);
IdentifiableXMLConverter.populateIdentifiableXML(document, subModelRoot, subModel);
@@ -95,4 +110,4 @@
}
return root;
}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/HasDataSpecificationXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/HasDataSpecificationXMLConverter.java
index cd725fe..9eb7956 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/HasDataSpecificationXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/HasDataSpecificationXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.factory.xml.converters.qualifier;
import java.util.ArrayList;
@@ -41,23 +50,25 @@
* @param hasDataSpecificationMap the IHasDataSpecification object to be populated -treated as Map here-
*/
public static void populateHasDataSpecification(Map<String, Object> xmlObject,
- Map<String, Object> hasDataSpecificationMap) {
- HasDataSpecification hasDataSpecification = HasDataSpecification.createAsFacade(hasDataSpecificationMap);
+ HasDataSpecification hasDataSpecification) {
if (xmlObject == null || hasDataSpecification == null) return;
Object xmlDataSpecObj = xmlObject.get(EMBEDDED_DATA_SPECIFICATION);
- List<IEmbeddedDataSpecification> embeddedSpecList = new ArrayList<>();
- List<Map<String, Object>> xmlSpecList = XMLHelper.getList(xmlDataSpecObj);
- for (Map<String, Object> xmlSpec : xmlSpecList) {
- IReference ref = parseReference(xmlSpec);
- IDataSpecificationContent content = parseContent(xmlSpec);
- EmbeddedDataSpecification spec = new EmbeddedDataSpecification();
- spec.setDataSpecificationTemplate(ref);
- // TODO: Also support other templates
- spec.setContent((DataSpecificationIEC61360Content) content);
- embeddedSpecList.add(spec);
+ if (xmlDataSpecObj != null ) {
+ List<IEmbeddedDataSpecification> embeddedSpecList = new ArrayList<>();
+ List<Map<String, Object>> xmlSpecList = XMLHelper.getList(xmlDataSpecObj);
+ for (Map<String, Object> xmlSpec : xmlSpecList) {
+ IReference ref = parseReference(xmlSpec);
+ IDataSpecificationContent content = parseContent(xmlSpec);
+ EmbeddedDataSpecification spec = new EmbeddedDataSpecification();
+ spec.setDataSpecificationTemplate(ref);
+ // TODO: Also support other templates
+ spec.setContent((DataSpecificationIEC61360Content) content);
+ embeddedSpecList.add(spec);
+ }
+ hasDataSpecification.setEmbeddedDataSpecifications(embeddedSpecList);
}
- hasDataSpecification.setEmbeddedDataSpecifications(embeddedSpecList);
+
// Note: DataSpecificationReferences are not serialized in XML
// "http://admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360/2/0" could always be added here,
@@ -135,6 +146,7 @@
root.appendChild(embeddedDataSpecRoot);
}
}
+
/**
* Populates a DataSpecificationContent XML from the IDataSpecificationContent object
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/HasSemanticsXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/HasSemanticsXMLConverter.java
index 6f0f55a..b5ea693 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/HasSemanticsXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/HasSemanticsXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.factory.xml.converters.qualifier;
import java.util.Map;
@@ -21,17 +30,17 @@
/**
- * Populates a given IHasSemantics object with the data form the given XML
+ * Populates a given HasSemantics object with the data form the given XML
*
* @param xmlObject the XML map containing the <aas:semanticId> tag
- * @param hasSemantics the IHasDataSpecification object to be populated -treated as Map here-
+ * @param hasSemantics the HasSemantics object to be populated
*/
@SuppressWarnings("unchecked")
- public static void populateHasSemantics(Map<String, Object> xmlObject, Map<String, Object> hasSemantics) {
- //The IHasSemantics object has to be treated as Map here, as the Interface has no Setters
-
+ public static void populateHasSemantics(Map<String, Object> xmlObject, HasSemantics hasSemantics) {
Map<String, Object> xmlSemanticIDObj = (Map<String, Object>) xmlObject.get(SEMANTIC_ID);
- hasSemantics.put(HasSemantics.SEMANTICID, ReferenceXMLConverter.parseReference(xmlSemanticIDObj));
+ if (xmlSemanticIDObj != null) {
+ hasSemantics.setSemanticId(ReferenceXMLConverter.parseReference(xmlSemanticIDObj));
+ }
}
@@ -53,4 +62,4 @@
root.appendChild(semanticIdRoot);
}
}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/IdentifiableXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/IdentifiableXMLConverter.java
index b87eee1..6dd0fb5 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/IdentifiableXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/IdentifiableXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.factory.xml.converters.qualifier;
import java.util.Map;
@@ -5,12 +14,13 @@
import org.eclipse.basyx.submodel.factory.xml.XMLHelper;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
import org.eclipse.basyx.submodel.metamodel.api.qualifier.IIdentifiable;
-import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.AdministrativeInformation;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+import com.google.common.base.Strings;
+
/**
* Handles the conversion between an IIdentifiable object and the XML tags<br>
* <aas:administration> and <aas:identification> in both directions
@@ -28,36 +38,32 @@
/**
- * Populates a given IIdentifiable object with the data form the given XML
+ * Populates a given Identifiable object with the data form the given XML
*
* @param xmlObject the XML map containing the <aas:administration> and <aas:identification> tags
- * @param identifiable the IIdentifiable object to be populated -treated as Map here-
+ * @param identifiable the Identifiable object to be populated
*/
@SuppressWarnings("unchecked")
- public static void populateIdentifiable(Map<String, Object> xmlObject, Map<String, Object> identifiable) {
- //The IIdentifiable object has to be treated as Map here, as the Interface has no Setters
-
- String id="";
- String idType="";
- String version="";
- String revision="";
-
+ public static void populateIdentifiable(Map<String, Object> xmlObject, Identifiable identifiable) {
ReferableXMLConverter.populateReferable(xmlObject, identifiable);
Map<String, Object> identierFromXML = (Map<String, Object>) xmlObject.get(IDENTIFICATION);
- if(identierFromXML != null) {
- id = XMLHelper.getString(identierFromXML.get(XMLHelper.TEXT));
- idType = XMLHelper.getString(identierFromXML.get(IDTYPE));
+ if (identierFromXML == null) {
+ throw createInvalidIdentifierException(xmlObject);
}
+ String id = XMLHelper.getString(identierFromXML.get(XMLHelper.TEXT));
+ String idType = XMLHelper.getString(identierFromXML.get(IDTYPE));
+ if (Strings.isNullOrEmpty(id) || Strings.isNullOrEmpty(idType)) {
+ throw createInvalidIdentifierException(xmlObject);
+ }
+ identifiable.setIdentification(IdentifierType.fromString(idType), id);
- if(xmlObject.containsKey(ADMINISTRATION)) {
- Map<String, Object> administrationFromXML = (Map<String, Object>) xmlObject.get(ADMINISTRATION);
- version = XMLHelper.getString(administrationFromXML.get(VERSION));
- revision = XMLHelper.getString(administrationFromXML.get(REVISION));
+ Map<String, Object> administrationFromXML = (Map<String, Object>) xmlObject.get(ADMINISTRATION);
+ if(administrationFromXML != null) {
+ String version = XMLHelper.getString(administrationFromXML.get(VERSION));
+ String revision = XMLHelper.getString(administrationFromXML.get(REVISION));
+ identifiable.setAdministration(new AdministrativeInformation(version, revision));
}
-
- identifiable.put(Identifiable.ADMINISTRATION, new AdministrativeInformation(version, revision));
- identifiable.put(Identifiable.IDENTIFICATION, new Identifier(IdentifierType.fromString(idType), id));
}
@@ -117,4 +123,8 @@
}
}
}
-}
\ No newline at end of file
+
+ private static RuntimeException createInvalidIdentifierException(Map<String, Object> xmlObject) {
+ return new RuntimeException("Invalid XML of Identifiable. No valid identification is present. " + xmlObject.toString());
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/LangStringsXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/LangStringsXMLConverter.java
index b666389..e302fcc 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/LangStringsXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/LangStringsXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.factory.xml.converters.qualifier;
import java.util.List;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/ReferableXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/ReferableXMLConverter.java
index 6c62b13..e4922f2 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/ReferableXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/ReferableXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.factory.xml.converters.qualifier;
import java.util.Map;
@@ -11,6 +20,8 @@
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+import com.google.common.base.Strings;
+
/**
* Handles the conversion between an IReferable object and the XML tags<br>
* <aas:idShort>, <aas:category>, <aas:parent> and <aas:description> in both directions
@@ -26,26 +37,33 @@
public static final String DESCRIPTION = "aas:description";
/**
- * Populates a given IReferable object with the data form the given XML
+ * Populates a given Referable object with the data form the given XML
*
* @param xmlObject the XML map containing the tag relevant for IReferable
- * @param referable the IReferable object to be populated -treated as Map here-
+ * @param referable the Referable object to be populated
*/
@SuppressWarnings("unchecked")
- public static void populateReferable(Map<String, Object> xmlObject, Map<String, Object> referable) {
- //The IReferable object has to be treated as Map here, as the Interface has no Setters
-
+ public static void populateReferable(Map<String, Object> xmlObject, Referable referable) {
String idShort = XMLHelper.getString(xmlObject.get(ID_SHORT));
String category = XMLHelper.getString(xmlObject.get(CATEGORY));
LangStrings description = parseDescription(xmlObject);
Reference parent = ReferenceXMLConverter.parseReference((Map<String, Object>) xmlObject.get(PARENT));
+ if (Strings.isNullOrEmpty(idShort)) {
+ throw new RuntimeException("Invalid XML of Referable. No valid idShort is present. " + xmlObject.toString());
+ }
+ referable.setIdShort(idShort);
- referable.put(Referable.IDSHORT, idShort);
- referable.put(Referable.CATEGORY, category);
- referable.put(Referable.DESCRIPTION, description);
- referable.put(Referable.PARENT, parent);
+ if (!Strings.isNullOrEmpty(category)) {
+ referable.setCategory(category);
+ }
+ if (description != null) {
+ referable.setDescription(description);
+ }
+ if (parent != null) {
+ referable.setParent(parent);
+ }
}
@@ -60,7 +78,7 @@
Map<String, Object> descObj = (Map<String, Object>) xmlObject.get(DESCRIPTION);
if (descObj == null) {
- return new LangStrings();
+ return null;
}
return LangStringsXMLConverter.parseLangStrings(descObj);
@@ -91,7 +109,7 @@
root.appendChild(categoryElem);
}
- if(!referable.getDescription().isEmpty()) {
+ if(referable.getDescription() != null && !referable.getDescription().isEmpty()) {
Element descriptionRoot = document.createElement(DESCRIPTION);
LangStringsXMLConverter.buildLangStringsXML(document, descriptionRoot, referable.getDescription());
root.appendChild(descriptionRoot);
@@ -106,4 +124,4 @@
}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/haskind/HasKindXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/haskind/HasKindXMLConverter.java
index f76f6ae..09a3d1f 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/haskind/HasKindXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/haskind/HasKindXMLConverter.java
@@ -1,13 +1,25 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.factory.xml.converters.qualifier.haskind;
import java.util.Map;
import org.eclipse.basyx.submodel.factory.xml.XMLHelper;
import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.IHasKind;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.haskind.HasKind;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+import com.google.common.base.Strings;
+
/**
* Handles the conversion between an IHasKind object and the XML tag <aas:kind> in both directions
*
@@ -20,16 +32,16 @@
/**
- * Populates a given IHasKind object with the data form the given XML
+ * Populates a given HasKind object with the data form the given XML
*
* @param xmlObject the XML map containing the <aas:kind> tag
- * @param hasKind the IHasKind object to be populated -treated as Map here-
+ * @param hasKind the HasKind object to be populated
*/
- public static void populateHasKind(Map<String, Object> xmlObject, Map<String, Object> hasKind) {
- //The IHasKind object has to be treated as Map here, as the Interface has no Setters
-
+ public static void populateHasKind(Map<String, Object> xmlObject, HasKind hasKind) {
String hasKindValue = XMLHelper.getString(xmlObject.get(KIND));
- hasKind.put(HasKind.KIND, hasKindValue);
+ if (!Strings.isNullOrEmpty(hasKindValue)) {
+ hasKind.setModelingKind(ModelingKind.fromString(hasKindValue));
+ }
}
@@ -48,4 +60,4 @@
root.appendChild(kindRoot);
}
}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/qualifiable/QualifiableXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/qualifiable/QualifiableXMLConverter.java
index dfd209c..c4ab1d6 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/qualifiable/QualifiableXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/qualifiable/QualifiableXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.factory.xml.converters.qualifier.qualifiable;
import java.util.Collection;
@@ -13,10 +22,14 @@
import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IQualifiable;
import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IQualifier;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Formula;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifiable;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifier;
import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueTypeHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -28,8 +41,9 @@
*/
public class QualifiableXMLConverter {
+ private static Logger logger = LoggerFactory.getLogger(QualifiableXMLConverter.class);
+
public static final String QUALIFIER = "aas:qualifier";
- public static final String QUALIFIERS = "aas:qualifiers";
public static final String FORMULA = "aas:formula";
public static final String DEPENDS_ON_REFS = "aas:dependsOnRefs";
public static final String REFERENCE = "aas:reference";
@@ -40,17 +54,17 @@
/**
- * Populates a given IQualifiable object with the data form the given XML
+ * Populates a given Qualifiable object with the data form the given XML
*
* @param xmlObject the XML map containing the <aas:qualifier> tag
- * @param qualifiable the IQualifiable object to be populated -treated as Map here-
+ * @param qualifiable the Qualifiable object to be populated
*/
@SuppressWarnings("unchecked")
- public static void populateQualifiable(Map<String, Object> xmlObject, Map<String, Object> qualifiable) {
- //The IQualifiable object has to be treated as Map here, as the Interface has no Setters
-
+ public static void populateQualifiable(Map<String, Object> xmlObject, Qualifiable qualifiable) {
Map<String, Object> qualifierObj = (Map<String, Object>) xmlObject.get(QUALIFIER);
- qualifiable.put(Qualifiable.CONSTRAINTS, parseConstraints(qualifierObj));
+ if (qualifierObj != null) {
+ qualifiable.setQualifiers(parseConstraints(qualifierObj));
+ }
}
@@ -60,26 +74,18 @@
* @param xmlConstraints the XML map containing the <aas:formula> and <aas:qualifier> tags
* @return the Set of IConstraint objects parsed
*/
- @SuppressWarnings("unchecked")
private static Collection<IConstraint> parseConstraints(Map<String, Object> xmlConstraints) {
Collection<IConstraint> constraints = new HashSet<>();
if(xmlConstraints == null) return constraints;
- List<Map<String, Object>> xmlQualifiersList = XMLHelper.getList(xmlConstraints.get(QUALIFIERS));
-
- for (Map<String, Object> xmlQualifiers : xmlQualifiersList) {
+ List<Map<String, Object>> xmlQualifier = XMLHelper.getList(xmlConstraints.get(QUALIFIER));
+ xmlQualifier.stream().map(QualifiableXMLConverter::parseQualifier).forEach(constraints::add);
+
- Map<String, Object> xmlFormula = (Map<String, Object>) xmlQualifiers.get(FORMULA);
- if(xmlFormula != null) {
- constraints.add(parseFormula(xmlFormula));
- }
+ List<Map<String, Object>> xmlFormula = XMLHelper.getList(xmlConstraints.get(FORMULA));
+ xmlFormula.stream().map(QualifiableXMLConverter::parseFormula).forEach(constraints::add);
- Map<String, Object> xmlQualifier = (Map<String, Object>) xmlQualifiers.get(QUALIFIER);
- if(xmlQualifier != null) {
- constraints.add(parseQualifier(xmlQualifier));
- }
- }
return constraints;
}
@@ -121,13 +127,17 @@
Reference ref = ReferenceXMLConverter.parseReference(qualifierValueIdObj);
Qualifier qualifier = new Qualifier();
- HasSemanticsXMLConverter.populateHasSemantics(xmlQualifier, qualifier);
+ HasSemanticsXMLConverter.populateHasSemantics(xmlQualifier, HasSemantics.createAsFacade(qualifier));
qualifier.setType(type);
qualifier.setValue(value);
qualifier.setValueId(ref);
- qualifier.setValueType(valueType);
-
+
+ if (valueType == null || valueType.isEmpty()) {
+ logger.warn("Creating element " + xmlQualifier + " without mandatory valueType!");
+ } else {
+ qualifier.setValueType(ValueTypeHelper.fromName(valueType));
+ }
return qualifier;
}
@@ -143,17 +153,17 @@
* @param qualifiable the IQualifiable object to be converted to XML
*/
public static void populateQualifiableXML(Document document, Element root, IQualifiable qualifiable) {
- if(qualifiable.getQualifier() == null || qualifiable.getQualifier().size() == 0) return;
+ if(qualifiable.getQualifiers() == null || qualifiable.getQualifiers().size() == 0) return;
- Collection<IConstraint> constraints = qualifiable.getQualifier();
+ Collection<IConstraint> constraints = qualifiable.getQualifiers();
Element qualifierRoot = document.createElement(QUALIFIER);
for (IConstraint constraint : constraints) {
qualifierRoot.appendChild(buildQualifiersXML(document, constraint));
}
-
+
root.appendChild(qualifierRoot);
}
@@ -161,21 +171,22 @@
/**
* Builds XML from a given IConstraint objcet
*
- * @param document the XML document
- * @param constraint the IConstraint to be converted to XML
- * @return the <aas:qualifiers> XML tag build from the IConstraint
+ * @param document
+ * the XML document
+ * @param constraint
+ * the IConstraint to be converted to XML
+ * @return the <aas:qualifier> XML tag build from the IConstraint
*/
private static Element buildQualifiersXML(Document document, IConstraint constraint) {
- Element qualifiersRoot = document.createElement(QUALIFIERS);
-
+
//the constraints can be IFormula or IQualifier
if(constraint instanceof IFormula) {
- qualifiersRoot.appendChild(buildFormulaXML(document, (IFormula) constraint));
+ return buildFormulaXML(document, (IFormula) constraint);
} else if(constraint instanceof IQualifier) {
- qualifiersRoot.appendChild(buildQualifierXML(document, (IQualifier) constraint));
+ return buildQualifierXML(document, (IQualifier) constraint);
}
- return qualifiersRoot;
+ throw new RuntimeException("Unknown qualifier type " + constraint);
}
@@ -209,7 +220,7 @@
IReference qualId = qualifier.getValueId();
String type = XMLHelper.getString(qualifier.getType());
String value = XMLHelper.getString(qualifier.getValue());
- String valueType = XMLHelper.getString(qualifier.getValueType());
+ String valueType = qualifier.getValueType().toString();
Element qualifierRoot = document.createElement(QUALIFIER);
Element qualifierValueId = document.createElement(VALUE_ID);
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/reference/ReferenceXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/reference/ReferenceXMLConverter.java
index 1f19023..39afdad 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/reference/ReferenceXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/reference/ReferenceXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.factory.xml.converters.reference;
import java.util.ArrayList;
@@ -181,4 +190,4 @@
return xmlKey;
}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/SubmodelElementCollectionXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/SubmodelElementCollectionXMLConverter.java
index 38cfc77..8768403 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/SubmodelElementCollectionXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/SubmodelElementCollectionXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement;
import java.util.Collection;
@@ -67,7 +76,7 @@
orderedElem.appendChild(document.createTextNode(isOrdered));
smElemCollectionRoot.appendChild(orderedElem);
- Collection<ISubmodelElement> elems = smElemCollection.getValue();
+ Collection<ISubmodelElement> elems = smElemCollection.getSubmodelElements().values();
//recursively build the SubmodelElements contained in the ElementCollection
if(elems != null) {
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/SubmodelElementXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/SubmodelElementXMLConverter.java
index 46b88e1..6d0545d 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/SubmodelElementXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/SubmodelElementXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement;
import java.util.ArrayList;
@@ -20,7 +29,9 @@
import org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.entity.EntityXMLConverter;
import org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.event.BasicEventXMLConverter;
import org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.operation.OperationXMLConverter;
+import org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.relationship.AnnotatedRelationshipElementXMLConverter;
import org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.relationship.RelationshipElementXMLConverter;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IBlob;
@@ -32,25 +43,32 @@
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.entity.IEntity;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.event.IBasicEvent;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.relationship.IAnnotatedRelationshipElement;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.relationship.IRelationshipElement;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.haskind.HasKind;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifiable;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Blob;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Range;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.ReferenceElement;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.Range;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.entity.Entity;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.event.BasicEvent;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.AnnotatedRelationshipElement;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElement;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
* Parses <aas:submodelElements> and builds the SubmodelElement objects from it <br>
- * Builds <aas:submodelElements> form a given Collection of SubmodelElement
+ * Builds <aas:submodelElements> from a given Collection of SubmodelElement
*
* @author conradi
*
@@ -59,8 +77,10 @@
public static final String SUBMODEL_ELEMENTS = "aas:submodelElements";
public static final String SUBMODEL_ELEMENT = "aas:submodelElement";
+ public static final String DATA_ELEMENT = "aas:dataElement";
public static final String VALUE = "aas:value";
public static final String VALUE_TYPE = "aas:valueType";
+ public static final String VALUE_ID = "aas:valueId";
public static final String MIME_TYPE = "aas:mimeType";
@@ -68,7 +88,7 @@
* Parses a given Map containing the XML tag <aas:submodelElements>
*
* @param xmlSubmodelElements a Map of the XML tag <aas:submodelElements>
- * @return a List with the ISubmodelElement Objects parsed form the XML
+ * @return a List with the ISubmodelElement Objects parsed from the XML
*/
@SuppressWarnings("unchecked")
public static List<ISubmodelElement> parseSubmodelElements(Map<String, Object> xmlSubmodelElements) {
@@ -78,10 +98,10 @@
/**
- * Parses the individual <aas:submodelElement> tags form the Map
+ * Parses the individual <aas:submodelElement> tags from the Map
*
* @param xmlObject a Map of <aas:submodelElement> tags
- * @return a List with the ISubmodelElement Objects parsed form the XML
+ * @return a List with the ISubmodelElement Objects parsed from the XML
*/
protected static List<ISubmodelElement> getSubmodelElements(Map<String, Object> xmlObject) {
List<ISubmodelElement> submodelElemList = new ArrayList<>();
@@ -100,14 +120,14 @@
* Parses the one SubmodelElement
*
* @param xmlObject a Map of the SubmodelElement XML
- * @return a List with the ISubmodelElement Objects parsed form the XML
+ * @return a List with the ISubmodelElement Objects parsed from the XML
*/
@SuppressWarnings("unchecked")
- protected static SubmodelElement getSubmodelElement(Map<String, Object> xmlObject) {
+ public static SubmodelElement getSubmodelElement(Map<String, Object> xmlObject) {
if (xmlObject.containsKey(PropertyXMLConverter.PROPERTY)) {
xmlObject = (Map<String, Object>) xmlObject.get(PropertyXMLConverter.PROPERTY);
- return PropertyXMLConverter.parsePropery(xmlObject);
+ return PropertyXMLConverter.parseProperty(xmlObject);
}
else if (xmlObject.containsKey(BasicEventXMLConverter.BASIC_EVENT)) {
xmlObject = (Map<String, Object>) xmlObject.get(BasicEventXMLConverter.BASIC_EVENT);
@@ -149,6 +169,11 @@
RelationshipElementXMLConverter.RELATIONSHIP_ELEMENT);
return RelationshipElementXMLConverter.parseRelationshipElement(xmlObject);
}
+ else if(xmlObject.containsKey(AnnotatedRelationshipElementXMLConverter.ANNOTATED_RELATIONSHIP_ELEMENT)) {
+ xmlObject = (Map<String, Object>) xmlObject.get(
+ AnnotatedRelationshipElementXMLConverter.ANNOTATED_RELATIONSHIP_ELEMENT);
+ return AnnotatedRelationshipElementXMLConverter.parseAnnotatedRelationshipElement(xmlObject);
+ }
else if(xmlObject.containsKey(OperationXMLConverter.OPERATION)) {
xmlObject = (Map<String, Object>) xmlObject.get(OperationXMLConverter.OPERATION);
return OperationXMLConverter.parseOperation(xmlObject);
@@ -166,11 +191,11 @@
*/
@SuppressWarnings("unchecked")
protected static void populateSubmodelElement(Map<String, Object> xmlObject, ISubmodelElement submodelElement) {
- ReferableXMLConverter.populateReferable(xmlObject, (Map<String, Object>) submodelElement);
- QualifiableXMLConverter.populateQualifiable(xmlObject, (Map<String, Object>) submodelElement);
- HasDataSpecificationXMLConverter.populateHasDataSpecification(xmlObject, (Map<String, Object>) submodelElement);
- HasSemanticsXMLConverter.populateHasSemantics(xmlObject, (Map<String, Object>) submodelElement);
- HasKindXMLConverter.populateHasKind(xmlObject, (Map<String, Object>) submodelElement);
+ ReferableXMLConverter.populateReferable(xmlObject, Referable.createAsFacadeNonStrict((Map<String, Object>) submodelElement, KeyElements.SUBMODELELEMENT));
+ QualifiableXMLConverter.populateQualifiable(xmlObject, Qualifiable.createAsFacade((Map<String, Object>) submodelElement));
+ HasDataSpecificationXMLConverter.populateHasDataSpecification(xmlObject, HasDataSpecification.createAsFacade((Map<String, Object>) submodelElement));
+ HasSemanticsXMLConverter.populateHasSemantics(xmlObject, HasSemantics.createAsFacade((Map<String, Object>) submodelElement));
+ HasKindXMLConverter.populateHasKind(xmlObject, HasKind.createAsFacade((Map<String, Object>) submodelElement));
}
@@ -180,7 +205,7 @@
* Builds the SubmodelElemensts XML tag <aas:submodelElements>
*
* @param document the XML document
- * @param submodelElements the SubmodelElements of the SubModel
+ * @param submodelElements the SubmodelElements of the Submodel
* @return XML Element with the root tag <aas:submodelElements>
*/
public static Element buildSubmodelElementsXML(Document document, Collection<ISubmodelElement> submodelElements) {
@@ -191,7 +216,7 @@
/**
- * Builds the individual SubmodelElement XML tags form a List of SubmodelElements and <br>
+ * Builds the individual SubmodelElement XML tags from a List of SubmodelElements and <br>
* populates the given root Element with them
*
* @param document the XML document
@@ -215,7 +240,7 @@
* @param submodelElement the SubmodelElement to build the XML for
* @return the SubmodelElement XML tag
*/
- protected static Element buildSubmodelElement(Document document, ISubmodelElement submodelElement) {
+ public static Element buildSubmodelElement(Document document, ISubmodelElement submodelElement) {
String type = submodelElement.getModelType();
switch (type) {
@@ -243,6 +268,9 @@
case RelationshipElement.MODELTYPE:
return RelationshipElementXMLConverter.buildRelationshipElement(
document, (IRelationshipElement) submodelElement);
+ case AnnotatedRelationshipElement.MODELTYPE:
+ return AnnotatedRelationshipElementXMLConverter.buildAnnotatedRelationshipElement(
+ document, (IAnnotatedRelationshipElement) submodelElement);
case Operation.MODELTYPE:
return OperationXMLConverter.buildOperation(document, (IOperation) submodelElement);
default:
@@ -265,4 +293,4 @@
QualifiableXMLConverter.populateQualifiableXML(document, root, submodelElement);
HasDataSpecificationXMLConverter.populateHasDataSpecificationXML(document, root, submodelElement);
}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/BlobXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/BlobXMLConverter.java
index c9e522f..64f7615 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/BlobXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/BlobXMLConverter.java
@@ -1,6 +1,14 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.dataelement;
-import java.util.Base64;
import java.util.Map;
import org.eclipse.basyx.submodel.factory.xml.XMLHelper;
@@ -29,12 +37,11 @@
* @return the parsed Blob
*/
public static Blob parseBlob(Map<String, Object> xmlObject) {
-
String mimeType = XMLHelper.getString(xmlObject.get(MIME_TYPE));
String value = XMLHelper.getString(xmlObject.get(VALUE));
- byte[] valueBytes = Base64.getDecoder().decode(value.getBytes());
-
- Blob blob = new Blob(valueBytes, mimeType);
+ Blob blob = new Blob();
+ blob.setMimeType(mimeType);
+ blob.setValue(value);
populateSubmodelElement(xmlObject, blob);
return blob;
}
@@ -54,7 +61,8 @@
populateSubmodelElement(document, blobRoot, blob);
- String value = Base64.getEncoder().encodeToString(blob.getValue());
+ // Base64 encoded string
+ String value = blob.getValue();
String mimeType = blob.getMimeType();
if(value != null) {
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/FileXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/FileXMLConverter.java
index d44f0f0..0301509 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/FileXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/FileXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.dataelement;
import java.util.Map;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/MultiLanguagePropertyXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/MultiLanguagePropertyXMLConverter.java
index 400ecc9..8b919c7 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/MultiLanguagePropertyXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/MultiLanguagePropertyXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.dataelement;
import java.util.Map;
@@ -15,7 +24,7 @@
/**
* Parses <aas:multiLanguageProperty> and builds the MultiLanguageProperty object from it <br>
- * Builds <aas:multiLanguageProperty> form a given MultiLanguageProperty object
+ * Builds <aas:multiLanguageProperty> from a given MultiLanguageProperty object
*
* @author conradi
*
@@ -23,7 +32,6 @@
public class MultiLanguagePropertyXMLConverter extends SubmodelElementXMLConverter {
public static final String MULTI_LANGUAGE_PROPERTY = "aas:multiLanguageProperty";
- public static final String VALUE_ID = "aas:valueId";
/**
* Parses a Map containing the content of XML tag <aas:multiLanguageProperty>
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/PropertyXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/PropertyXMLConverter.java
index 182f3b5..b402c72 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/PropertyXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/PropertyXMLConverter.java
@@ -1,12 +1,24 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.dataelement;
import java.util.Map;
import org.eclipse.basyx.submodel.factory.xml.XMLHelper;
+import org.eclipse.basyx.submodel.factory.xml.converters.reference.ReferenceXMLConverter;
import org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.SubmodelElementXMLConverter;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDefHelper;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueTypeHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
@@ -14,7 +26,7 @@
/**
* Parses <aas:property> and builds the Property object from it <br>
- * Builds <aas:property> form a given Property object
+ * Builds <aas:property> from a given Property object
*
* @author conradi
*
@@ -32,7 +44,8 @@
* @param xmlObject the Map with the content of XML tag <aas:property>
* @return the parsed Property
*/
- public static Property parsePropery(Map<String, Object> xmlObject) {
+ @SuppressWarnings("unchecked")
+ public static Property parseProperty(Map<String, Object> xmlObject) {
Property property = new Property();
@@ -41,9 +54,15 @@
String valueType = XMLHelper.getString(xmlObject.get(SubmodelElementXMLConverter.VALUE_TYPE));
String value = XMLHelper.getString(xmlObject.get(SubmodelElementXMLConverter.VALUE));
- property.set(value, PropertyValueTypeDefHelper.fromName(valueType));
+ Map<String, Object> xmlValueId = (Map<String, Object>) xmlObject.get(VALUE_ID);
+ Reference valueId = ReferenceXMLConverter.parseReference(xmlValueId);
- //FIXME the XML-ELement valueId has no corresponding field in Property
+ property.set(value, ValueTypeHelper.fromName(valueType));
+
+ if(valueId != null) {
+ property.setValueId(valueId);
+ }
+
return property;
}
@@ -62,12 +81,18 @@
populateSubmodelElement(document, propertyRoot, prop);
- //FIXME the XML-ELement valueId has no corresponding field in Property
String value = null;
+ IReference valueId = prop.getValueId();
+ if(valueId != null) {
+ Element valueIdRoot = document.createElement(VALUE_ID);
+ valueIdRoot.appendChild(ReferenceXMLConverter.buildReferenceXML(document, valueId));
+ propertyRoot.appendChild(valueIdRoot);
+ }
+
//for some reason, get() in ISingleProperty might throw an Exception
try {
- Object valueObj = prop.get();
+ Object valueObj = prop.getValue();
value = valueObj == null ? null : valueObj.toString();
} catch (Exception e) {
logger.error("Exeption in buildProperty!", e);
@@ -79,7 +104,7 @@
propertyRoot.appendChild(valueEle);
}
- String valueType = prop.getValueType();
+ String valueType = prop.getValueType().toString();
if (valueType != null) {
Element valueTypeElem = document.createElement(SubmodelElementXMLConverter.VALUE_TYPE);
valueTypeElem.appendChild(document.createTextNode(valueType));
@@ -88,4 +113,4 @@
return propertyRoot;
}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/RangeXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/RangeXMLConverter.java
index 833b012..58fdb7c 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/RangeXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/RangeXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.dataelement;
import java.util.Map;
@@ -5,7 +14,8 @@
import org.eclipse.basyx.submodel.factory.xml.XMLHelper;
import org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.SubmodelElementXMLConverter;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IRange;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Range;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueTypeHelper;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.Range;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -33,7 +43,7 @@
String valueType = XMLHelper.getString(xmlObject.get(VALUE_TYPE));
String min = XMLHelper.getString(xmlObject.get(MIN));
String max = XMLHelper.getString(xmlObject.get(MAX));
- Range range = new Range(valueType, min, max);
+ Range range = new Range(ValueTypeHelper.fromName(valueType), min, max);
populateSubmodelElement(xmlObject, range);
return range;
}
@@ -68,7 +78,7 @@
rangeRoot.appendChild(minRoot);
}
- String valueType = range.getValueType();
+ String valueType = range.getValueType().toString();
if(valueType != null) {
Element valueTypeRoot = document.createElement(VALUE_TYPE);
valueTypeRoot.appendChild(document.createTextNode(valueType));
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/ReferenceElementXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/ReferenceElementXMLConverter.java
index b5ab11e..f51283f 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/ReferenceElementXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/ReferenceElementXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.dataelement;
import java.util.Map;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/entity/EntityXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/entity/EntityXMLConverter.java
index c705416..60a81ef 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/entity/EntityXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/entity/EntityXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.entity;
import java.util.Collection;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/event/BasicEventXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/event/BasicEventXMLConverter.java
index 784e9ed..c8b3051 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/event/BasicEventXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/event/BasicEventXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.event;
import java.util.Map;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/operation/OperationXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/operation/OperationXMLConverter.java
index 773e851..890f941 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/operation/OperationXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/operation/OperationXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.operation;
import java.util.ArrayList;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/relationship/AnnotatedRelationshipElementXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/relationship/AnnotatedRelationshipElementXMLConverter.java
new file mode 100644
index 0000000..2843268
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/relationship/AnnotatedRelationshipElementXMLConverter.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.relationship;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.submodel.factory.xml.XMLHelper;
+import org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.SubmodelElementCollectionXMLConverter;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IDataElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.relationship.IAnnotatedRelationshipElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.AnnotatedRelationshipElement;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Parses <aas:annotatedRelationshipElement> and builds an AnnotatedRelationshipElement object from it <br>
+ * Builds <aas:annotatedRelationshipElement> from a given AnnotatedRelationshipElement
+ *
+ * @author conradi
+ *
+ */
+public class AnnotatedRelationshipElementXMLConverter {
+ public static final String ANNOTATED_RELATIONSHIP_ELEMENT = "aas:annotatedRelationshipElement";
+ public static final String ANNOTATIONS = "aas:annotations";
+
+ /**
+ * Builds a AnnotatedRelationshipElement object from the given XML
+ *
+ * @param xmlObject the Map with the content of XML tag <aas:annotatedRelationshipElement>
+ * @return the parsed AnnotatedRelationshipElement
+ */
+ @SuppressWarnings("unchecked")
+ public static AnnotatedRelationshipElement parseAnnotatedRelationshipElement(Map<String, Object> xmlObject) {
+ AnnotatedRelationshipElement annotatedElement = new AnnotatedRelationshipElement();
+
+ RelationshipElementXMLConverter.populateRelationshipElement(xmlObject, annotatedElement);
+
+ Map<String, Object> xmlAnnotations = (Map<String, Object>) xmlObject.get(ANNOTATIONS);
+ List<Map<String, Object>> xmlDataElements = XMLHelper.getList(xmlAnnotations.get(SubmodelElementCollectionXMLConverter.DATA_ELEMENT));
+
+
+ List<IDataElement> dataElements = new ArrayList<>();
+ for(Map<String, Object> element: xmlDataElements) {
+ ISubmodelElement smElement = SubmodelElementCollectionXMLConverter.getSubmodelElement(element);
+
+ // Check if all Elements contained in <aas:annotations> is an IDataElement
+ if(smElement instanceof IDataElement) {
+ dataElements.add((IDataElement) smElement);
+ } else {
+ throw new RuntimeException("AnnotatedRelationshipElement '" + annotatedElement.getIdShort() + "' can only contain IDataElement as annotation");
+ }
+ }
+
+ annotatedElement.setAnnotation(dataElements);
+ return annotatedElement;
+ }
+
+
+
+
+ /**
+ * Builds the <aas:annotatedRelationshipElement> XML tag for a AnnotatedRelationshipElement
+ *
+ * @param document the XML document
+ * @param relElem the IAnnotatedRelationshipElement to build the XML for
+ * @return the <aas:annotatedRelationshipElement> XML tag for the given AnnotatedRelationshipElement
+ */
+ public static Element buildAnnotatedRelationshipElement(Document document, IAnnotatedRelationshipElement annotatedElement) {
+ Element root = document.createElement(ANNOTATED_RELATIONSHIP_ELEMENT);
+ RelationshipElementXMLConverter.populateRelationshipElement(document, root, annotatedElement);
+
+ Element annotationsRoot = document.createElement(ANNOTATIONS);
+ root.appendChild(annotationsRoot);
+
+ for(IDataElement dataElement: annotatedElement.getValue().getAnnotations()) {
+ Element dataElementRoot = document.createElement(SubmodelElementCollectionXMLConverter.DATA_ELEMENT);
+ Element dataElementContent = SubmodelElementCollectionXMLConverter.buildSubmodelElement(document, dataElement);
+ dataElementRoot.appendChild(dataElementContent);
+ annotationsRoot.appendChild(dataElementRoot);
+ }
+
+ return root;
+ }
+
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/relationship/RelationshipElementXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/relationship/RelationshipElementXMLConverter.java
index 892771d..c75c7f2 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/relationship/RelationshipElementXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/relationship/RelationshipElementXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.relationship;
import java.util.Map;
@@ -8,6 +17,7 @@
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.relationship.IRelationshipElement;
import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElementValue;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -26,27 +36,38 @@
/**
- * Parses a Map containing the content of XML tag <aas:relationshipElement>
+ * Builds a RelationshipElement object from the given XML
*
* @param xmlObject the Map with the content of XML tag <aas:relationshipElement>
* @return the parsed RelationshipElement
*/
- @SuppressWarnings("unchecked")
public static RelationshipElement parseRelationshipElement(Map<String, Object> xmlObject) {
+ RelationshipElement relElement = new RelationshipElement();
+ populateRelationshipElement(xmlObject, relElement);
+ return relElement;
+ }
+
+ /**
+ * Parses a Map containing the content of XML tag <aas:relationshipElement>
+ * and populates a given RelationshipElement object
+ *
+ * @param xmlObject the Map with the content of XML tag <aas:relationshipElement>
+ * @param relElement the RelationshipElement to be populated
+ */
+ @SuppressWarnings("unchecked")
+ public static void populateRelationshipElement(Map<String, Object> xmlObject, IRelationshipElement relElement) {
Map<String, Object> firstMap = (Map<String, Object>) xmlObject.get(FIRST);
Reference first = ReferenceXMLConverter.parseReference(firstMap);
Map<String, Object> secondMap = (Map<String, Object>) xmlObject.get(SECOND);
Reference second = ReferenceXMLConverter.parseReference(secondMap);
- RelationshipElement relElement = new RelationshipElement(first, second);
+ relElement.setValue(new RelationshipElementValue(first, second));
+
populateSubmodelElement(xmlObject, relElement);
- return relElement;
}
-
-
/**
* Builds the <aas:relationshipElement> XML tag for a RelationshipElement
*
@@ -56,22 +77,34 @@
*/
public static Element buildRelationshipElement(Document document, IRelationshipElement relElem) {
Element relElemRoot = document.createElement(RELATIONSHIP_ELEMENT);
+ populateRelationshipElement(document, relElemRoot, relElem);
+ return relElemRoot;
+ }
+
+ /**
+ * Builds the content for a given <aas:relationshipElement> XML tag
+ *
+ * @param document the XML document
+ * @param root the root Element of the new RelationshipElement
+ * @param relElem the RelationShipElement
+ */
+ public static void populateRelationshipElement(Document document, Element root, IRelationshipElement relElem) {
+ populateSubmodelElement(document, root, relElem);
- populateSubmodelElement(document, relElemRoot, relElem);
-
- IReference first = relElem.getFirst();
+ RelationshipElementValue value = relElem.getValue();
+
+ IReference first = value.getFirst();
if(first != null) {
Element derivedFromRoot = document.createElement(FIRST);
derivedFromRoot.appendChild(ReferenceXMLConverter.buildReferenceXML(document, first));
- relElemRoot.appendChild(derivedFromRoot);
+ root.appendChild(derivedFromRoot);
}
- IReference second = relElem.getSecond();
+ IReference second = value.getSecond();
if(second != null) {
Element derivedFromRoot = document.createElement(SECOND);
derivedFromRoot.appendChild(ReferenceXMLConverter.buildReferenceXML(document, second));
- relElemRoot.appendChild(derivedFromRoot);
+ root.appendChild(derivedFromRoot);
}
- return relElemRoot;
}
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/IElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/IElement.java
index baccd95..bcb7d10 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/IElement.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/IElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/IElementContainer.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/IElementContainer.java
index 093e1b2..cb27a8a 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/IElementContainer.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/IElementContainer.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api;
import java.util.Map;
@@ -18,7 +27,7 @@
*
* @param element
*/
- public void addSubModelElement(ISubmodelElement element);
+ public void addSubmodelElement(ISubmodelElement element);
/**
* Gets all contained submodel elements
@@ -41,4 +50,16 @@
*/
public Map<String, IOperation> getOperations();
+ /**
+ * Gets a submodel element by name
+ * @param id
+ * @return submodel element
+ */
+ ISubmodelElement getSubmodelElement(String id);
+
+ /**
+ * Deletes a submodel element by name
+ * @param id
+ */
+ void deleteSubmodelElement(String id);
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/ISubModel.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/ISubModel.java
deleted file mode 100644
index 2f716ab..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/ISubModel.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.eclipse.basyx.submodel.metamodel.api;
-
-import org.eclipse.basyx.submodel.metamodel.api.qualifier.IHasDataSpecification;
-import org.eclipse.basyx.submodel.metamodel.api.qualifier.IHasSemantics;
-import org.eclipse.basyx.submodel.metamodel.api.qualifier.IIdentifiable;
-import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.IHasKind;
-import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IQualifiable;
-
-/**
- * A submodel defines a specific aspect of the asset represented by the
- * AAS.<br/>
- * <br />
- * A submodel is used to structure the digital representation and technical
- * functionality of an Administration Shell into distinguishable parts. Each
- * submodel refers to a well-defined domain or subject matter. Submodels can
- * become standardized and thus become submodels types. Submodels can have
- * different life-cycles.
- *
- * @author kuhn, schnicke
- *
- */
-public interface ISubModel extends IElement, IHasSemantics, IIdentifiable, IQualifiable, IHasDataSpecification, IHasKind, IElementContainer {
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/ISubmodel.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/ISubmodel.java
new file mode 100644
index 0000000..e034690
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/ISubmodel.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.api;
+
+import java.util.Map;
+
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.IHasDataSpecification;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.IHasSemantics;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.IIdentifiable;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.IHasKind;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IQualifiable;
+
+/**
+ * A submodel defines a specific aspect of the asset represented by the
+ * AAS.<br/>
+ * <br />
+ * A submodel is used to structure the digital representation and technical
+ * functionality of an Administration Shell into distinguishable parts. Each
+ * submodel refers to a well-defined domain or subject matter. Submodels can
+ * become standardized and thus become submodels types. Submodels can have
+ * different life-cycles.
+ *
+ * @author kuhn, schnicke
+ *
+ */
+public interface ISubmodel extends IElement, IHasSemantics, IIdentifiable, IQualifiable, IHasDataSpecification, IHasKind, IElementContainer {
+
+ /**
+ * Gets a Map<IdShort, smElement.getValue()> containing the values of all submodelElements
+ *
+ * @return a Map with the values of all submodelElements
+ */
+ public Map<String, Object> getValues();
+
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecification.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecification.java
index 58e2cca..bf44669 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecification.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecification.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.dataspecification;
import org.eclipse.basyx.submodel.metamodel.api.qualifier.IIdentifiable;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecificationContent.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecificationContent.java
index 6521605..8b9d837 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecificationContent.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecificationContent.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.dataspecification;
/**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecificationIEC61360Content.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecificationIEC61360Content.java
index 99cb931..955a51c 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecificationIEC61360Content.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecificationIEC61360Content.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.dataspecification;
import java.util.Collection;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IEmbeddedDataSpecification.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IEmbeddedDataSpecification.java
index 212bbbb..b86fcf9 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IEmbeddedDataSpecification.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IEmbeddedDataSpecification.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.dataspecification;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IValueReferencePair.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IValueReferencePair.java
index ba8f45a..e9603f5 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IValueReferencePair.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IValueReferencePair.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.dataspecification;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/enums/DataTypeIEC61360.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/enums/DataTypeIEC61360.java
index e8bc45f..7dc731c 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/enums/DataTypeIEC61360.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/enums/DataTypeIEC61360.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.dataspecification.enums;
import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnum;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/enums/LevelType.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/enums/LevelType.java
index a5e6c87..436b2b4 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/enums/LevelType.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/enums/LevelType.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.dataspecification.enums;
import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnum;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/identifier/IIdentifier.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/identifier/IIdentifier.java
index 279ed92..4fb6faa 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/identifier/IIdentifier.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/identifier/IIdentifier.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.identifier;
/**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/identifier/IdentifierType.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/identifier/IdentifierType.java
index 58e232b..4082a5d 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/identifier/IdentifierType.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/identifier/IdentifierType.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.identifier;
import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnum;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/parts/IConceptDescription.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/parts/IConceptDescription.java
index cae6f17..ab2e2f8 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/parts/IConceptDescription.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/parts/IConceptDescription.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.parts;
import java.util.Collection;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IAdministrativeInformation.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IAdministrativeInformation.java
index d30e318..0809b44 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IAdministrativeInformation.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IAdministrativeInformation.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.qualifier;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IHasDataSpecification.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IHasDataSpecification.java
index 712e3c6..9914831 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IHasDataSpecification.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IHasDataSpecification.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.qualifier;
import java.util.Collection;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IHasSemantics.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IHasSemantics.java
index a206a63..daed9c1 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IHasSemantics.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IHasSemantics.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.qualifier;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IIdentifiable.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IIdentifiable.java
index b3bbe10..617425e 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IIdentifiable.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IIdentifiable.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.qualifier;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IReferable.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IReferable.java
index e66b823..1c58991 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IReferable.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IReferable.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.qualifier;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IdShortValidator.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IdShortValidator.java
new file mode 100644
index 0000000..79c96e9
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IdShortValidator.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.api.qualifier;
+
+/**
+ * Tests the validity of IdShorts according to DotAAS
+ *
+ * @author schnicke
+ *
+ */
+public class IdShortValidator {
+ /*
+ * Taken from DotAAS p. 50: "Constraint AASd-002: idShort shall only feature
+ * letters, digits, underscore ("_"); starting mandatory with a letter."
+ */
+ public static final String IDSHORT_REGEX = "[a-zA-Z][a-zA-Z0-9_]+";
+
+ /**
+ * Returns true iff the idShort is valid according to DotAAS
+ *
+ * @param idShort
+ * to test
+ * @return test result
+ */
+ public static boolean isValid(String idShort) {
+ if (idShort == null) {
+ return false;
+ }
+
+ return idShort.matches(IDSHORT_REGEX);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/haskind/IHasKind.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/haskind/IHasKind.java
index ebf6bbc..2581347 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/haskind/IHasKind.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/haskind/IHasKind.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind;
/**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/haskind/ModelingKind.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/haskind/ModelingKind.java
index fff732b..b88a692 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/haskind/ModelingKind.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/haskind/ModelingKind.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind;
import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnum;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IConstraint.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IConstraint.java
index 736af18..b7050ad 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IConstraint.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IConstraint.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable;
/**
* Interface for Constraint
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IFormula.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IFormula.java
index 30be093..0cc79da 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IFormula.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IFormula.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable;
import java.util.Collection;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IQualifiable.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IQualifiable.java
index 28b33f7..a27ee2f 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IQualifiable.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IQualifiable.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable;
import java.util.Collection;
@@ -9,5 +18,5 @@
*/
public interface IQualifiable {
- public Collection<IConstraint> getQualifier();
+ public Collection<IConstraint> getQualifiers();
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IQualifier.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IQualifier.java
index cfda524..c7c1e81 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IQualifier.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IQualifier.java
@@ -1,7 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable;
import org.eclipse.basyx.submodel.metamodel.api.qualifier.IHasSemantics;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
/**
* Interface for Qualifier
@@ -13,9 +23,9 @@
public interface IQualifier extends IHasSemantics, IConstraint {
public String getType();
- public String getValue();
+ public Object getValue();
public IReference getValueId();
- public String getValueType();
+ public ValueType getValueType();
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/IKey.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/IKey.java
index 449045f..33eec09 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/IKey.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/IKey.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.reference;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/IReference.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/IReference.java
index 6b97698..936250e 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/IReference.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/IReference.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.reference;
import java.util.List;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/enums/KeyElements.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/enums/KeyElements.java
index be8b979..15b5401 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/enums/KeyElements.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/enums/KeyElements.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.reference.enums;
import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnum;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/enums/KeyType.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/enums/KeyType.java
index 74408b3..9e969a5 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/enums/KeyType.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/enums/KeyType.java
@@ -1,5 +1,15 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.reference.enums;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnum;
import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnumHelper;
@@ -16,7 +26,7 @@
/**
* Enum values of IdentifierType
*/
- CUSTOM("Custom"), IRDI("IRDI"), IRI("IRI"),
+ CUSTOM(IdentifierType.CUSTOM.toString()), IRDI(IdentifierType.IRDI.toString()), IRI(IdentifierType.IRI.toString()),
/**
* Enum values of LocalKeyType
@@ -39,6 +49,10 @@
return standardizedLiteral;
}
+ public static KeyType fromIdentifierType(IdentifierType type) {
+ return fromString(type.toString());
+ }
+
public static KeyType fromString(String str) {
return StandardizedLiteralEnumHelper.fromLiteral(KeyType.class, str);
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ICapability.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ICapability.java
index 911be7c..ccac1ac 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ICapability.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ICapability.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.submodelelement;
/**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ISubmodelElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ISubmodelElement.java
index 61eadb5..2fde991 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ISubmodelElement.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ISubmodelElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.submodelelement;
import org.eclipse.basyx.submodel.metamodel.api.IElement;
@@ -6,6 +15,7 @@
import org.eclipse.basyx.submodel.metamodel.api.qualifier.IReferable;
import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.IHasKind;
import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IQualifiable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
/**
* A submodel element is an element suitable for the description and
@@ -16,4 +26,10 @@
*/
public interface ISubmodelElement extends IElement, IHasDataSpecification, IReferable, IQualifiable, IHasSemantics, IHasKind {
public String getModelType();
+
+ public Object getValue();
+
+ public void setValue(Object value);
+
+ public SubmodelElement getLocalCopy();
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ISubmodelElementCollection.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ISubmodelElementCollection.java
index 547978e..321afdf 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ISubmodelElementCollection.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ISubmodelElementCollection.java
@@ -1,8 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.submodelelement;
-import java.util.Collection;
import java.util.Map;
+import org.eclipse.basyx.submodel.metamodel.api.IElementContainer;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
@@ -12,9 +21,7 @@
* @author rajashek, schnicke
*
*/
-public interface ISubmodelElementCollection extends ISubmodelElement {
-
- public Collection<ISubmodelElement> getValue();
+public interface ISubmodelElementCollection extends ISubmodelElement, IElementContainer {
/**
* Gets if the collection is ordered or unordered
@@ -35,6 +42,7 @@
*
* @return
*/
+ @Override
public Map<String, ISubmodelElement> getSubmodelElements();
/**
@@ -42,6 +50,7 @@
*
* @return
*/
+ @Override
public Map<String, IProperty> getProperties();
/**
@@ -49,5 +58,6 @@
*
* @return
*/
+ @Override
public Map<String, IOperation> getOperations();
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/SubmodelElementIdShortBlacklist.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/SubmodelElementIdShortBlacklist.java
new file mode 100644
index 0000000..d7c3617
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/SubmodelElementIdShortBlacklist.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.api.submodelelement;
+
+import java.util.Arrays;
+
+/**
+ * Tests if an IdShort of a SubmodelElement is blacklisted due to API
+ * constraints
+ *
+ * @author schnicke
+ *
+ */
+public class SubmodelElementIdShortBlacklist {
+ /*
+ * Due to API definition for SubmodelElementCollections
+ * (/submodelElements/$IdShort1/.../$IdShortN) it is not possible to distinguish
+ * if a SubmodelElement with idShort "value" or "invocationList" was requested
+ * or the endpoint defined in the API. Thus, these keywords are forbidden as
+ * idShort
+ *
+ * E.g. /submodelElements/smCollectionId/value --> Is value here the /value
+ * endpoint or a SubmodelElement with idShort value?
+ */
+ public static final String[] BLACKLIST = { "value", "invocationList" };
+
+ /**
+ * Returns true iff an idShort is blacklisted
+ *
+ * @param idShort
+ * to test
+ * @return test result
+ */
+ public static boolean isBlacklisted(String idShort) {
+ return Arrays.asList(BLACKLIST).contains(idShort);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IBlob.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IBlob.java
index 4e972e2..051676c 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IBlob.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IBlob.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement;
/**
@@ -9,13 +18,50 @@
*/
public interface IBlob extends IDataElement {
/**
- * Gets the value of the BLOB instance of a blob data element.
+ * Gets the value of the Blob instance of a blob data element.
+ * The returned value is Base64 encoded.
*
* @return
*/
- public byte[] getValue();
+ @Override
+ public String getValue();
/**
+ * Sets a Base64 encoded value of the BLOB instance of a blob data element.
+ *
+ * @param bytes
+ */
+ public void setValue(String value);
+
+ /**
+ * Gets the value of the Blob instance of a blob data element.
+ *
+ * @return
+ */
+ public byte[] getByteArrayValue();
+
+ /**
+ * Sets the value of the Blob instance of a blob data element.
+ *
+ * @param bytes
+ */
+ public void setByteArrayValue(byte[] value);
+
+ /**
+ * Returns the UTF8 String representation of the byte array BLOB value
+ *
+ * @return
+ */
+ public String getUTF8String();
+
+ /**
+ * Sets an UTF8 string as an encoded byte array in the BLOB data element value
+ *
+ * @param text
+ */
+ public void setUTF8String(String text);
+
+ /**
* Gets the mime type of the content of the BLOB. The mime type states which
* file extension the file has. <br />
* Valid values are e.g. “application/json”, “application/xls”, ”image/jpg”.
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IDataElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IDataElement.java
index 1210776..1b21612 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IDataElement.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IDataElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IFile.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IFile.java
index c3f8686..4c86bcb 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IFile.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IFile.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement;
/**
@@ -14,9 +23,18 @@
*
* @return
*/
+ @Override
public String getValue();
/**
+ * Sets path and name of the referenced file (with file extension). The path can
+ * be absolute or relative.
+ *
+ * @param value
+ */
+ public void setValue(String value);
+
+ /**
* Gets mime type of the content of the file.
*
* @return
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IMultiLanguageProperty.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IMultiLanguageProperty.java
index d05f307..af10ec8 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IMultiLanguageProperty.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IMultiLanguageProperty.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
@@ -12,13 +21,21 @@
public interface IMultiLanguageProperty extends IDataElement {
/**
- * Gets the value of the property instance
+ * Gets the {@link LangStrings} value of the property instance
*
* @return
*/
+ @Override
LangStrings getValue();
/**
+ * Sets the {@link LangStrings} value of the property instance
+ *
+ * @param value
+ */
+ void setValue(LangStrings value);
+
+ /**
* Gets the reference to the global unique id of a coded value.
*
* @return
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IProperty.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IProperty.java
index 20d1381..9f5c486 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IProperty.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IProperty.java
@@ -1,8 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement;
import org.eclipse.basyx.submodel.metamodel.api.IElement;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
-import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
/**
* Interface for IElement properties
@@ -12,26 +21,11 @@
*/
public interface IProperty extends IElement, IDataElement {
/**
- * Get property value
- *
- * @return Property value
- * @throws Exception
- */
- public Object get() throws Exception;
-
- /**
- * Set property value
- *
- * @throws ProviderException
- */
- public void set(Object newValue) throws ProviderException;
-
- /**
* Gets the data type of the value
*
* @return
*/
- public String getValueType();
+ public ValueType getValueType();
/**
* Gets the reference to the global unique id of a coded value.
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IRange.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IRange.java
index db8a6f2..c7d5bdb 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IRange.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IRange.java
@@ -1,5 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.RangeValue;
+
/**
* A range data element is a data element that defines a range with min and max.
*
@@ -12,7 +24,7 @@
*
* @return
*/
- String getValueType();
+ ValueType getValueType();
/**
* Returns the minimum value of the range. <br />
@@ -31,4 +43,15 @@
* infinite.
*/
Object getMax();
+
+ @Override
+ RangeValue getValue();
+
+ /**
+ * Sets the value of the range represented by the Range submodel element
+ *
+ * @param value
+ * the range
+ */
+ void setValue(RangeValue value);
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IReferenceElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IReferenceElement.java
index 92b016b..7634155 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IReferenceElement.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IReferenceElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
@@ -18,6 +27,15 @@
*
* @return
*/
+ @Override
public IReference getValue();
+ /**
+ * Sets the reference to any other referable element of the same or of any other
+ * AAS or a reference to an external object or entity
+ *
+ * @param value
+ */
+ public void setValue(IReference value);
+
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/entity/EntityType.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/entity/EntityType.java
index aa71c65..9c0f124 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/entity/EntityType.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/entity/EntityType.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.submodelelement.entity;
import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnum;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/entity/IEntity.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/entity/IEntity.java
index a8c557f..be095a8 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/entity/IEntity.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/entity/IEntity.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.submodelelement.entity;
import java.util.Collection;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/event/IBasicEvent.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/event/IBasicEvent.java
index cace411..e35022c 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/event/IBasicEvent.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/event/IBasicEvent.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.submodelelement.event;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/event/IEvent.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/event/IEvent.java
index 3686e5e..9ec86c6 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/event/IEvent.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/event/IEvent.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.submodelelement.event;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IAsyncInvocation.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IAsyncInvocation.java
new file mode 100644
index 0000000..583d12a
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IAsyncInvocation.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation;
+
+/**
+ * An AsyncInvocation is used for asynchronously invoking operation
+ *
+ * @author conradi
+ *
+ */
+public interface IAsyncInvocation {
+
+ /**
+ * Gets the result of the async Invocation<br>
+ * Will block if execution is not finished yet
+ *
+ * @return the result of the Invocation
+ */
+ public Object getResult();
+
+ /**
+ * Gets the status of the async Invocation
+ *
+ * @return true if execution is completed; false otherwise
+ */
+ public boolean isFinished();
+
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IOperation.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IOperation.java
index c7b32ae..42d850e 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IOperation.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IOperation.java
@@ -1,9 +1,19 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation;
import java.util.Collection;
import org.eclipse.basyx.submodel.metamodel.api.IElement;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
/**
* An operation is a submodel element with input and output variables.
@@ -37,10 +47,42 @@
/**
* Invoke operation with given parameter
*
+ *
* @param params
- * Operation parameter
+ * Operation parameter
* @return If multiple values are returned, Object is here a list of Objects
* @throws Exception
*/
- public Object invoke(Object... params) throws Exception;
+ public Object invoke(Object... params);
+
+ /**
+ * Invoke operation with parameters wrapped as SubmodelElements
+ *
+ *
+ * @param params
+ * Operation parameters
+ * @return List of results
+ * @throws Exception
+ */
+ public SubmodelElement[] invoke(SubmodelElement... elems);
+
+ /**
+ * Invoke operation with given parameter asynchronously
+ *
+ * @param params
+ * Operation parameter
+ * @return An IAsyncInvocation
+ */
+ public IAsyncInvocation invokeAsync(Object... params);
+
+ /**
+ * Invoke operation with given parameter asynchronously and use a user-defined timeout
+ *
+ * @param timeout
+ * The timeout in ms
+ * @param params
+ * Operation parameter
+ * @return An IAsyncInvocation
+ */
+ public IAsyncInvocation invokeAsyncWithTimeout(int timeout, Object... params);
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IOperationVariable.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IOperationVariable.java
index b7cb183..258a836 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IOperationVariable.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IOperationVariable.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/relationship/IAnnotatedRelationShipElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/relationship/IAnnotatedRelationShipElement.java
deleted file mode 100644
index ca78dbe..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/relationship/IAnnotatedRelationShipElement.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.eclipse.basyx.submodel.metamodel.api.submodelelement.relationship;
-
-import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
-
-/**
- * An annotated relationship element is a relationship element that can be
- * annotated withadditional data elements.
- *
- * @author schnicke
- *
- */
-public interface IAnnotatedRelationShipElement extends IRelationshipElement {
- /**
- * Annotations that hold for the relationships between the two elements.
- *
- * @return
- */
- IReference getAnnotation();
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/relationship/IAnnotatedRelationshipElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/relationship/IAnnotatedRelationshipElement.java
new file mode 100644
index 0000000..7573d3d
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/relationship/IAnnotatedRelationshipElement.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.api.submodelelement.relationship;
+
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.AnnotatedRelationshipElementValue;
+
+/**
+ * An annotated relationship element is a relationship element that can be
+ * annotated with additional data elements.
+ *
+ * @author schnicke
+ *
+ */
+public interface IAnnotatedRelationshipElement extends IRelationshipElement {
+ @Override
+ AnnotatedRelationshipElementValue getValue();
+
+ void setValue(AnnotatedRelationshipElementValue value);
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/relationship/IRelationshipElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/relationship/IRelationshipElement.java
index 3fc679d..ce976e8 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/relationship/IRelationshipElement.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/relationship/IRelationshipElement.java
@@ -1,7 +1,16 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.api.submodelelement.relationship;
-import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElementValue;
/**
* A relationship element is used to define a relationship between two referable
@@ -11,17 +20,14 @@
*
*/
public interface IRelationshipElement extends ISubmodelElement {
- /**
- * Gets the first element in the relationship taking the role of the subject.
- *
- * @return
- */
- IReference getFirst();
+
+ @Override
+ RelationshipElementValue getValue();
/**
- * Gets the second element in the relationship taking the role of the object.
+ * Sets the relationship of the RelationshipElement submodel element
*
- * @return
+ * @param value
*/
- IReference getSecond();
+ void setValue(RelationshipElementValue value);
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/ConnectedElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/ConnectedElement.java
index bed6f3d..a9dcc33 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/ConnectedElement.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/ConnectedElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.connected;
import java.util.Map;
@@ -16,7 +25,7 @@
public class ConnectedElement implements IElement {
private VABElementProxy proxy;
- private VABModelMap<Object> cached;
+ protected VABModelMap<Object> cached;
public VABElementProxy getProxy() {
return proxy;
@@ -35,8 +44,8 @@
* @return
*/
@SuppressWarnings("unchecked")
- protected VABModelMap<Object> getElemLive() {
- VABModelMap<Object> map = new VABModelMap<>((Map<String, Object>) getProxy().getModelPropertyValue(""));
+ public VABModelMap<Object> getElemLive() {
+ VABModelMap<Object> map = new VABModelMap<>((Map<String, Object>) getProxy().getValue(""));
// update cache
cached = map;
return map;
@@ -49,7 +58,7 @@
*
* @return
*/
- protected VABModelMap<Object> getElem() {
+ public VABModelMap<Object> getElem() {
if (cached == null) {
return getElemLive();
} else {
@@ -57,6 +66,11 @@
}
}
+ @Override
+ public String toString() {
+ return getElemLive().toString();
+ }
+
protected void throwNotSupportedException() {
throw new RuntimeException("Not supported on remote object");
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/ConnectedSubModel.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/ConnectedSubModel.java
deleted file mode 100644
index 5d0a57a..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/ConnectedSubModel.java
+++ /dev/null
@@ -1,143 +0,0 @@
-package org.eclipse.basyx.submodel.metamodel.connected;
-
-import java.util.Collection;
-import java.util.Map;
-
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
-import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IEmbeddedDataSpecification;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.submodel.metamodel.api.qualifier.IAdministrativeInformation;
-import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
-import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IConstraint;
-import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
-import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IDataElement;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
-import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.ConnectedSubmodelElementFactory;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.AdministrativeInformation;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.haskind.HasKind;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifiable;
-import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-
-
-/**
- * "Connected" implementation of SubModel
- *
- * @author rajashek
- *
- */
-public class ConnectedSubModel extends ConnectedElement implements ISubModel {
-
- public ConnectedSubModel(VABElementProxy proxy) {
- super(proxy);
- }
-
- protected KeyElements getKeyElement() {
- return KeyElements.SUBMODELELEMENT;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public IReference getSemanticId() {
- return Reference.createAsFacade((Map<String, Object>) getElem().get(HasSemantics.SEMANTICID));
- }
-
- @Override
- public IAdministrativeInformation getAdministration() {
- return AdministrativeInformation.createAsFacade(getElem());
- }
-
- @Override
- public IIdentifier getIdentification() {
- return Identifiable.createAsFacade(getElem(), getKeyElement()).getIdentification();
- }
-
- @Override
- public Collection<IReference> getDataSpecificationReferences() {
- return HasDataSpecification.createAsFacade(getElem()).getDataSpecificationReferences();
- }
-
- @Override
- public Collection<IEmbeddedDataSpecification> getEmbeddedDataSpecifications() {
- return HasDataSpecification.createAsFacade(getElem()).getEmbeddedDataSpecifications();
- }
-
- @Override
- public ModelingKind getModelingKind() {
- return HasKind.createAsFacade(getElem()).getModelingKind();
- }
-
- @Override
- public String getIdShort() {
- return (String) getElem().get(Referable.IDSHORT);
- }
-
- @Override
- public String getCategory() {
- return (String) getElem().get(Referable.CATEGORY);
- }
-
- @Override
- public LangStrings getDescription() {
- return Referable.createAsFacade(getElem(), getKeyElement()).getDescription();
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public IReference getParent() {
- return Reference.createAsFacade((Map<String, Object>) getElem().getPath(Referable.PARENT));
- }
-
- @Override
- public Collection<IConstraint> getQualifier() {
- return Qualifiable.createAsFacade(getElem()).getQualifier();
- }
-
- @Override
- public void addSubModelElement(ISubmodelElement element) {
- if (element instanceof SubmodelElement) {
- ((SubmodelElement) element).setParent(getReference());
- }
-
- if (element instanceof IDataElement) {
- getProxy().createValue(SubmodelElementProvider.PROPERTIES, element);
- } else if (element instanceof IOperation) {
- getProxy().createValue(SubmodelElementProvider.OPERATIONS, element);
- } else if (element instanceof ISubmodelElement) {
- getProxy().createValue(SubmodelElementProvider.ELEMENTS, element);
- }
- }
-
- @Override
- public Map<String, IProperty> getProperties() {
- return ConnectedSubmodelElementFactory.getProperties(getProxy(), SubmodelElementProvider.PROPERTIES,
- SubmodelElementProvider.PROPERTIES);
- }
-
- @Override
- public Map<String, IOperation> getOperations() {
- return ConnectedSubmodelElementFactory.getOperations(getProxy(), SubmodelElementProvider.OPERATIONS,
- SubmodelElementProvider.OPERATIONS);
- }
-
- @Override
- public Map<String, ISubmodelElement> getSubmodelElements() {
- return ConnectedSubmodelElementFactory.getConnectedSubmodelElements(getProxy(),
- SubmodelElementProvider.ELEMENTS, SubmodelElementProvider.ELEMENTS);
- }
-
- @Override
- public IReference getReference() {
- return Identifiable.createAsFacade(getElem(), getKeyElement()).getReference();
- }
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/ConnectedSubmodel.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/ConnectedSubmodel.java
new file mode 100644
index 0000000..d5c0fa6
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/ConnectedSubmodel.java
@@ -0,0 +1,206 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.connected;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IEmbeddedDataSpecification;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.IAdministrativeInformation;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IConstraint;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
+import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.ConnectedSubmodelElementFactory;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.haskind.HasKind;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifiable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+
+
+/**
+ * "Connected" implementation of Submodel
+ *
+ * @author rajashek
+ *
+ */
+public class ConnectedSubmodel extends ConnectedElement implements ISubmodel {
+
+ public ConnectedSubmodel(VABElementProxy proxy) {
+ super(proxy);
+ }
+
+ /**
+ * Creates a ConnectedSubmodel based on a proxy and an already cached local copy
+ *
+ * @param proxy
+ * @param localCopy
+ */
+ public ConnectedSubmodel(VABElementProxy proxy, Submodel localCopy) {
+ super(proxy);
+ cached = localCopy;
+ }
+
+ protected KeyElements getKeyElement() {
+ return KeyElements.SUBMODEL;
+ }
+
+ @Override
+ public IReference getSemanticId() {
+ return HasSemantics.createAsFacade(getElem()).getSemanticId();
+ }
+
+ @Override
+ public IAdministrativeInformation getAdministration() {
+ return Identifiable.createAsFacade(getElem(), getKeyElement()).getAdministration();
+ }
+
+ @Override
+ public IIdentifier getIdentification() {
+ return Identifiable.createAsFacade(getElem(), getKeyElement()).getIdentification();
+ }
+
+ @Override
+ public Collection<IReference> getDataSpecificationReferences() {
+ return HasDataSpecification.createAsFacade(getElem()).getDataSpecificationReferences();
+ }
+
+ @Override
+ public Collection<IEmbeddedDataSpecification> getEmbeddedDataSpecifications() {
+ return HasDataSpecification.createAsFacade(getElem()).getEmbeddedDataSpecifications();
+ }
+
+ @Override
+ public ModelingKind getModelingKind() {
+ return HasKind.createAsFacade(getElem()).getModelingKind();
+ }
+
+ @Override
+ public String getIdShort() {
+ return (String) getElem().get(Referable.IDSHORT);
+ }
+
+ @Override
+ public String getCategory() {
+ return (String) getElem().get(Referable.CATEGORY);
+ }
+
+ @Override
+ public LangStrings getDescription() {
+ return Referable.createAsFacade(getElem(), getKeyElement()).getDescription();
+ }
+
+ @Override
+ public IReference getParent() {
+ return Referable.createAsFacade(getElem(), getKeyElement()).getParent();
+ }
+
+ @Override
+ public Collection<IConstraint> getQualifiers() {
+ return Qualifiable.createAsFacade(getElem()).getQualifiers();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void addSubmodelElement(ISubmodelElement element) {
+ String path = VABPathTools.concatenatePaths(MultiSubmodelElementProvider.ELEMENTS, element.getIdShort());
+
+ if (element instanceof SubmodelElement) {
+ ((SubmodelElement) element).setParent(getReference());
+
+ // Convert "value" in SubmodelElementCollection from Map to Collection
+ if (element instanceof SubmodelElementCollection) {
+ Map<String, Object> converted = SubmodelElementMapCollectionConverter.smElementToMap((Map<String, Object>) element);
+
+ getProxy().setValue(path, converted);
+ return;
+ }
+ }
+ getProxy().setValue(path, element);
+ }
+
+ @Override
+ public Map<String, IProperty> getProperties() {
+ return ConnectedSubmodelElementFactory.getProperties(getProxy(), MultiSubmodelElementProvider.ELEMENTS,
+ MultiSubmodelElementProvider.ELEMENTS);
+ }
+
+ @Override
+ public Map<String, IOperation> getOperations() {
+ return ConnectedSubmodelElementFactory.getOperations(getProxy(), MultiSubmodelElementProvider.ELEMENTS,
+ MultiSubmodelElementProvider.ELEMENTS);
+ }
+
+ @Override
+ public Map<String, ISubmodelElement> getSubmodelElements() {
+ return ConnectedSubmodelElementFactory.getConnectedSubmodelElements(getProxy(),
+ MultiSubmodelElementProvider.ELEMENTS, MultiSubmodelElementProvider.ELEMENTS);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Map<String, Object> getValues() {
+ return (Map<String, Object>) getProxy().getValue(SubmodelProvider.VALUES);
+ }
+
+ @Override
+ public IReference getReference() {
+ return Identifiable.createAsFacade(getElem(), getKeyElement()).getReference();
+ }
+
+ /**
+ * Returns a local copy of the submodel, i.e. a snapshot of the current state.
+ * <br>
+ * No changes of this copy are reflected in the remote Submodel
+ *
+ * @return the local copy
+ */
+ public Submodel getLocalCopy() {
+ return Submodel.createAsFacade(getElem());
+ }
+
+ /**
+ * Get submodel element by given id
+ * @param id
+ * @return specific submodel element
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public ISubmodelElement getSubmodelElement(String id) {
+ Map<String, Object> node =(Map<String, Object>) getProxy().getValue(VABPathTools.concatenatePaths(MultiSubmodelElementProvider.ELEMENTS, id));
+ ISubmodelElement element = ConnectedSubmodelElementFactory.getConnectedSubmodelElement(getProxy(), MultiSubmodelElementProvider.ELEMENTS, id, node);
+ return element;
+ }
+
+ /**
+ * Delete a submodel element by given id
+ * @param id
+ */
+ @Override
+ public void deleteSubmodelElement(String id) {
+ getProxy().deleteValue(VABPathTools.concatenatePaths(MultiSubmodelElementProvider.ELEMENTS, id));
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedEvent.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedEvent.java
index 22856fa..a92532e 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedEvent.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedEvent.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.connected.submodelelement;
/**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElement.java
index a56d67e..b439740 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElement.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.connected.submodelelement;
import java.util.Collection;
@@ -17,6 +26,8 @@
import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.haskind.HasKind;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifiable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
/**
@@ -54,8 +65,8 @@
}
@Override
- public Collection<IConstraint> getQualifier() {
- return Qualifiable.createAsFacade(getElem()).getQualifier();
+ public Collection<IConstraint> getQualifiers() {
+ return Qualifiable.createAsFacade(getElem()).getQualifiers();
}
@Override
@@ -89,4 +100,14 @@
public IReference getReference() {
return Referable.createAsFacade(getElem(), getKeyElement()).getReference();
}
+
+ @Override
+ public void setValue(Object value) {
+ getProxy().setValue(MultiSubmodelElementProvider.VALUE, value);
+ }
+
+ @Override
+ public SubmodelElement getLocalCopy() {
+ return SubmodelElement.createAsFacade(getElem()).getLocalCopy();
+ }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElementCollection.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElementCollection.java
index b4139e3..7a5a23d 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElementCollection.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElementCollection.java
@@ -1,6 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.connected.submodelelement;
-import java.util.Collection;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import java.util.Map;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
@@ -8,6 +19,8 @@
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
@@ -24,8 +37,8 @@
}
@Override
- public Collection<ISubmodelElement> getValue() {
- return getSubmodelElements().values();
+ public List<ISubmodelElement> getValue() {
+ return Collections.unmodifiableList(new ArrayList<>(getSubmodelElements().values()));
}
@Override
@@ -57,4 +70,52 @@
protected KeyElements getKeyElement() {
return KeyElements.SUBMODELELEMENTCOLLECTION;
}
+
+ /**
+ * Get submodel element by given id
+ * @param id
+ * @return specific submodel element
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public ISubmodelElement getSubmodelElement(String id) {
+ Map<String, Object> node =(Map<String, Object>) getProxy().getValue(id);
+ ISubmodelElement element = ConnectedSubmodelElementFactory.getConnectedSubmodelElement(getProxy(), "", id, node);
+ return element;
+ }
+
+ /**
+ * Delete a submodel element by given id
+ * @param id
+ */
+ @Override
+ public void deleteSubmodelElement(String id) {
+ getProxy().deleteValue(id);
+ }
+
+ /**
+ * adds a submodel element to the collection
+ * @param element
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public void addSubmodelElement(ISubmodelElement element) {
+ if (element instanceof SubmodelElement) {
+ ((SubmodelElement) element).setParent(getReference());
+
+ // Convert "value" in SubmodelElementCollection from Map to Collection
+ if (element instanceof SubmodelElementCollection) {
+ Map<String, Object> converted = SubmodelElementMapCollectionConverter.smElementToMap((Map<String, Object>) element);
+ getProxy().setValue(element.getIdShort(), converted);
+ return;
+ }
+ }
+
+ getProxy().setValue(element.getIdShort(), element);
+ }
+
+ @Override
+ public SubmodelElementCollection getLocalCopy() {
+ return SubmodelElementCollection.createAsFacade(getElem()).getLocalCopy();
+ }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElementFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElementFactory.java
index c87d8c7..f0bcadd 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElementFactory.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElementFactory.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.connected.submodelelement;
@@ -19,17 +28,19 @@
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedReferenceElement;
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.event.ConnectedBasicEvent;
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.operation.ConnectedOperation;
+import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.relationship.ConnectedAnnotatedRelationshipElement;
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.relationship.ConnectedRelationshipElement;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Blob;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Range;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.ReferenceElement;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.Range;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.event.BasicEvent;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.AnnotatedRelationshipElement;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElement;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
import org.eclipse.basyx.vab.modelprovider.VABPathTools;
@@ -56,7 +67,7 @@
String collectionPath, String elementPath) {
// Query the whole list of elements
Collection<Map<String, Object>> mapElemList = (Collection<Map<String, Object>>) rootProxy
- .getModelPropertyValue(collectionPath);
+ .getValue(collectionPath);
// Get the type and idShort for each element and create the corresponding connected variant
Map<String, ISubmodelElement> ret = new HashMap<>();
for (Map<String, Object> node : mapElemList) {
@@ -80,7 +91,7 @@
String collectionPath, String elementPath) {
// Query the whole list of elements
Collection<Map<String, Object>> mapElemList = (Collection<Map<String, Object>>) rootProxy
- .getModelPropertyValue(collectionPath);
+ .getValue(collectionPath);
// Get the type and idShort for each element and create the corresponding connected variant
Collection<ISubmodelElement> ret = new ArrayList<>();
for (Map<String, Object> node : mapElemList) {
@@ -99,7 +110,7 @@
* @param elementPath path in the proxy for accessing single elements by short ids
* @return The connected variant of the requested submodel element
*/
- private static ISubmodelElement getConnectedSubmodelElement(VABElementProxy rootProxy,
+ public static ISubmodelElement getConnectedSubmodelElement(VABElementProxy rootProxy,
String elementPath, String idShort, Map<String, Object> mapContent) {
String subPath = VABPathTools.concatenatePaths(elementPath, idShort);
VABElementProxy proxy = rootProxy.getDeepProxy(subPath);
@@ -117,6 +128,8 @@
return new ConnectedRange(proxy);
} else if(ReferenceElement.isReferenceElement(mapContent)) {
return new ConnectedReferenceElement(proxy);
+ } else if (AnnotatedRelationshipElement.isAnnotatedRelationshipElement(mapContent)) {
+ return new ConnectedAnnotatedRelationshipElement(proxy);
} else if (RelationshipElement.isRelationshipElement(mapContent)) {
return new ConnectedRelationshipElement(proxy);
} else if (Operation.isOperation(mapContent)) {
@@ -141,7 +154,7 @@
String elementPath) {
// Query the whole list of elements
Collection<Map<String, Object>> mapElemList = (Collection<Map<String, Object>>) rootProxy
- .getModelPropertyValue(collectionPath);
+ .getValue(collectionPath);
// Get the type and idShort for each operation and create the corresponding connected variant
Map<String, IOperation> ret = new HashMap<>();
@@ -169,7 +182,7 @@
String elementPath) {
// Query the whole list of elements
Collection<Map<String, Object>> mapElemList = (Collection<Map<String, Object>>) rootProxy
- .getModelPropertyValue(collectionPath);
+ .getValue(collectionPath);
// Get the type and idShort for each operation and create the corresponding connected variant
Map<String, IDataElement> ret = new HashMap<>();
@@ -206,7 +219,7 @@
public static Map<String, IProperty> getProperties(VABElementProxy rootProxy, String collectionPath,
String elementPath) {
// Query the whole list of elements
- Collection<Map<String, Object>> mapElemList = (Collection<Map<String, Object>>) rootProxy.getModelPropertyValue(collectionPath);
+ Collection<Map<String, Object>> mapElemList = (Collection<Map<String, Object>>) rootProxy.getValue(collectionPath);
// Get the type and idShort for each operation and create the corresponding
// connected variant
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedBlob.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedBlob.java
index f2d1b12..102a430 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedBlob.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedBlob.java
@@ -1,6 +1,16 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement;
-import java.util.Map;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IBlob;
@@ -19,13 +29,14 @@
super(proxy);
}
- @SuppressWarnings("unchecked")
@Override
- public byte[] getValue() {
-
- // FIXME: This is a hack, fix this when API is clear
- Property value = Property.createAsFacade((Map<String, Object>) getProxy().getModelPropertyValue(Property.VALUE));
- return ((String) value.get()).getBytes();
+ public String getValue() {
+ Object connectedValue = getProxy().getValue(Property.VALUE);
+ if (connectedValue instanceof String) {
+ return (String) connectedValue;
+ } else {
+ return null;
+ }
}
@Override
@@ -37,5 +48,47 @@
protected KeyElements getKeyElement() {
return KeyElements.BLOB;
}
+
+ @Override
+ public Blob getLocalCopy() {
+ return Blob.createAsFacade(getElem()).getLocalCopy();
+ }
+
+ @Override
+ public void setValue(String value) {
+ if (value instanceof String) {
+ // Assume a Base64 encoded String
+ setValue((Object) value);
+ } else {
+ throw new IllegalArgumentException("Given Object is not a String");
+ }
+ }
+
+
+ @Override
+ public byte[] getByteArrayValue() {
+ String value = getValue();
+ if (value != null) {
+ return Base64.getDecoder().decode(value);
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public void setByteArrayValue(byte[] value) {
+ setValue((Object) Base64.getEncoder().encodeToString(value));
+ }
+
+ @Override
+ public String getUTF8String() {
+ return getLocalCopy().getUTF8String();
+ }
+
+ @Override
+ public void setUTF8String(String text) {
+ byte[] byteArray = text.getBytes(StandardCharsets.UTF_8);
+ setByteArrayValue(byteArray);
+ }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedDataElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedDataElement.java
index 6c5f6c9..23aacda 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedDataElement.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedDataElement.java
@@ -1,8 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IDataElement;
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.ConnectedSubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.DataElement;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
/**
@@ -20,4 +30,14 @@
protected KeyElements getKeyElement() {
return KeyElements.DATAELEMENT;
}
+
+ @Override
+ public Object getValue() {
+ throw new UnsupportedOperationException("getValue is only possible in specific Element");
+ }
+
+ @Override
+ public DataElement getLocalCopy() {
+ return DataElement.createAsFacade(getElem()).getLocalCopy();
+ }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedFile.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedFile.java
index 6d443b9..ea8ca78 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedFile.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedFile.java
@@ -1,7 +1,14 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement;
-import java.util.Map;
-
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IFile;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
@@ -19,13 +26,11 @@
super(proxy);
}
- @SuppressWarnings("unchecked")
@Override
public String getValue() {
// FIXME: This is a hack, fix this when API is clear
- Property value = Property.createAsFacade((Map<String, Object>) getProxy().getModelPropertyValue(Property.VALUE));
- return (String) value.get();
+ return (String) getProxy().getValue(Property.VALUE);
}
@Override
@@ -38,4 +43,13 @@
return KeyElements.FILE;
}
+ @Override
+ public File getLocalCopy() {
+ return File.createAsFacade(getElem()).getLocalCopy();
+ }
+
+ @Override
+ public void setValue(String value) {
+ setValue((Object) value);
+ }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedMultiLanguageProperty.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedMultiLanguageProperty.java
index e3c4d4b..0e6c0d8 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedMultiLanguageProperty.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedMultiLanguageProperty.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement;
import java.util.Collection;
@@ -38,4 +47,14 @@
protected KeyElements getKeyElement() {
return KeyElements.MULTILANGUAGEPROPERTY;
}
+
+ @Override
+ public MultiLanguageProperty getLocalCopy() {
+ return MultiLanguageProperty.createAsFacade(getElem()).getLocalCopy();
+ }
+
+ @Override
+ public void setValue(LangStrings value) {
+ setValue((Object) value);
+ }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedProperty.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedProperty.java
index 8bf18c1..e6124e6 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedProperty.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedProperty.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement;
import java.util.Map;
@@ -6,10 +15,9 @@
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDefHelper;
-import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueTypeHelper;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
/**
@@ -26,31 +34,19 @@
}
@Override
- public Object get() throws Exception {
- return retrieveObject();
- }
-
- @Override
- public void set(Object newValue) throws ProviderException {
- getProxy().setModelPropertyValue(Property.VALUE, newValue);
- }
-
- @SuppressWarnings({ "unchecked" })
- @Override
- public String getValueType() {
- Object o = getProxy().getModelPropertyValue("");
- return PropertyValueTypeDefHelper.readTypeDef(((Map<String, Object>) o).get(Property.VALUETYPE)).toString();
+ public ValueType getValueType() {
+ return ValueTypeHelper.readTypeDef(getElem().getPath(Property.VALUETYPE));
}
@SuppressWarnings("unchecked")
@Override
public IReference getValueId() {
- return Reference.createAsFacade((Map<String, Object>) getProxy().getModelPropertyValue(MultiLanguageProperty.VALUEID));
+ return Reference.createAsFacade((Map<String, Object>) getElem().getPath(Property.VALUEID));
}
@SuppressWarnings("unchecked")
protected <T> T retrieveObject() {
- return (T) ((Map<String, Object>) getProxy().getModelPropertyValue(Property.VALUE)).get(Property.VALUE);
+ return (T) getProxy().getValue(Property.VALUE);
}
@Override
@@ -58,4 +54,23 @@
return KeyElements.PROPERTY;
}
+ @Override
+ public Object getValue() {
+ Object value = retrieveObject();
+ if(value instanceof String) {
+ return ValueTypeHelper.getJavaObject(value, getValueType());
+ }else {
+ return value;
+ }
+ }
+
+ @Override
+ public void setValue(Object value) {
+ getProxy().setValue(Property.VALUE, ValueTypeHelper.prepareForSerialization(value));
+ }
+
+ @Override
+ public Property getLocalCopy() {
+ return Property.createAsFacade(getElem()).getLocalCopy();
+ }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedRange.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedRange.java
index ff97641..d2a1d1d 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedRange.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedRange.java
@@ -1,8 +1,23 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement;
+import java.util.Map;
+
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IRange;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Range;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueTypeHelper;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.Range;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.RangeValue;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
/**
@@ -17,22 +32,59 @@
}
@Override
- public String getValueType() {
- return (String) getElem().getPath(Range.VALUETYPE);
+ public ValueType getValueType() {
+ return ValueTypeHelper.readTypeDef(getElem().getPath(Range.VALUETYPE));
}
@Override
public Object getMin() {
- return getElem().getPath(Range.MIN);
+ Object min = getElem().getPath(Range.MIN);
+ return ValueTypeHelper.getJavaObject(min, getValueType());
}
@Override
public Object getMax() {
- return getElem().getPath(Range.MAX);
+ Object max = getElem().getPath(Range.MAX);
+ return ValueTypeHelper.getJavaObject(max, getValueType());
}
@Override
protected KeyElements getKeyElement() {
return KeyElements.RANGE;
}
-}
\ No newline at end of file
+
+ @Override
+ public RangeValue getValue() {
+ return new RangeValue(getMin(), getMax());
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void setValue(Object value) {
+ if(RangeValue.isRangeValue(value)) {
+ RangeValue rangeValue = RangeValue.createAsFacade((Map<String, Object>) value);
+ setValue(rangeValue);
+ } else {
+ throw new IllegalArgumentException("Given object " + value + " is not a RangeValue");
+ }
+ }
+
+ @Override
+ public Range getLocalCopy() {
+ return Range.createAsFacade(getElem()).getLocalCopy();
+ }
+
+ @Override
+ public void setValue(RangeValue rangeValue) {
+ Object minRaw = rangeValue.getMin();
+ Object maxRaw = rangeValue.getMax();
+
+ RangeValue prepared = new RangeValue(
+ ValueTypeHelper.prepareForSerialization(minRaw),
+ ValueTypeHelper.prepareForSerialization(maxRaw)
+ );
+
+
+ getProxy().setValue(MultiSubmodelElementProvider.VALUE, prepared);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedReferenceElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedReferenceElement.java
index 036c884..f5c4a40 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedReferenceElement.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedReferenceElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement;
import java.util.Map;
@@ -6,6 +15,7 @@
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IReferenceElement;
import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.ReferenceElement;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
@@ -30,4 +40,13 @@
return KeyElements.REFERENCEELEMENT;
}
-}
\ No newline at end of file
+ @Override
+ public ReferenceElement getLocalCopy() {
+ return ReferenceElement.createAsFacade(getElem()).getLocalCopy();
+ }
+
+ @Override
+ public void setValue(IReference value) {
+ setValue((Object) value);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/event/ConnectedBasicEvent.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/event/ConnectedBasicEvent.java
index 5c1386f..f38d274 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/event/ConnectedBasicEvent.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/event/ConnectedBasicEvent.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.event;
import java.util.Map;
@@ -31,4 +40,14 @@
protected KeyElements getKeyElement() {
return KeyElements.BASICEVENT;
}
+
+ @Override
+ public IReference getValue() {
+ return getObserved();
+ }
+
+ @Override
+ public BasicEvent getLocalCopy() {
+ return BasicEvent.createAsFacade(getElem()).getLocalCopy();
+ }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/operation/ConnectedAsyncInvocation.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/operation/ConnectedAsyncInvocation.java
new file mode 100644
index 0000000..11365be
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/operation/ConnectedAsyncInvocation.java
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.operation;
+
+import java.util.Map;
+
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IAsyncInvocation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationExecutionErrorException;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationExecutionTimeoutException;
+import org.eclipse.basyx.submodel.restapi.OperationProvider;
+import org.eclipse.basyx.submodel.restapi.operation.CallbackResponse;
+import org.eclipse.basyx.submodel.restapi.operation.ExecutionState;
+import org.eclipse.basyx.submodel.restapi.operation.InvocationRequest;
+import org.eclipse.basyx.submodel.restapi.operation.InvocationResponse;
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+
+/**
+ * Connected variant of IAsyncInvocation
+ *
+ * @author conradi
+ *
+ */
+public class ConnectedAsyncInvocation implements IAsyncInvocation {
+
+ private String operationId;
+ private String requestId;
+
+ private VABElementProxy proxy;
+
+ private Object result = null;
+ private boolean resultRetrieved = false;
+
+ @SuppressWarnings("unchecked")
+ public ConnectedAsyncInvocation(VABElementProxy proxy, String operationId, InvocationRequest request) {
+ this.proxy = proxy;
+ this.operationId = operationId;
+ CallbackResponse response = CallbackResponse.createAsFacade((Map<String, Object>) proxy.invokeOperation(Operation.INVOKE + OperationProvider.ASYNC, request));
+ requestId = response.getRequestId();
+ }
+
+ @Override
+ public Object getResult() {
+ // Wait for Operation to finish
+ while (!isFinished()) {
+ try {
+ Thread.sleep(50);
+ } catch (InterruptedException e) {
+ }
+ }
+
+ // Side-effect of isFinished is querying the result.
+ // Thus, it can be assumed, the the result will be available here
+
+ if (result instanceof Exception) {
+ throw new OperationExecutionErrorException("Exception while executing Invocation '"
+ + requestId + "' of Operation '" + operationId + "'");
+ } else if (ExecutionState.FAILED == result) {
+ throw new OperationExecutionErrorException("Exception while executing Invocation '" + requestId
+ + "' of Operation '" + operationId + "'; Operation failed");
+ } else if (ExecutionState.TIMEOUT == result) {
+ throw new OperationExecutionTimeoutException(
+ "Invocation '" + requestId + "' of Operation '" + operationId + "' timed out");
+ } else {
+ return result;
+ }
+ }
+
+ /**
+ * Queries the operation with the connected proxy to see, if the result is already finished
+ */
+ @Override
+ public boolean isFinished() {
+ if (resultRetrieved) {
+ // If the result was already retrieved the Operation is done
+ return true;
+ }
+
+ retrieveResultDirectly();
+ return resultRetrieved;
+ }
+
+ @SuppressWarnings("unchecked")
+ private void retrieveResultDirectly() {
+ // 1. Retrieve InvocationResponse from proxy
+ Object responseObj = null;
+ try {
+ responseObj = proxy.getValue(getListPath());
+ } catch (ProviderException e) {
+ // As the Submodel-API does not specify a request to ask whether
+ // the operation is finished, it has to be done via the retrieval of the value.
+ // If the execution resulted in an Exception this Exception would be thrown here
+ // -> if a ProviderException with a RuntimeException as cause is thrown,
+ // the Operation is finished.
+ if (e.getCause() instanceof RuntimeException) {
+ resultRetrieved = true;
+ result = e;
+ } else {
+ // If it is something else -> rethrow it
+ throw e;
+ }
+ }
+
+ // 2. Cast response to InvocationResponse
+ InvocationResponse response = null;
+ if ( responseObj instanceof InvocationResponse ) {
+ response = (InvocationResponse) responseObj;
+ } else if ( result instanceof Map<?, ?> ) {
+ response = InvocationResponse.createAsFacade((Map<String, Object>) result);
+ } else {
+ // got no valid InvocationResponse
+ throw new ProviderException("Response for requestId " + requestId + " invalid!");
+ }
+
+ // 3. Transform to direct result
+ switch (response.getExecutionState()) {
+ case COMPLETED:
+ // Finished => set internal state
+ resultRetrieved = true;
+ result = response.getFirstOutput();
+ break;
+ case FAILED:
+ case TIMEOUT:
+ // Finished, but no result => set internal state
+ resultRetrieved = true;
+ result = response.getExecutionState();
+ break;
+ default:
+ // Not finished, yet, result hasn't been retrieved
+ }
+ }
+
+ public String getRequestId() {
+ return requestId;
+ }
+
+ public String getOperationId() {
+ return operationId;
+ }
+
+ private String getListPath() {
+ return VABPathTools.concatenatePaths(OperationProvider.INVOCATION_LIST, requestId);
+ }
+
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/operation/ConnectedOperation.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/operation/ConnectedOperation.java
index cd5bb41..4c2e6b3 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/operation/ConnectedOperation.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/operation/ConnectedOperation.java
@@ -1,17 +1,36 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.operation;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
-import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
import java.util.Map;
+import java.util.UUID;
+import java.util.stream.Collectors;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperationVariable;
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.ConnectedSubmodelElement;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDefHelper;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
+import org.eclipse.basyx.submodel.restapi.operation.InvocationRequest;
+import org.eclipse.basyx.submodel.restapi.operation.InvocationResponse;
+import org.eclipse.basyx.vab.exception.provider.WrongNumberOfParametersException;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
/**
@@ -21,6 +40,9 @@
*
*/
public class ConnectedOperation extends ConnectedSubmodelElement implements IOperation {
+ // Default timeout for asynchronous operation calls
+ public static final int DEFAULT_ASYNC_TIMEOUT = Operation.DEFAULT_ASYNC_TIMEOUT;
+
public ConnectedOperation(VABElementProxy proxy) {
super(proxy);
}
@@ -41,28 +63,105 @@
}
/**
- * Invoke a remote operation TODO C# includes idShort
+ * Invoke a remote operation
*/
+ @Override
+ public Object invoke(Object... params) {
+ // Wrap simple params
+ SubmodelElement[] wrapper = createElementWrapper(params);
+
+ // Invoke with submodel elements
+ SubmodelElement[] result = invoke(wrapper);
+
+ // Unwrap result wrapper
+ return unwrapResult(result);
+ }
+
@SuppressWarnings("unchecked")
@Override
- public Object invoke(Object... params) throws Exception {
+ public SubmodelElement[] invoke(SubmodelElement... elems) {
+ // Create request
+ InvocationRequest request = createInvocationRequest(DEFAULT_ASYNC_TIMEOUT, elems);
- // Wrap parameter with valuetype information
+ // Invoke the operation
+ Object responseObj = getProxy().invokeOperation(Operation.INVOKE, request);
+ InvocationResponse response = InvocationResponse.createAsFacade((Map<String, Object>) responseObj);
+
+ // Extract the output elements
+ Collection<IOperationVariable> outputArguments = response.getOutputArguments();
+ List<ISubmodelElement> elements = outputArguments.stream().map(IOperationVariable::getValue)
+ .collect(Collectors.toList());
+
+ // Cast them to an array
+ SubmodelElement[] result = new SubmodelElement[elements.size()];
+ elements.toArray(result);
+ return result;
+ }
+
+ private InvocationRequest createInvocationRequest(int timeout, SubmodelElement... elems) {
+ // Wrap parameters in operation variables
+ Collection<IOperationVariable> inputArguments = Arrays.asList(elems).stream().map(OperationVariable::new)
+ .collect(Collectors.toList());
+ // Generate random request id
+ String requestId = UUID.randomUUID().toString();
+
+ // Create invokation request
+ return new InvocationRequest(requestId, new ArrayList<>(), inputArguments, timeout);
+ }
+
+ private SubmodelElement[] createElementWrapper(Object... params) {
+ Collection<IOperationVariable> inputVariables = getInputVariables();
+ if (inputVariables.size() != params.length) {
+ throw new WrongNumberOfParametersException(getIdShort(), inputVariables, params);
+ }
+
+ // Copy parameter values into SubmodelElements according to InputVariables
+ SubmodelElement[] ret = new SubmodelElement[params.length];
+ Iterator<IOperationVariable> iterator = inputVariables.iterator();
int i = 0;
- for (Object param : params) {
- HashMap<String, Object> valueWrapper = new HashMap<>();
- valueWrapper.put(Property.VALUETYPE, PropertyValueTypeDefHelper.getTypeWrapperFromObject(param));
- valueWrapper.put(Property.VALUE, param);
-
- params[i] = valueWrapper;
+ while (iterator.hasNext()) {
+ IOperationVariable matchedInput = iterator.next();
+ ISubmodelElement inputElement = matchedInput.getValue();
+ SubmodelElement copy = inputElement.getLocalCopy();
+ copy.setValue(params[i]);
+ ret[i] = copy;
i++;
}
- // Invoke operation passing an empty string, since the used proxy already points
- // to the operation
- Object result = getProxy().invokeOperation("", params);
+ return ret;
+ }
- // Unwrap result value
+ @Override
+ public ConnectedAsyncInvocation invokeAsync(Object... params) {
+ SubmodelElement[] smElements = createElementWrapper(params);
+ InvocationRequest request = createInvocationRequest(DEFAULT_ASYNC_TIMEOUT, smElements);
+ return new ConnectedAsyncInvocation(getProxy(), getIdShort(), request);
+ }
+
+ @Override
+ public ConnectedAsyncInvocation invokeAsyncWithTimeout(int timeout, Object... params) {
+ SubmodelElement[] smElements = createElementWrapper(params);
+ InvocationRequest request = createInvocationRequest(timeout, smElements);
+ return new ConnectedAsyncInvocation(getProxy(), getIdShort(), request);
+ }
+
+ @Override
+ protected KeyElements getKeyElement() {
+ return KeyElements.OPERATION;
+ }
+
+ @Override
+ public Object getValue() {
+ throw new UnsupportedOperationException("An Operation has no value");
+ }
+
+ @Override
+ public void setValue(Object value) {
+ throw new UnsupportedOperationException("An Operation has no value");
+ }
+
+ @SuppressWarnings("unchecked")
+ private Object unwrapResult(Object result) {
if (result instanceof Collection<?>) {
Collection<Object> coll = (Collection<Object>) result;
if (coll.isEmpty()) {
@@ -72,16 +171,20 @@
if (resultWrapper instanceof Map<?, ?>) {
Map<String, Object> map = (Map<String, Object>) resultWrapper;
if (map.get(Referable.IDSHORT).equals("Response") && map.get(Property.VALUE) != null) {
- result = map.get(Property.VALUE);
+ return map.get(Property.VALUE);
}
}
+ } else if (result instanceof SubmodelElement[]) {
+ SubmodelElement[] arr = (SubmodelElement[]) result;
+ if (arr.length > 0 && arr[0] instanceof Map<?, ?>) {
+ return arr[0].getValue();
+ }
}
-
return result;
}
-
+
@Override
- protected KeyElements getKeyElement() {
- return KeyElements.OPERATION;
+ public Operation getLocalCopy() {
+ return Operation.createAsFacade(getElem()).getLocalCopy();
}
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/relationship/ConnectedAnnotatedRelationshipElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/relationship/ConnectedAnnotatedRelationshipElement.java
new file mode 100644
index 0000000..6a8133c
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/relationship/ConnectedAnnotatedRelationshipElement.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.relationship;
+
+import java.util.Map;
+
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.relationship.IAnnotatedRelationshipElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.AnnotatedRelationshipElementValue;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+
+/**
+ * "Connected" implementation of AnnotatedRelationshipElement
+ *
+ * @author schnicke, conradi
+ *
+ */
+public class ConnectedAnnotatedRelationshipElement extends ConnectedRelationshipElement implements IAnnotatedRelationshipElement {
+
+ public ConnectedAnnotatedRelationshipElement(VABElementProxy proxy) {
+ super(proxy);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public AnnotatedRelationshipElementValue getValue() {
+ Object obj = getProxy().getValue(Property.VALUE);
+
+ return AnnotatedRelationshipElementValue.createAsFacade((Map<String, Object>) obj);
+ }
+
+ @Override
+ public void setValue(AnnotatedRelationshipElementValue value) {
+ setValue((Object) value);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/relationship/ConnectedRelationshipElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/relationship/ConnectedRelationshipElement.java
index 4ccb2e0..735ae6f 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/relationship/ConnectedRelationshipElement.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/relationship/ConnectedRelationshipElement.java
@@ -1,13 +1,22 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.relationship;
import java.util.Map;
-import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.relationship.IRelationshipElement;
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.ConnectedSubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElementValue;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
/**
@@ -20,31 +29,27 @@
public ConnectedRelationshipElement(VABElementProxy proxy) {
super(proxy);
}
-
- public void setFirst(IReference first) {
- getProxy().setModelPropertyValue(RelationshipElement.FIRST, first);
-
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public IReference getFirst() {
- return Reference.createAsFacade((Map<String, Object>) getElem().getPath(RelationshipElement.FIRST));
- }
-
- public void setSecond(IReference second) {
- getProxy().setModelPropertyValue(RelationshipElement.SECOND, second);
-
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public IReference getSecond() {
- return Reference.createAsFacade((Map<String, Object>) getElem().getPath(RelationshipElement.SECOND));
- }
@Override
protected KeyElements getKeyElement() {
return KeyElements.RELATIONSHIPELEMENT;
}
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public RelationshipElementValue getValue() {
+ Object obj = getProxy().getValue(Property.VALUE);
+
+ return RelationshipElementValue.createAsFacade((Map<String, Object>) obj);
+ }
+
+ @Override
+ public RelationshipElement getLocalCopy() {
+ return RelationshipElement.createAsFacade(getElem()).getLocalCopy();
+ }
+
+ @Override
+ public void setValue(RelationshipElementValue value) {
+ setValue((Object) value);
+ }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/enumhelper/StandardizedLiteralEnum.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/enumhelper/StandardizedLiteralEnum.java
index bad3b4d..c3293b5 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/enumhelper/StandardizedLiteralEnum.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/enumhelper/StandardizedLiteralEnum.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.enumhelper;
/**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/enumhelper/StandardizedLiteralEnumHelper.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/enumhelper/StandardizedLiteralEnumHelper.java
index 2f32a25..48dde83 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/enumhelper/StandardizedLiteralEnumHelper.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/enumhelper/StandardizedLiteralEnumHelper.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.enumhelper;
import com.google.common.base.Strings;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelElementMapCollectionConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelElementMapCollectionConverter.java
new file mode 100644
index 0000000..56181c1
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelElementMapCollectionConverter.java
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.facade;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.facade.submodelelement.SubmodelElementFacadeFactory;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+
+
+/**
+ * This class provides the functionality to convert the
+ * smElements of a Submodel/SubmodelElementCollection from a Collection to a Map and vice versa.<br>
+ * The given Submodel/Map is not changed.<br>
+ * This is necessary, because internally smElements are represented as Map and externally as Collection.
+ *
+ * @author conradi
+ *
+ */
+public class SubmodelElementMapCollectionConverter {
+
+
+ /**
+ * Builds a Submodel from a given Map.<br>
+ * Converts the Submodel.SUBMODELELEMENT entry of a Map to a Map<IdShort, SMElement>.<br>
+ * Creates Facades for all smElements.
+ *
+ * @param submodel a Map representing the Submodel to be converted.
+ * @return a new Submodel made from the given Map with the smElements as Map
+ */
+ public static Submodel mapToSM(Map<String, Object> submodel) {
+
+ // Put the content of the Map into a SM and replace its smElements with the new Map of smElements
+ Submodel ret = new Submodel();
+ ret.setMap(submodel);
+
+ Object smElements = submodel.get(Submodel.SUBMODELELEMENT);
+
+ ret.put(Submodel.SUBMODELELEMENT, convertCollectionToIDMap(smElements));
+
+ return ret;
+ }
+
+ /**
+ * Converts a given Submodel to a Map<br>
+ * Converts the Submodel.SUBMODELELEMENT entry of a Submodel to a Collection.<br>
+ *
+ * @param submodel the Submodel to be converted.
+ * @return a Map made from the given Submodel containing the smElements as Collection.
+ */
+ @SuppressWarnings("unchecked")
+ public static Map<String, Object> smToMap(Submodel submodel) {
+
+ // Get the smElements Map from the given Submodel
+ Map<String, ISubmodelElement> smElements = submodel.getSubmodelElements();
+
+ // Put the Entries of the SM in a new Map
+ Map<String, Object> ret = new HashMap<>();
+ ret.putAll(submodel);
+
+ // Feed all contained smElements through smElementToMap to deal with smElemCollections
+ List<Map<String, Object>> newElements = smElements.values().stream()
+ .map(e -> smElementToMap((Map<String, Object>) e)).collect(Collectors.toList());
+
+ // Replace the smElements Map with the Collection of Elements
+ ret.put(Submodel.SUBMODELELEMENT, newElements);
+
+ return ret;
+ }
+
+
+ /**
+ * Builds a SubmodelElementCollection from a given Map.<br>
+ * Converts the Property.VALUE entry of a Map to a Map<IdShort, SMElement>.<br>
+ * Creates Facades for all smElements.
+ *
+ * @param smECollection a Map representing the SubmodelElementCollection to be converted.
+ * @return a new SubmodelElementCollection made from the given Map with the smElements as Map
+ */
+ public static SubmodelElementCollection mapToSmECollection(Map<String, Object> smECollection) {
+
+ // Put the content of the Map into a SM and replace its smElements with the new Map of smElements
+ SubmodelElementCollection ret = new SubmodelElementCollection();
+ ret.setMap(smECollection);
+
+ Object smElements = smECollection.get(Property.VALUE);
+
+ ret.put(Property.VALUE, convertCollectionToIDMap(smElements));
+
+ return ret;
+ }
+
+ /**
+ * Converts a given SubmodelElementCollection to a Map<br>
+ * Converts the Property.VALUE entry of a SubmodelElementCollection to a Collection.<br>
+ * If given Element is not a SubmodelElementCollection it will be returned unchanged.
+ *
+ * @param smElement the SubmodelElement to be converted.
+ * @return a Map made from the given SubmodelElement.
+ */
+ public static Map<String, Object> smElementToMap(Map<String, Object> smElement) {
+
+ if(!SubmodelElementCollection.isSubmodelElementCollection((Map<String, Object>) smElement)) {
+ return (Map<String, Object>) smElement;
+ }
+
+ // Put the Entries of the SM in a new Map
+ Map<String, Object> ret = new HashMap<>();
+ ret.putAll(smElement);
+
+ ret.put(Property.VALUE, convertIDMapToCollection(smElement.get(Property.VALUE)));
+
+ return ret;
+ }
+
+
+ /**
+ * Converts a given smElement Collection/Map to a Map<idShort, smElement>.
+ *
+ * @param smElements the smElements to be converted
+ * @return a Map<idSHort, smElement>
+ */
+ @SuppressWarnings("unchecked")
+ public static Map<String, Object> convertCollectionToIDMap(Object smElements) {
+ Map<String, Object> smElementsMap = new HashMap<>();
+
+ if(smElements == null) {
+ // if null was given, return an empty Map
+ return smElementsMap;
+ }
+
+ // SubmodelElemets can be given as Map, Set or List
+ // If it is a Set or List, convert it to a Map first
+ if(smElements instanceof Collection<?>) {
+ Collection<Object> smElementsSet = (Collection<Object>) smElements;
+ for (Object o: smElementsSet) {
+ Map<String, Object> smElement = (Map<String, Object>) o;
+ String id = (String) smElement.get(Referable.IDSHORT);
+ smElementsMap.put(id, smElement);
+ }
+ } else if(smElements instanceof Map<?, ?>){
+ smElementsMap = (Map<String, Object>) smElements;
+ } else {
+ throw new RuntimeException("Elements must be given as Map or Collection");
+ }
+
+ // Iterate through all SubmodelElements and create Facades for them
+ smElementsMap.replaceAll((id, smElement) ->
+ SubmodelElementFacadeFactory.createSubmodelElement((Map<String, Object>) smElement));
+
+ return smElementsMap;
+ }
+
+
+ /**
+ * Converts a given Map<idShort, smElement> to a smElement Collection.
+ *
+ * @param smElements the smElements to be converted
+ * @return Collection<smElement>
+ */
+ @SuppressWarnings("unchecked")
+ public static Collection<Map<String, Object>> convertIDMapToCollection(Object map) {
+ Collection<Object> smElements = null;
+
+ // Check if the contained value is a Map or a Collection
+ if(map instanceof Collection<?>) {
+ // It it is a Collection proceed, as there could be nested Collections that need conversion
+ smElements = (Collection<Object>) map;
+ } else if(map instanceof Map<?, ?>) {
+ smElements = ((Map<String, Object>) map).values();
+ } else {
+ throw new RuntimeException("The SubmodelElementCollection contains neither a Collection nor a Map as value.");
+ }
+
+ // Feed all contained smElements recursively through smElementToMap again to deal with nested smElemCollections
+ List<Map<String, Object>> newElements = smElements.stream()
+ .map(e -> smElementToMap((Map<String, Object>) e)).collect(Collectors.toList());
+
+ return newElements;
+ }
+
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelFacadeCustomSemantics.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelFacadeCustomSemantics.java
index a0c3714..5f8053a 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelFacadeCustomSemantics.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelFacadeCustomSemantics.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.facade;
import java.util.Collection;
@@ -7,7 +16,7 @@
import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
@@ -28,7 +37,7 @@
* @author kuhn
*
*/
-public class SubmodelFacadeCustomSemantics extends SubModel {
+public class SubmodelFacadeCustomSemantics extends Submodel {
/**
* Constructor without arguments - create a sub model with all meta properties empty / set to default values
*/
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelFacadeIRDISemantics.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelFacadeIRDISemantics.java
index 4e9b53a..e4579a1 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelFacadeIRDISemantics.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelFacadeIRDISemantics.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.facade;
import java.util.Collection;
@@ -7,7 +16,7 @@
import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
@@ -25,7 +34,7 @@
* @author kuhn
*
*/
-public class SubmodelFacadeIRDISemantics extends SubModel {
+public class SubmodelFacadeIRDISemantics extends Submodel {
/**
* Constructor without arguments - create a sub model with all meta properties
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelValuesHelper.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelValuesHelper.java
new file mode 100644
index 0000000..8bf2b52
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelValuesHelper.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.facade;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+
+/**
+ * Helperclass for getting the /values Map from a Submodel.
+ *
+ * @author conradi
+ *
+ */
+public class SubmodelValuesHelper {
+
+ /**
+ * Gets the Values from a Submodel
+ *
+ * @param sm the Submodel to get the values from.
+ * @return A Map mapping idShort to the value of the SubmodelElement
+ */
+ @SuppressWarnings("unchecked")
+ public static Map<String, Object> getSubmodelValue(Submodel sm) {
+ Map<String, ISubmodelElement> elements = sm.getSubmodelElements();
+
+ return (Map<String, Object>) handleValue(elements.values());
+ }
+
+
+ @SuppressWarnings("unchecked")
+ private static Object handleValue(Object value) {
+ // Check if it is a collection but not a LangStrings (is internally also a Collection)
+ if (value instanceof Collection<?> && !(value instanceof LangStrings)) {
+ return handleValueCollection((Collection<ISubmodelElement>) value);
+ } else {
+ // The value is not a collection -> return it as is
+ return value;
+ }
+ }
+
+
+ private static Map<String, Object> handleValueCollection(Collection<ISubmodelElement> collection) {
+ Map<String, Object> ret = new HashMap<>();
+ for(ISubmodelElement element: collection) {
+ try {
+ ret.put(element.getIdShort(), handleValue(element.getValue()));
+ } catch (UnsupportedOperationException e) {
+ // this Element has no value (e.g. an Operation)
+ // -> just ignore it
+ }
+ }
+ return ret;
+ }
+
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/submodelelement/SubmodelElementFacadeFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/submodelelement/SubmodelElementFacadeFactory.java
index d68e4b2..06c615e 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/submodelelement/SubmodelElementFacadeFactory.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/submodelelement/SubmodelElementFacadeFactory.java
@@ -1,19 +1,28 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.facade.submodelelement;
import java.util.Map;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Blob;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Range;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.ReferenceElement;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.Range;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.entity.Entity;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.event.BasicEvent;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.AnnotatedRelationshipElement;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElement;
/**
@@ -31,34 +40,34 @@
* @return the actual of the given SubmodelElement map created as facade
*/
public static ISubmodelElement createSubmodelElement(Map<String, Object> submodelElement) {
- String type = ModelType.createAsFacade(submodelElement).getName();
-
- switch (type) {
- case Property.MODELTYPE:
- return Property.createAsFacade(submodelElement);
- case BasicEvent.MODELTYPE:
- return BasicEvent.createAsFacade(submodelElement);
- case MultiLanguageProperty.MODELTYPE:
- return MultiLanguageProperty.createAsFacade(submodelElement);
- case Range.MODELTYPE:
- return Range.createAsFacade(submodelElement);
- case Entity.MODELTYPE:
- return Entity.createAsFacade(submodelElement);
- case File.MODELTYPE:
- return File.createAsFacade(submodelElement);
- case Blob.MODELTYPE:
- return Blob.createAsFacade(submodelElement);
- case ReferenceElement.MODELTYPE:
- return ReferenceElement.createAsFacade(submodelElement);
- case SubmodelElementCollection.MODELTYPE:
- return SubmodelElementCollection.createAsFacade(submodelElement);
- case RelationshipElement.MODELTYPE:
- return RelationshipElement.createAsFacade(submodelElement);
- case Operation.MODELTYPE:
- return Operation.createAsFacade(submodelElement);
- default:
- throw new RuntimeException("Can not create a submodel element from given map");
+ if (Property.isProperty(submodelElement)) {
+ return Property.createAsFacade(submodelElement);
+ } else if (Blob.isBlob(submodelElement)) {
+ return Blob.createAsFacade(submodelElement);
+ } else if (File.isFile(submodelElement)) {
+ return File.createAsFacade(submodelElement);
+ } else if (SubmodelElementCollection.isSubmodelElementCollection(submodelElement)) {
+ return SubmodelElementCollection.createAsFacade(submodelElement);
+ } else if (MultiLanguageProperty.isMultiLanguageProperty(submodelElement)) {
+ return MultiLanguageProperty.createAsFacade(submodelElement);
+ } else if (Entity.isEntity(submodelElement)) {
+ return Entity.createAsFacade(submodelElement);
+ } else if (Range.isRange(submodelElement)) {
+ return Range.createAsFacade(submodelElement);
+ } else if (ReferenceElement.isReferenceElement(submodelElement)) {
+ return ReferenceElement.createAsFacade(submodelElement);
+ } else if (RelationshipElement.isRelationshipElement(submodelElement)) {
+ return RelationshipElement.createAsFacade(submodelElement);
+ } else if (AnnotatedRelationshipElement.isAnnotatedRelationshipElement(submodelElement)) {
+ return AnnotatedRelationshipElement.createAsFacade(submodelElement);
+ } else if (Operation.isOperation(submodelElement)) {
+ return Operation.createAsFacade(submodelElement);
+ } else if (BasicEvent.isBasicEvent(submodelElement)) {
+ return BasicEvent.createAsFacade(submodelElement);
+ } else {
+ throw new RuntimeException("Can not create a submodel element from given map: " + submodelElement);
}
}
+
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/SubModel.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/SubModel.java
deleted file mode 100644
index 93c3f8b..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/SubModel.java
+++ /dev/null
@@ -1,311 +0,0 @@
-package org.eclipse.basyx.submodel.metamodel.map;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.eclipse.basyx.submodel.metamodel.api.IElementContainer;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
-import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IEmbeddedDataSpecification;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
-import org.eclipse.basyx.submodel.metamodel.api.qualifier.IAdministrativeInformation;
-import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
-import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IConstraint;
-import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
-import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
-import org.eclipse.basyx.submodel.metamodel.facade.submodelelement.SubmodelElementFacadeFactory;
-import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.AdministrativeInformation;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.haskind.HasKind;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifiable;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
-import org.eclipse.basyx.vab.model.VABModelMap;
-
-/**
- * A submodel defines a specific aspect of the asset represented by the AAS.
- * <br />
- * <br />
- * A submodel is used to structure the digital representation and technical
- * functionality of an Administration Shell into distinguishable parts. Each
- * submodel refers to a well-defined domain or subject matter. Submodels can
- * become standardized and thus become submodels types. Submodels can have
- * different life-cycles.
- *
- * @author kuhn, schnicke
- *
- *
- */
-public class SubModel extends VABModelMap<Object> implements IElementContainer, ISubModel {
-
- public static final String SUBMODELELEMENT = "submodelElements";
- public static final String MODELTYPE = "Submodel";
-
- /**
- * Constructor
- */
- public SubModel() {
- // Add model type
- putAll(new ModelType(MODELTYPE));
-
- // Add qualifiers
- putAll(new HasSemantics());
- putAll(new Identifiable());
- putAll(new Qualifiable());
- putAll(new HasDataSpecification());
- putAll(new HasKind());
-
- // Attributes
- put(SUBMODELELEMENT, new HashMap<String, ISubmodelElement>());
- }
-
-
- /**
- * Constructor
- */
- public SubModel(HasSemantics semantics, Identifiable identifiable, Qualifiable qualifiable,
- HasDataSpecification specification, HasKind hasKind) {
- // Add qualifiers
- putAll(semantics);
- putAll(identifiable);
- putAll(qualifiable);
- putAll(specification);
- putAll(hasKind);
-
- // Attributes
- put(SUBMODELELEMENT, new HashMap<String, ISubmodelElement>());
- }
-
- /**
- * Constructor
- */
- public SubModel(List<Property> properties) {
- this();
- properties.forEach(this::addSubModelElement);
- }
-
- /**
- * Constructor
- */
- public SubModel(List<Property> properties, List<Operation> operations) {
- this();
- properties.forEach(this::addSubModelElement);
- operations.forEach(this::addSubModelElement);
- }
-
-
- @SuppressWarnings("unchecked")
- public static SubModel createAsFacade(Map<String, Object> map) {
- if (map == null) {
- return null;
- }
-
- SubModel ret = new SubModel();
-
- Map<String, Object> smElements = new HashMap<>();
-
- //SubmodelElemets can be given as Map, Set or List
- //If it is a Set or List, convert it to a Map first
- if(map.get(SUBMODELELEMENT) instanceof Collection<?>) {
- Collection<Object> smElementsSet = (Collection<Object>) map.get(SUBMODELELEMENT);
- for (Object o: smElementsSet) {
- Map<String, Object> smElement = (Map<String, Object>) o;
- String id = (String) smElement.get(Referable.IDSHORT);
- smElements.put(id, smElement);
- }
- } else {
- smElements = (Map<String, Object>) map.get(SUBMODELELEMENT);
- }
-
- // Transfer map and overwrite SUBMODELELEMENt to prepare it for manual setting
- ret.setMap(map);
- ret.put(SUBMODELELEMENT, new HashMap<String, Object>());
-
- //Iterate through all SubmodelELements and create Facades for them
- for(Entry<String, Object> smElement: smElements.entrySet()) {
- ret.getSubmodelElements().put(smElement.getKey(),
- SubmodelElementFacadeFactory.createSubmodelElement(
- (Map<String, Object>) smElement.getValue()));
- }
-
- return ret;
- }
-
- @Override
- public IReference getSemanticId() {
- return HasSemantics.createAsFacade(this).getSemanticId();
- }
-
- public void setSemanticId(IReference ref) {
- HasSemantics.createAsFacade(this).setSemanticID(ref);
- }
-
- @Override
- public IAdministrativeInformation getAdministration() {
- return Identifiable.createAsFacade(this, getKeyElement()).getAdministration();
- }
-
- @Override
- public IIdentifier getIdentification() {
- return Identifiable.createAsFacade(this, getKeyElement()).getIdentification();
- }
-
- public void setAdministration(AdministrativeInformation information) {
- Identifiable.createAsFacade(this, getKeyElement()).setAdministration(information);
- }
-
- public void setIdentification(IdentifierType idType, String id) {
- Identifiable.createAsFacade(this, getKeyElement()).setIdentification(idType, id);
- }
-
- @Override
- public Collection<IReference> getDataSpecificationReferences() {
- return HasDataSpecification.createAsFacade(this).getDataSpecificationReferences();
- }
-
- public void setDataSpecificationReferences(Collection<IReference> ref) {
- HasDataSpecification.createAsFacade(this).setDataSpecificationReferences(ref);
- }
-
- @Override
- public Collection<IEmbeddedDataSpecification> getEmbeddedDataSpecifications() {
- return HasDataSpecification.createAsFacade(this).getEmbeddedDataSpecifications();
- }
-
- public void setEmbeddedDataSpecifications(Collection<IEmbeddedDataSpecification> embeddedDataSpecifications) {
- HasDataSpecification.createAsFacade(this).setEmbeddedDataSpecifications(embeddedDataSpecifications);
- }
-
- @Override
- public ModelingKind getModelingKind() {
- return HasKind.createAsFacade(this).getModelingKind();
- }
-
- public void setModelingKind(ModelingKind kind) {
- HasKind.createAsFacade(this).setModelingKind(kind);
- }
-
- @Override
- public String getIdShort() {
- return Referable.createAsFacade(this, getKeyElement()).getIdShort();
- }
-
- public void setIdShort(String id) {
- Referable.createAsFacade(this, getKeyElement()).setIdShort(id);
- }
-
- public void setProperties(Map<String, IProperty> properties) {
- // first, remove all properties
- Set<Entry<String, ISubmodelElement>> elementSet = getSubmodelElements().entrySet();
- for ( Iterator<Entry<String, ISubmodelElement>> iterator = elementSet.iterator(); iterator.hasNext(); ) {
- Entry<String, ISubmodelElement> entry = iterator.next();
- if (entry.getValue() instanceof IProperty) {
- iterator.remove();
- }
- }
- // then add all given data properties
- properties.values().forEach(this::addSubModelElement);
- }
-
- public void setOperations(Map<String, IOperation> operations) {
- // first, remove all operations
- Set<Entry<String, ISubmodelElement>> elementSet = getSubmodelElements().entrySet();
- for (Iterator<Entry<String, ISubmodelElement>> iterator = elementSet.iterator(); iterator.hasNext();) {
- Entry<String, ISubmodelElement> entry = iterator.next();
- if (entry.getValue() instanceof IOperation) {
- iterator.remove();
- }
- }
- // then add all given operations
- operations.values().forEach(this::addSubModelElement);
- }
-
- @Override
- public String getCategory() {
- return Referable.createAsFacade(this, getKeyElement()).getCategory();
- }
-
- @Override
- public LangStrings getDescription() {
- return Referable.createAsFacade(this, getKeyElement()).getDescription();
- }
-
- @Override
- public IReference getParent() {
- return Referable.createAsFacade(this, getKeyElement()).getParent();
- }
-
- public void setCategory(String category) {
- Referable.createAsFacade(this, getKeyElement()).setCategory(category);
- }
-
- public void setDescription(LangStrings description) {
- Referable.createAsFacade(this, getKeyElement()).setDescription(description);
- }
-
- public void setParent(IReference obj) {
- Referable.createAsFacade(this, getKeyElement()).setParent(obj);
- }
-
- private KeyElements getKeyElement() {
- return KeyElements.SUBMODEL;
- }
-
- @Override
- public void addSubModelElement(ISubmodelElement element) {
- if (element instanceof SubmodelElement) {
- ((SubmodelElement) element).setParent(getReference());
- }
- getSubmodelElements().put(element.getIdShort(), element);
- }
-
- @Override
- public Map<String, IProperty> getProperties() {
- Map<String, IProperty> properties = new HashMap<>();
- getSubmodelElements().values().forEach(e -> {
- if (e instanceof IProperty) {
- properties.put(e.getIdShort(), (IProperty) e);
- }
- });
- return properties;
- }
-
- @Override
- public Map<String, IOperation> getOperations() {
- Map<String, IOperation> operations = new HashMap<>();
- getSubmodelElements().values().forEach(e -> {
- if (e instanceof IOperation) {
- operations.put(e.getIdShort(), (IOperation) e);
- }
- });
- return operations;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public Map<String, ISubmodelElement> getSubmodelElements() {
- return (Map<String, ISubmodelElement>) get(SUBMODELELEMENT);
- }
- @Override
- public Collection<IConstraint> getQualifier() {
- return Qualifiable.createAsFacade(this).getQualifier();
- }
-
- @Override
- public IReference getReference() {
- return Identifiable.createAsFacade(this, getKeyElement()).getReference();
- }
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/Submodel.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/Submodel.java
new file mode 100644
index 0000000..d3d2374
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/Submodel.java
@@ -0,0 +1,356 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.map;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.IElementContainer;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IEmbeddedDataSpecification;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.IAdministrativeInformation;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IConstraint;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelValuesHelper;
+import org.eclipse.basyx.submodel.metamodel.map.helper.ElementContainerHelper;
+import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.AdministrativeInformation;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.haskind.HasKind;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifiable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.vab.model.VABModelMap;
+
+/**
+ * A submodel defines a specific aspect of the asset represented by the AAS.
+ * <br />
+ * <br />
+ * A submodel is used to structure the digital representation and technical
+ * functionality of an Administration Shell into distinguishable parts. Each
+ * submodel refers to a well-defined domain or subject matter. Submodels can
+ * become standardized and thus become submodels types. Submodels can have
+ * different life-cycles.
+ *
+ * @author kuhn, schnicke
+ *
+ *
+ */
+public class Submodel extends VABModelMap<Object> implements IElementContainer, ISubmodel {
+
+ public static final String SUBMODELELEMENT = "submodelElements";
+ public static final String MODELTYPE = "Submodel";
+
+ /**
+ * Constructor
+ */
+ public Submodel() {
+ // Add qualifiers
+ putAll(new Identifiable());
+ putAll(new HasDataSpecification());
+
+ // Add model type
+ putAll(new ModelType(MODELTYPE));
+ setModelingKind(ModelingKind.INSTANCE);
+
+ put(SUBMODELELEMENT, new HashMap<String, ISubmodelElement>());
+
+ }
+
+ /**
+ * Constructor accepting only mandatory attribute
+ * @param idShort
+ * @param identification
+ */
+ public Submodel(String idShort, IIdentifier identification) {
+ this();
+ setIdentification(identification);
+ setIdShort(idShort);
+ }
+
+
+ /**
+ * Constructor
+ */
+ public Submodel(HasSemantics semantics, Identifiable identifiable, Qualifiable qualifiable,
+ HasDataSpecification specification, HasKind hasKind) {
+ this();
+ // Add qualifiers
+ putAll(semantics);
+ putAll(identifiable);
+ putAll(qualifiable);
+ putAll(specification);
+ putAll(hasKind);
+
+ // Attributes
+ put(SUBMODELELEMENT, new HashMap<String, ISubmodelElement>());
+ }
+
+ /**
+ * Constructor
+ */
+ public Submodel(List<Property> properties) {
+ this();
+ properties.forEach(this::addSubmodelElement);
+ }
+
+ /**
+ * Constructor
+ */
+ public Submodel(List<Property> properties, List<Operation> operations) {
+ this();
+ properties.forEach(this::addSubmodelElement);
+ operations.forEach(this::addSubmodelElement);
+ }
+
+ public static Submodel createAsFacade(Map<String, Object> map) {
+ if (map == null) {
+ return null;
+ }
+
+ if (!isValid(map)) {
+ throw new MetamodelConstructionException(Submodel.class, map);
+ }
+
+ if (!map.containsKey(SUBMODELELEMENT)) {
+ map.put(SUBMODELELEMENT, new ArrayList<>());
+ }
+
+ return SubmodelElementMapCollectionConverter.mapToSM(map);
+ }
+
+ /**
+ * Check whether all mandatory elements for the metamodel
+ * exist in a map
+ * @return true/false
+ */
+ public static boolean isValid(Map<String, Object> map) {
+ return Identifiable.isValid(map);
+ }
+
+ @Override
+ public IReference getSemanticId() {
+ return HasSemantics.createAsFacade(this).getSemanticId();
+ }
+
+ public void setSemanticId(IReference ref) {
+ HasSemantics.createAsFacade(this).setSemanticId(ref);
+ }
+
+ @Override
+ public IAdministrativeInformation getAdministration() {
+ return Identifiable.createAsFacade(this, getKeyElement()).getAdministration();
+ }
+
+ @Override
+ public IIdentifier getIdentification() {
+ return Identifiable.createAsFacade(this, getKeyElement()).getIdentification();
+ }
+
+ public void setAdministration(AdministrativeInformation information) {
+ Identifiable.createAsFacade(this, getKeyElement()).setAdministration(information);
+ }
+
+ public void setIdentification(IIdentifier id) {
+ setIdentification(id.getIdType(), id.getId());
+ }
+
+ public void setIdentification(IdentifierType idType, String id) {
+ Identifiable.createAsFacadeNonStrict(this, getKeyElement()).setIdentification(idType, id);
+ }
+
+ @Override
+ public Collection<IReference> getDataSpecificationReferences() {
+ return HasDataSpecification.createAsFacade(this).getDataSpecificationReferences();
+ }
+
+ public void setDataSpecificationReferences(Collection<IReference> ref) {
+ HasDataSpecification.createAsFacade(this).setDataSpecificationReferences(ref);
+ }
+
+ @Override
+ public Collection<IEmbeddedDataSpecification> getEmbeddedDataSpecifications() {
+ return HasDataSpecification.createAsFacade(this).getEmbeddedDataSpecifications();
+ }
+
+ public void setEmbeddedDataSpecifications(Collection<IEmbeddedDataSpecification> embeddedDataSpecifications) {
+ HasDataSpecification.createAsFacade(this).setEmbeddedDataSpecifications(embeddedDataSpecifications);
+ }
+
+ @Override
+ public ModelingKind getModelingKind() {
+ return HasKind.createAsFacade(this).getModelingKind();
+ }
+
+ public void setModelingKind(ModelingKind kind) {
+ HasKind.createAsFacade(this).setModelingKind(kind);
+ }
+
+ @Override
+ public String getIdShort() {
+ return Referable.createAsFacade(this, getKeyElement()).getIdShort();
+ }
+
+ public void setIdShort(String id) {
+ Referable.createAsFacadeNonStrict(this, getKeyElement()).setIdShort(id);
+ }
+
+ public void setProperties(Map<String, IProperty> properties) {
+ // first, remove all properties
+ Set<Entry<String, ISubmodelElement>> elementSet = getSubmodelElements().entrySet();
+ for ( Iterator<Entry<String, ISubmodelElement>> iterator = elementSet.iterator(); iterator.hasNext(); ) {
+ Entry<String, ISubmodelElement> entry = iterator.next();
+ if (entry.getValue() instanceof IProperty) {
+ iterator.remove();
+ }
+ }
+ // then add all given data properties
+ properties.values().forEach(this::addSubmodelElement);
+ }
+
+ public void setOperations(Map<String, IOperation> operations) {
+ // first, remove all operations
+ Set<Entry<String, ISubmodelElement>> elementSet = getSubmodelElements().entrySet();
+ for (Iterator<Entry<String, ISubmodelElement>> iterator = elementSet.iterator(); iterator.hasNext();) {
+ Entry<String, ISubmodelElement> entry = iterator.next();
+ if (entry.getValue() instanceof IOperation) {
+ iterator.remove();
+ }
+ }
+ // then add all given operations
+ operations.values().forEach(this::addSubmodelElement);
+ }
+
+ @Override
+ public String getCategory() {
+ return Referable.createAsFacade(this, getKeyElement()).getCategory();
+ }
+
+ @Override
+ public LangStrings getDescription() {
+ return Referable.createAsFacade(this, getKeyElement()).getDescription();
+ }
+
+ @Override
+ public IReference getParent() {
+ return Referable.createAsFacade(this, getKeyElement()).getParent();
+ }
+
+ public void setCategory(String category) {
+ Referable.createAsFacade(this, getKeyElement()).setCategory(category);
+ }
+
+ public void setDescription(LangStrings description) {
+ Referable.createAsFacade(this, getKeyElement()).setDescription(description);
+ }
+
+ public void setParent(IReference obj) {
+ Referable.createAsFacade(this, getKeyElement()).setParent(obj);
+ }
+
+ private KeyElements getKeyElement() {
+ return KeyElements.SUBMODEL;
+ }
+
+ @Override
+ public void addSubmodelElement(ISubmodelElement element) {
+ if (element instanceof SubmodelElement) {
+ ((SubmodelElement) element).setParent(getReference());
+ }
+ getSubmodelElements().put(element.getIdShort(), element);
+ }
+
+ @Override
+ public Map<String, IProperty> getProperties() {
+ Map<String, IProperty> properties = new HashMap<>();
+ getSubmodelElements().values().forEach(e -> {
+ if (e instanceof IProperty) {
+ properties.put(e.getIdShort(), (IProperty) e);
+ }
+ });
+ return properties;
+ }
+
+ @Override
+ public Map<String, IOperation> getOperations() {
+ Map<String, IOperation> operations = new HashMap<>();
+ getSubmodelElements().values().forEach(e -> {
+ if (e instanceof IOperation) {
+ operations.put(e.getIdShort(), (IOperation) e);
+ }
+ });
+ return operations;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Map<String, ISubmodelElement> getSubmodelElements() {
+ return (Map<String, ISubmodelElement>) get(SUBMODELELEMENT);
+ }
+
+ @Override
+ public Map<String, Object> getValues() {
+ return SubmodelValuesHelper.getSubmodelValue(this);
+ }
+
+ @Override
+ public Collection<IConstraint> getQualifiers() {
+ return Qualifiable.createAsFacade(this).getQualifiers();
+ }
+
+ public void setQualifiers(Collection<IConstraint> qualifiers) {
+ Qualifiable.createAsFacade(this).setQualifiers(qualifiers);
+ }
+
+ @Override
+ public IReference getReference() {
+ return Identifiable.createAsFacade(this, getKeyElement()).getReference();
+ }
+
+ /**
+ * Retrieves an element from element collection
+ * @param id
+ * @return retrieved element
+ */
+ @Override
+ public ISubmodelElement getSubmodelElement(String id) {
+ Map<String, ISubmodelElement> submodelElems = getSubmodelElements();
+ return ElementContainerHelper.getElementById(submodelElems, id);
+ }
+
+ /**
+ * Deletes an element from element collection
+ * @param id
+ */
+ @Override
+ public void deleteSubmodelElement(String id) {
+ Map<String, ISubmodelElement> submodelElems = getSubmodelElements();
+ ElementContainerHelper.removeElementById(submodelElems, id);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationContent.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationContent.java
index 85de2d0..d1a43b4 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationContent.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationContent.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.dataspecification;
import java.util.Map;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationIEC61360.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationIEC61360.java
index 316aac1..4faeb68 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationIEC61360.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationIEC61360.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.dataspecification;
import java.util.Map;
@@ -23,8 +32,6 @@
* Creates an empty DataSpecificationIEC61360
*/
public DataSpecificationIEC61360() {
- // Add model type
- put(CONTENT, null);
put(DATASPECIFICATION, TEMPLATE_REFERENCE);
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationIEC61360Content.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationIEC61360Content.java
index 09121a3..d39e877 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationIEC61360Content.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationIEC61360Content.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.dataspecification;
import java.util.ArrayList;
@@ -37,22 +46,7 @@
/**
* Constructor
*/
- public DataSpecificationIEC61360Content() {
- // Default values
- put(PREFERREDNAME, null);
- put(SHORTNAME, null);
- put(UNIT, null);
- put(UNITID, null);
- put(SOURCEOFDEFINITION, null);
- put(SYMBOL, null);
- put(DATATYPE, null);
- put(DEFINITION, null);
- put(VALUEFORMAT, null);
- put(VALUELIST, null);
- put(VALUE, null);
- put(VALUEID, null);
- put(LEVELTYPE, null);
- }
+ public DataSpecificationIEC61360Content() {}
/**
* Constructor
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/EmbeddedDataSpecification.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/EmbeddedDataSpecification.java
index 37c31e0..2a0e4a4 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/EmbeddedDataSpecification.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/EmbeddedDataSpecification.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.dataspecification;
import java.util.Map;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/ValueReferencePair.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/ValueReferencePair.java
index c34aae7..d73393e 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/ValueReferencePair.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/ValueReferencePair.java
@@ -1,7 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.dataspecification;
import java.util.Map;
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IValueReferencePair;
import org.eclipse.basyx.submodel.metamodel.api.qualifier.IIdentifiable;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
@@ -25,10 +35,7 @@
/**
* Constructor
*/
- public ValueReferencePair() {
- setValue(null);
- setValueId(null);
- }
+ public ValueReferencePair() {}
/**
* Constructs a reference based on an {@link IIdentifiable} and additional
@@ -54,11 +61,28 @@
if (map == null) {
return null;
}
-
+
+ if (!isValid(map)) {
+ throw new MetamodelConstructionException(ValueReferencePair.class, map);
+ }
+
ValueReferencePair ret = new ValueReferencePair();
ret.setMap(map);
return ret;
}
+
+ /**
+ * Check whether all mandatory elements for the metamodel
+ * exist in a map
+ * @return true/false
+ */
+ @SuppressWarnings("unchecked")
+ public static boolean isValid(Map<String, Object> map) {
+ return map != null &&
+ map.containsKey(VALUE) &&
+ map.containsKey(VALUEID) &&
+ Reference.isValid((Map<String, Object>)map.get(VALUEID));
+ }
@Override
@SuppressWarnings("unchecked")
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/helper/ElementContainerHelper.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/helper/ElementContainerHelper.java
new file mode 100644
index 0000000..2ce6438
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/helper/ElementContainerHelper.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.map.helper;
+
+import java.util.Map;
+
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+
+/**
+ * Contains helper methods of element container
+ * @author haque
+ *
+ */
+public class ElementContainerHelper {
+
+ public static ISubmodelElement getElementById(Map<String, ISubmodelElement> elements, String id) {
+ if (elements != null && elements.containsKey(id)) {
+ return elements.get(id);
+ }
+ throw new ResourceNotFoundException("Submodel Element with id: " + id + " does not exist");
+ }
+
+ public static void removeElementById(Map<String, ISubmodelElement> elements, String id) {
+ if (elements != null && elements.containsKey(id)) {
+ elements.remove(id);
+ return;
+ }
+ throw new ResourceNotFoundException("Submodel Element with id: " + id + " does not exist");
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/identifier/Identifier.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/identifier/Identifier.java
index cbb20b4..7eddd66 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/identifier/Identifier.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/identifier/Identifier.java
@@ -1,7 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.identifier;
import java.util.Map;
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
import org.eclipse.basyx.vab.model.VABModelMap;
@@ -37,11 +47,24 @@
if (map == null) {
return null;
}
-
+
+ if (!isValid(map)) {
+ throw new MetamodelConstructionException(Identifier.class, map);
+ }
+
Identifier ret = new Identifier();
ret.setMap(map);
return ret;
}
+
+ /**
+ * Check whether all mandatory elements for the metamodel
+ * exist in a map
+ * @return true/false
+ */
+ public static boolean isValid(Map<String, Object> map) {
+ return map != null && map.containsKey(IDTYPE) && map.containsKey(ID);
+ }
/**
* Constructor that accepts parameter
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/modeltype/ModelType.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/modeltype/ModelType.java
index cd77177..d6cf8ed 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/modeltype/ModelType.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/modeltype/ModelType.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.modeltype;
import java.util.HashMap;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/parts/ConceptDescription.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/parts/ConceptDescription.java
index 986e30c..a2475e0 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/parts/ConceptDescription.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/parts/ConceptDescription.java
@@ -1,9 +1,19 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.parts;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IEmbeddedDataSpecification;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
@@ -42,6 +52,17 @@
// Add attributes
put(ISCASEOF, new HashSet<Reference>());
}
+
+ /**
+ * Constructor accepting only mandatory attribute
+ * @param idShort
+ * @param identification
+ */
+ public ConceptDescription(String idShort, IIdentifier identification) {
+ this();
+ setIdentification(identification.getIdType(), identification.getId());
+ setIdShort(idShort);
+ }
/**
* Creates a DataSpecificationIEC61360 object from a map
@@ -55,10 +76,23 @@
if (map == null) {
return null;
}
-
+
+ if (!isValid(map)) {
+ throw new MetamodelConstructionException(ConceptDescription.class, map);
+ }
+
ConceptDescription ret = new ConceptDescription();
ret.setMap(map);
- return ret;
+ return ret;
+ }
+
+ /**
+ * Check whether all mandatory elements for the metamodel
+ * exist in a map
+ * @return true/false
+ */
+ public static boolean isValid(Map<String, Object> map) {
+ return Identifiable.isValid(map);
}
@Override
@@ -94,7 +128,7 @@
}
public void setIdentification(IdentifierType idType, String id) {
- Identifiable.createAsFacade(this, getKeyElement()).setIdentification(idType, id);
+ Identifiable.createAsFacadeNonStrict(this, getKeyElement()).setIdentification(idType, id);
}
@Override
@@ -126,7 +160,7 @@
}
public void setIdShort(String idShort) {
- Referable.createAsFacade(this, getKeyElement()).setIdShort(idShort);
+ Referable.createAsFacadeNonStrict(this, getKeyElement()).setIdShort(idShort);
}
@@ -152,4 +186,4 @@
return Identifiable.createAsFacade(this, getKeyElement()).getReference();
}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/AdministrativeInformation.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/AdministrativeInformation.java
index 5235bc7..e654e3e 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/AdministrativeInformation.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/AdministrativeInformation.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.qualifier;
import java.util.Collection;
@@ -8,6 +17,8 @@
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
import org.eclipse.basyx.vab.model.VABModelMap;
+import com.google.common.base.Strings;
+
/**
* AdministrativeInformation class
*
@@ -26,9 +37,6 @@
// Add qualifier
putAll(new HasDataSpecification());
- // Default values
- put(VERSION, "");
- put(REVISION, "");
}
/**
@@ -38,9 +46,7 @@
// Add qualifier
putAll(new HasDataSpecification());
- // Default values
- put(VERSION, version);
- put(REVISION, revision);
+ setVersionInformation(version, revision);
}
/**
@@ -78,8 +84,29 @@
public void setEmbeddedDataSpecifications(Collection<IEmbeddedDataSpecification> embeddedDataSpecifications) {
HasDataSpecification.createAsFacade(this).setEmbeddedDataSpecifications(embeddedDataSpecifications);
}
+
+ /**
+ * Sets version and revision
+ * @param version
+ * @param revision
+ *
+ * @throws RuntimeException when revision is given without a valid version
+ */
+ public void setVersionInformation(String version, String revision) {
+ setVersion(version);
+ if (!Strings.isNullOrEmpty(revision)) {
+ if (Strings.isNullOrEmpty(version)) {
+ throw new RuntimeException("revision cannot be set while version is not set");
+ }
+ }
+ setRevision(revision);
+ }
- public void setVersion(String version) {
+ /**
+ *
+ * @param version
+ */
+ private void setVersion(String version) {
put(AdministrativeInformation.VERSION, version);
}
@@ -88,7 +115,11 @@
return (String) get(AdministrativeInformation.VERSION);
}
- public void setRevision(String revision) {
+ /**
+ *
+ * @param revision
+ */
+ private void setRevision(String revision) {
put(AdministrativeInformation.REVISION, revision);
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/HasDataSpecification.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/HasDataSpecification.java
index 2a29a69..aaa624a 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/HasDataSpecification.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/HasDataSpecification.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.qualifier;
import java.util.Collection;
@@ -69,7 +78,7 @@
@Override
public Collection<IEmbeddedDataSpecification> getEmbeddedDataSpecifications() {
Collection<Map<String, Object>> collection = (Collection<Map<String, Object>>) get(EMBEDDEDDATASPECIFICATIONS);
- return collection.stream().map(EmbeddedDataSpecification::createAsFacade).collect(Collectors.toSet());
+ return collection == null ? new HashSet<IEmbeddedDataSpecification>() : collection.stream().map(EmbeddedDataSpecification::createAsFacade).collect(Collectors.toSet());
}
public void setEmbeddedDataSpecifications(Collection<IEmbeddedDataSpecification> embeddedDataSpecifications) {
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/HasSemantics.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/HasSemantics.java
index 233bd6b..e835cb6 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/HasSemantics.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/HasSemantics.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.qualifier;
import java.util.Map;
@@ -19,16 +28,13 @@
/**
* Constructor
*/
- public HasSemantics() {
- // Default values
- put(SEMANTICID, null);
- }
+ public HasSemantics() {}
/**
* Constructor
*/
public HasSemantics(IReference ref) {
- this.setSemanticID(ref);
+ this.setSemanticId(ref);
}
/**
@@ -54,7 +60,7 @@
return Reference.createAsFacade((Map<String, Object>) get(HasSemantics.SEMANTICID));
}
- public void setSemanticID(IReference ref) {
+ public void setSemanticId(IReference ref) {
put(HasSemantics.SEMANTICID, ref);
}
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/Identifiable.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/Identifiable.java
index d6c6807..e0b8e43 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/Identifiable.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/Identifiable.java
@@ -1,7 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.qualifier;
import java.util.Map;
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
import org.eclipse.basyx.submodel.metamodel.api.qualifier.IAdministrativeInformation;
@@ -27,12 +37,19 @@
public Identifiable() {
// Add qualifier
putAll(new Referable());
-
- // Administrative information of an element. (AdministrativeInformation)
- put(ADMINISTRATION, new AdministrativeInformation());
// The globally unique identification of an element. (Identificator)
put(IDENTIFICATION, new Identifier());
}
+
+ /**
+ * Constructor with mandatory attribute
+ * @param idShort
+ * @param identification
+ */
+ public Identifiable(String idShort, IIdentifier identification) {
+ super(idShort);
+ setIdentification(identification.getIdType(), identification.getId());
+ }
/**
* Constructor that accepts values for most relevant properties
@@ -58,7 +75,41 @@
if (map == null) {
return null;
}
-
+
+ if (!isValid(map)) {
+ throw new MetamodelConstructionException(Identifiable.class, map);
+ }
+
+ Identifiable ret = new Identifiable();
+ ret.setMap(map);
+ ret.setElementType(type);
+ return ret;
+ }
+
+ /**
+ * Check whether all mandatory elements for the metamodel
+ * exist in a map
+ * @return true/false
+ */
+ @SuppressWarnings("unchecked")
+ public static boolean isValid(Map<String, Object> map) {
+ return Referable.isValid(map) &&
+ map.containsKey(Identifiable.IDENTIFICATION) &&
+ Identifier.isValid((Map<String, Object>)map.get(Identifiable.IDENTIFICATION));
+ }
+
+ /**
+ * Creates an Identifiable object from a map
+ * Without checking mandatory attributes present
+ * @param map
+ * @param type
+ * @return
+ */
+ public static Identifiable createAsFacadeNonStrict(Map<String, Object> map, KeyElements type) {
+ if (map == null) {
+ return null;
+ }
+
Identifiable ret = new Identifiable();
ret.setMap(map);
ret.setElementType(type);
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/LangString.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/LangString.java
index c22444c..f1f84be 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/LangString.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/LangString.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.qualifier;
import java.util.Map;
@@ -12,7 +21,7 @@
*/
public class LangString extends VABModelMap<Object> {
private static final String LANGUAGE = "language";
- private static final String DESCRIPTION = "description";
+ private static final String DESCRIPTION = "text";
private LangString() {
}
@@ -44,6 +53,17 @@
return ret;
}
+ @SuppressWarnings("unchecked")
+ public static boolean isLangString(Object value) {
+ if(!(value instanceof Map<?, ?>)) {
+ return false;
+ }
+
+ Map<String, Object> map = (Map<String, Object>) value;
+
+ return map.get(LANGUAGE) instanceof String && map.get(DESCRIPTION) instanceof String;
+ }
+
/**
* Get Language of the langString
* @return Language
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/LangStrings.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/LangStrings.java
index ba12fe6..c3782d1 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/LangStrings.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/LangStrings.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.qualifier;
import java.util.Collection;
@@ -65,6 +74,17 @@
}
return ret;
}
+
+ @SuppressWarnings("unchecked")
+ public static boolean isLangStrings(Object value) {
+ if(!(value instanceof Collection<?>)) {
+ return false;
+ }
+
+ Collection<Map<String, Object>> collection = (Collection<Map<String, Object>>) value;
+
+ return collection.stream().allMatch(LangString::isLangString);
+ }
/**
*
@@ -92,4 +112,4 @@
}
return languageSet;
}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/Referable.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/Referable.java
index 476aa5c..329ad4e 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/Referable.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/Referable.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.qualifier;
import java.util.ArrayList;
@@ -5,7 +14,9 @@
import java.util.List;
import java.util.Map;
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
import org.eclipse.basyx.submodel.metamodel.api.qualifier.IReferable;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.IdShortValidator;
import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
@@ -13,6 +24,8 @@
import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
import org.eclipse.basyx.vab.model.VABModelMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Referable class
@@ -21,6 +34,8 @@
*
*/
public class Referable extends VABModelMap<Object> implements IReferable {
+ private static Logger logger = LoggerFactory.getLogger(Referable.class);
+
public static final String IDSHORT="idShort";
public static final String CATEGORY="category";
@@ -37,16 +52,14 @@
public Referable() {
// Identifies an element within its name space (String)
put(IDSHORT, "");
- // Coded value that gives further meta information w.r.t. to the type of the
- // element. It affects the
- // expected existence of attributes and the applicability of constraints.
- // (String)
- put(CATEGORY, "");
- // Description or comments on the element (String)
-
- put(DESCRIPTION, new LangStrings());
- // Reference to the parent of this element (Referable)
- put(PARENT, null);
+ }
+
+ /**
+ * Constructor with mandatory attribute
+ * @param idShort
+ */
+ public Referable(String idShort) {
+ setIdShort(idShort);
}
/**
@@ -68,8 +81,6 @@
put(CATEGORY, category);
// Description or comments on the element
put(DESCRIPTION, description);
- // Reference to the parent of this element (Referable)
- put(PARENT, null);
}
/**
@@ -83,12 +94,43 @@
if (map == null) {
return null;
}
-
+
+ if (!isValid(map)) {
+ throw new MetamodelConstructionException(Referable.class, map);
+ }
Referable ret = new Referable();
ret.setMap(map);
ret.setElementType(type);
- return ret;
+ return ret;
+ }
+
+ /**
+ * Check whether all mandatory elements for the metamodel
+ * exist in a map
+ * @return true/false
+ */
+ public static boolean isValid(Map<String, Object> map) {
+ return map != null && map.get(Referable.IDSHORT) != null;
+ }
+
+ /**
+ * Creates a Referable object from a map
+ * without checking the mandatory attributes present
+ * @param map
+ * @param type
+ * @return
+ */
+ public static Referable createAsFacadeNonStrict(Map<String, Object> map, KeyElements type) {
+ if (map == null) {
+ return null;
+ }
+
+ Referable ret = new Referable();
+ ret.setMap(map);
+ ret.setElementType(type);
+
+ return ret;
}
@Override
@@ -114,6 +156,15 @@
}
public void setIdShort(String idShort) {
+ if(!IdShortValidator.isValid(idShort)) {
+ /*
+ * Currently, the AASX package explorer does support creating arbitrary
+ * idShorts. Thus, if this is an exception, AASX files created with the AASX
+ * package explorer may not be loadable
+ * TODO: Replace this with a RuntimeException
+ */
+ logger.warn("The passed idShort " + idShort + " is not valid! It has to satisfy the RegEx " + IdShortValidator.IDSHORT_REGEX);
+ }
put(Referable.IDSHORT, idShort);
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/haskind/HasKind.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/haskind/HasKind.java
index 28946ad..a1c535f 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/haskind/HasKind.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/haskind/HasKind.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.qualifier.haskind;
import java.util.Map;
@@ -18,11 +27,7 @@
/**
* Constructor
*/
- public HasKind() {
- // Default value
-
- put(KIND, null);
- }
+ public HasKind() {}
/**
* Constructor that takes
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Constraint.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Constraint.java
index ac188a5..c7c78f6 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Constraint.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Constraint.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable;
import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IConstraint;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Formula.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Formula.java
index c676f9a..9865766 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Formula.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Formula.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable;
import java.util.Collection;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Qualifiable.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Qualifiable.java
index 35da4c2..d3b1c7f 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Qualifiable.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Qualifiable.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable;
import java.util.Collection;
@@ -16,16 +25,12 @@
*
*/
public class Qualifiable extends VABModelMap<Object> implements IQualifiable {
- public static final String CONSTRAINTS = "constraints";
+ public static final String QUALIFIERS = "qualifiers";
/**
* Constructor
*/
- public Qualifiable() {
- // The instance of an element may be further qualified by one or more
- // qualifiers.
- put(CONSTRAINTS, null);
- }
+ public Qualifiable() {}
/**
* Constructor
@@ -38,16 +43,16 @@
// The instance of an element may be further qualified by one or more
// qualifiers.
- put(CONSTRAINTS, qualifiers);
+ put(QUALIFIERS, qualifiers);
}
/**
* Constructor
*/
- public Qualifiable(Collection<Constraint> qualifier) {
+ public Qualifiable(Collection<Constraint> qualifiers) {
// The instance of an element may be further qualified by one or more
// qualifiers.
- put(CONSTRAINTS, qualifier);
+ put(QUALIFIERS, qualifiers);
}
/**
@@ -67,15 +72,15 @@
return ret;
}
- public void setQualifier(Collection<IConstraint> qualifiers) {
- put(Qualifiable.CONSTRAINTS, qualifiers);
+ public void setQualifiers(Collection<IConstraint> qualifiers) {
+ put(Qualifiable.QUALIFIERS, qualifiers);
}
@SuppressWarnings("unchecked")
@Override
- public Collection<IConstraint> getQualifier() {
+ public Collection<IConstraint> getQualifiers() {
// Transform set of maps to set of IConstraints
- Collection<Map<String, Object>> set = (Collection<Map<String, Object>>) get(Qualifiable.CONSTRAINTS);
+ Collection<Map<String, Object>> set = (Collection<Map<String, Object>>) get(Qualifiable.QUALIFIERS);
Collection<IConstraint> ret = new HashSet<>();
if (set != null) {
for (Map<String, Object> m : set) {
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Qualifier.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Qualifier.java
index f5aa959..15d91ac 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Qualifier.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Qualifier.java
@@ -1,12 +1,24 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable;
import java.util.Map;
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IQualifier;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueTypeHelper;
/**
* Qualifier class
@@ -33,24 +45,20 @@
public Qualifier() {
// Add model type
putAll(new ModelType(MODELTYPE));
-
- // Add all attributes from HasSemantics
- this.putAll(new HasSemantics());
-
- // Default values
- put(TYPE, "");
- put(VALUE, null);
- put(VALUEID, null);
- put(VALUETYPE, "");
+ }
+
+ /**
+ * Constructor accepting mandatory attributes
+ * @param type
+ * @param valueType
+ */
+ public Qualifier(String type, String valueType) {
+ this(type, null, valueType, null);
}
public Qualifier(String type, String value, String valueType, Reference valueId) {
- // Add all attributes from HasSemantics
- this.putAll(new HasSemantics());
-
- // Default values
put(TYPE,type);
- put(VALUE, value);
+ put(VALUE, ValueTypeHelper.prepareForSerialization(value));
put(VALUEID, valueId);
put(VALUETYPE, valueType);
}
@@ -66,11 +74,26 @@
if (map == null) {
return null;
}
-
+
+ if (!isValid(map)) {
+ throw new MetamodelConstructionException(Qualifier.class, map);
+ }
+
Qualifier ret = new Qualifier();
ret.setMap(map);
return ret;
}
+
+ /**
+ * Check whether all mandatory elements for the metamodel
+ * exist in a map
+ * @return true/false
+ */
+ public static boolean isValid(Map<String, Object> map) {
+ return map != null &&
+ map.containsKey(TYPE) &&
+ map.containsKey(VALUETYPE);
+ }
public void setType(String obj) {
put(Qualifier.TYPE, obj);
@@ -81,13 +104,22 @@
return (String) get(Qualifier.TYPE);
}
- public void setValue(String obj) {
- put(Qualifier.VALUE, obj);
+ public void setValue(Object obj) {
+ put(Qualifier.VALUE, ValueTypeHelper.prepareForSerialization(obj));
+ // Value type is only set if it is not set before
+ if(getValueType() == null) {
+ put(Qualifier.VALUETYPE, ValueTypeHelper.getType(obj).toString());
+ }
}
@Override
- public String getValue() {
- return (String) get(Qualifier.VALUE);
+ public Object getValue() {
+ Object value = get(Qualifier.VALUE);
+ if(value instanceof String) {
+ return ValueTypeHelper.getJavaObject(value, getValueType());
+ }else {
+ return value;
+ }
}
public void setValueId(IReference obj) {
@@ -100,13 +132,13 @@
return Reference.createAsFacade((Map<String, Object>) get(Qualifier.VALUEID));
}
- public void setValueType(String obj) {
- put(Qualifier.VALUETYPE, obj);
+ public void setValueType(ValueType obj) {
+ put(Qualifier.VALUETYPE, obj.toString());
}
@Override
- public String getValueType() {
- return (String) get(Qualifier.VALUETYPE);
+ public ValueType getValueType() {
+ return ValueTypeHelper.readTypeDef(get(Qualifier.VALUETYPE));
}
@Override
@@ -114,7 +146,7 @@
return HasSemantics.createAsFacade(this).getSemanticId();
}
- public void setSemanticID(IReference ref) {
- HasSemantics.createAsFacade(this).setSemanticID(ref);
+ public void setSemanticId(IReference ref) {
+ HasSemantics.createAsFacade(this).setSemanticId(ref);
}
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/Key.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/Key.java
index d6dc50d..9424e61 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/Key.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/Key.java
@@ -1,7 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.reference;
import java.util.Map;
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
@@ -74,11 +84,53 @@
if (map == null) {
return null;
}
-
+
+ if (!isValid(map)) {
+ throw new MetamodelConstructionException(Key.class, map);
+ }
+
Key ret = new Key();
ret.setMap(map);
return ret;
}
+
+ /**
+ * Check whether all mandatory elements for the metamodel
+ * exist in a map
+ * @return true/false
+ */
+ public static boolean isValid(Map<String, Object> map) {
+ return map != null &&
+ map.containsKey(TYPE) &&
+ map.containsKey(LOCAL) &&
+ map.containsKey(VALUE) &&
+ map.containsKey(IDTYPE);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static boolean isKey(Object value) {
+ if(!(value instanceof Map<?, ?>)) {
+ return false;
+ }
+
+ Map<String, Object> map = (Map<String, Object>) value;
+
+ if(!(map.get(LOCAL) instanceof Boolean && map.get(VALUE) instanceof String
+ && map.get(IDTYPE) instanceof String && map.get(TYPE) instanceof String)) {
+ return false;
+ }
+
+ try {
+ // Try to convert the Strings to Enum-Types
+ // If that fails an Exception is thrown
+ KeyType.fromString((String) map.get(IDTYPE));
+ KeyElements.fromString((String) map.get(TYPE));
+ } catch (IllegalArgumentException e) {
+ return false;
+ }
+
+ return true;
+ }
@Override
public KeyElements getType() {
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/Reference.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/Reference.java
index d7f7717..23502c0 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/Reference.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/Reference.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.reference;
import java.util.ArrayList;
@@ -6,6 +15,7 @@
import java.util.List;
import java.util.Map;
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
import org.eclipse.basyx.submodel.metamodel.api.qualifier.IIdentifiable;
import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
@@ -87,11 +97,67 @@
if (map == null) {
return null;
}
-
+
+ if (!isValid(map)) {
+ throw new MetamodelConstructionException(Reference.class, map);
+ }
+
Reference ret = new Reference();
ret.setMap(map);
return ret;
}
+
+ /**
+ * Check whether all mandatory elements for the metamodel
+ * exist in a map
+ * @return true/false
+ */
+ @SuppressWarnings("unchecked")
+ public static boolean isValid(Map<String, Object> map) {
+ if (map != null && map.containsKey(Reference.KEY)) {
+ Collection<Map<String, Object>> keysCollection = (Collection<Map<String, Object>>)map.get(Reference.KEY);
+ for (Map<String, Object> key : keysCollection) {
+ if (!Key.isValid(key)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Creates a Reference object from a map
+ * without checking mandatory attributes present
+ *
+ * @param obj
+ * a Reference object as raw map
+ * @return a Reference object, that behaves like a facade for the given map
+ */
+ public static Reference createAsFacadeNonStrict(Map<String, Object> map) {
+ if (map == null) {
+ return null;
+ }
+
+ Reference ret = new Reference();
+ ret.setMap(map);
+ return ret;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static boolean isReference(Object value) {
+ if(!(value instanceof Map<?, ?>)) {
+ return false;
+ }
+
+ Map<String, Object> map = (Map<String, Object>) value;
+
+ if(!(map.get(KEY) instanceof Collection<?>)) {
+ return false;
+ }
+
+ return ((Collection<Key>) map.get(KEY)).stream().allMatch(Key::isKey);
+ }
@SuppressWarnings("unchecked")
@Override
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/ReferenceHelper.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/ReferenceHelper.java
index 8be4399..de82c04 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/ReferenceHelper.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/ReferenceHelper.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.reference;
import java.util.Collection;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/SubmodelElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/SubmodelElement.java
index f1a81bb..6d151ae 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/SubmodelElement.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/SubmodelElement.java
@@ -1,14 +1,25 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.submodelelement;
import java.util.Collection;
import java.util.Map;
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IEmbeddedDataSpecification;
import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IConstraint;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.SubmodelElementIdShortBlacklist;
import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
@@ -31,12 +42,16 @@
protected SubmodelElement() {
// Add model type
putAll(new ModelType(MODELTYPE));
+ setModelingKind(ModelingKind.INSTANCE);
+ }
- putAll(new HasDataSpecification());
- putAll(new Referable());
- putAll(new Qualifiable());
- putAll(new HasSemantics());
- putAll(new HasKind());
+ /**
+ * Constructor with only mandatory attribute
+ * @param idShort
+ */
+ protected SubmodelElement(String idShort) {
+ this();
+ setIdShort(idShort);
}
/**
@@ -46,10 +61,27 @@
* @return a SubmodelElement object, that behaves like a facade for the given map
*/
public static SubmodelElement createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (!isValid(obj)) {
+ throw new MetamodelConstructionException(SubmodelElement.class, obj);
+ }
+
SubmodelElement ret = new SubmodelElement();
ret.setMap(obj);
return ret;
}
+
+ /**
+ * Check whether all mandatory elements for the metamodel
+ * exist in a map
+ * @return true/false
+ */
+ public static boolean isValid(Map<String, Object> obj) {
+ return Referable.isValid(obj);
+ }
@Override
public Collection<IReference> getDataSpecificationReferences() {
@@ -94,7 +126,11 @@
}
public void setIdShort(String idShort) {
- Referable.createAsFacade(this, getKeyElement()).setIdShort(idShort);
+ if (SubmodelElementIdShortBlacklist.isBlacklisted(idShort)) {
+ throw new RuntimeException("The passed idShort " + idShort + " is blacklisted.");
+ }
+
+ Referable.createAsFacadeNonStrict(this, getKeyElement()).setIdShort(idShort);
}
public void setCategory(String category) {
@@ -109,13 +145,13 @@
Referable.createAsFacade(this, getKeyElement()).setParent(obj);
}
- public void setQualifier(Collection<IConstraint> qualifiers) {
- Qualifiable.createAsFacade(this).setQualifier(qualifiers);
+ public void setQualifiers(Collection<IConstraint> qualifiers) {
+ Qualifiable.createAsFacade(this).setQualifiers(qualifiers);
}
@Override
- public Collection<IConstraint> getQualifier() {
- return Qualifiable.createAsFacade(this).getQualifier();
+ public Collection<IConstraint> getQualifiers() {
+ return Qualifiable.createAsFacade(this).getQualifiers();
}
@Override
@@ -123,8 +159,8 @@
return HasSemantics.createAsFacade(this).getSemanticId();
}
- public void setSemanticID(IReference ref) {
- HasSemantics.createAsFacade(this).setSemanticID(ref);
+ public void setSemanticId(IReference ref) {
+ HasSemantics.createAsFacade(this).setSemanticId(ref);
}
@Override
@@ -146,4 +182,21 @@
public IReference getReference() {
return Referable.createAsFacade(this, getKeyElement()).getReference();
}
+
+ @Override
+ public Object getValue() {
+ throw new UnsupportedOperationException("getValue is only possible in specific Element");
+ }
+
+ @Override
+ public void setValue(Object value) {
+ throw new UnsupportedOperationException("setValue is only possible in specific Element");
+ }
+
+ public SubmodelElement getLocalCopy() {
+ // Return a shallow copy
+ SubmodelElement copy = new SubmodelElement();
+ copy.putAll(this);
+ return copy;
+ }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/SubmodelElementCollection.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/SubmodelElementCollection.java
index 4047e14..df8a35b 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/SubmodelElementCollection.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/SubmodelElementCollection.java
@@ -1,18 +1,30 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.submodelelement;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.IElementContainer;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
-import org.eclipse.basyx.submodel.metamodel.facade.submodelelement.SubmodelElementFacadeFactory;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.helper.ElementContainerHelper;
import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
@@ -27,7 +39,7 @@
* @author schnicke
*
*/
-public class SubmodelElementCollection extends SubmodelElement implements ISubmodelElementCollection {
+public class SubmodelElementCollection extends SubmodelElement implements ISubmodelElementCollection, IElementContainer {
public static final String ORDERED = "ordered";
public static final String ALLOWDUPLICATES = "allowDuplicates";
public static final String MODELTYPE = "SubmodelElementCollection";
@@ -41,10 +53,25 @@
putAll(new ModelType(MODELTYPE));
// Put attributes
- put(Property.VALUE, new ArrayList<>());
+ put(Property.VALUE, new HashMap<>());
put(ORDERED, true);
put(ALLOWDUPLICATES, true);
}
+
+ /**
+ * Constructor with only mandatory attribute
+ * @param idShort
+ */
+ public SubmodelElementCollection(String idShort) {
+ super(idShort);
+ // Add model type
+ putAll(new ModelType(MODELTYPE));
+
+ // Put attributes
+ setValue(new ArrayList<>());
+ setOrdered(true);
+ setAllowDuplicates(true);
+ }
/**
*
@@ -63,7 +90,7 @@
putAll(new ModelType(MODELTYPE));
// Put attributes
- put(Property.VALUE, value);
+ put(Property.VALUE, SubmodelElementMapCollectionConverter.convertCollectionToIDMap(value));
put(ORDERED, ordered);
put(ALLOWDUPLICATES, allowDuplicates);
}
@@ -75,9 +102,24 @@
* @return a SubmodelElementCollection object, that behaves like a facade for the given map
*/
public static SubmodelElementCollection createAsFacade(Map<String, Object> obj) {
- SubmodelElementCollection ret = new SubmodelElementCollection();
- ret.setMap(obj);
- return ret;
+ if (obj == null) {
+ return null;
+ }
+
+ if (!isValid(obj)) {
+ throw new MetamodelConstructionException(SubmodelElementCollection.class, obj);
+ }
+
+ return SubmodelElementMapCollectionConverter.mapToSmECollection(obj);
+ }
+
+ /**
+ * Check whether all mandatory elements for the metamodel
+ * exist in a map
+ * @return true/false
+ */
+ public static boolean isValid(Map<String, Object> obj) {
+ return SubmodelElement.isValid(obj);
}
/**
@@ -86,8 +128,8 @@
public static boolean isSubmodelElementCollection(Map<String, Object> map) {
String modelType = ModelType.createAsFacade(map).getName();
// Either model type is set or the element type specific attributes are contained (fallback)
- return MODELTYPE.equals(modelType)
- || (map.containsKey(Property.VALUE) && map.containsKey(ORDERED) && map.containsKey(ALLOWDUPLICATES));
+ return MODELTYPE.equals(modelType) || (modelType == null
+ && (map.containsKey(Property.VALUE) && map.containsKey(ORDERED) && map.containsKey(ALLOWDUPLICATES)));
}
/**
@@ -96,11 +138,12 @@
* @param elem
*/
@SuppressWarnings("unchecked")
- public void addElement(ISubmodelElement elem) {
+ @Override
+ public void addSubmodelElement(ISubmodelElement elem) {
if (elem instanceof SubmodelElement) {
((SubmodelElement) elem).setParent(getReference());
}
- ((List<Object>) get(Property.VALUE)).add(elem);
+ ((Map<String, ISubmodelElement>) get(Property.VALUE)).put(elem.getIdShort(), elem);
}
@Override
@@ -129,20 +172,14 @@
return Referable.createAsFacade(this, getKeyElement()).getDescription();
}
- public void setValue(Collection<ISubmodelElement> value) {
- put(Property.VALUE, value);
+ @Override
+ public void setValue(Object value) {
+ put(Property.VALUE, SubmodelElementMapCollectionConverter.convertCollectionToIDMap(value));
}
@Override
- @SuppressWarnings("unchecked")
public Collection<ISubmodelElement> getValue() {
- Collection<ISubmodelElement> ret = new ArrayList<>();
- Collection<Object> smElems = (ArrayList<Object>) get(Property.VALUE);
- for(Object smElemO: smElems) {
- Map<String, Object> smElem = (Map<String, Object>) smElemO;
- ret.add(SubmodelElementFacadeFactory.createSubmodelElement(smElem));
- }
- return ret;
+ return Collections.unmodifiableList(new ArrayList<>((getSubmodelElements()).values()));
}
public void setOrdered(boolean value) {
@@ -164,38 +201,31 @@
}
public void setElements(Map<String, ISubmodelElement> value) {
- put(Property.VALUE, value.values());
- }
-
- public void setElements(Collection<ISubmodelElement> value) {
put(Property.VALUE, value);
}
- @Override
+ public void setElements(Collection<ISubmodelElement> value) {
+ put(Property.VALUE, SubmodelElementMapCollectionConverter.convertCollectionToIDMap(value));
+ }
+
@SuppressWarnings("unchecked")
+ @Override
public Map<String, ISubmodelElement> getSubmodelElements() {
- Map<String, ISubmodelElement> ret = new HashMap<>();
- Collection<Object> smElems = (Collection<Object>) get(Property.VALUE);
- for(Object smElemO: smElems) {
- Map<String, Object> smElem = (Map<String, Object>) smElemO;
- ret.put((String) smElem.get(Referable.IDSHORT), SubmodelElementFacadeFactory.createSubmodelElement(smElem));
- }
- return ret;
+ return (Map<String, ISubmodelElement>) get(Property.VALUE);
}
@SuppressWarnings("unchecked")
@Override
public Map<String, IProperty> getProperties() {
Map<String, IProperty> ret = new HashMap<>();
- Collection<Object> smElems = (Collection<Object>) get(Property.VALUE);
- for (Object smElemO : smElems) {
- Map<String, Object> smElem = (Map<String, Object>) smElemO;
- if (Property.isProperty(smElem)) {
- String idShort = Referable.createAsFacade(smElem, KeyElements.DATAELEMENT).getIdShort();
- IProperty dataElement = (IProperty) SubmodelElementFacadeFactory.createSubmodelElement(smElem);
- ret.put(idShort, dataElement);
+ Map<String, ISubmodelElement> smElems = (Map<String, ISubmodelElement>) get(Property.VALUE);
+
+ for(ISubmodelElement smElement: smElems.values()) {
+ if (Property.isProperty((Map<String, Object>) smElement)) {
+ ret.put(smElement.getIdShort(), (IProperty) smElement);
}
}
+
return ret;
}
@@ -203,19 +233,56 @@
@Override
public Map<String, IOperation> getOperations() {
Map<String, IOperation> ret = new HashMap<>();
- Collection<Object> smElems = (Collection<Object>) get(Property.VALUE);
- for (Object smElemO : smElems) {
- Map<String, Object> smElem = (Map<String, Object>) smElemO;
- if (Operation.isOperation(smElem)) {
- String idShort = Referable.createAsFacade(smElem, KeyElements.OPERATION).getIdShort();
- ret.put(idShort, Operation.createAsFacade(smElem));
+ Map<String, ISubmodelElement> smElems = (Map<String, ISubmodelElement>) get(Property.VALUE);
+
+ for(ISubmodelElement smElement: smElems.values()) {
+ if (Operation.isOperation(smElement)) {
+ ret.put(smElement.getIdShort(), (IOperation) smElement);
}
}
+
return ret;
}
+
+ /**
+ * Retrieves an element from element collection
+ * @param id
+ * @return retrieved element
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public ISubmodelElement getSubmodelElement(String id) {
+ Map<String, ISubmodelElement> submodelElems = (Map<String, ISubmodelElement>) get(Property.VALUE);
+ return ElementContainerHelper.getElementById(submodelElems, id);
+ }
+
+ /**
+ * Deletes an element from element collection
+ * @param id
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public void deleteSubmodelElement(String id) {
+ Map<String, ISubmodelElement> submodelElems = (Map<String, ISubmodelElement>) get(Property.VALUE);
+ ElementContainerHelper.removeElementById(submodelElems, id);
+ }
@Override
protected KeyElements getKeyElement() {
return KeyElements.SUBMODELELEMENTCOLLECTION;
}
+
+ @Override
+ public SubmodelElementCollection getLocalCopy() {
+ // Create a shallow copy
+ SubmodelElementCollection copy = new SubmodelElementCollection();
+ copy.putAll(this);
+ // Then clone all submodelElements
+ Collection<ISubmodelElement> value = getValue();
+ Collection<ISubmodelElement> clonedValue = new ArrayList<>();
+ value.forEach(element -> clonedValue.add(element.getLocalCopy()));
+ // And return this copy with the cloned values
+ copy.setValue(clonedValue);
+ return copy;
+ }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/Blob.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/Blob.java
index ef72c24..2926c82 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/Blob.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/Blob.java
@@ -1,7 +1,19 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
import java.util.Map;
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IBlob;
import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
@@ -14,8 +26,8 @@
*
*/
public class Blob extends DataElement implements IBlob {
- public static final String MIMETYPE="mimeType";
- public static final String MODELTYPE = "blob";
+ public static final String MIMETYPE = "mimeType";
+ public static final String MODELTYPE = "Blob";
/**
* Creates an empty Blob object
@@ -24,6 +36,17 @@
// Add model type
putAll(new ModelType(MODELTYPE));
}
+
+ /**
+ * Constructor accepting only mandatory attribute
+ * @param idShort
+ * @param mimeType
+ */
+ public Blob(String idShort, String mimeType) {
+ super(idShort);
+ putAll(new ModelType(MODELTYPE));
+ setMimeType(mimeType);
+ }
/**
* Has to have a MimeType
@@ -38,7 +61,7 @@
// Add model type
putAll(new ModelType(MODELTYPE));
- setValue(value);
+ setByteArrayValue(value);
setMimeType(mimeType);
}
@@ -49,12 +72,29 @@
* @return a Blob object, that behaves like a facade for the given map
*/
public static Blob createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (!isValid(obj)) {
+ throw new MetamodelConstructionException(Blob.class, obj);
+ }
+
Blob facade = new Blob();
facade.setMap(obj);
return facade;
}
/**
+ * Check whether all mandatory elements for the metamodel
+ * exist in a map
+ * @return true/false
+ */
+ public static boolean isValid(Map<String, Object> obj) {
+ return DataElement.isValid(obj) && obj.containsKey(Blob.MIMETYPE);
+ }
+
+ /**
* Returns true if the given submodel element map is recognized as a blob
*/
public static boolean isBlob(Map<String, Object> map) {
@@ -62,22 +102,51 @@
// Either model type is set or the element type specific attributes are contained (fallback)
// Note: Fallback is ambiguous - File has exactly the same attributes
// => would need value parsing in order to be able to differentiate
- return MODELTYPE.equals(modelType) || (map.containsKey(Property.VALUE) && map.containsKey(MIMETYPE));
- }
-
- public void setValue(byte[] value) {
- put(Property.VALUE, new String(value));
-
+ return MODELTYPE.equals(modelType)
+ || (modelType == null && (map.containsKey(Property.VALUE) && map.containsKey(MIMETYPE)));
}
@Override
- public byte[] getValue() {
- return ((String) get(Property.VALUE)).getBytes();
+ public void setValue(Object value) {
+ if (value instanceof String) {
+ // Assume a Base64 encoded String
+ setValue((String) value);
+ } else {
+ throw new IllegalArgumentException("Given Object is not a String");
+ }
+ }
+
+ @Override
+ public String getValue() {
+ if (!containsKey(Property.VALUE)) {
+ return null;
+ }
+ return (String) get(Property.VALUE);
+ }
+
+ @Override
+ public byte[] getByteArrayValue() {
+ String value = getValue();
+ if ( value != null ) {
+ return Base64.getDecoder().decode(value);
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public String getUTF8String() {
+ byte[] value = getByteArrayValue();
+ return new String(value, StandardCharsets.UTF_8);
+ }
+
+ @Override
+ public void setUTF8String(String text) {
+ setByteArrayValue(text.getBytes(StandardCharsets.UTF_8));
}
public void setMimeType(String mimeType) {
put(Blob.MIMETYPE, mimeType);
-
}
@Override
@@ -89,4 +158,26 @@
protected KeyElements getKeyElement() {
return KeyElements.BLOB;
}
+
+ @Override
+ public Blob getLocalCopy() {
+ // Return a shallow copy
+ Blob copy = new Blob();
+ copy.putAll(this);
+ return copy;
+ }
+
+ @Override
+ public void setByteArrayValue(byte[] value) {
+ if (value != null) {
+ setValue(Base64.getEncoder().encodeToString(value));
+ } else {
+ setValue(null);
+ }
+ }
+
+ @Override
+ public void setValue(String value) {
+ put(Property.VALUE, value);
+ }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/DataElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/DataElement.java
index 7c72dc1..e939a82 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/DataElement.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/DataElement.java
@@ -1,12 +1,23 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement;
import java.util.Map;
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IDataElement;
import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.Range;
public class DataElement extends SubmodelElement implements IDataElement {
public static final String MODELTYPE = "DataElement";
@@ -15,8 +26,48 @@
// Add model type
putAll(new ModelType(MODELTYPE));
}
+
+ /**
+ * Constructor with mandatory attribute
+ * @param idShort
+ */
+ public DataElement(String idShort) {
+ super(idShort);
+
+ // Add model type
+ putAll(new ModelType(MODELTYPE));
+ }
/**
+ * Creates a DataElement object from a map
+ *
+ * @param obj a DataElement object as raw map
+ * @return a DataElement object, that behaves like a facade for the given map
+ */
+ public static DataElement createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (!isValid(obj)) {
+ throw new MetamodelConstructionException(DataElement.class, obj);
+ }
+
+ DataElement facade = new DataElement();
+ facade.setMap(obj);
+ return facade;
+ }
+
+ /**
+ * Check whether all mandatory elements for the metamodel
+ * exist in a map
+ * @return true/false
+ */
+ public static boolean isValid(Map<String, Object> obj) {
+ return SubmodelElement.isValid(obj);
+ }
+
+ /**
* Returns true if the given submodel element map is recognized as a data element
*/
public static boolean isDataElement(Map<String, Object> map) {
@@ -30,4 +81,12 @@
protected KeyElements getKeyElement() {
return KeyElements.DATAELEMENT;
}
+
+ @Override
+ public DataElement getLocalCopy() {
+ // Return a shallow copy
+ DataElement copy = new DataElement();
+ copy.putAll(this);
+ return copy;
+ }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/File.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/File.java
index da90b35..8ebde4f 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/File.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/File.java
@@ -1,7 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement;
import java.util.Map;
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IFile;
import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
@@ -26,6 +36,15 @@
}
/**
+ * Constructor accepting only mandatory attribute
+ * @param mimeType
+ */
+ public File(String mimeType) {
+ this();
+ setMimeType(mimeType);
+ }
+
+ /**
* Creates a file data element. It has to have a mimeType <br/>
* An absolute path is used in the case that the file exists independently of
* the AAS. A relative path, relative to the package root should be used if the
@@ -54,10 +73,27 @@
* @return a File object, that behaves like a facade for the given map
*/
public static File createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (!isValid(obj)) {
+ throw new MetamodelConstructionException(File.class, obj);
+ }
+
File facade = new File();
facade.setMap(obj);
return facade;
}
+
+ /**
+ * Check whether all mandatory elements for the metamodel
+ * exist in a map
+ * @return true/false
+ */
+ public static boolean isValid(Map<String, Object> obj) {
+ return DataElement.isValid(obj) && obj.containsKey(File.MIMETYPE);
+ }
/**
* Returns true if the given submodel element map is recognized as a fiel
@@ -67,11 +103,19 @@
// Either model type is set or the element type specific attributes are contained (fallback)
// Note: Fallback is ambiguous - Blob has exactly the same attributes
// => would need value parsing in order to be able to differentiate
- return MODELTYPE.equals(modelType) || (map.containsKey(Property.VALUE) && map.containsKey(MIMETYPE));
+ return MODELTYPE.equals(modelType)
+ || (modelType == null && (map.containsKey(Property.VALUE) && map.containsKey(MIMETYPE)));
}
- public void setValue(String value) {
- put(Property.VALUE, value);
+ @Override
+ public void setValue(Object value) {
+ if(value instanceof String) {
+ setValue((String) value);
+ }
+ else {
+ throw new IllegalArgumentException("Given Object is not a String");
+ }
+
}
@Override
@@ -92,4 +136,17 @@
protected KeyElements getKeyElement() {
return KeyElements.FILE;
}
+
+ @Override
+ public File getLocalCopy() {
+ // Return a shallow copy
+ File copy = new File();
+ copy.putAll(this);
+ return copy;
+ }
+
+ @Override
+ public void setValue(String value) {
+ put(Property.VALUE, value);
+ }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/MultiLanguageProperty.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/MultiLanguageProperty.java
index 5510004..daa9ca2 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/MultiLanguageProperty.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/MultiLanguageProperty.java
@@ -1,8 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement;
import java.util.Collection;
import java.util.Map;
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IMultiLanguageProperty;
@@ -28,6 +38,16 @@
putAll(new ModelType(MODELTYPE));
}
+ /**
+ * Constructor accepting only mandatory attribute
+ * @param idShort
+ */
+ public MultiLanguageProperty(String idShort) {
+ super(idShort);
+ // Add model type
+ putAll(new ModelType(MODELTYPE));
+ }
+
public MultiLanguageProperty(Reference reference, LangStrings langStrings) {
this();
put(VALUE, langStrings);
@@ -41,20 +61,37 @@
* @return a MultiLanguageProperty object, that behaves like a facade for the given map
*/
public static MultiLanguageProperty createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (!isValid(obj)) {
+ throw new MetamodelConstructionException(MultiLanguageProperty.class, obj);
+ }
+
MultiLanguageProperty facade = new MultiLanguageProperty();
facade.setMap(obj);
return facade;
}
/**
+ * Check whether all mandatory elements for the metamodel
+ * exist in a map
+ * @return true/false
+ */
+ public static boolean isValid(Map<String, Object> obj) {
+ return DataElement.isValid(obj);
+ }
+
+ /**
* Returns true if the given submodel element map is recognized as a MultiLanguageProperty
*/
public static boolean isMultiLanguageProperty(Map<String, Object> map) {
String modelType = ModelType.createAsFacade(map).getName();
// Either model type is set or the element type specific attributes are contained (fallback)
return MODELTYPE.equals(modelType)
- || (map.containsKey(VALUE) && map.containsKey(VALUE) && map.containsKey(VALUEID)
- && !map.containsKey(Property.VALUETYPE));
+ || (modelType == null && (map.containsKey(VALUE) && map.containsKey(VALUE) && map.containsKey(VALUEID)
+ && !map.containsKey(Property.VALUETYPE)));
}
@Override
@@ -73,4 +110,29 @@
protected KeyElements getKeyElement() {
return KeyElements.MULTILANGUAGEPROPERTY;
}
-}
\ No newline at end of file
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void setValue(Object value) {
+ if(LangStrings.isLangStrings(value)) {
+ LangStrings strings = LangStrings.createAsFacade((Collection<Map<String, Object>>) value);
+ setValue(strings);
+ }
+ else {
+ throw new IllegalArgumentException("Given Object is not a LangStrings");
+ }
+ }
+
+ @Override
+ public MultiLanguageProperty getLocalCopy() {
+ // Return a shallow copy
+ MultiLanguageProperty copy = new MultiLanguageProperty();
+ copy.putAll(this);
+ return copy;
+ }
+
+ @Override
+ public void setValue(LangStrings value) {
+ put(VALUE, value);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/Range.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/Range.java
deleted file mode 100644
index a608db2..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/Range.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement;
-
-import java.util.Map;
-
-import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IRange;
-import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
-
-/**
- * A range element as defined in DAAS document
- *
- * @author conradi
- *
- */
-public class Range extends DataElement implements IRange {
-
- public static final String MODELTYPE = "Range";
- public static final String VALUETYPE = "valueType";
- public static final String MIN = "min";
- public static final String MAX = "max";
-
-
- public Range() {
- // Add model type
- putAll(new ModelType(MODELTYPE));
- }
-
- public Range(String valueType) {
- this();
- put(VALUETYPE, valueType);
- }
-
- public Range(String valueType, Object min, Object max) {
- this(valueType);
- put(MIN, min);
- put(MAX, max);
- }
-
- /**
- * Creates a Range object from a map
- *
- * @param obj a Range object as raw map
- * @return a Range object, that behaves like a facade for the given map
- */
- public static Range createAsFacade(Map<String, Object> obj) {
- Range facade = new Range();
- facade.setMap(obj);
- return facade;
- }
-
- /**
- * Returns true if the given submodel element map is recognized as a Range element
- */
- public static boolean isRange(Map<String, Object> map) {
- String modelType = ModelType.createAsFacade(map).getName();
- // Either model type is set or the element type specific attributes are contained (fallback)
- return MODELTYPE.equals(modelType)
- || (map.containsKey(MIN) && map.containsKey(MAX) && map.containsKey(VALUETYPE));
- }
-
- @Override
- public String getValueType() {
- return (String) get(VALUETYPE);
- }
-
- @Override
- public Object getMin() {
- return get(MIN);
- }
-
- @Override
- public Object getMax() {
- return get(MAX);
- }
-
- @Override
- protected KeyElements getKeyElement() {
- return KeyElements.RANGE;
- }
-
-}
\ No newline at end of file
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/ReferenceElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/ReferenceElement.java
index d041e2d..52e2c52 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/ReferenceElement.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/ReferenceElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement;
import java.util.Map;
@@ -28,8 +37,28 @@
public ReferenceElement() {
// Add model type
putAll(new ModelType(MODELTYPE));
+ }
- put(Property.VALUE, null);
+ /**
+ * Constructor with mandatory attribute
+ *
+ * @param idShort
+ */
+ public ReferenceElement(String idShort) {
+ super(idShort);
+ putAll(new ModelType(MODELTYPE));
+ }
+
+ /**
+ *
+ * @param idShort
+ * @param ref
+ * Reference to any other referable element of the same or any other
+ * AAS or a reference to an external object or entity
+ */
+ public ReferenceElement(String idShort, Reference ref) {
+ this(idShort);
+ setValue(ref);
}
/**
@@ -50,6 +79,10 @@
* @return a ReferenceElement object, that behaves like a facade for the given map
*/
public static ReferenceElement createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
ReferenceElement ret = new ReferenceElement();
ret.setMap(obj);
return ret;
@@ -62,15 +95,11 @@
String modelType = ModelType.createAsFacade(map).getName();
// Either model type is set or the element type specific attributes are contained (fallback)
// Ambiguous - fallback could be further improved by parsing the value and recognizing references
- return MODELTYPE.equals(modelType) || (map.containsKey(Property.VALUE) && !map.containsKey(Property.VALUETYPE)
+ return MODELTYPE.equals(modelType)
+ || (modelType == null && (map.containsKey(Property.VALUE) && !map.containsKey(Property.VALUETYPE)
&& !map.containsKey(Property.VALUEID) && !map.containsKey(File.MIMETYPE)
&& !map.containsKey(SubmodelElementCollection.ORDERED)
- && !map.containsKey(SubmodelElementCollection.ALLOWDUPLICATES));
- }
-
- public void setValue(IReference ref) {
- put(Property.VALUE, ref);
-
+ && !map.containsKey(SubmodelElementCollection.ALLOWDUPLICATES)));
}
@Override
@@ -79,9 +108,32 @@
return Reference.createAsFacade((Map<String, Object>) get(Property.VALUE));
}
+ @SuppressWarnings("unchecked")
+ @Override
+ public void setValue(Object value) {
+ if(Reference.isReference(value)) {
+ setValue(Reference.createAsFacade((Map<String, Object>) value));
+ }
+ else {
+ throw new IllegalArgumentException("Given Object is not a Reference");
+ }
+ }
+
@Override
protected KeyElements getKeyElement() {
return KeyElements.REFERENCEELEMENT;
}
+ @Override
+ public ReferenceElement getLocalCopy() {
+ // Return a shallow copy
+ ReferenceElement copy = new ReferenceElement();
+ copy.putAll(this);
+ return copy;
+ }
+
+ @Override
+ public void setValue(IReference value) {
+ put(Property.VALUE, value);
+ }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/AASLambdaPropertyHelper.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/AASLambdaPropertyHelper.java
index 568482b..a52d769 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/AASLambdaPropertyHelper.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/AASLambdaPropertyHelper.java
@@ -1,10 +1,19 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property;
import java.util.function.Consumer;
import java.util.function.Supplier;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDef;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDefHelper;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueTypeHelper;
import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProviderHelper;
@@ -25,7 +34,7 @@
*/
public static Property setLambdaValue(Property property, Supplier<Object> get, Consumer<Object> set) {
Object newValue = VABLambdaProviderHelper.createSimple(get, set);
- PropertyValueTypeDef newType = PropertyValueTypeDefHelper.getType(get.get());
+ ValueType newType = ValueTypeHelper.getType(get.get());
property.set(newValue, newType);
return property;
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/Property.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/Property.java
index d28e776..bb9ccc5 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/Property.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/Property.java
@@ -1,7 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property;
import java.util.Map;
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
import org.eclipse.basyx.submodel.metamodel.api.parts.IConceptDescription;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
@@ -12,8 +22,8 @@
import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifiable;
import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.DataElement;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDef;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDefHelper;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueTypeHelper;
import org.eclipse.basyx.vab.exception.provider.ProviderException;
/**
@@ -39,6 +49,38 @@
put(Property.VALUE, null);
put(Property.VALUEID, null);
}
+
+ /**
+ * Constructor accepting only mandatory attribute
+ *
+ * @param idShort
+ * @param valueType
+ */
+ public Property(String idShort, ValueType valueType) {
+ super(idShort);
+ setValueType(valueType);
+ setIdShort(idShort);
+
+ // Add model type
+ putAll(new ModelType(MODELTYPE));
+ }
+
+ /**
+ * Constructor accepting an idShort and a value
+ * The valueType is set automatically
+ * @param idShort the idShort for the Property
+ * @param value the value for the Property
+ */
+ public Property(String idShort, Object value) {
+ setIdShort(idShort);
+
+ // Add model type
+ putAll(new ModelType(MODELTYPE));
+
+ // Set the value for the Property
+ // set() also automatically sets the value type
+ setValue(value);
+ }
/**
* Creates a Property object from a map
@@ -47,10 +89,27 @@
* @return a Property object, that behaves like a facade for the given map
*/
public static Property createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (!isValid(obj)) {
+ throw new MetamodelConstructionException(Property.class, obj);
+ }
+
Property facade = new Property();
facade.setMap(obj);
return facade;
}
+
+ /**
+ * Check whether all mandatory elements for the metamodel
+ * exist in a map
+ * @return true/false
+ */
+ public static boolean isValid(Map<String, Object> obj) {
+ return DataElement.isValid(obj) && obj.containsKey(Property.VALUETYPE);
+ }
/**
* Returns true if the given submodel element map is recognized as a property
@@ -59,7 +118,7 @@
String modelType = ModelType.createAsFacade(map).getName();
// Either model type is set or the element type specific attributes are contained (fallback)
return MODELTYPE.equals(modelType)
- || (map.containsKey(VALUE) && map.containsKey(VALUETYPE));
+ || (modelType == null && (map.containsKey(VALUE) && map.containsKey(VALUETYPE)));
}
/**
@@ -73,7 +132,7 @@
this();
// Put attributes
put(Property.VALUEID, null);
- set(value);
+ setValue(value);
}
public Property(Object value, Referable referable, Reference semanticId, Qualifiable qualifiable) {
@@ -90,8 +149,11 @@
* @param type
* manually determined type of the value
*/
- public void setValueType(PropertyValueTypeDef type) {
- put(Property.VALUETYPE, PropertyValueTypeDefHelper.getWrapper(type));
+ public void setValueType(ValueType type) {
+ if(type == null) {
+ throw new RuntimeException("Can not set null as valueType");
+ }
+ put(Property.VALUETYPE, type.toString());
}
public void setValueId(IReference ref) {
@@ -106,31 +168,25 @@
return Reference.createAsFacade((Map<String, Object>) get(VALUEID));
}
- @Override
- public void set(Object value) {
- put(Property.VALUE, value);
- put(Property.VALUETYPE, PropertyValueTypeDefHelper.getTypeWrapperFromObject(value));
- }
-
/**
* Sets the value and explicitly specifies the type of this value.
*
* @throws ProviderException
*/
- public void set(Object newValue, PropertyValueTypeDef newType) throws ProviderException {
+ public void set(Object newValue, ValueType newType) throws ProviderException {
put(Property.VALUE, newValue);
setValueType(newType);
}
- @Override
- public Object get() {
- return get(Property.VALUE);
- }
@Override
- public String getValueType() {
- PropertyValueTypeDef def = PropertyValueTypeDefHelper.readTypeDef(get(Property.VALUETYPE));
- return def!=null ? def.toString() : "";
+ public ValueType getValueType() {
+ String valueType = (String) get(Property.VALUETYPE);
+ if (valueType == null) {
+ return null;
+ } else {
+ return ValueTypeHelper.fromName(valueType);
+ }
}
/**
@@ -142,11 +198,45 @@
*/
public void addConceptDescription(IConceptDescription description) {
Reference ref = new Reference(description, KeyElements.CONCEPTDESCRIPTION, true);
- setSemanticID(ref);
+ setSemanticId(ref);
}
@Override
protected KeyElements getKeyElement() {
return KeyElements.PROPERTY;
}
+
+ @Override
+ public Object getValue() {
+ Object value = get(Property.VALUE);
+ if (value instanceof String) {
+ return ValueTypeHelper.getJavaObject(value, getValueType());
+ } else {
+ return value;
+ }
+ }
+
+ @Override
+ public void setValue(Object value) {
+ put(Property.VALUE, ValueTypeHelper.prepareForSerialization(value));
+ // Value type is only set if it is not set before
+ if (getValueType() == null) {
+
+ // If valueType has not been set yet,
+ // a null can not be accepted as value, because valueType needs to be set
+ if (value == null) {
+ throw new RuntimeException("Can not set mandatory attribute 'valueType' with null as value");
+ }
+
+ put(Property.VALUETYPE, ValueTypeHelper.getType(value).toString());
+ }
+ }
+
+ @Override
+ public Property getLocalCopy() {
+ // Return a shallow copy
+ Property copy = new Property();
+ copy.putAll(this);
+ return copy;
+ }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueType.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueType.java
new file mode 100644
index 0000000..6377fd4
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueType.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype;
+
+import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnum;
+import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnumHelper;
+
+/**
+ * Helper enum to handle anySimpleTypeDef as defined in DAAS document <br />
+ * Represents the type of a data entry <br />
+ * TODO: Extend this to support rest of types (cf. p. 58)
+ *
+ * @author schnicke
+ *
+ */
+public enum ValueType implements StandardizedLiteralEnum {
+ Int8("byte"), Int16("short"), Int32("int"), Int64("long"),
+ UInt8("unsignedByte"), UInt16("unsignedShort"), UInt32("unsignedInt"), UInt64("unsignedLong"),
+ String("string"), LangString("langString"),
+ AnyURI("anyuri"), Base64Binary("base64Binary"), HexBinary("hexBinary"), NOTATION("notation"), ENTITY("entity"), ID("id"), IDREF("idref"),
+ Integer("integer"), NonPositiveInteger("nonPositiveInteger"), NonNegativeInteger("nonNegativeInteger"), PositiveInteger("positiveInteger"), NegativeInteger("negativeInteger"),
+ Double("double"), Float("float"), Boolean("boolean"),
+ Duration("duration"), DayTimeDuration("dayTimeDuration"), YearMonthDuration("yearMonthDuration"),
+ DateTime("dateTime"), DateTimeStamp("dateTimeStamp"), GDay("gDay"), GMonth("gMonth"), GMonthDay("gMonthDay"), GYear("gYear"), GYearMonth("gYearMonth"),
+ QName("qName"),
+ None("none"), AnyType("anyType"), AnySimpleType("anySimpleType");
+
+ private String standardizedLiteral;
+
+ private ValueType(String standardizedLiteral) {
+ this.standardizedLiteral = standardizedLiteral;
+ }
+
+ @Override
+ public String getStandardizedLiteral() {
+ return standardizedLiteral;
+ }
+
+ @Override
+ public String toString() {
+ return standardizedLiteral;
+ }
+
+ public static ValueType fromString(String str) {
+ return StandardizedLiteralEnumHelper.fromLiteral(ValueType.class, str);
+ }
+
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueTypeHelper.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueTypeHelper.java
new file mode 100644
index 0000000..c3db504
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueTypeHelper.java
@@ -0,0 +1,244 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype;
+
+import java.math.BigInteger;
+import java.time.Duration;
+import java.time.Period;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.datatype.DatatypeConfigurationException;
+import javax.xml.datatype.DatatypeFactory;
+import javax.xml.datatype.XMLGregorianCalendar;
+import javax.xml.namespace.QName;
+
+
+/**
+ * Provides utility functions for
+ * {@link org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType
+ * PropertyValueTypeDef} <br />
+ * * Creating a PropertyValueTypeDef from name <br/>
+ * * Creating a PropertyValueTypeDef for an object
+ *
+ * @author schnicke
+ *
+ */
+public class ValueTypeHelper {
+ private static Map<String, ValueType> typeMap = new HashMap<>();
+
+ // insert all types into a Map to allow getting a PropertyValueType based on a
+ // String
+ static {
+ for (ValueType t : ValueType.values()) {
+ typeMap.put(t.toString(), t);
+ }
+ }
+
+ // Strings required for meta-model conformant valueType format
+ private static final String TYPE_NAME = "name";
+ private static final String TYPE_OBJECT = "dataObjectType";
+
+ /**
+ * Map the name of a PropertyValueTypeDef to a PropertyValueTypeDef
+ *
+ * @param name
+ * @return
+ */
+ public static ValueType fromName(String name) {
+ if (typeMap.containsKey(name)) {
+ return typeMap.get(name);
+ } else {
+ throw new RuntimeException("Unknown type name " + name + "; can not handle this PropertyValueType");
+ }
+ }
+
+ /**
+ * Creates the PropertyValueTypeDef for an arbitrary object
+ *
+ * @param obj
+ * @return
+ */
+ public static ValueType getType(Object obj) {
+ ValueType objectType;
+
+ if (obj == null) {
+ objectType = ValueType.None;
+ } else {
+ Class<?> c = obj.getClass();
+ if(c == byte.class || c == Byte.class) {
+ objectType = ValueType.Int8;
+ }else if(c == short.class || c == Short.class) {
+ objectType = ValueType.Int16;
+ }else if (c == int.class || c == Integer.class) {
+ objectType = ValueType.Integer;
+ } else if (c == long.class || c == Long.class) {
+ objectType = ValueType.Int64;
+ } else if (c == BigInteger.class) {
+ BigInteger tmp = (BigInteger) obj;
+ if (tmp.compareTo(new BigInteger("0")) > 0) {
+ objectType = ValueType.PositiveInteger;
+ } else if (tmp.compareTo(new BigInteger("0")) < 0) {
+ objectType = ValueType.NegativeInteger;
+ } else {
+ objectType = ValueType.NonNegativeInteger;
+ }
+
+ } else if (c == void.class || c == Void.class) {
+ objectType = ValueType.None;
+ } else if (c == boolean.class || c == Boolean.class) {
+ objectType = ValueType.Boolean;
+ } else if (c == float.class || c == Float.class) {
+ // TODO C# deprecated due to new serialization
+ objectType = ValueType.Float;
+ } else if (c == double.class || c == Double.class) {
+ objectType = ValueType.Double;
+ } else if (c == String.class) {
+ objectType = ValueType.String;
+ } else if (c == Duration.class) {
+ objectType = ValueType.Duration;
+ } else if (c == Period.class) {
+ objectType = ValueType.YearMonthDuration;
+ } else if (c == QName.class) {
+ objectType = ValueType.QName;
+ } else if (c == XMLGregorianCalendar.class) {
+ objectType = ValueType.DateTime;
+ } else {
+ throw new RuntimeException("Cannot map object " + obj + " to any PropertyValueTypeDef");
+ }
+ }
+ return objectType;
+ }
+
+ /**
+ * Map the PropertyValueType to Java type
+ *
+ */
+ public static Object getJavaObject(Object value, ValueType objType) {
+ Object target = null;
+ if(objType != null) {
+ switch(objType) {
+ case Int8:
+ if(((String)value).isEmpty()){
+ target = new Byte("NaN");
+ }else {
+ target = new Byte((String)value);
+ }
+ break;
+ case Int16: case UInt8:
+ if(((String)value).isEmpty()){
+ target = new Short("NaN");
+ }else {
+ target = new Short((String)value);
+ }
+ break;
+ case Int32: case UInt16:
+ if(((String)value).isEmpty()){
+ target = new Integer("NaN");
+ }else {
+ target = new Integer((String)value);
+ }
+ break;
+ case Int64: case UInt32:
+ if(((String)value).isEmpty()){
+ target = new Long("NaN");
+ }else {
+ target = new Long((String)value);
+ }
+ break;
+ case UInt64:
+ if(((String)value).isEmpty()){
+ target = new BigInteger("NaN");
+ }else {
+ target = new BigInteger((String)value);
+ }
+ break;
+ case Double:
+ if(((String)value).isEmpty()){
+ target = new Double("NaN");
+ }else {
+ target = new Double((String)value);
+ }
+ break;
+ case Float:
+ if(((String)value).isEmpty()){
+ target = new Float("NaN");
+ }else {
+ target = new Float((String)value);
+ }
+ break;
+ case Boolean:
+ target = new Boolean((String)value);
+ break;
+ case AnySimpleType: case String: case LangString: case AnyURI: case Base64Binary: case HexBinary: case NOTATION: case ENTITY: case ID: case IDREF:
+ target = (String) value;
+ break;
+ case Duration: case DayTimeDuration:
+ target = Duration.parse((String)value);
+ break;
+ case YearMonthDuration:
+ target = Period.parse((String)value);
+ break;
+ case DateTime: case DateTimeStamp: case GDay: case GMonth: case GMonthDay: case GYear: case GYearMonth:
+ try {
+ target = DatatypeFactory.newInstance().newXMLGregorianCalendar((String)value);
+ break;
+ } catch (DatatypeConfigurationException e) {
+ e.printStackTrace();
+ throw new RuntimeException("Could not create DatatypeFactory for XMLGregorianCaldner handling");
+ }
+ case QName:
+ target = QName.valueOf((String)value);
+ break;
+ default:
+ target = value;
+ break;
+ }
+ return target;
+ }else {
+ return null;
+ }
+
+
+ }
+
+ /**
+ * Convert an object which has special types (Duration, period, Qname, Date) to
+ * String object Used by Property.set() or ConnectedProperty.set(), prepare for the serialization
+ *
+ * @param value - the target object
+ * @return
+ */
+ public static Object prepareForSerialization(Object value) {
+ if(value != null) {
+ Class<?> c = value.getClass();
+ if (c == Duration.class || c == Period.class || c == QName.class || c == XMLGregorianCalendar.class) {
+ return value.toString();
+ }
+ }
+ return value;
+
+ }
+
+ @SuppressWarnings("unchecked")
+ public static ValueType readTypeDef(Object vTypeMap) {
+ if (vTypeMap instanceof String) {
+ // From xml/json-schema point of view, this should be only a string.
+ return fromName((String) vTypeMap);
+ } else if (vTypeMap instanceof Map<?, ?>) {
+ // Reading still supported, but should be a simple string
+ Map<String, Object> map = (Map<String, Object>) vTypeMap;
+ Map<String, Object> dot = (Map<String, Object>) map.get(TYPE_OBJECT);
+
+ return fromName(dot.get(TYPE_NAME).toString());
+ }
+ return null;
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetypedef/PropertyValueTypeDef.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetypedef/PropertyValueTypeDef.java
deleted file mode 100644
index 61c4022..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetypedef/PropertyValueTypeDef.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef;
-
-import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnum;
-import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnumHelper;
-
-/**
- * Helper enum to handle anySimpleTypeDef as defined in DAAS document <br />
- * Represents the type of a data entry <br />
- * TODO: Extend this to support rest of types (cf. p. 58)
- *
- * @author schnicke
- *
- */
-public enum PropertyValueTypeDef implements StandardizedLiteralEnum {
- Double("double"), Float("float"), Integer("int"), String("string"), Boolean("boolean"), Void("void"), Null("null");
-
- private String standardizedLiteral;
-
- private PropertyValueTypeDef(String standardizedLiteral) {
- this.standardizedLiteral = standardizedLiteral;
- }
-
- @Override
- public String getStandardizedLiteral() {
- return standardizedLiteral;
- }
-
- @Override
- public String toString() {
- return standardizedLiteral;
- }
-
- public static PropertyValueTypeDef fromString(String str) {
- return StandardizedLiteralEnumHelper.fromLiteral(PropertyValueTypeDef.class, str);
- }
-
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetypedef/PropertyValueTypeDefHelper.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetypedef/PropertyValueTypeDefHelper.java
deleted file mode 100644
index 4025801..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetypedef/PropertyValueTypeDefHelper.java
+++ /dev/null
@@ -1,118 +0,0 @@
-package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Provides utility functions for
- * {@link org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDef
- * PropertyValueTypeDef} <br />
- * * Creating a PropertyValueTypeDef from name <br/>
- * * Creating a PropertyValueTypeDef for an object
- *
- * @author schnicke
- *
- */
-public class PropertyValueTypeDefHelper {
- private static Map<String, PropertyValueTypeDef> typeMap = new HashMap<>();
-
- // insert all types into a Map to allow getting a PropertyValueType based on a
- // String
- static {
- for (PropertyValueTypeDef t : PropertyValueTypeDef.values()) {
- typeMap.put(t.toString(), t);
- }
- }
-
- // Strings required for meta-model conformant valueType format
- private static final String TYPE_NAME = "name";
- private static final String TYPE_OBJECT = "dataObjectType";
-
- /**
- * Map the name of a PropertyValueTypeDef to a PropertyValueTypeDef
- *
- * @param name
- * @return
- */
- public static PropertyValueTypeDef fromName(String name) {
- if (typeMap.containsKey(name)) {
- return typeMap.get(name);
- } else {
- throw new RuntimeException("Unknown type name " + name + "; can not handle this PropertyValueType");
- }
- }
-
- /**
- * Creates the appropriate type map for a given object
- *
- * @param obj
- * @return
- */
- public static Map<String, Object> getTypeWrapperFromObject(Object obj) {
- return getWrapper(getType(obj));
- }
-
- /**
- * Creates the PropertyValueTypeDef for an arbitrary object
- *
- * @param obj
- * @return
- */
- public static PropertyValueTypeDef getType(Object obj) {
- PropertyValueTypeDef objectType;
-
- if (obj == null) {
- objectType = PropertyValueTypeDef.Null;
- } else {
- Class<?> c = obj.getClass();
- if (c == int.class || c == Integer.class) {
- objectType = PropertyValueTypeDef.Integer;
- } else if (c == void.class || c == Void.class) {
- objectType = PropertyValueTypeDef.Void;
- } else if (c == boolean.class || c == Boolean.class) {
- objectType = PropertyValueTypeDef.Boolean;
- } else if (c == float.class || c == Float.class) {
- // TODO C# deprecated due to new serialization
- objectType = PropertyValueTypeDef.Float;
- } else if (c == double.class || c == Double.class) {
- objectType = PropertyValueTypeDef.Double;
- } else if (c == String.class) {
- objectType = PropertyValueTypeDef.String;
- } else {
- throw new RuntimeException("Cannot map object " + obj + " to any PropertyValueTypeDef");
- }
- }
- return objectType;
- }
-
- /**
- * Creates the appropriate type map for a given type
- *
- * @param type
- * @return
- */
- public static Map<String, Object> getWrapper(PropertyValueTypeDef type) {
- HashMap<String, Object> valueTypeWrapper = new HashMap<>();
- HashMap<String, Object> dataObjectTypeWrapper = new HashMap<>();
- valueTypeWrapper.put(TYPE_OBJECT, dataObjectTypeWrapper);
- dataObjectTypeWrapper.put(TYPE_NAME, type.toString());
- return valueTypeWrapper;
- }
-
- @SuppressWarnings("unchecked")
- public static PropertyValueTypeDef readTypeDef(Object vTypeMap) {
-
- if (vTypeMap instanceof Map<?,?>) {
-
- Map<String, Object> map = (Map<String, Object>) vTypeMap;
- Map<String, Object> dot = (Map<String, Object>) map.get(TYPE_OBJECT);
-
- return fromName(dot.get(TYPE_NAME).toString());
-
- } else if (vTypeMap instanceof String) {
- // From xml/json-schema point of view, this should be only a string.
- return fromName((String)vTypeMap);
- }
- return null;
- }
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/range/Range.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/range/Range.java
new file mode 100644
index 0000000..fbdf1d6
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/range/Range.java
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range;
+
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IRange;
+import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.DataElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueTypeHelper;
+
+/**
+ * A range element as defined in DAAS document
+ *
+ * @author conradi
+ *
+ */
+public class Range extends DataElement implements IRange {
+
+ public static final String MODELTYPE = "Range";
+ public static final String VALUETYPE = "valueType";
+ public static final String MIN = "min";
+ public static final String MAX = "max";
+
+
+ public Range() {
+ // Add model type
+ putAll(new ModelType(MODELTYPE));
+ }
+
+ public Range(ValueType valueType) {
+ this();
+ setValueType(valueType);
+ }
+
+ /**
+ * Constructor accepting only mandatory attribute
+ * @param idShort
+ * @param valueType
+ */
+ public Range(String idShort, ValueType valueType) {
+ super(idShort);
+ // Add model type
+ putAll(new ModelType(MODELTYPE));
+ setValueType(valueType);
+ }
+
+ public Range(ValueType valueType, Object min, Object max) {
+ this(valueType);
+ put(MIN, min);
+ put(MAX, max);
+ }
+
+ /**
+ * Creates a Range object from a map
+ *
+ * @param obj a Range object as raw map
+ * @return a Range object, that behaves like a facade for the given map
+ */
+ public static Range createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (!isValid(obj)) {
+ throw new MetamodelConstructionException(Range.class, obj);
+ }
+
+ Range facade = new Range();
+ facade.setMap(obj);
+ return facade;
+ }
+
+ /**
+ * Check whether all mandatory elements for the metamodel
+ * exist in a map
+ * @return true/false
+ */
+ public static boolean isValid(Map<String, Object> obj) {
+ return DataElement.isValid(obj) && obj.containsKey(VALUETYPE);
+ }
+
+ /**
+ * Returns true if the given submodel element map is recognized as a Range element
+ */
+ public static boolean isRange(Map<String, Object> map) {
+ String modelType = ModelType.createAsFacade(map).getName();
+ // Either model type is set or the element type specific attributes are contained (fallback)
+ return MODELTYPE.equals(modelType)
+ || (modelType == null && (map.containsKey(MIN) && map.containsKey(MAX) && map.containsKey(VALUETYPE)));
+ }
+
+ private void setValueType(ValueType valueType) {
+ put(Range.VALUETYPE, valueType.toString());
+ }
+
+ @Override
+ public ValueType getValueType() {
+ return ValueTypeHelper.readTypeDef(get(Range.VALUETYPE));
+ }
+
+ @Override
+ public Object getMin() {
+ Object value = get(MIN);
+ if(value instanceof String) {
+ return ValueTypeHelper.getJavaObject(value, getValueType());
+ }else {
+ return value;
+ }
+ }
+
+ @Override
+ public Object getMax() {
+ Object value = get(MAX);
+ if(value instanceof String) {
+ return ValueTypeHelper.getJavaObject(value, getValueType());
+ }else {
+ return value;
+ }
+ }
+
+ @Override
+ protected KeyElements getKeyElement() {
+ return KeyElements.RANGE;
+ }
+
+ @Override
+ public RangeValue getValue() {
+ return new RangeValue(getMin(), getMax());
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void setValue(Object value) {
+ if(RangeValue.isRangeValue(value)) {
+ RangeValue rv = RangeValue.createAsFacade((Map<String, Object>) value);
+ setValue(rv);
+ } else {
+ throw new IllegalArgumentException("Given Object is not a RangeValue");
+ }
+ }
+
+ @Override
+ public void setValue(RangeValue rv) {
+ Object minValue = rv.getMin();
+ Object maxValue = rv.getMax();
+
+ put(Range.MIN, ValueTypeHelper.prepareForSerialization(minValue));
+ put(Range.MAX, ValueTypeHelper.prepareForSerialization(maxValue));
+ if (getValueType() == null) {
+ setValueType(ValueTypeHelper.getType(minValue));
+ }
+ }
+
+ @Override
+ public Range getLocalCopy() {
+ // Return a shallow copy
+ Range copy = new Range();
+ copy.putAll(this);
+ return copy;
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/range/RangeValue.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/range/RangeValue.java
new file mode 100644
index 0000000..322bcac
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/range/RangeValue.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range;
+
+import java.util.Map;
+
+import org.eclipse.basyx.vab.model.VABModelMap;
+
+
+/**
+ * Container class for holding the value of Range
+ *
+ * @author conradi
+ *
+ */
+public class RangeValue extends VABModelMap<Object> {
+
+ private RangeValue() {}
+
+ public RangeValue(Object min, Object max) {
+ put(Range.MIN, min);
+ put(Range.MAX, max);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static boolean isRangeValue(Object value) {
+
+ // Given Object must be a Map
+ if(!(value instanceof Map<?, ?>)) {
+ return false;
+ }
+
+ Map<String, Object> map = (Map<String, Object>) value;
+
+ // Given Map must contain all necessary Entries
+ return map.containsKey(Range.MIN) && map.containsKey(Range.MAX);
+ }
+
+ /**
+ * Creates a RangeValue object from a map
+ *
+ * @param obj a RangeValue object as raw map
+ * @return a RangeValue object, that behaves like a facade for the given map
+ */
+ public static RangeValue createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ RangeValue facade = new RangeValue();
+ facade.setMap(obj);
+ return facade;
+ }
+
+ public Object getMin() {
+ return get(Range.MIN);
+ }
+
+ public Object getMax() {
+ return get(Range.MAX);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/entity/Entity.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/entity/Entity.java
index 4741f09..333b87f 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/entity/Entity.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/entity/Entity.java
@@ -1,9 +1,19 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.submodelelement.entity;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
@@ -32,6 +42,19 @@
putAll(new ModelType(MODELTYPE));
}
+ /**
+ * Constructor accepting only mandatory attribute
+ * @param idShort
+ * @param entityType
+ */
+ public Entity(String idShort, EntityType entityType) {
+ super(idShort);
+ setEntityType(entityType);
+
+ // Add model type
+ putAll(new ModelType(MODELTYPE));
+ }
+
public Entity(EntityType entityType, Collection<ISubmodelElement> statements, IReference asset) {
this();
setEntityType(entityType);
@@ -51,6 +74,12 @@
put(ENTITY_TYPE, entityType.toString());
}
+ public static boolean isEntity(Map<String, Object> map) {
+ String modelType = ModelType.createAsFacade(map).getName();
+ // Either model type is set or the element type specific attributes are contained (fallback)
+ return MODELTYPE.equals(modelType) || (modelType == null && map.containsKey(Entity.STATEMENT));
+ }
+
/**
* Creates an Entity object from a map
*
@@ -58,10 +87,27 @@
* @return an Entity object, that behaves like a facade for the given map
*/
public static Entity createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (!isValid(obj)) {
+ throw new MetamodelConstructionException(Entity.class, obj);
+ }
+
Entity facade = new Entity();
facade.setMap(obj);
return facade;
}
+
+ /**
+ * Check whether all mandatory elements for the metamodel
+ * exist in a map
+ * @return true/false
+ */
+ public static boolean isValid(Map<String, Object> obj) {
+ return SubmodelElement.isValid(obj) && obj.containsKey(ENTITY_TYPE);
+ }
@Override
@SuppressWarnings("unchecked")
@@ -91,4 +137,29 @@
return KeyElements.ENTITY;
}
+ @Override
+ public EntityValue getValue() {
+ return new EntityValue(getStatements(), getAsset());
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void setValue(Object value) {
+ if(EntityValue.isEntityValue(value)) {
+ EntityValue ev = EntityValue.createAsFacade((Map<String, Object>) value);
+ put(Entity.STATEMENT, ev.getStatement());
+ put(Entity.ASSET, ev.getAsset());
+ }
+ else {
+ throw new IllegalArgumentException("Given Object is not an EntityValue");
+ }
+ }
+
+ @Override
+ public Entity getLocalCopy() {
+ // Return a shallow copy
+ Entity copy = new Entity();
+ copy.putAll(this);
+ return copy;
+ }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/entity/EntityValue.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/entity/EntityValue.java
new file mode 100644
index 0000000..cdce0a7
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/entity/EntityValue.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.map.submodelelement.entity;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.facade.submodelelement.SubmodelElementFacadeFactory;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.vab.model.VABModelMap;
+
+
+/**
+ * Container class for holding the value of Entity
+ *
+ * @author conradi
+ *
+ */
+public class EntityValue extends VABModelMap<Object> {
+
+ private EntityValue() {}
+
+ public EntityValue(Collection<ISubmodelElement> statements, IReference asset) {
+ put(Entity.STATEMENT, statements);
+ put(Entity.ASSET, asset);
+ }
+
+ /**
+ * Creates a EntityValue object from a map
+ *
+ * @param obj a EntityValue object as raw map
+ * @return a EntityValue object, that behaves like a facade for the given map
+ */
+ public static EntityValue createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ EntityValue facade = new EntityValue();
+ facade.setMap(obj);
+ return facade;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static boolean isEntityValue(Object value) {
+
+ // Given Object must be a Map
+ if(!(value instanceof Map<?, ?>)) {
+ return false;
+ }
+
+ Map<String, Object> map = (Map<String, Object>) value;
+
+ // Given Map must contain all necessary Entries
+ if(!(map.get(Entity.STATEMENT) instanceof Collection<?>
+ && Reference.isReference(map.get(Entity.ASSET)))) {
+ return false;
+ }
+
+ try {
+ // Try to create a Facade for each Element
+ // If one of the Objects in STATEMENT is not a smElement,
+ // SubmodelElementFacadeFactory throws an Exception
+ ((Collection<Map<String, Object>>) map.get(Entity.STATEMENT)).stream()
+ .forEach(SubmodelElementFacadeFactory::createSubmodelElement);
+ } catch (RuntimeException e) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Collection<ISubmodelElement> getStatement() {
+ Collection<Map<String, Object>> elements = (Collection<Map<String, Object>>) get(Entity.STATEMENT);
+ return elements.stream().map(e -> SubmodelElementFacadeFactory.createSubmodelElement(e)).collect(Collectors.toList());
+ }
+
+ @SuppressWarnings("unchecked")
+ public IReference getAsset() {
+ return Reference.createAsFacade((Map<String, Object>) get(Entity.ASSET));
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/event/BasicEvent.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/event/BasicEvent.java
index cac3aaf..f04bd0b 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/event/BasicEvent.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/event/BasicEvent.java
@@ -1,7 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.submodelelement.event;
import java.util.Map;
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.event.IBasicEvent;
@@ -30,6 +40,19 @@
put(OBSERVED, observed);
}
+ /**
+ * Constructor accepting only mandatory attribute
+ * @param idShort
+ * @param observed
+ */
+ public BasicEvent(String idShort, IReference observed) {
+ super(idShort);
+
+ // Add model type
+ putAll(new ModelType(MODELTYPE));
+ put(OBSERVED, observed);
+ }
+
@Override
protected KeyElements getKeyElement() {
return KeyElements.BASICEVENT;
@@ -42,18 +65,35 @@
* @return a BasicEvent object, that behaves like a facade for the given map
*/
public static BasicEvent createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (!isValid(obj)) {
+ throw new MetamodelConstructionException(BasicEvent.class, obj);
+ }
+
BasicEvent facade = new BasicEvent();
facade.setMap(obj);
return facade;
}
/**
+ * Check whether all mandatory elements for the metamodel
+ * exist in a map
+ * @return true/false
+ */
+ public static boolean isValid(Map<String, Object> obj) {
+ return SubmodelElement.isValid(obj) && obj.containsKey(OBSERVED);
+ }
+
+ /**
* Returns true if the given submodel element map is recognized as an BasicEvent element
*/
public static boolean isBasicEvent(Map<String, Object> map) {
String modelType = ModelType.createAsFacade(map).getName();
// Either model type is set or the element type specific attributes are contained (fallback)
- return MODELTYPE.equals(modelType) || map.containsKey(OBSERVED);
+ return MODELTYPE.equals(modelType) || (modelType == null && map.containsKey(OBSERVED));
}
@Override
@@ -61,4 +101,28 @@
public IReference getObserved() {
return Reference.createAsFacade((Map<String, Object>) get(OBSERVED));
}
+
+ @Override
+ public IReference getValue() {
+ return getObserved();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void setValue(Object value) {
+ if(Reference.isReference(value)) {
+ put(OBSERVED, Reference.createAsFacade((Map<String, Object>) value));
+ }
+ else {
+ throw new IllegalArgumentException("Given Object is not a Reference");
+ }
+ }
+
+ @Override
+ public BasicEvent getLocalCopy() {
+ // Return a shallow copy
+ BasicEvent copy = new BasicEvent();
+ copy.putAll(this);
+ return copy;
+ }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/AsyncInvocation.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/AsyncInvocation.java
new file mode 100644
index 0000000..193818c
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/AsyncInvocation.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
+
+import org.apache.poi.ss.formula.functions.T;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IAsyncInvocation;
+
+/**
+ * Local implementation of IAsyncInvocation.
+ *
+ * @author conradi, espen
+ *
+ */
+public class AsyncInvocation implements IAsyncInvocation {
+ // Delayer for timeouts
+ private static ScheduledThreadPoolExecutor delayer = new ScheduledThreadPoolExecutor(0);
+
+ private String operationId;
+ private CompletableFuture<Void> future;
+ private Object result;
+ private RuntimeException exception;
+
+ @SuppressWarnings("unchecked")
+ public AsyncInvocation(Operation operation, int timeout, Object... parameters) {
+ operationId = operation.getIdShort();
+
+ Function<Object[], Object> invokable = (Function<Object[], Object>) operation.get(Operation.INVOKABLE);
+ future = CompletableFuture.supplyAsync(
+ // Run Operation asynchronously
+ () -> invokable.apply(parameters))
+ // Accept either result or throw exception on timeout
+ .acceptEither(setTimeout(timeout),
+ // result accepted => write result (or timeout exception)
+ futureResult -> this.result = futureResult
+ ).exceptionally(throwable -> {
+ // result not accepted? set operation state
+ if (throwable.getCause() instanceof OperationExecutionTimeoutException) {
+ exception = (RuntimeException) throwable.getCause();
+ } else {
+ // result not accepted? set operation state
+ exception = new OperationExecutionErrorException(
+ "Exception while executing Operation Operation '" + operationId + "'", throwable);
+ }
+ return null;
+ });
+ }
+
+ /**
+ * Function for scheduling a timeout function with completable futures
+ */
+ private CompletableFuture<T> setTimeout(int timeout) {
+ CompletableFuture<T> timeoutFuture = new CompletableFuture<>();
+ delayer.schedule(
+ () -> timeoutFuture.completeExceptionally(
+ new OperationExecutionTimeoutException("Operation " + operationId + " timed out")),
+ timeout, TimeUnit.MILLISECONDS);
+ return timeoutFuture;
+ }
+
+ @Override
+ public Object getResult() {
+ try {
+ future.get();
+ } catch (Exception e) {
+ // Some RuntimeException occured when finishing the future
+ throw new OperationExecutionErrorException(
+ "Exception while executing Operation Operation '" + operationId + "'", e.getCause());
+ }
+ if (exception instanceof OperationExecutionTimeoutException
+ || exception instanceof OperationExecutionErrorException) {
+ // Future finished with an exception
+ throw exception;
+ }
+ return result;
+ }
+
+ @Override
+ public boolean isFinished() {
+ return future.isDone();
+ }
+
+ public String getOperationId() {
+ return operationId;
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/Operation.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/Operation.java
index cbbcdd7..1568c82 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/Operation.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/Operation.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation;
import java.util.ArrayList;
@@ -5,8 +14,10 @@
import java.util.Map;
import java.util.function.Function;
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IAsyncInvocation;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperationVariable;
import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
@@ -14,6 +25,7 @@
import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
+import org.eclipse.basyx.vab.exception.provider.WrongNumberOfParametersException;
/**
* Operation as defined in DAAS document <br/>
@@ -23,12 +35,17 @@
*
*/
public class Operation extends SubmodelElement implements IOperation {
+ // Default timeout for asynchronous operation calls
+ public static final int DEFAULT_ASYNC_TIMEOUT = 10000;
+
public static final String IN = "inputVariables";
public static final String OUT = "outputVariables";
public static final String INOUT = "inoutputVariables";
public static final String INVOKABLE = "invokable";
public static final String MODELTYPE = "Operation";
+
+ public static final String INVOKE = "invoke";
/**
* Constructor
@@ -45,9 +62,25 @@
// Variables, that are input and output
put(INOUT, new ArrayList<OperationVariable>());
+ }
+
+ /**
+ * Constructor accepting only mandatory attribute
+ * @param idShort
+ */
+ public Operation(String idShort) {
+ super(idShort);
+ // Add model type
+ putAll(new ModelType(MODELTYPE));
- // Extension of DAAS specification for function storage
- put(INVOKABLE, null);
+ // Input variables
+ setInputVariables(new ArrayList<OperationVariable>());
+
+ // Output variables
+ setOutputVariables(new ArrayList<OperationVariable>());
+
+ // Variables, that are input and output
+ setInOutputVariables(new ArrayList<OperationVariable>());
}
/**
@@ -89,7 +122,7 @@
*/
public Operation(Function<Object[], Object> function) {
this();
- setInvocable(function);
+ setInvokable(function);
}
/**
@@ -100,18 +133,43 @@
* @return an Operation object, that behaves like a facade for the given map
*/
public static Operation createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (!isValid(obj)) {
+ throw new MetamodelConstructionException(Operation.class, obj);
+ }
+
Operation ret = new Operation();
ret.setMap(obj);
return ret;
}
+
+ /**
+ * Check whether all mandatory elements for the metamodel
+ * exist in a map
+ * @return true/false
+ */
+ public static boolean isValid(Map<String, Object> obj) {
+ return SubmodelElement.isValid(obj);
+ }
/**
* Returns true if the given submodel element map is recognized as an operation
*/
- public static boolean isOperation(Map<String, Object> map) {
+ @SuppressWarnings("unchecked")
+ public static boolean isOperation(Object value) {
+ if(!(value instanceof Map<?, ?>)) {
+ return false;
+ }
+
+ Map<String, Object> map = (Map<String, Object>) value;
+
String modelType = ModelType.createAsFacade(map).getName();
// Either model type is set or the element type specific attributes are contained
- return MODELTYPE.equals(modelType) || (map.containsKey(IN) && map.containsKey(OUT) && map.containsKey(INOUT));
+ return MODELTYPE.equals(modelType)
+ || (modelType == null && (map.containsKey(IN) && map.containsKey(OUT) && map.containsKey(INOUT)));
}
@Override
@@ -145,10 +203,29 @@
@SuppressWarnings("unchecked")
@Override
- public Object invoke(Object... params) throws Exception {
+ public Object invoke(Object... params) {
+ if (params.length != getInputVariables().size()) {
+ throw new WrongNumberOfParametersException(getIdShort(), getInputVariables(), params);
+ }
return ((Function<Object[], Object>) get(INVOKABLE)).apply(params);
}
+ @Override
+ public SubmodelElement[] invoke(SubmodelElement... elems) {
+ throw new UnsupportedOperationException(
+ "SubmodelElement matching logic is only supported for connected Operations");
+ }
+
+ @Override
+ public AsyncInvocation invokeAsync(Object... params) {
+ return new AsyncInvocation(this, 10000, params);
+ }
+
+ @Override
+ public IAsyncInvocation invokeAsyncWithTimeout(int timeout, Object... params) {
+ return new AsyncInvocation(this, timeout, params);
+ }
+
public void setInputVariables(Collection<OperationVariable> in) {
put(Operation.IN, in);
}
@@ -161,7 +238,7 @@
put(Operation.INOUT, inOut);
}
- public void setInvocable(Function<Object[], Object> endpoint) {
+ public void setInvokable(Function<Object[], Object> endpoint) {
put(Operation.INVOKABLE, endpoint);
}
@@ -194,4 +271,37 @@
protected KeyElements getKeyElement() {
return KeyElements.OPERATION;
}
+
+ @Override
+ public Object getValue() {
+ throw new UnsupportedOperationException("An Operation has no value");
+ }
+
+ @Override
+ public void setValue(Object value) {
+ throw new UnsupportedOperationException("An Operation has no value");
+ }
+
+ @Override
+ public Operation getLocalCopy() {
+ // Create a shallow copy
+ Operation copy = new Operation();
+ copy.putAll(this);
+ // Copy InputVariables
+ Collection<IOperationVariable> inVars = copy.getInputVariables();
+ Collection<OperationVariable> inVarCopy = new ArrayList<>();
+ inVars.stream().forEach(v -> inVarCopy.add(new OperationVariable(v.getValue().getLocalCopy())));
+ copy.setInputVariables(inVarCopy);
+ // Copy OutputVariables
+ Collection<IOperationVariable> outVars = copy.getOutputVariables();
+ Collection<OperationVariable> outVarCopy = new ArrayList<>();
+ outVars.stream().forEach(v -> outVarCopy.add(new OperationVariable(v.getValue().getLocalCopy())));
+ copy.setOutputVariables(outVarCopy);
+ // Copy Input/Output-Variables
+ Collection<IOperationVariable> inoutVars = copy.getInOutputVariables();
+ Collection<OperationVariable> inoutVarCopy = new ArrayList<>();
+ inoutVars.stream().forEach(v -> inoutVarCopy.add(new OperationVariable(v.getValue().getLocalCopy())));
+ copy.setInOutputVariables(inoutVarCopy);
+ return copy;
+ }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationExecutionErrorException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationExecutionErrorException.java
new file mode 100644
index 0000000..a3bf951
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationExecutionErrorException.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation;
+
+/**
+ * Used to indicate that the execution of an Operation failed
+ *
+ * @author conradi
+ *
+ */
+public class OperationExecutionErrorException extends RuntimeException {
+
+
+ /**
+ * Version information for serialized instances
+ */
+ private static final long serialVersionUID = 1L;
+
+
+ /**
+ * Store message
+ */
+ protected String message = null;
+
+
+ /**
+ * Constructor
+ */
+ public OperationExecutionErrorException(String msg) {
+ // Store message
+ message = msg;
+ }
+
+
+ public OperationExecutionErrorException(Exception e) {
+ super(e);
+ }
+
+
+ public OperationExecutionErrorException(String message, Throwable cause) {
+ super(cause);
+ this.message = message;
+ }
+
+
+ /**
+ * Return detailed message
+ */
+ @Override
+ public String getMessage() {
+ return message;
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationExecutionTimeoutException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationExecutionTimeoutException.java
new file mode 100644
index 0000000..4ad5021
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationExecutionTimeoutException.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation;
+
+/**
+ * Used to indicate that the execution of an Operation timed out
+ *
+ * @author espen
+ *
+ */
+public class OperationExecutionTimeoutException extends RuntimeException {
+
+
+ /**
+ * Version information for serialized instances
+ */
+ private static final long serialVersionUID = 1L;
+
+
+ /**
+ * Store message
+ */
+ protected String message = null;
+
+
+ /**
+ * Constructor
+ */
+ public OperationExecutionTimeoutException(String msg) {
+ // Store message
+ message = msg;
+ }
+
+
+ public OperationExecutionTimeoutException(Exception e) {
+ super(e);
+ }
+
+
+ public OperationExecutionTimeoutException(String message, Throwable cause) {
+ super(cause);
+ this.message = message;
+ }
+
+
+ /**
+ * Return detailed message
+ */
+ @Override
+ public String getMessage() {
+ return message;
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationHelper.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationHelper.java
index 800e874..cee7219 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationHelper.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationHelper.java
@@ -1,11 +1,20 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation;
import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDef;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
public class OperationHelper {
- public static Property createPropertyTemplate(PropertyValueTypeDef type) {
+ public static Property createPropertyTemplate(ValueType type) {
Property prop = new Property();
prop.setValueType(type);
prop.setModelingKind(ModelingKind.TEMPLATE);
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationVariable.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationVariable.java
index 15f6f22..0376c83 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationVariable.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationVariable.java
@@ -1,14 +1,28 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation;
import java.util.Map;
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperationVariable;
import org.eclipse.basyx.submodel.metamodel.facade.submodelelement.SubmodelElementFacadeFactory;
import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.haskind.HasKind;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
import org.eclipse.basyx.vab.model.VABModelMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* OperationVariable as described by DAAS document An operation variable is a
@@ -18,6 +32,8 @@
*
*/
public class OperationVariable extends VABModelMap<Object> implements IOperationVariable {
+ public static final Logger logger = LoggerFactory.getLogger(OperationVariable.class);
+
public static final String MODELTYPE = "OperationVariable";
/**
@@ -30,7 +46,7 @@
// Add model type
putAll(new ModelType(MODELTYPE));
- put(Property.VALUE, value);
+ setValue(value);
}
public OperationVariable() {
@@ -45,12 +61,44 @@
* @return an OperationVariable object, that behaves like a facade for the given map
*/
public static OperationVariable createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (!isValid(obj)) {
+ throw new MetamodelConstructionException(OperationVariable.class, obj);
+ }
+
OperationVariable facade = new OperationVariable();
facade.setMap(obj);
return facade;
}
+
+ /**
+ * Check whether all mandatory elements for the metamodel
+ * exist in a map
+ * @return true/false
+ */
+ @SuppressWarnings("unchecked")
+ public static boolean isValid(Map<String, Object> obj) {
+ return obj != null &&
+ obj.containsKey(Property.VALUE) &&
+ SubmodelElement.isValid((Map<String, Object>) obj.get(Property.VALUE));
+ }
+ /**
+ * Sets value of operation variable
+ *
+ * @param value
+ * @throws RuntimeException if modelingkind of the value is not of modelingkind.template
+ */
+ @SuppressWarnings("unchecked")
public void setValue(ISubmodelElement value) {
+ if (value.getModelingKind() != ModelingKind.TEMPLATE) {
+ // TODO: Change with 1.0 Release
+ logger.warn("Modeling kind of Operation variable was wrong and automatically changed to ModelingKind.TEMPLATE");
+ HasKind.createAsFacade((Map<String, Object>) value).setModelingKind(ModelingKind.TEMPLATE);
+ }
put(Property.VALUE, value);
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/AnnotatedRelationshipElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/AnnotatedRelationshipElement.java
new file mode 100644
index 0000000..8e4fb1f
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/AnnotatedRelationshipElement.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IDataElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.relationship.IAnnotatedRelationshipElement;
+import org.eclipse.basyx.submodel.metamodel.facade.submodelelement.SubmodelElementFacadeFactory;
+import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
+
+/**
+ * AnnotatedRelationshipElement as defined in DAAS document <br/>
+ * An annotated relationship element is a relationship element that can be annotated with additional data elements.
+ *
+ * @author schnicke, conradi
+ *
+ */
+public class AnnotatedRelationshipElement extends RelationshipElement implements IAnnotatedRelationshipElement {
+ public static final String ANNOTATIONS = "annotation";
+ public static final String MODELTYPE = "AnnotatedRelationshipElement";
+
+ public AnnotatedRelationshipElement() {
+ super();
+ // Add model type
+ putAll(new ModelType(MODELTYPE));
+ }
+
+ public AnnotatedRelationshipElement(String idShort, IReference first, IReference second) {
+ super(idShort, first, second);
+ // Add model type
+ putAll(new ModelType(MODELTYPE));
+ }
+
+ public void setAnnotation(Collection<IDataElement> annotations) {
+ put(ANNOTATIONS, annotations);
+ }
+
+
+ @SuppressWarnings("unchecked")
+ private Collection<IDataElement> getAnnotations() {
+ Collection<IDataElement> list = new ArrayList<>();
+ Collection<Map<String, Object>> annotations = (Collection<Map<String, Object>>) get(ANNOTATIONS);
+
+ // If non mandatory element annotations does not exist, return empty list
+ if(annotations == null) {
+ return list;
+ }
+
+ annotations.stream()
+ .map(m -> SubmodelElementFacadeFactory.createSubmodelElement(m))
+ .filter(e -> e instanceof IDataElement).forEach(e -> list.add((IDataElement)e));
+
+ return list;
+ }
+
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void setValue(Object obj) {
+ if (AnnotatedRelationshipElementValue.isAnnotatedRelationshipElementValue(obj)) {
+ AnnotatedRelationshipElementValue value = AnnotatedRelationshipElementValue.createAsFacade((Map<String, Object>) obj);
+ setValue(value);
+ } else {
+ throw new IllegalArgumentException("Given Object is not an AnnotatedRelationshipElementValue");
+ }
+ }
+
+ /**
+ * Creates a AnnotatedRelationshipElement object from a map
+ *
+ * @param obj
+ * a AnnotatedRelationshipElement object as raw map
+ * @return a AnnotatedRelationshipElement object, that behaves like a facade for
+ * the given map
+ */
+ public static AnnotatedRelationshipElement createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (!isValid(obj)) {
+ throw new MetamodelConstructionException(AnnotatedRelationshipElement.class, obj);
+ }
+
+ AnnotatedRelationshipElement ret = new AnnotatedRelationshipElement();
+ ret.setMap(obj);
+ return ret;
+ }
+
+ /**
+ * Check whether all mandatory elements for the metamodel exist in a map
+ *
+ * @return true/false
+ */
+ public static boolean isValid(Map<String, Object> obj) {
+ return RelationshipElement.isValid(obj);
+ }
+
+ public static boolean isAnnotatedRelationshipElement(Map<String, Object> value) {
+ String modelType = ModelType.createAsFacade(value).getName();
+ // Either model type is set or the element type specific attributes are
+ // contained
+ return MODELTYPE.equals(modelType) || (modelType == null && isValid(value));
+ }
+
+ @Override
+ public AnnotatedRelationshipElementValue getValue() {
+ return new AnnotatedRelationshipElementValue(getFirst(), getSecond(), getAnnotations());
+ }
+
+ @Override
+ public void setValue(AnnotatedRelationshipElementValue value) {
+ super.setValue(value);
+ setAnnotation(value.getAnnotations());
+ }
+
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/AnnotatedRelationshipElementValue.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/AnnotatedRelationshipElementValue.java
new file mode 100644
index 0000000..b65f2ba
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/AnnotatedRelationshipElementValue.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IDataElement;
+import org.eclipse.basyx.submodel.metamodel.facade.submodelelement.SubmodelElementFacadeFactory;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+
+/**
+ * Container class for holding the value of RelationshipElement
+ *
+ * @author schnicke, conradi
+ *
+ */
+public class AnnotatedRelationshipElementValue extends RelationshipElementValue {
+
+ public AnnotatedRelationshipElementValue(IReference first, IReference second, Collection<IDataElement> annotations) {
+ super(first, second);
+ put(AnnotatedRelationshipElement.ANNOTATIONS, annotations);
+ }
+
+ private AnnotatedRelationshipElementValue() {
+ super();
+ }
+
+ /**
+ * Creates a AnnotatedRelationshipElementValue object from a map
+ *
+ * @param obj
+ * a AnnotatedRelationshipElementValue object as raw map
+ * @return a AnnotatedRelationshipElementValue object, that behaves like a
+ * facade for the given map
+ */
+ public static AnnotatedRelationshipElementValue createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ AnnotatedRelationshipElementValue facade = new AnnotatedRelationshipElementValue();
+ facade.setMap(obj);
+ return facade;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static boolean isAnnotatedRelationshipElementValue(Object value) {
+ if(!RelationshipElementValue.isRelationshipElementValue(value)) {
+ return false;
+ } else {
+ Map<String, Object> map = (Map<String, Object>) value;
+ return Reference.isReference(map.get(AnnotatedRelationshipElement.ANNOTATIONS));
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public Collection<IDataElement> getAnnotations() {
+ Collection<IDataElement> list = new ArrayList<>();
+
+ // Feed all Elements in ANNOTATIONS through the SubmodelElementFacadeFactory
+ // then collect them in a List<IDataElement>
+ ((Collection<Map<String, Object>>) get(AnnotatedRelationshipElement.ANNOTATIONS)).stream()
+ .map(m -> SubmodelElementFacadeFactory.createSubmodelElement(m))
+ .filter(e -> e instanceof IDataElement).forEach(e -> list.add((IDataElement)e));
+
+ return list;
+ }
+
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/RelationshipElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/RelationshipElement.java
index bb9d5c6..b288e54 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/RelationshipElement.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/RelationshipElement.java
@@ -1,7 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship;
import java.util.Map;
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.relationship.IRelationshipElement;
@@ -29,9 +39,6 @@
public RelationshipElement() {
// Add model type
putAll(new ModelType(MODELTYPE));
-
- put(FIRST, null);
- put(SECOND, null);
}
/**
@@ -41,7 +48,7 @@
* @param second
* Second element in the relationship taking the role of the object.
*/
- public RelationshipElement(Reference first, Reference second) {
+ public RelationshipElement(IReference first, IReference second) {
// Add model type
putAll(new ModelType(MODELTYPE));
@@ -50,16 +57,50 @@
}
/**
+ * Constructor with only mandatory attributes
+ * @param idShort
+ * @param first
+ * @param second
+ */
+ public RelationshipElement(String idShort, IReference first, IReference second) {
+ this(first, second);
+ setIdShort(idShort);
+ }
+
+ /**
* Creates a RelationshipElement object from a map
*
* @param obj a RelationshipElement object as raw map
* @return a RelationshipElement object, that behaves like a facade for the given map
*/
public static RelationshipElement createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (!isValid(obj)) {
+ throw new MetamodelConstructionException(RelationshipElement.class, obj);
+ }
+
+
RelationshipElement ret = new RelationshipElement();
ret.setMap(obj);
return ret;
}
+
+ /**
+ * Check whether all mandatory elements for the metamodel
+ * exist in a map
+ * @return true/false
+ */
+ @SuppressWarnings("unchecked")
+ public static boolean isValid(Map<String, Object> obj) {
+ return SubmodelElement.isValid(obj) &&
+ obj.containsKey(FIRST) &&
+ obj.containsKey(SECOND) &&
+ Reference.isValid((Map<String, Object>)obj.get(FIRST)) &&
+ Reference.isValid((Map<String, Object>)obj.get(SECOND));
+ }
/**
* Returns true if the given submodel element map is recognized as a RelationshipElement
@@ -67,7 +108,7 @@
public static boolean isRelationshipElement(Map<String, Object> map) {
String modelType = ModelType.createAsFacade(map).getName();
// Either model type is set or the element type specific attributes are contained
- return MODELTYPE.equals(modelType) || (map.containsKey(FIRST) && map.containsKey(SECOND));
+ return MODELTYPE.equals(modelType) || (modelType == null && map.containsKey(FIRST) && map.containsKey(SECOND));
}
public void setFirst(IReference first) {
@@ -75,7 +116,6 @@
}
- @Override
@SuppressWarnings("unchecked")
public IReference getFirst() {
return Reference.createAsFacade((Map<String, Object>) get(RelationshipElement.FIRST));
@@ -86,7 +126,6 @@
}
- @Override
@SuppressWarnings("unchecked")
public IReference getSecond() {
return Reference.createAsFacade((Map<String, Object>) get(RelationshipElement.SECOND));
@@ -96,4 +135,35 @@
protected KeyElements getKeyElement() {
return KeyElements.RELATIONSHIPELEMENT;
}
+
+ @Override
+ public RelationshipElementValue getValue() {
+ return new RelationshipElementValue(getFirst(), getSecond());
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void setValue(Object value) {
+ if(RelationshipElementValue.isRelationshipElementValue(value)) {
+ RelationshipElementValue rev =
+ RelationshipElementValue.createAsFacade((Map<String, Object>) value);
+ setValue(rev);
+ } else {
+ throw new IllegalArgumentException("Given Object is not an RelationshipElementValue");
+ }
+ }
+
+ @Override
+ public RelationshipElement getLocalCopy() {
+ // Return a shallow copy
+ RelationshipElement copy = new RelationshipElement();
+ copy.putAll(this);
+ return copy;
+ }
+
+ @Override
+ public void setValue(RelationshipElementValue value) {
+ setFirst(value.getFirst());
+ setSecond(value.getSecond());
+ }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/RelationshipElementValue.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/RelationshipElementValue.java
new file mode 100644
index 0000000..952540b
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/RelationshipElementValue.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship;
+
+import java.util.Map;
+
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.vab.model.VABModelMap;
+
+
+/**
+ * Container class for holding the value of RelationshipElement
+ *
+ * @author conradi
+ *
+ */
+public class RelationshipElementValue extends VABModelMap<Object> {
+
+ protected RelationshipElementValue() {
+ }
+
+ public RelationshipElementValue(IReference first, IReference second) {
+ put(RelationshipElement.FIRST, first);
+ put(RelationshipElement.SECOND, second);
+ }
+
+ /**
+ * Creates a RelationshipElementValue object from a map
+ *
+ * @param obj a RelationshipElementValue object as raw map
+ * @return a RelationshipElementValue object, that behaves like a facade for the given map
+ */
+ public static RelationshipElementValue createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ RelationshipElementValue facade = new RelationshipElementValue();
+ facade.setMap(obj);
+ return facade;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static boolean isRelationshipElementValue(Object value) {
+
+ // Given Object must be a Map
+ if(!(value instanceof Map<?, ?>)) {
+ return false;
+ }
+
+ Map<String, Object> map = (Map<String, Object>) value;
+
+ return Reference.isReference(map.get(RelationshipElement.FIRST))
+ && Reference.isReference(map.get(RelationshipElement.SECOND));
+ }
+
+ @SuppressWarnings("unchecked")
+ public IReference getFirst() {
+ return Reference.createAsFacade((Map<String, Object>) get(RelationshipElement.FIRST));
+ }
+
+ @SuppressWarnings("unchecked")
+ public IReference getSecond() {
+ return Reference.createAsFacade((Map<String, Object>) get(RelationshipElement.SECOND));
+ }
+
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/MetaModelProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/MetaModelProvider.java
deleted file mode 100644
index dd40749..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/MetaModelProvider.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package org.eclipse.basyx.submodel.restapi;
-
-import java.util.Map;
-
-import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-
-/**
- * Abstract class that acts as base for each handler of the AAS meta model
- *
- * @author schnicke
- *
- */
-public abstract class MetaModelProvider implements IModelProvider {
-
- /**
- * Unwraps a parameter by retrieving the "value" entry
- *
- * @param parameter
- * @return
- */
- @SuppressWarnings("unchecked")
- protected Object unwrapParameter(Object parameter) {
- if (parameter instanceof Map<?, ?>) {
- Map<String, Object> map = (Map<String, Object>) parameter;
- // Parameters have a strictly defined order and may not be omitted at all.
- // Enforcing the structure with valueType is ok, but we should unwrap null values, too.
- if (map.get("valueType") != null && map.containsKey("value")) {
- return map.get("value");
- }
- }
- return parameter;
- }
-
- /**
- * Creates generic exception with Unknown path message
- *
- * @param path
- * @return
- */
- protected RuntimeException getUnknownPathException(String path) {
- return new RuntimeException("Unknown path: " + path);
- }
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/MultiSubmodelElementProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/MultiSubmodelElementProvider.java
new file mode 100644
index 0000000..9b01728
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/MultiSubmodelElementProvider.java
@@ -0,0 +1,191 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.restapi;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+
+/**
+ * Provider that handles container properties. Container properties can contain other submodel elements.
+ *
+ * @author espen, conradi
+ *
+ */
+public class MultiSubmodelElementProvider implements IModelProvider {
+ // Constants for API-Access
+ public static final String ELEMENTS = "submodelElements";
+ public static final String VALUE = "value";
+
+ // The VAB model provider containing the submodelElements this SubmodelElementProvider is based on
+ // Assumed to be a map that maps idShorts to the submodel elements
+ private IModelProvider modelProvider;
+
+ /**
+ * Constructor based on a model provider that contains the container property
+ */
+ public MultiSubmodelElementProvider(IModelProvider provider) {
+ this.modelProvider = provider;
+ }
+
+ /**
+ * The elements are stored in a map => convert them to a list
+ */
+ @SuppressWarnings("unchecked")
+ protected Collection<Map<String, Object>> getElementsList() {
+ Object elements = modelProvider.getValue("");
+ Map<String, Map<String, Object>> all = (Map<String, Map<String, Object>>) elements;
+
+ // Feed all ELements through their Providers, in case someting needs to be done to them (e.g. smElemCollections)
+ return all.entrySet().stream().map(e -> (Map<String, Object>) getSingleElement(ELEMENTS + "/" + e.getKey())).collect(Collectors.toList());
+ }
+
+ /**
+ * Single elements can be directly accessed in maps => return a proxy
+ */
+ private IModelProvider getElementProxy(String[] pathElements) {
+ String idShort = pathElements[1];
+ return new VABElementProxy(idShort, modelProvider);
+ }
+
+ private Object getSingleElement(String path) {
+ // Build new proxy pointing at sub-property of a submodelelement and forward the
+ // remaininig part of the path to an appropriate provider
+ String[] pathElements = VABPathTools.splitPath(path);
+ String qualifier = pathElements[0];
+ IModelProvider elementProxy = getElementProxy(pathElements);
+
+ if (qualifier.equals(ELEMENTS)) {
+ String subPath = VABPathTools.buildPath(pathElements, 2);
+ return new SubmodelElementProvider(elementProxy).getValue(subPath);
+ } else {
+ throw new MalformedRequestException("Given path '" + path + "' does not start with /submodelElements");
+ }
+ }
+
+ @Override
+ public Object getValue(String path) throws ProviderException {
+ String[] pathElements = VABPathTools.splitPath(path);
+ String qualifier = pathElements[0];
+
+ if(!qualifier.equals(ELEMENTS)) {
+ // No other qualifier in a submodel element container can be directly accessed
+ throw new MalformedRequestException("Given path '" + path + "' does not start with /submodelElements");
+ }
+
+ if (pathElements.length == 1) {
+ // returns all elements
+ return getElementsList();
+ } else {
+ // The path requests a single Element
+ return getSingleElement(path);
+ }
+ }
+
+ @Override
+ public void setValue(String path, Object newValue) throws ProviderException {
+ String[] pathElements = VABPathTools.splitPath(path);
+ String qualifier = pathElements[0];
+ if (pathElements.length < 2 || !qualifier.equals(ELEMENTS)) {
+ // only possible to set values in a data elements, currently
+ throw new MalformedRequestException("Given path '" + path + "' is invalid for set");
+ }
+
+ IModelProvider elementProxy = getElementProxy(pathElements);
+ String subPath = VABPathTools.buildPath(pathElements, 2);
+
+ new SubmodelElementProvider(elementProxy).setValue(subPath, newValue);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void createValue(String path, Object newEntity) throws ProviderException {
+ String[] pathElements = VABPathTools.splitPath(path);
+ String qualifier = pathElements[0];
+ String subPath = VABPathTools.buildPath(pathElements, 2);
+
+
+ if (!qualifier.equals(ELEMENTS)) {
+ throw new MalformedRequestException("Given path '" + path + "' does not start with /submodelElements");
+ }
+
+ // Check if the passed element is a SubmodelElementCollection. If yes, the value
+ // of the "value" key needs to be handled
+ if (SubmodelElementCollection.isSubmodelElementCollection((Map<String, Object>) newEntity)) {
+ SubmodelElementCollection smCollection = SubmodelElementCollection.createAsFacade((Map<String, Object>) newEntity);
+ newEntity = SubmodelElementMapCollectionConverter.mapToSmECollection(smCollection);
+ }
+
+ if (pathElements.length == 2) {
+ // It is allowed to overwrite existing properties inside of a submodel
+ try {
+ modelProvider.setValue(pathElements[1], newEntity);
+ } catch (ResourceNotFoundException e) {
+ modelProvider.createValue(pathElements[1], newEntity);
+ }
+ } else {
+ IModelProvider elementProxy = getElementProxy(pathElements);
+ new SubmodelElementProvider(elementProxy).createValue(subPath, newEntity);
+ }
+ }
+
+ @Override
+ public void deleteValue(String path) throws ProviderException {
+ String[] pathElements = VABPathTools.splitPath(path);
+ String qualifier = pathElements[0];
+ String subPath;
+ IModelProvider elementProvider;
+
+ if (!qualifier.equals(ELEMENTS)) {
+ throw new MalformedRequestException("Given path '" + path + "' does not start with /submodelElements");
+ }
+
+ // If the first Element is a Collection, use its Provider
+ if(pathElements.length > 2) {
+ IModelProvider elementProxy = getElementProxy(pathElements);
+ elementProvider = new SubmodelElementProvider(elementProxy);
+ subPath = VABPathTools.buildPath(pathElements, 2);
+ } else {
+ elementProvider = modelProvider;
+ subPath = VABPathTools.buildPath(pathElements, 1);
+ }
+
+ // Delete a specific submodel element
+ elementProvider.deleteValue(subPath);
+ }
+
+ @Override
+ public void deleteValue(String path, Object obj) {
+ throw new MalformedRequestException("Delete with a passed argument not allowed");
+ }
+
+ @Override
+ public Object invokeOperation(String path, Object... parameters) throws ProviderException {
+ String[] pathElements = VABPathTools.splitPath(path);
+ String subPath = VABPathTools.buildPath(pathElements, 2);
+
+ String qualifier = pathElements[0];
+ if (!qualifier.equals(ELEMENTS)) {
+ throw new MalformedRequestException("Given path '" + path + "' does not start with /submodelElements");
+ }
+
+ IModelProvider elementProxy = getElementProxy(pathElements);
+ return new SubmodelElementProvider(elementProxy).invokeOperation(subPath, parameters);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/OperationProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/OperationProvider.java
index 024c750..a962722 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/OperationProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/OperationProvider.java
@@ -1,10 +1,31 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.restapi;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.Map;
+import java.util.UUID;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperationVariable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
+import org.eclipse.basyx.submodel.restapi.operation.AsyncOperationHandler;
+import org.eclipse.basyx.submodel.restapi.operation.CallbackResponse;
+import org.eclipse.basyx.submodel.restapi.operation.ExecutionState;
+import org.eclipse.basyx.submodel.restapi.operation.InvocationRequest;
+import org.eclipse.basyx.submodel.restapi.operation.InvocationResponse;
import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
import org.eclipse.basyx.vab.modelprovider.VABPathTools;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
@@ -14,59 +35,189 @@
* @author schnicke
*
*/
-public class OperationProvider extends MetaModelProvider {
+public class OperationProvider implements IModelProvider {
+ public static final String ASYNC = "?async=true";
+ public static final String INVOCATION_LIST = "invocationList";
+ public String operationId;
- IModelProvider modelProvider;
+ private IModelProvider modelProvider;
public OperationProvider(IModelProvider modelProvider) {
this.modelProvider = modelProvider;
+ operationId = getIdShort(modelProvider.getValue(""));
}
@Override
- public Object getModelPropertyValue(String path) throws ProviderException {
+ public Object getValue(String path) throws ProviderException {
+ String[] splitted = VABPathTools.splitPath(path);
if (path.isEmpty()) {
- return modelProvider.getModelPropertyValue("");
+ return modelProvider.getValue("");
+ } else if (splitted[0].equals(INVOCATION_LIST) && splitted.length == 2) {
+ String requestId = splitted[1];
+ return AsyncOperationHandler.retrieveResult(requestId, operationId);
+
} else {
- throw new MalformedRequestException("Invalid access path");
+ throw new MalformedRequestException("Get of an Operation supports only empty or /invocationList/{requestId} paths");
}
}
@Override
- public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
- throw new MalformedRequestException("Invalid access path");
+ public void setValue(String path, Object newValue) throws ProviderException {
+ throw new MalformedRequestException("Set not allowed at path '" + path + "'");
}
@Override
public void createValue(String path, Object newEntity) throws ProviderException {
- throw new MalformedRequestException("Invalid access path");
+ throw new MalformedRequestException("Create not allowed at path '" + path + "'");
}
@Override
public void deleteValue(String path) throws ProviderException {
// Deletion of operation is handled by parent provider
- throw new MalformedRequestException("Invalid access path");
+ throw new MalformedRequestException("Delete not allowed at path '" + path + "'");
}
@Override
public void deleteValue(String path, Object obj) throws ProviderException {
- throw new MalformedRequestException("Invalid access path");
+ throw new MalformedRequestException("Delete not allowed at path '" + path + "'");
}
@Override
public Object invokeOperation(String path, Object... parameters) throws ProviderException {
- // Unwrap parameters, if they are wrapped
- for (int i = 0; i < parameters.length; i++) {
- parameters[i] = unwrapParameter(parameters[i]);
+ // Fix path
+ boolean async = path.endsWith(ASYNC);
+ // remove the "invoke" from the end of the path
+ path = VABPathTools.stripInvokeFromPath(path);
+
+ // TODO: Only allow wrapped parameters with InvokationRequests
+ Object[] unwrappedParameters;
+ InvocationRequest request = getInvocationRequest(parameters);
+ String requestId;
+ if (request != null) {
+ unwrappedParameters = request.unwrapInputParameters();
+ requestId = request.getRequestId();
+ } else {
+ // => not necessary, if it is only allowed to use InvocationRequests
+ unwrappedParameters = unwrapDirectParameters(parameters);
+ // Generate random request id
+ requestId = UUID.randomUUID().toString();
}
// Invoke /invokable instead of an Operation property if existent
- Object childElement = modelProvider.getModelPropertyValue(path);
- if (childElement instanceof Map<?, ?> && ((Map<?, ?>) childElement).containsKey(Operation.INVOKABLE)) {
+ Object childElement = modelProvider.getValue(path);
+ if (Operation.isOperation(childElement)) {
path = VABPathTools.concatenatePaths(path, Operation.INVOKABLE);
}
+
+ // Handle async operations
+ if (async) {
+ // Async call? No return value, yet
+ Collection<IOperationVariable> outputVars = copyOutputVariables();
+ IModelProvider provider = new VABElementProxy(path, modelProvider);
- // Forward call to model provider
- return modelProvider.invokeOperation(path, parameters);
+ // Only necessary as long as invocations without InvokationRequest is allowed
+ if (request != null) {
+ AsyncOperationHandler.invokeAsync(provider, operationId, request, outputVars);
+ } else {
+ AsyncOperationHandler.invokeAsync(provider, operationId, requestId, unwrappedParameters, outputVars,
+ 10000);
+ }
+
+ // Request id has to be returned for caller to be able to retrieve result
+ // => Use callback response and leave url empty
+ return new CallbackResponse(requestId, "");
+ }
+
+ // Handle synchronous operations
+ // Forward direct operation call to modelprovider
+ Object directResult = modelProvider.invokeOperation(path, unwrappedParameters);
+ if (request == null) {
+ // Parameters have been passed directly? Directly return the result
+ return directResult;
+ }
+ return createInvocationResponseFromDirectResult(request, directResult);
+ }
+
+ /**
+ * Directly creates an InvocationResponse from an operation result
+ */
+ private Object createInvocationResponseFromDirectResult(InvocationRequest request, Object directResult) {
+ // Get SubmodelElement output template
+ Collection<IOperationVariable> outputs = copyOutputVariables();
+ SubmodelElement outputElem = (SubmodelElement) outputs.iterator().next().getValue();
+ // Set result object
+ outputElem.setValue(directResult);
+
+ // Create and return InvokationResponse
+ return new InvocationResponse(request.getRequestId(), new ArrayList<>(), outputs, ExecutionState.COMPLETED);
+ }
+
+ /**
+ * Extracts an invokation request from a generic parameter array
+ *
+ * @param parameters
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ private InvocationRequest getInvocationRequest(Object[] parameters) {
+ if (parameters.length == 1 && parameters[0] instanceof Map<?, ?>) {
+ Map<String, Object> requestMap = (Map<String, Object>) parameters[0];
+ return InvocationRequest.createAsFacade(requestMap);
+ }
+ return null;
+ }
+
+ /**
+ * Gets the (first) output parameter from the underlying object
+ *
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ private Collection<IOperationVariable> copyOutputVariables() {
+ Map<String, Object> operationMap = (Map<String, Object>) getValue("");
+ Operation op = Operation.createAsFacade(operationMap);
+ Collection<IOperationVariable> outputs = op.getOutputVariables();
+ Collection<IOperationVariable> outCopy = new ArrayList<>();
+ outputs.stream().forEach(o -> outCopy.add(new OperationVariable(o.getValue().getLocalCopy())));
+ return outCopy;
+ }
+
+ @SuppressWarnings("unchecked")
+ private String getIdShort(Object operation) {
+ if(Operation.isOperation(operation)) {
+ return Operation.createAsFacade((Map<String, Object>) operation).getIdShort();
+ } else {
+ // Should never happen as SubmodelElementProvider.getElementProvider
+ // already checked that it is an Operation, if the Provider is used as intended
+ throw new ProviderException("The Object this OperationProvider is pointing to is not an Operation");
+ }
+ }
+
+ /**
+ * Unwraps a parameter by retrieving the "value" entry
+ *
+ * @param parameter
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ private Object[] unwrapDirectParameters(Object[] parameters) {
+ // Unwrap parameters, if they are wrapped
+ Object[] unwrappedParameters = new Object[parameters.length];
+ for (int i = 0; i < parameters.length; i++) {
+ Object parameter = parameters[i];
+ if (parameter instanceof Map<?, ?>) {
+ Map<String, Object> map = (Map<String, Object>) parameter;
+ // Parameters have a strictly defined order and may not be omitted at all.
+ // Enforcing the structure with valueType is ok, but we should unwrap null
+ // values, too.
+ if (map.get("valueType") != null && map.containsKey("value")) {
+ unwrappedParameters[i] = map.get("value");
+ continue;
+ }
+ }
+ unwrappedParameters[i] = parameter;
+ }
+ return unwrappedParameters;
}
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/PropertyProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/PropertyProvider.java
index 91b2030..846fe85 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/PropertyProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/PropertyProvider.java
@@ -1,10 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.restapi;
-import java.util.HashMap;
import java.util.Map;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDefHelper;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueTypeHelper;
import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
import org.eclipse.basyx.vab.exception.provider.ProviderException;
import org.eclipse.basyx.vab.modelprovider.VABPathTools;
@@ -16,7 +24,7 @@
* @author schnicke
*
*/
-public class PropertyProvider extends MetaModelProvider {
+public class PropertyProvider implements IModelProvider {
private IModelProvider proxy;
@@ -26,64 +34,54 @@
@SuppressWarnings("unchecked")
@Override
- public Object getModelPropertyValue(String path) throws ProviderException {
+ public Object getValue(String path) throws ProviderException {
path = VABPathTools.stripSlashes(path);
// Handle "/value" path
if (path.equals(Property.VALUE)) {
- // Build map containing value & valueType
- Map<String, Object> p = (Map<String, Object>) proxy.getModelPropertyValue("");
- Map<String, Object> ret = new HashMap<>();
- Object o = p.get(Property.VALUE);
+ // return value
+ Map<String, Object> p = (Map<String, Object>) proxy.getValue("");
+ return p.get(Property.VALUE);
- // Wrap return value in map describing it
- ret.put(Property.VALUE, o);
- ret.put(Property.VALUEID, p.get(Property.VALUEID));
- if (p.containsKey(Property.VALUETYPE)) {
- ret.put(Property.VALUETYPE, p.get(Property.VALUETYPE));
- } else {
- ret.put(Property.VALUETYPE, PropertyValueTypeDefHelper.getTypeWrapperFromObject(o));
- }
- return ret;
} else if (path.isEmpty()) {
// Handle "" path by returning complete property
- return proxy.getModelPropertyValue("");
+ return proxy.getValue("");
} else {
- throw getUnknownPathException(path);
+ throw new MalformedRequestException("Unknown path: " + path);
}
}
@Override
- public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
+ public void setValue(String path, Object newValue) throws ProviderException {
path = VABPathTools.stripSlashes(path);
// Only handle "/value" paths
if (path.equals(Property.VALUE)) {
// Set value and type
- proxy.setModelPropertyValue(Property.VALUE, newValue);
- proxy.setModelPropertyValue(Property.VALUETYPE, PropertyValueTypeDefHelper.getTypeWrapperFromObject(newValue));
+ proxy.setValue(Property.VALUE, newValue);
+ proxy.setValue(Property.VALUETYPE, ValueTypeHelper.getType(newValue).toString());
} else {
- throw new MalformedRequestException("Invalid access path");
+ throw new MalformedRequestException("Given Set path '" + path + "' does not end in /value");
}
}
@Override
public void createValue(String path, Object newEntity) throws ProviderException {
- throw new MalformedRequestException("Invalid access path");
+ throw new MalformedRequestException("Create not allowed at path '" + path + "'");
}
@Override
public void deleteValue(String path) throws ProviderException {
- throw new MalformedRequestException("Invalid access path");
+ throw new MalformedRequestException("Delete not allowed at path '" + path + "'");
}
@Override
public void deleteValue(String path, Object obj) throws ProviderException {
- throw new MalformedRequestException("Invalid access path");
+ throw new MalformedRequestException("Delete not allowed at path '" + path + "'");
}
@Override
public Object invokeOperation(String path, Object... parameter) throws ProviderException {
- throw new MalformedRequestException("Invalid access path");
+ throw new MalformedRequestException("Invoke not allowed at path '" + path + "'");
}
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/SubModelProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/SubModelProvider.java
deleted file mode 100644
index 97ebf4f..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/SubModelProvider.java
+++ /dev/null
@@ -1,224 +0,0 @@
-package org.eclipse.basyx.submodel.restapi;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI;
-import org.eclipse.basyx.submodel.restapi.vab.VABSubmodelAPI;
-import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
-import org.eclipse.basyx.vab.exception.provider.ProviderException;
-import org.eclipse.basyx.vab.modelprovider.VABPathTools;
-import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
-
-/**
- * Additional VAB provider specific for providing submodels together
- * with other SDKs by implementing the submodel API.
- *
- * The VAB provides generic models without considering high-level information.
- * For example, Operation submodel elements are realized as a Map. The function
- * is contained and can be accessed at /operations/opId/invokable. Therefore
- * invoking the Operation directly at /operations/opId/ attempts to invoke the
- * Map, which does not have any effect for the VABModelProvider.
- *
- * This provider maps these requests to the VAB primitives to generate the
- * desired behavior as it is described in the BaSys documentation.
- *
- * @author espen, schnicke
- *
- */
-public class SubModelProvider extends MetaModelProvider {
-
- ISubmodelAPI submodelAPI;
-
- /**
- * Default constructor - based on an empty submodel with a lambda provider
- */
- public SubModelProvider() {
- this(new SubModel());
- }
-
- /**
- * Creates a SubmodelProvider based on the VAB API, wrapping the passed provider
- *
- * @param provider
- * to be wrapped by submodel API
- */
- public SubModelProvider(IModelProvider provider) {
- submodelAPI = new VABSubmodelAPI(provider);
- }
-
- /**
- * Creates a SubModelProvider based on a lambda provider and a given model
- */
- public SubModelProvider(SubModel model) {
- submodelAPI = new VABSubmodelAPI(new VABLambdaProvider(model));
- }
-
- /**
- * Creates a SubModelProvider based on a given ISubmodelAPI.
- */
- public SubModelProvider(ISubmodelAPI submodelAPI) {
- this.submodelAPI = submodelAPI;
- }
-
- /**
- * Strips submodel prefix if it exists
- *
- * @param path
- * @return
- */
- private String removeSubmodelPrefix(String path) {
- path = VABPathTools.stripSlashes(path);
- if (path.startsWith("submodel/")) {
- path = path.replaceFirst("submodel/", "");
- } else if (path.equals("submodel")) {
- path = "";
- }
- path = VABPathTools.stripSlashes(path);
- return path;
- }
-
- @Override
- public Object getModelPropertyValue(String path) throws ProviderException {
- VABPathTools.checkPathForNull(path);
- path = removeSubmodelPrefix(path);
- if (path.isEmpty()) {
- return submodelAPI.getSubmodel();
- } else {
- String[] splitted = VABPathTools.splitPath(path);
- String qualifier = splitted[0];
- if (splitted.length == 1 && isQualifier(splitted[0])) { // Request for either properties, operations or submodelElements
- switch (qualifier) {
- case SubmodelElementProvider.ELEMENTS:
- return submodelAPI.getElements();
- case SubmodelElementProvider.OPERATIONS:
- return submodelAPI.getOperations();
- case SubmodelElementProvider.PROPERTIES:
- return submodelAPI.getProperties();
- }
- } else if (splitted.length >= 2 && isQualifier(splitted[0])) { // Request for element with specific idShort
- String idShort = splitted[1];
- if (splitted.length == 2) {
- return submodelAPI.getSubmodelElement(idShort);
- } else if (isPropertyValuePath(splitted)) { // Request for the value of an property
- return submodelAPI.getPropertyValue(idShort);
- } else if (isSubmodelElementListPath(splitted)) {
- // Create list from array and wrap it in ArrayList to ensure modifiability
- List<String> idShorts = getIdShorts(splitted);
-
- if (endsWithValue(splitted)) {
- return submodelAPI.getNestedPropertyValue(idShorts);
- } else {
- return submodelAPI.getNestedSubmodelElement(idShorts);
- }
- }
- }
- }
- throw new MalformedRequestException("Unknown path " + path + " was requested");
- }
-
- private List<String> getIdShorts(String[] splitted) {
- // Create list from array and wrap it in ArrayList to ensure modifiability
- List<String> idShorts = new ArrayList<>(Arrays.asList(splitted));
-
- // Drop inital "submodels"
- idShorts.remove(0);
-
- // If value is contained in path, remove it
- if (splitted[splitted.length - 1].equals(Property.VALUE)) {
- idShorts.remove(idShorts.size() - 1);
- }
- return idShorts;
- }
-
- private boolean isPropertyValuePath(String[] splitted) {
- return splitted.length == 3 && splitted[0].equals(SubmodelElementProvider.PROPERTIES) && endsWithValue(splitted);
- }
-
- private boolean endsWithValue(String[] splitted) {
- return splitted[splitted.length - 1].equals(Property.VALUE);
- }
-
- private boolean isSubmodelElementListPath(String[] splitted) {
- return splitted.length > 2 && splitted[0].equals(SubmodelElementProvider.ELEMENTS);
- }
-
- @Override
- public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
- path = removeSubmodelPrefix(path);
- if (path.isEmpty()) {
- throw new MalformedRequestException("Set on \"submodel\" not supported");
- } else {
- String[] splitted = VABPathTools.splitPath(path);
- if (isPropertyValuePath(splitted)) {
- String idShort = splitted[1];
- submodelAPI.updateProperty(idShort, newValue);
- } else {
- throw new MalformedRequestException("Update on path " + path + " not supported");
- }
- }
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public void createValue(String path, Object newEntity) throws ProviderException {
- path = removeSubmodelPrefix(path);
- if (path.isEmpty()) {
- // not possible to overwrite existing submodels
- throw new MalformedRequestException("Invalid access");
- } else {
- submodelAPI.addSubmodelElement(SubmodelElement.createAsFacade((Map<String, Object>) newEntity));
- }
- }
-
- @Override
- public void deleteValue(String path) throws ProviderException {
- path = removeSubmodelPrefix(path);
- if (!path.isEmpty()) {
- String[] splitted = VABPathTools.splitPath(path);
- if (splitted.length == 2 && isQualifier(splitted[0])) {
- String idShort = splitted[1];
- submodelAPI.deleteSubmodelElement(idShort);
- } else {
- throw new MalformedRequestException("Path " + path + " not supported for delete");
- }
- } else {
- throw new MalformedRequestException("Path \"submodel\" not supported for delete");
- }
- }
-
- private boolean isQualifier(String str) {
- return str.equals(SubmodelElementProvider.ELEMENTS) || str.equals(SubmodelElementProvider.OPERATIONS) || str.equals(SubmodelElementProvider.PROPERTIES);
- }
-
- @Override
- public void deleteValue(String path, Object obj) throws ProviderException {
- throw new MalformedRequestException("Delete with a passed argument not allowed");
- }
-
- @Override
- public Object invokeOperation(String path, Object... parameters) throws ProviderException {
- path = removeSubmodelPrefix(path);
- if (path.isEmpty()) {
- throw new MalformedRequestException("Invalid access");
- } else {
- String[] splitted = VABPathTools.splitPath(path);
- if (splitted.length == 2 && splitted[0].equals(SubmodelElementProvider.OPERATIONS)) {
- String idShort = splitted[1];
- return submodelAPI.invokeOperation(idShort, parameters);
- } else {
- throw new MalformedRequestException("Unknown path " + path);
- }
- }
- }
-
- protected void setAPI(ISubmodelAPI api) {
- this.submodelAPI = api;
- }
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelElementCollectionProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelElementCollectionProvider.java
index b9da328..19f66b7 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelElementCollectionProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelElementCollectionProvider.java
@@ -1,24 +1,31 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.restapi;
-import java.util.Collection;
import java.util.Map;
-import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
import org.eclipse.basyx.vab.exception.provider.ProviderException;
import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
import org.eclipse.basyx.vab.modelprovider.VABPathTools;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
/**
* Handles access to SubmodelElementCollections.
*
- * @author espen
+ * @author espen, conradi
*/
-public class SubmodelElementCollectionProvider extends MetaModelProvider {
+public class SubmodelElementCollectionProvider implements IModelProvider {
private IModelProvider proxy;
@@ -27,60 +34,62 @@
}
/**
- * Single list elements cannot be directly accessed => resolve it and return a provider
- * for the single element
+ * Get a single smElement for a given idShort and return a provider for it
*/
- @SuppressWarnings("unchecked")
protected IModelProvider getElementProvider(String idShort) {
- // Not possible to access single list elements via provider => copy it and wrap it into the
- // correspondent ElementProvider
- // Resolve the list and return a wrapper provider for the queried element
- Collection<Map<String, Object>> list = (Collection<Map<String, Object>>) proxy
- .getModelPropertyValue(Property.VALUE);
+ // The "value" before the id is needed by the providers lower down in order to handle collections correctly
+ // The paths then look like e.g. "submodelElements/collectionID/value/propertyID"
+ IModelProvider defaultProvider = new VABElementProxy(
+ VABPathTools.concatenatePaths(MultiSubmodelElementProvider.VALUE, idShort), proxy);
- // Wrap the resolved property with idShort into a SubmodelElementProvider and return that provider
- Map<String, Object> element = findElementInList(idShort, list);
- IModelProvider defaultProvider = new VABMapProvider(element);
- return SubmodelElementProvider.getElementProvider(element, defaultProvider);
+ // Wrap the property with idShort into a SubmodelElementProvider and return that provider
+ return new SubmodelElementProvider(defaultProvider);
}
- private Map<String, Object> findElementInList(String idShort, Collection<Map<String, Object>> list) {
- for (Map<String, Object> elem : list) {
- if (idShort.equals(Referable.createAsFacade(elem, KeyElements.SUBMODELELEMENT).getIdShort())) {
- return elem;
- }
- }
- throw new ResourceNotFoundException("The element \"" + idShort + "\" could not be found");
- }
-
+ @SuppressWarnings("unchecked")
@Override
- public Object getModelPropertyValue(String path) throws ProviderException {
+ public Object getValue(String path) throws ProviderException {
path = VABPathTools.stripSlashes(path);
String[] pathElements = VABPathTools.splitPath(path);
- if (path.isEmpty() || path.equals(Property.VALUE)) {
- return proxy.getModelPropertyValue(path);
+ if (path.isEmpty()) {
+ // Convert the internally used Map to a Collection before returning the smECollection
+ Map<String, Object> map = (Map<String, Object>) proxy.getValue(path);
+ SubmodelElementCollection smElemColl = SubmodelElementCollection.createAsFacade(map);
+ return SubmodelElementMapCollectionConverter.smElementToMap(smElemColl);
+ } else if(path.equals(MultiSubmodelElementProvider.VALUE)) {
+ // Return only a Collection of Elements. Not the internally used Map.
+ return SubmodelElementMapCollectionConverter.convertIDMapToCollection(proxy.getValue(path));
} else {
// Directly access an element inside of the collection
String idShort = pathElements[0];
String subPath = VABPathTools.buildPath(pathElements, 1);
- return getElementProvider(idShort).getModelPropertyValue(subPath);
+
+ return getElementProvider(idShort).getValue(subPath);
}
}
+ @SuppressWarnings("unchecked")
@Override
- public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
+ public void setValue(String path, Object newValue) throws ProviderException {
path = VABPathTools.stripSlashes(path);
String[] pathElements = VABPathTools.splitPath(path);
- if (path.isEmpty() || path.equals(Property.VALUE)) {
- proxy.setModelPropertyValue(path, newValue);
+ if (path.isEmpty()) {
+ // Convert the Collection of Elements to the internally used Map
+ Map<String, Object> value =
+ SubmodelElementMapCollectionConverter.mapToSmECollection((Map<String, Object>) newValue);
+ proxy.setValue(path, value);
+ } else if(path.equals(MultiSubmodelElementProvider.VALUE)) {
+ // Convert the Collection of Elements to the internally used Map
+ Map<String, Object> value = SubmodelElementMapCollectionConverter.convertCollectionToIDMap(newValue);
+ proxy.setValue(path, value);
} else {
// Directly access an element inside of the collection
String idShort = pathElements[0];
String subPath = VABPathTools.buildPath(pathElements, 1);
- getElementProvider(idShort).setModelPropertyValue(subPath, newValue);
+ getElementProvider(idShort).setValue(subPath, newValue);
}
}
@@ -89,8 +98,14 @@
path = VABPathTools.stripSlashes(path);
String[] pathElements = VABPathTools.splitPath(path);
- if (path.isEmpty() || path.equals(Property.VALUE)) {
- proxy.createValue(path, newEntity);
+ if (pathElements.length == 1) {
+ String valuePath = VABPathTools.concatenatePaths(MultiSubmodelElementProvider.VALUE, path);
+ // It is allowed to overwrite existing properties inside of collections
+ try {
+ proxy.setValue(valuePath, newEntity);
+ } catch (ResourceNotFoundException e) {
+ proxy.createValue(valuePath, newEntity);
+ }
} else {
// Directly access an element inside of the collection
String idShort = pathElements[0];
@@ -101,22 +116,28 @@
@Override
public void deleteValue(String path) throws ProviderException {
- throw new MalformedRequestException("Invalid access path");
+ path = VABPathTools.stripSlashes(path);
+ String[] pathElements = VABPathTools.splitPath(path);
+
+ // "value" is a keyword and can not be used as the ID of an Element
+ if (path.isEmpty() || path.equals(MultiSubmodelElementProvider.VALUE)) {
+ throw new MalformedRequestException("Path must not be empty or /value");
+ } else {
+ // If Path contains only one Element, use the proxy directly
+ if(pathElements.length == 1) {
+ proxy.deleteValue(VABPathTools.concatenatePaths(MultiSubmodelElementProvider.VALUE, path));
+ } else {
+ // If Path contains more Elements, get the Provider for the first Element in Path
+ String idShort = pathElements[0];
+ String subPath = VABPathTools.buildPath(pathElements, 1);
+ getElementProvider(idShort).deleteValue(subPath);
+ }
+ }
}
@Override
public void deleteValue(String path, Object obj) throws ProviderException {
- path = VABPathTools.stripSlashes(path);
- String[] pathElements = VABPathTools.splitPath(path);
-
- if (path.isEmpty() || path.equals(Property.VALUE)) {
- proxy.deleteValue(path, obj);
- } else {
- // Directly access an element inside of the collection
- String idShort = pathElements[0];
- String subPath = VABPathTools.buildPath(pathElements, 1);
- getElementProvider(idShort).deleteValue(subPath, obj);
- }
+ throw new MalformedRequestException("Delete with a passed argument not allowed");
}
@Override
@@ -124,8 +145,8 @@
path = VABPathTools.stripSlashes(path);
String[] pathElements = VABPathTools.splitPath(path);
- if (path.isEmpty() || path.equals(Property.VALUE)) {
- throw new MalformedRequestException("Invalid access path");
+ if (path.isEmpty() || path.equals(MultiSubmodelElementProvider.VALUE)) {
+ throw new MalformedRequestException("Path must not be empty or /value");
} else {
// Directly access an element inside of the collection
String idShort = pathElements[0];
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelElementProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelElementProvider.java
index ed7bc85..d441a41 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelElementProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelElementProvider.java
@@ -1,240 +1,154 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.restapi;
-import java.util.Collection;
import java.util.Map;
-import java.util.stream.Collectors;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.facade.submodelelement.SubmodelElementFacadeFactory;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.DataElement;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
import org.eclipse.basyx.vab.exception.provider.ProviderException;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
import org.eclipse.basyx.vab.modelprovider.VABPathTools;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
/**
- * Provider that handles container properties. Container properties can contain other submodel elements.
+ * Handles a SubmodelElement according to AAS meta model
*
- * @author espen
+ * @author schnicke, conradi
*
*/
-public class SubmodelElementProvider extends MetaModelProvider {
- // Constants for API-Access
- public static final String ELEMENTS = "submodelElements";
- public static final String PROPERTIES = "properties";
- public static final String OPERATIONS = "operations";
+public class SubmodelElementProvider implements IModelProvider {
- // The VAB model provider containing the submodelElements this SubmodelElementProvider is based on
- // Assumed to be a map that maps idShorts to the submodel elements
- private IModelProvider modelProvider;
-
- /**
- * Constructor based on a model provider that contains the container property
- */
- public SubmodelElementProvider(IModelProvider provider) {
- this.modelProvider = provider;
- }
-
- /**
- * Method for wrapping a generic Map-SubmodelElement in a concrete provider
- *
- * @param element The data with the submodel element
- * @param genericProxy A generic element provider for the element
- * @return A specific submodel element model provider (e.g. OperationProvider)
- */
- public static IModelProvider getElementProvider(Map<String, Object> element, IModelProvider genericProxy) {
- if (DataElement.isDataElement(element)) {
- return new PropertyProvider(genericProxy);
- } else if (Operation.isOperation(element)) {
- return new OperationProvider(genericProxy);
- } else if (SubmodelElementCollection.isSubmodelElementCollection(element)) {
- return new SubmodelElementCollectionProvider(genericProxy);
- } else {
- return genericProxy;
- }
- }
-
- /**
- * The elements are stored in a map => convert them to a list
- */
- @SuppressWarnings("unchecked")
- protected Collection<Map<String, Object>> getElementsList() {
- Object elements = modelProvider.getModelPropertyValue("");
- Map<String, Map<String, Object>> all = (Map<String, Map<String, Object>>) elements;
- return all.values().stream().collect(Collectors.toList());
- }
+ private IModelProvider proxy;
- private Collection<Map<String, Object>> getPropertyList() {
- Collection<Map<String, Object>> all = getElementsList();
- // Property detection => has ("value" but not "ordered") or ("min" and "max")
- return all.stream().filter(Property::isProperty).collect(Collectors.toList());
- }
+ // Flag used to indicate whether a specialized ElementProvider is used
+ private boolean specializedProvider = false;
- private Collection<Map<String, Object>> getOperationList() {
- Collection<Map<String, Object>> all = getElementsList();
- return all.stream().filter(Operation::isOperation).collect(Collectors.toList());
+ public SubmodelElementProvider(IModelProvider proxy) {
+ IModelProvider unchangedProxy = proxy;
+ this.proxy = getElementProvider(proxy);
+ // if the returned element provider is the same, no specialized provider exists
+ specializedProvider = unchangedProxy != this.proxy;
}
/**
- * Handles first-level access on submodel elements (e.g. /properties/)
+ * Used to find out if an Element needs a specialized Provider (Collection, Operation)
+ *
+ * @param proxy the Provider given from above
+ * @return either the unchanged Provider or the Provider nested into a specialized ElementProvider
*/
- private Object handleQualifierGet(String qualifier, String path) {
- if (qualifier.equals(PROPERTIES)) {
- return getPropertyList();
- } else if (qualifier.equals(OPERATIONS)) {
- return getOperationList();
- } else if (qualifier.equals(ELEMENTS)) {
- // returns all elements
- return getElementsList();
- } else {
- // No other qualifier in a submodel element container can be directly accessed
- throw getUnknownPathException(path);
- }
- }
-
- /**
- * Single elements can be directly accessed in maps => return a proxy
- */
- private IModelProvider getElementProxy(String[] pathElements) {
- String idShort = pathElements[1];
- return new VABElementProxy(idShort, modelProvider);
- }
-
@SuppressWarnings("unchecked")
- private Object handleDetailGet(String path) {
- // Build new proxy pointing at sub-property of a submodelelement and forward the
- // remaininig part of the path to an appropriate provider
- String[] pathElements = VABPathTools.splitPath(path);
- String qualifier = pathElements[0];
- String subPath = VABPathTools.buildPath(pathElements, 2);
- IModelProvider elementProxy = getElementProxy(pathElements);
- Map<String, Object> element = (Map<String, Object>) elementProxy.getModelPropertyValue("");
-
- if (pathElements.length == 2) {
- return element;
- }
-
- switch (qualifier) {
- case (ELEMENTS):
- return getElementProvider(element, elementProxy).getModelPropertyValue(subPath);
- case (PROPERTIES):
- return new PropertyProvider(elementProxy).getModelPropertyValue(subPath);
- case (OPERATIONS):
- return new OperationProvider(elementProxy).getModelPropertyValue(subPath);
- default:
- throw new MalformedRequestException("Invalid access");
- }
- }
-
- @Override
- public Object getModelPropertyValue(String path) throws ProviderException {
- String[] pathElements = VABPathTools.splitPath(path);
- String qualifier = pathElements[0];
- if (pathElements.length == 1) {
- return handleQualifierGet(qualifier, path);
+ public static IModelProvider getElementProvider(IModelProvider proxy) {
+ Map<String, Object> elementMap = (Map<String, Object>) proxy.getValue("");
+ if(Operation.isOperation(elementMap)) {
+ return new OperationProvider(proxy);
+ } else if (SubmodelElementCollection.isSubmodelElementCollection(elementMap)) {
+ return new SubmodelElementCollectionProvider(proxy);
+ } else if(Property.isProperty(elementMap)) {
+ return new PropertyProvider(proxy);
} else {
- return handleDetailGet(path);
+ return proxy;
}
}
@SuppressWarnings("unchecked")
@Override
- public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
- String[] pathElements = VABPathTools.splitPath(path);
- String qualifier = pathElements[0];
- if (pathElements.length < 2 || (!qualifier.equals(PROPERTIES) && !qualifier.equals(ELEMENTS))) {
- // only possible to set values in a data elements, currently
- throw new MalformedRequestException("Invalid access");
- }
+ public Object getValue(String path) throws ProviderException {
+ path = VABPathTools.stripSlashes(path);
- IModelProvider elementProxy = getElementProxy(pathElements);
- Map<String, Object> element = (Map<String, Object>) elementProxy.getModelPropertyValue("");
- newValue = unwrapParameter(newValue);
- if (Operation.isOperation(element)) {
- throw new MalformedRequestException("Invalid access");
- } else if (Property.isProperty(element)) {
- String subPath = VABPathTools.buildPath(pathElements, 2);
- new PropertyProvider(elementProxy).setModelPropertyValue(subPath, newValue);
+ if (path.equals(MultiSubmodelElementProvider.VALUE)) {
+ // Handle "/value" path
+ // return value
+
+ if(specializedProvider) {
+ return proxy.getValue(path);
+ }
+
+ Map<String, Object> elementMap = (Map<String, Object>) proxy.getValue("");
+
+ ISubmodelElement element = SubmodelElementFacadeFactory.createSubmodelElement(elementMap);
+
+ try {
+ return element.getValue();
+ } catch (UnsupportedOperationException e) {
+ // e.g. an Operation
+ throw new MalformedRequestException("The requested Element '" + element.getIdShort() + "' has no value.");
+ }
} else {
- // API for other elements not specified, yet => let modelprovider resolve request
- String subPath = VABPathTools.buildPath(pathElements, 2);
- elementProxy.setModelPropertyValue(subPath, newValue);
+ // Path has more Elements -> pass it to Provider below
+ return proxy.getValue(path);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void setValue(String path, Object newValue) throws ProviderException {
+ path = VABPathTools.stripSlashes(path);
+
+ if(!path.endsWith(MultiSubmodelElementProvider.VALUE)) {
+ throw new MalformedRequestException("The given path '" + path + "' does not end in /value.");
+ }
+
+ if (!specializedProvider && path.equals(MultiSubmodelElementProvider.VALUE)) {
+ // Path is only "value" and no specialized Provider has to be used -> update the Element of this Provider
+ Map<String, Object> elementMap = (Map<String, Object>) proxy.getValue("");
+
+ ISubmodelElement element = SubmodelElementFacadeFactory.createSubmodelElement(elementMap);
+
+ try {
+ element.setValue(newValue);
+ } catch (IllegalArgumentException e) {
+ throw new MalformedRequestException("The given Value was not valid for Element '" + path + "'");
+ }
+
+ proxy.setValue("", element);
+
+ } else {
+ // Path has more Elements -> pass it to Provider below
+ proxy.setValue(path, newValue);
}
}
@Override
public void createValue(String path, Object newEntity) throws ProviderException {
- if (path.equals(PROPERTIES) || path.equals(OPERATIONS) || path.equals(ELEMENTS)) {
- createSubmodelElement(newEntity);
+ if(!specializedProvider) {
+ // In a regular SubmodelElement nothing can be created
+ throw new MalformedRequestException("Creating a new Element is not allowed at '" + path + "'");
} else {
- String[] pathElements = VABPathTools.splitPath(path);
- IModelProvider elementProxy = getElementProxy(pathElements);
- String subPath = VABPathTools.buildPath(pathElements, 2);
- // API for other elements not specified, yet => let modelprovider resolve request
- elementProxy.createValue(subPath, newEntity);
+ // If a specialized Provider is used, pass it down
+ proxy.createValue(path, newEntity);
}
}
@Override
public void deleteValue(String path) throws ProviderException {
- String[] pathElements = VABPathTools.splitPath(path);
- if (pathElements.length < 2) {
- // only possible to directly delete elements with this deletion type
- throw new MalformedRequestException("Invalid access");
- }
-
- String qualifier = pathElements[0];
- String idShort = pathElements[1];
- if (qualifier.equals(PROPERTIES) || qualifier.equals(OPERATIONS) || qualifier.equals(ELEMENTS)) {
- // Delete a specific submodel element
- modelProvider.deleteValue(idShort);
+ if(!specializedProvider) {
+ // From a regular SubmodelElement nothing can be deleted
+ throw new MalformedRequestException("Deleting the Element '" + path + "' is not allowed");
} else {
- throw new MalformedRequestException("Unknown access path " + path);
+ // If a specialized Provider is used, pass it down
+ proxy.deleteValue(path);
}
}
@Override
- public void deleteValue(String path, Object obj) {
- String[] pathElements = VABPathTools.splitPath(path);
- String qualifier = pathElements[0];
- if (!qualifier.equals(ELEMENTS) && !qualifier.equals(PROPERTIES)) {
- // only possible to delete values from data elements (or in collections)
- throw new MalformedRequestException("Invalid access");
- }
- IModelProvider elementProxy = getElementProxy(pathElements);
- String subPath = VABPathTools.buildPath(pathElements, 2);
- elementProxy.deleteValue(subPath, obj);
+ public void deleteValue(String path, Object obj) throws ProviderException {
+ throw new MalformedRequestException("Delete with a passed argument not allowed");
}
- @SuppressWarnings("unchecked")
@Override
- public Object invokeOperation(String path, Object... parameters) throws ProviderException {
- String[] pathElements = VABPathTools.splitPath(path);
- String qualifier = pathElements[0];
- if (pathElements.length < 2 || (!qualifier.equals(OPERATIONS) && !qualifier.equals(ELEMENTS))) {
- // only possible to invoke operations
- throw new MalformedRequestException("Invalid access");
- }
-
- IModelProvider elementProxy = getElementProxy(pathElements);
- Map<String, Object> element = (Map<String, Object>) elementProxy.getModelPropertyValue("");
-
- if (!Operation.isOperation(element)) {
- // only possible to invoke operations
- throw new MalformedRequestException("Invalid access");
- }
-
- String subPath = VABPathTools.buildPath(pathElements, 2);
- return new OperationProvider(elementProxy).invokeOperation(subPath, parameters);
+ public Object invokeOperation(String path, Object... parameter) throws ProviderException {
+ return proxy.invokeOperation(path, parameter);
}
- @SuppressWarnings("unchecked")
- private void createSubmodelElement(Object newEntity) {
- // Create Operation or DataElement in a map
- String id = SubmodelElement.createAsFacade((Map<String, Object>) newEntity).getIdShort();
- modelProvider.createValue(id, newEntity);
- }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelProvider.java
new file mode 100644
index 0000000..3dcb31b
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelProvider.java
@@ -0,0 +1,259 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.restapi;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI;
+import org.eclipse.basyx.submodel.restapi.vab.VABSubmodelAPI;
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
+
+/**
+ * Additional VAB provider specific for providing submodels together
+ * with other SDKs by implementing the submodel API.
+ *
+ * The VAB provides generic models without considering high-level information.
+ * For example, Operation submodel elements are realized as a Map. The function
+ * is contained and can be accessed at /operations/opId/invokable. Therefore
+ * invoking the Operation directly at /operations/opId/ attempts to invoke the
+ * Map, which does not have any effect for the VABModelProvider.
+ *
+ * This provider maps these requests to the VAB primitives to generate the
+ * desired behavior as it is described in the BaSys documentation.
+ *
+ * @author espen, schnicke
+ *
+ */
+public class SubmodelProvider implements IModelProvider {
+
+ public static final String VALUES = "values";
+ public static final String SUBMODEL = "submodel";
+
+ ISubmodelAPI submodelAPI;
+
+ /**
+ * Default constructor - based on an empty submodel with a lambda provider
+ */
+ public SubmodelProvider() {
+ this(new Submodel());
+ }
+
+ /**
+ * Creates a SubmodelProvider based on the VAB API, wrapping the passed provider
+ *
+ * @param provider
+ * to be wrapped by submodel API
+ */
+ public SubmodelProvider(IModelProvider provider) {
+ submodelAPI = new VABSubmodelAPI(provider);
+ }
+
+ /**
+ * Creates a SubmodelProvider based on a lambda provider and a given model
+ */
+ public SubmodelProvider(Submodel model) {
+ submodelAPI = new VABSubmodelAPI(new VABLambdaProvider(model));
+ }
+
+ /**
+ * Creates a SubmodelProvider based on a given ISubmodelAPI.
+ */
+ public SubmodelProvider(ISubmodelAPI submodelAPI) {
+ this.submodelAPI = submodelAPI;
+ }
+
+ /**
+ * Strips submodel prefix if it exists
+ *
+ * @param path
+ * @return
+ */
+ private String removeSubmodelPrefix(String path) {
+ path = VABPathTools.stripSlashes(path);
+ String submodelWithSlash = SUBMODEL + "/";
+ if (path.startsWith(submodelWithSlash)) {
+ path = path.replaceFirst("submodel/", "");
+ } else if (path.equals(SUBMODEL)) {
+ path = "";
+ }
+ path = VABPathTools.stripSlashes(path);
+ return path;
+ }
+
+ @Override
+ public Object getValue(String path) throws ProviderException {
+ VABPathTools.checkPathForNull(path);
+ path = removeSubmodelPrefix(path);
+ if (path.isEmpty()) {
+ ISubmodel sm = submodelAPI.getSubmodel();
+
+ // Change internal map representation to set
+ if (sm instanceof Submodel) {
+ return SubmodelElementMapCollectionConverter.smToMap((Submodel) sm);
+ } else {
+ return sm;
+ }
+ } else {
+ String[] splitted = VABPathTools.splitPath(path);
+ // Request for submodelElements
+ if (splitted.length == 1 && splitted[0].equals(VALUES)) {
+ // Request for values of all submodelElements
+ return submodelAPI.getSubmodel().getValues();
+ } else if (splitted.length == 1 && splitted[0].equals(MultiSubmodelElementProvider.ELEMENTS)) {
+ return submodelAPI.getSubmodelElements();
+ } else if (splitted.length >= 2 && isQualifier(splitted[0])) { // Request for element with specific idShort
+ // Remove initial "/submodelElements"
+ path = removeSMElementPrefix(path);
+
+ if (endsWithValue(splitted)) { // Request for the value of an property
+ String idShortPath = path.replaceFirst(Pattern.quote("/value"), "");
+ return submodelAPI.getSubmodelElementValue(idShortPath);
+ } else if (isInvocationListPath(splitted)) {
+ List<String> idShorts = getIdShorts(splitted);
+
+ // Remove invocationList/{requestId} from the idShorts
+ idShorts.remove(idShorts.size() - 1);
+ idShorts.remove(idShorts.size() - 1);
+ return submodelAPI.getOperationResult(idShorts.get(0), splitted[splitted.length - 1]);
+ } else {
+ return submodelAPI.getSubmodelElement(path);
+ }
+ }
+ }
+ throw new MalformedRequestException("Unknown path " + path + " was requested");
+ }
+
+ private List<String> getIdShorts(String[] splitted) {
+ // Create list from array and wrap it in ArrayList to ensure modifiability
+ List<String> idShorts = new ArrayList<>(Arrays.asList(splitted));
+
+ // Drop inital "submodelElements"
+ idShorts.remove(0);
+
+ // If value is contained in path, remove it
+ if (splitted[splitted.length - 1].equals(Property.VALUE)) {
+ idShorts.remove(idShorts.size() - 1);
+ }
+ return idShorts;
+ }
+
+
+ private boolean endsWithValue(String[] splitted) {
+ return splitted[splitted.length - 1].equals(Property.VALUE);
+ }
+
+
+ private boolean isInvocationListPath(String[] splitted) {
+ return splitted.length > 2 && splitted[splitted.length - 2].equals(OperationProvider.INVOCATION_LIST);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void setValue(String path, Object newValue) throws ProviderException {
+ path = removeSubmodelPrefix(path);
+ if (path.isEmpty()) {
+ throw new MalformedRequestException("Set on \"submodel\" not supported");
+ } else {
+ String[] splitted = VABPathTools.splitPath(path);
+ path = removeSMElementPrefix(path);
+ String idshortPath = path.replaceFirst(Pattern.quote("/value"), "");
+ if (endsWithValue(splitted)) {
+ submodelAPI.updateSubmodelElement(idshortPath, newValue);
+ } else {
+
+ SubmodelElement element = SubmodelElement.createAsFacade((Map<String, Object>) newValue);
+
+ if(!path.endsWith(element.getIdShort())) {
+ throw new MalformedRequestException("The idShort of given Element '"
+ + element.getIdShort() + "' does not match the ending of the given path '" + path + "'");
+ }
+
+ submodelAPI.addSubmodelElement(idshortPath, element);
+ }
+ }
+ }
+
+ @Override
+ public void createValue(String path, Object newEntity) throws ProviderException {
+ throw new MalformedRequestException("POST (create) on '" + path + "' not allowed. Use PUT (set) instead.");
+ }
+
+ @Override
+ public void deleteValue(String path) throws ProviderException {
+ path = removeSubmodelPrefix(path);
+ if (!path.isEmpty()) {
+ String[] splitted = VABPathTools.splitPath(path);
+ if (isQualifier(splitted[0])) {
+ if (splitted.length > 2) {
+ path = removeSMElementPrefix(path);
+ submodelAPI.deleteSubmodelElement(path);
+ } else {
+ submodelAPI.deleteSubmodelElement(splitted[1]);
+ }
+ } else {
+ throw new MalformedRequestException("Path " + path + " not supported for delete");
+ }
+ } else {
+ throw new MalformedRequestException("Path \"submodel\" not supported for delete");
+ }
+ }
+
+ private boolean isQualifier(String str) {
+ return str.equals(MultiSubmodelElementProvider.ELEMENTS);
+ }
+
+ @Override
+ public void deleteValue(String path, Object obj) throws ProviderException {
+ throw new MalformedRequestException("Delete with a passed argument not allowed");
+ }
+
+ @Override
+ public Object invokeOperation(String path, Object... parameters) throws ProviderException {
+ path = removeSubmodelPrefix(path);
+ if (path.isEmpty()) {
+ throw new MalformedRequestException("Given path must not be empty");
+ } else {
+ if (VABPathTools.isOperationInvokationPath(path)) {
+ if(path.endsWith(OperationProvider.ASYNC)) {
+ path = removeSMElementPrefix(path);
+ path = path.replaceFirst(Pattern.quote(Operation.INVOKE + OperationProvider.ASYNC), "");
+ return submodelAPI.invokeAsync(path, parameters);
+ } else {
+ path = removeSMElementPrefix(path);
+ return submodelAPI.invokeOperation(path, parameters);
+ }
+ } else {
+ throw new MalformedRequestException("Given path '" + path + "' does not end in /invoke");
+ }
+ }
+ }
+
+ protected void setAPI(ISubmodelAPI api) {
+ this.submodelAPI = api;
+ }
+
+ private String removeSMElementPrefix(String path) {
+ return path.replaceFirst(MultiSubmodelElementProvider.ELEMENTS, "");
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/api/ISubmodelAPI.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/api/ISubmodelAPI.java
index 214e7b7..0ba527b 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/api/ISubmodelAPI.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/api/ISubmodelAPI.java
@@ -1,11 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.restapi.api;
import java.util.Collection;
-import java.util.List;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
/**
@@ -21,39 +28,43 @@
*
* @return the submodel
*/
- public ISubModel getSubmodel();
+ public ISubmodel getSubmodel();
/**
- * Returns all submodel elements contained by the submodel
- *
- * @return the submodel elements
- */
- public Collection<ISubmodelElement> getElements();
-
- /**
- * Adds a submodel element to the submodel
+ * Adds a submodelElement to the submodel
*
* @param elem
- * the element to be added
+ * the submodelElement to be added
*/
public void addSubmodelElement(ISubmodelElement elem);
/**
- * Retrieves a submodel element
+ * Adds a submodelElement to the submodel
*
- * @param idShort
- * of the submodel element
- * @return the submodel element
+ * @param idShortPath
+ * the idShort path to the submodelElement
+ * @param elem
+ * the submodelElement to be added
*/
- public ISubmodelElement getSubmodelElement(String idShort);
+ public void addSubmodelElement(String idShortPath, ISubmodelElement elem);
/**
- * Removes a submodel element from the submodel
+ * Retrieves a submodelElement
*
- * @param idShort
- * of the element to be removed
+ * @param idShortPath
+ * the idShort Path to the submodelElement
+ * @return the submodelElement
*/
- public void deleteSubmodelElement(String idShort);
+ public ISubmodelElement getSubmodelElement(String idShortPath);
+
+ /**
+ * Removes a submodelElement from the submodel
+ *
+ * @param idShortPath
+ * the idShort path to the submodelElement, which is to be removed
+ */
+ public void deleteSubmodelElement(String idShortPath);
+
/**
* Helper function for quick access of operations
@@ -63,56 +74,64 @@
public Collection<IOperation> getOperations();
/**
- * Helper function for quick access of properties
+ * Helper function for quick access of submodelElements
*
- * @return all properties contained by the submodel
+ * @return all submodelElements contained by the submodel
*/
- public Collection<IProperty> getProperties();
+ public Collection<ISubmodelElement> getSubmodelElements();
/**
- * Updates the value of a property
+ * Updates the value of a submodelElement
*
- * @param idShort
- * of the property
+ * @param idShortPath
+ * the idShort path to the submodelElement
* @param newValue
- * new value of the property
+ * new value of the submodelElement
*/
- public void updateProperty(String idShort, Object newValue);
+ public void updateSubmodelElement(String idShortPath, Object newValue);
/**
- * Retrieves the value of a property
+ * Retrieves the value of a submodelElement
*
- * @param idShort
- * of the property
- * @return property value
+ * @param idShortPath
+ * the idShort path to the submodelElement
+ * @return submodelElement value
*/
- public Object getPropertyValue(String idShort);
+ public Object getSubmodelElementValue(String idShortPath);
- /**
- * Retrieves the value of a property nested inside a SubmodelElementCollection.
- *
- * @param idShorts
- * the idShort path to the property
- */
- public Object getNestedPropertyValue(List<String> idShorts);
-
- /**
- * Retrieves a submodel element nested inside a SubmodelElementCollection
- *
- * @param idShorts
- * the idShort path to the property
- * @return
- */
- public ISubmodelElement getNestedSubmodelElement(List<String> idShorts);
/**
* Invokes an operation
*
- * @param idShort
- * of the operation
+ * @param idShortPath
+ * the idShort path to the operation
* @param params
* to be passed to the operation
* @return the result of the operation
*/
- public Object invokeOperation(String idShort, Object... params);
+ public Object invokeOperation(String idShortPath, Object... params);
+
+
+ /**
+ * Invoke an operation asynchronously
+ *
+ * @param idShortPath
+ * the idShort path to the operation
+ * @param params
+ * to be passed to the operation
+ * @return the requestId of the invocation
+ */
+ public Object invokeAsync(String idShortPath, Object... params);
+
+ /**
+ * Gets the result of an asynchronously invoked operation
+ *
+ * @param idShort
+ * of the operation
+ * @param requestId
+ * the requestId of the invocation
+ * @return the result of the Operation or a Message that it is not finished yet
+ */
+ public Object getOperationResult(String idShort, String requestId);
+
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/api/ISubmodelAPIFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/api/ISubmodelAPIFactory.java
new file mode 100644
index 0000000..a5ef08c
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/api/ISubmodelAPIFactory.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.restapi.api;
+
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+
+/**
+ * Interface for providing an Submodel API
+ *
+ * @author espen
+ *
+ */
+public interface ISubmodelAPIFactory {
+ /**
+ * Return a constructed Submodel API
+ *
+ * @return
+ */
+ public ISubmodelAPI getSubmodelAPI(Submodel submodel);
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/AsyncOperationHandler.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/AsyncOperationHandler.java
new file mode 100644
index 0000000..d09b172
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/AsyncOperationHandler.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.restapi.operation;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.poi.ss.formula.functions.T;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperationVariable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationExecutionTimeoutException;
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+
+/**
+ * Helperclass used to keep and invoke operations asynchronously.
+ *
+ * @author conradi, espen
+ *
+ */
+public class AsyncOperationHandler {
+ private static Map<String, InvocationResponse> responses = new HashMap<>();
+ private static Map<String, String> responseOperationMap = new HashMap<>();
+ private static ScheduledThreadPoolExecutor delayer = new ScheduledThreadPoolExecutor(0);
+
+ /**
+ * Invokes an Operation with an invocation request
+ */
+ public static void invokeAsync(IModelProvider provider, String operationId, InvocationRequest request,
+ Collection<IOperationVariable> outputArguments) {
+ String requestId = request.getRequestId();
+ Collection<IOperationVariable> inOutArguments = request.getInOutArguments();
+ Object[] parameters = request.unwrapInputParameters();
+ invokeAsync(provider, operationId, requestId, parameters, inOutArguments, outputArguments,
+ request.getTimeout());
+ }
+
+ /**
+ * Invokes an Operation without an invocation request
+ */
+ public static void invokeAsync(IModelProvider provider, String operationId, String requestId, Object[] inputs,
+ Collection<IOperationVariable> outputArguments, int timeout) {
+ invokeAsync(provider, operationId, requestId, inputs, new ArrayList<>(), outputArguments, timeout);
+ }
+
+ /**
+ * Invokes an Operation and returns its requestId
+ */
+ private static void invokeAsync(IModelProvider provider, String operationId, String requestId, Object[] inputs,
+ Collection<IOperationVariable> inOutArguments,
+ Collection<IOperationVariable> outputArguments, int timeout) {
+ synchronized (responses) {
+ InvocationResponse response = new InvocationResponse(requestId, inOutArguments, outputArguments,
+ ExecutionState.INITIATED);
+
+ responses.put(requestId, response);
+ responseOperationMap.put(requestId, operationId);
+
+ CompletableFuture.supplyAsync(
+ // Run Operation asynchronously
+ () -> provider.invokeOperation("", inputs))
+ // Accept either result or throw exception on timeout
+ .acceptEither(setTimeout(timeout, requestId), result -> {
+ // result accepted? => Write execution state if there is an output
+ response.setExecutionState(ExecutionState.COMPLETED);
+ if (!response.getOutputArguments().isEmpty()) {
+ IOperationVariable output = response.getOutputArguments().iterator().next();
+ output.getValue().setValue(result);
+ }
+ }).exceptionally(throwable -> {
+ // result not accepted? set operation state
+ ProviderException exception = null;
+ if (throwable.getCause() instanceof OperationExecutionTimeoutException) {
+ response.setExecutionState(ExecutionState.TIMEOUT);
+ exception = new ProviderException("Request " + requestId + " timed out", throwable);
+ } else {
+ response.setExecutionState(ExecutionState.FAILED);
+ exception = new ProviderException("Request " + requestId + " failed", throwable);
+ }
+ // set provider exception if there is an output
+ if (!response.getOutputArguments().isEmpty()) {
+ IOperationVariable output = response.getOutputArguments().iterator().next();
+ output.getValue().setValue(exception);
+ }
+ return null;
+ });
+ }
+ }
+
+ /**
+ * Function for scheduling a timeout function with completable futures
+ */
+ private static CompletableFuture<T> setTimeout(int timeout, String requestId) {
+ CompletableFuture<T> result = new CompletableFuture<>();
+ delayer.schedule(
+ () -> result.completeExceptionally(
+ new OperationExecutionTimeoutException("Request " + requestId + " timed out")),
+ timeout, TimeUnit.MILLISECONDS);
+ return result;
+ }
+
+ /**
+ * Gets the result of an invocation
+ *
+ * @param operationIdShort the id of the requested Operation
+ * @param requestId the id of the request
+ * @return the result of the Operation or a Message that it is not yet finished
+ */
+ public static Object retrieveResult(String requestId, String operationId) {
+ // Remove the Invocation if it is finished and its result was retrieved
+ synchronized (responses) {
+ if (!responses.containsKey(requestId)) {
+ throw new ResourceNotFoundException(
+ "RequestId '" + requestId + "' not found for operation '" + operationId + "'.");
+ }
+
+ String validOperationId = responseOperationMap.get(requestId);
+ if (!operationId.equals(validOperationId)) {
+ throw new ResourceNotFoundException(
+ "RequestId '" + requestId + "' does not belong to Operation '" + operationId + "'");
+ }
+
+ InvocationResponse response = responses.get(requestId);
+ if (ExecutionState.COMPLETED == response.getExecutionState()
+ || ExecutionState.TIMEOUT == response.getExecutionState()
+ || ExecutionState.FAILED == response.getExecutionState()) {
+ responses.remove(requestId);
+ responseOperationMap.remove(requestId);
+ }
+ return response;
+ }
+ }
+
+ /**
+ * Checks if a given requestId exists
+ *
+ * @param requestId the id to be checked
+ * @return if the id exists
+ */
+ public static boolean hasRequestId(String requestId) {
+ synchronized (responses) {
+ return responses.containsKey(requestId);
+ }
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/CallbackResponse.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/CallbackResponse.java
new file mode 100644
index 0000000..fb10125
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/CallbackResponse.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.restapi.operation;
+
+import java.util.Map;
+
+import org.eclipse.basyx.vab.model.VABModelMap;
+
+/**
+ * Direct response when invoking an async operation
+ *
+ * @author espen
+ *
+ */
+public class CallbackResponse extends VABModelMap<Object> {
+ public static final String REQUESTID = "requestId";
+ public static final String CALLBACKURL = "callbackUrl";
+
+ public CallbackResponse() {
+ }
+
+ public static CallbackResponse createAsFacade(Map<String, Object> map) {
+ if (map == null) {
+ return null;
+ }
+
+ CallbackResponse ret = new CallbackResponse();
+ ret.setRequestId((String) map.get(REQUESTID));
+ ret.setCallbackUrl((String) map.get(CALLBACKURL));
+
+ return ret;
+ }
+
+ public CallbackResponse(String requestId, String url) {
+ setRequestId(requestId);
+ put(CALLBACKURL, url);
+ }
+
+ public String getRequestId() {
+ return (String) get(REQUESTID);
+ }
+
+ public void setRequestId(String requestId) {
+ put(REQUESTID, requestId);
+ }
+
+ public String getCallbackUrl() {
+ return (String) get(CALLBACKURL);
+ }
+
+ public void setCallbackUrl(String callbackUrl) {
+ put(CALLBACKURL, callbackUrl);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/ExecutionState.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/ExecutionState.java
new file mode 100644
index 0000000..4e085cb
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/ExecutionState.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.restapi.operation;
+
+import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnum;
+import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnumHelper;
+
+/**
+ * ExecutionState for Operations
+ *
+ * @author espen
+ *
+ */
+public enum ExecutionState implements StandardizedLiteralEnum {
+
+ /**
+ * Initial state
+ */
+ INITIATED("Initiated"),
+ /**
+ * State during execution
+ */
+ RUNNING("Running"),
+ /**
+ * Operation has been completed
+ */
+ COMPLETED("Completed"),
+ /**
+ * Operation has been canceled
+ */
+ CANCELED("Canceled"),
+ /**
+ * Operation has failed
+ */
+ FAILED("Failed"),
+ /**
+ * Operation has timed out
+ */
+ TIMEOUT("Timeout");
+
+ private String standardizedLiteral;
+
+ private ExecutionState(String standardizedLiteral) {
+ this.standardizedLiteral = standardizedLiteral;
+ }
+
+ @Override
+ public String getStandardizedLiteral() {
+ return standardizedLiteral;
+ }
+
+ @Override
+ public String toString() {
+ return standardizedLiteral;
+ }
+
+ public static ExecutionState fromString(String str) {
+ return StandardizedLiteralEnumHelper.fromLiteral(ExecutionState.class, str);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/InvocationRequest.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/InvocationRequest.java
new file mode 100644
index 0000000..4b0178e
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/InvocationRequest.java
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.restapi.operation;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperationVariable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
+import org.eclipse.basyx.vab.model.VABModelMap;
+
+/**
+ * Request for invoking operation submodel elements
+ *
+ * @author schnicke
+ *
+ */
+public class InvocationRequest extends VABModelMap<Object> {
+ public static final String REQUESTID = "requestId";
+ public static final String INOUTARGUMENTS = "inoutputArguments";
+ public static final String INPUTARGUMENTS = "inputArguments";
+ public static final String TIMEOUT = "timeout";
+
+ private InvocationRequest() {
+ }
+
+ public InvocationRequest(String requestId, Collection<IOperationVariable> inoutArguments, Collection<IOperationVariable> inputArguments, int timeout) {
+ put(REQUESTID, requestId);
+ put(INOUTARGUMENTS, inoutArguments);
+ put(INPUTARGUMENTS, inputArguments);
+ put(TIMEOUT, timeout);
+ }
+
+ public static InvocationRequest createAsFacade(Map<String, Object> map) {
+ if (map == null) {
+ return null;
+ }
+
+ InvocationRequest ret = new InvocationRequest();
+ ret.setRequestId((String) map.get(REQUESTID));
+ Collection<IOperationVariable> inoutArguments = createInoutArguments(map);
+ ret.setInOutArguments(inoutArguments);
+
+ Collection<IOperationVariable> inputArguments = createInputArguments(map);
+ ret.setInputArguments(inputArguments);
+
+ ret.setTimeout((int) map.get(TIMEOUT));
+
+ return ret;
+ }
+
+ /**
+ * Unwraps the values of the inputVars in the order of occurance in the collection of input arguments
+ *
+ * @return
+ */
+ public Object[] unwrapInputParameters() {
+ Collection<IOperationVariable> inputArguments = getInputArguments();
+ Object[] unwrappedParameters = new Object[inputArguments.size()];
+ Iterator<IOperationVariable> iterator = inputArguments.iterator();
+ int i = 0;
+ while (iterator.hasNext()) {
+ IOperationVariable next = iterator.next();
+ unwrappedParameters[i] = next.getValue().getValue();
+ i++;
+ }
+ return unwrappedParameters;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static Collection<IOperationVariable> createInputArguments(Map<String, Object> map) {
+ Collection<Map<String, Object>> inputMap = (Collection<Map<String, Object>>) map.get(INPUTARGUMENTS);
+ return createOperationVariables(inputMap);
+ }
+
+ /**
+ * @param map
+ */
+ @SuppressWarnings("unchecked")
+ private static Collection<IOperationVariable> createInoutArguments(Map<String, Object> map) {
+ Collection<Map<String, Object>> inoutMap = (Collection<Map<String, Object>>) map.get(INOUTARGUMENTS);
+ return createOperationVariables(inoutMap);
+ }
+
+ private static Collection<IOperationVariable> createOperationVariables(Collection<Map<String, Object>> variableMap) {
+ if (variableMap != null) {
+ return variableMap.stream().map(OperationVariable::createAsFacade).collect(Collectors.toList());
+ } else {
+ return new ArrayList<>();
+ }
+ }
+
+ private void setRequestId(String request) {
+ put(REQUESTID, request);
+ }
+
+ private void setInOutArguments(Collection<IOperationVariable> inoutArguments) {
+ put(INOUTARGUMENTS, inoutArguments);
+ }
+
+ private void setInputArguments(Collection<IOperationVariable> inputArguments) {
+ put(INPUTARGUMENTS, inputArguments);
+ }
+
+ private void setTimeout(int timeout) {
+ put(TIMEOUT, timeout);
+ }
+
+ public String getRequestId() {
+ return (String) get(REQUESTID);
+ }
+
+ @SuppressWarnings("unchecked")
+ public Collection<IOperationVariable> getInOutArguments() {
+ return (Collection<IOperationVariable>) get(INOUTARGUMENTS);
+ }
+
+ @SuppressWarnings("unchecked")
+ public Collection<IOperationVariable> getInputArguments() {
+ return (Collection<IOperationVariable>) get(INPUTARGUMENTS);
+ }
+
+ public int getTimeout() {
+ return (int) get(TIMEOUT);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/InvocationResponse.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/InvocationResponse.java
new file mode 100644
index 0000000..78e4170
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/InvocationResponse.java
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.restapi.operation;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.stream.Collectors;
+
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperationVariable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
+import org.eclipse.basyx.vab.model.VABModelMap;
+
+/**
+ * Response when invoking operation submodel elements
+ *
+ * @author espen
+ *
+ */
+public class InvocationResponse extends VABModelMap<Object> {
+ public static final String REQUESTID = "requestId";
+ public static final String INOUTARGUMENTS = "inoutputArguments";
+ public static final String OUTPUTARGUMENTS = "outputArguments";
+ public static final String EXECUTIONSTATE = "executionState";
+
+ private InvocationResponse() {
+ }
+
+ public InvocationResponse(String requestId, Collection<IOperationVariable> inoutArguments,
+ Collection<IOperationVariable> outputArguments, ExecutionState executionState) {
+ put(REQUESTID, requestId);
+ put(INOUTARGUMENTS, inoutArguments);
+ put(OUTPUTARGUMENTS, outputArguments);
+ put(EXECUTIONSTATE, executionState.toString());
+ }
+
+ public static InvocationResponse createAsFacade(Map<String, Object> map) {
+ if (map == null) {
+ return null;
+ }
+
+ InvocationResponse resp = new InvocationResponse();
+ resp.setRequestId((String) map.get(REQUESTID));
+ Collection<IOperationVariable> inoutArguments = createInoutArguments(map);
+ resp.setInOutArguments(inoutArguments);
+ Collection<IOperationVariable> outputArguments = createOutputArguments(map);
+ resp.setOutputArguments(outputArguments);
+
+ Object execStateObj = map.get(EXECUTIONSTATE);
+ if (execStateObj instanceof String) {
+ resp.setExecutionState(ExecutionState.fromString((String) execStateObj));
+ } else if (execStateObj instanceof ExecutionState) {
+ resp.setExecutionState((ExecutionState) execStateObj);
+ }
+ return resp;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static Collection<IOperationVariable> createOutputArguments(Map<String, Object> map) {
+ Collection<Map<String, Object>> outputMap = (Collection<Map<String, Object>>) map.get(OUTPUTARGUMENTS);
+ return createOperationVariables(outputMap);
+ }
+
+ /**
+ * @param map
+ */
+ @SuppressWarnings("unchecked")
+ private static Collection<IOperationVariable> createInoutArguments(Map<String, Object> map) {
+ Collection<Map<String, Object>> inoutMap = (Collection<Map<String, Object>>) map.get(INOUTARGUMENTS);
+ return createOperationVariables(inoutMap);
+ }
+
+ private static Collection<IOperationVariable> createOperationVariables(
+ Collection<Map<String, Object>> variableMap) {
+ if (variableMap != null) {
+ return variableMap.stream().map(OperationVariable::createAsFacade).collect(Collectors.toList());
+ } else {
+ return new ArrayList<>();
+ }
+ }
+
+ /**
+ * Gets the first output value of this response
+ *
+ * @return The output value and null, if there is no output
+ */
+ public Object getFirstOutput() {
+ try {
+ IOperationVariable next = getOutputArguments().iterator().next();
+ return next.getValue().getValue();
+ } catch (NoSuchElementException e) {
+ return null;
+ }
+ }
+
+ private void setRequestId(String request) {
+ put(REQUESTID, request);
+ }
+
+ private void setInOutArguments(Collection<IOperationVariable> inoutArguments) {
+ put(INOUTARGUMENTS, inoutArguments);
+ }
+
+ private void setOutputArguments(Collection<IOperationVariable> inputArguments) {
+ put(OUTPUTARGUMENTS, inputArguments);
+ }
+
+ public void setExecutionState(ExecutionState state) {
+ put(EXECUTIONSTATE, state.toString());
+ }
+
+ public String getRequestId() {
+ return (String) get(REQUESTID);
+ }
+
+ @SuppressWarnings("unchecked")
+ public Collection<IOperationVariable> getInOutArguments() {
+ return (Collection<IOperationVariable>) get(INOUTARGUMENTS);
+ }
+
+ @SuppressWarnings("unchecked")
+ public Collection<IOperationVariable> getOutputArguments() {
+ return (Collection<IOperationVariable>) get(OUTPUTARGUMENTS);
+ }
+
+ public ExecutionState getExecutionState() {
+ return ExecutionState.fromString((String) get(EXECUTIONSTATE));
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPI.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPI.java
index 0eedee7..3934a04 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPI.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPI.java
@@ -1,23 +1,30 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.submodel.restapi.vab;
import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
+import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
+import org.eclipse.basyx.submodel.restapi.OperationProvider;
import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.modelprovider.VABPathTools;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
/**
@@ -50,109 +57,88 @@
* @return returns the SubmodelElementProvider pointing to the contained
* submodelelements
*/
- private SubmodelElementProvider getElementProvider() {
- IModelProvider elementProxy = new VABElementProxy(SubModel.SUBMODELELEMENT, modelProvider);
- return new SubmodelElementProvider(elementProxy);
+ private MultiSubmodelElementProvider getElementProvider() {
+ IModelProvider elementProxy = new VABElementProxy(Submodel.SUBMODELELEMENT, modelProvider);
+ return new MultiSubmodelElementProvider(elementProxy);
}
@SuppressWarnings("unchecked")
@Override
- public ISubModel getSubmodel() {
+ public ISubmodel getSubmodel() {
// For access on the container property root, return the whole model
- Map<String, Object> map = (Map<String, Object>) modelProvider.getModelPropertyValue("");
+ Map<String, Object> map = (Map<String, Object>) modelProvider.getValue("");
- // Change internal maps to sets for submodelElements
- setMapToSet(map, SubModel.SUBMODELELEMENT);
-
- return SubModel.createAsFacade(map);
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public Collection<ISubmodelElement> getElements() {
- Collection<Map<String, Object>> operations = (Collection<Map<String, Object>>) getElementProvider().getModelPropertyValue(SubmodelElementProvider.ELEMENTS);
- return operations.stream().map(e -> SubmodelElement.createAsFacade(e)).collect(Collectors.toList());
+ // Only return a copy of the Submodel
+ Map<String, Object> smCopy = new HashMap<>();
+ smCopy.putAll(map);
+ return Submodel.createAsFacade(smCopy);
}
@Override
public void addSubmodelElement(ISubmodelElement elem) {
- getElementProvider().createValue(SubmodelElementProvider.ELEMENTS + "/" + elem.getIdShort(), elem);
+ getElementProvider().createValue(MultiSubmodelElementProvider.ELEMENTS + "/" + elem.getIdShort(), elem);
}
@Override
- public void deleteSubmodelElement(String idShort) {
- getElementProvider().deleteValue(SubmodelElementProvider.ELEMENTS + "/" + idShort);
+ public void addSubmodelElement(String idShortPath, ISubmodelElement elem) {
+ getElementProvider().createValue(MultiSubmodelElementProvider.ELEMENTS + "/" + idShortPath, elem);
}
- @SuppressWarnings("unchecked")
+ @Override
+ public void deleteSubmodelElement(String idShortPath) {
+ getElementProvider().deleteValue(MultiSubmodelElementProvider.ELEMENTS + "/" + idShortPath);
+ }
+
+
@Override
public Collection<IOperation> getOperations() {
- Collection<Map<String, Object>> operations = (Collection<Map<String, Object>>) getElementProvider().getModelPropertyValue(SubmodelElementProvider.OPERATIONS);
- return operations.stream().map(e -> Operation.createAsFacade(e)).collect(Collectors.toList());
- }
-
-
- /**
- * Converts a map entry to a set, if it is also a map
- */
- @SuppressWarnings("unchecked")
- private void setMapToSet(Map<String, Object> map, String key) {
- Object mapEntry = map.get(key);
- if (mapEntry instanceof Map<?, ?>) {
- Map<String, Object> elements = (Map<String, Object>) mapEntry;
- map.put(key, new HashSet<Object>(elements.values()));
- }
+ return getSubmodelElements().stream().filter(e -> e instanceof IOperation).map(e -> (IOperation) e).collect(Collectors.toList());
}
@SuppressWarnings("unchecked")
@Override
- public Collection<IProperty> getProperties() {
- Collection<Map<String, Object>> props = (Collection<Map<String, Object>>) getElementProvider().getModelPropertyValue(SubmodelElementProvider.PROPERTIES);
- return props.stream().map(e -> Property.createAsFacade(e)).collect(Collectors.toList());
+ public Collection<ISubmodelElement> getSubmodelElements() {
+ Collection<Map<String, Object>> elements = (Collection<Map<String, Object>>) getElementProvider()
+ .getValue(MultiSubmodelElementProvider.ELEMENTS);
+ return elements.stream().map(SubmodelElement::createAsFacade).collect(Collectors.toList());
}
@Override
- public void updateProperty(String idShort, Object newValue) {
- getElementProvider().setModelPropertyValue(buildValuePathForProperty(idShort), newValue);
+ public void updateSubmodelElement(String idShortPath, Object newValue) {
+ getElementProvider().setValue(buildValuePathForProperty(idShortPath), newValue);
}
@Override
- public Object getPropertyValue(String idShort) {
- return getElementProvider().getModelPropertyValue(buildValuePathForProperty(idShort));
+ public Object getSubmodelElementValue(String idShortPath) {
+ return getElementProvider().getValue(buildValuePathForProperty(idShortPath));
}
@SuppressWarnings("unchecked")
@Override
- public ISubmodelElement getSubmodelElement(String idShort) {
- return SubmodelElement.createAsFacade((Map<String, Object>) getElementProvider().getModelPropertyValue(SubmodelElementProvider.ELEMENTS + "/" + idShort));
+ public ISubmodelElement getSubmodelElement(String idShortPath) {
+ return SubmodelElement.createAsFacade((Map<String, Object>) getElementProvider().getValue(MultiSubmodelElementProvider.ELEMENTS + "/" + idShortPath));
}
@Override
- public Object invokeOperation(String idShort, Object... params) {
- return getElementProvider().invokeOperation(SubmodelElementProvider.OPERATIONS + "/" + idShort, params);
+ public Object invokeOperation(String idShortPath, Object... params) {
+ return getElementProvider().invokeOperation(MultiSubmodelElementProvider.ELEMENTS + "/" + idShortPath, params);
}
-
- private String buildValuePathForProperty(String idShort) {
- return SubmodelElementProvider.PROPERTIES + "/" + idShort + "/" + Property.VALUE;
- }
-
+
+
@Override
- public Object getNestedPropertyValue(List<String> idShorts) {
- return getElementProvider().getModelPropertyValue(buildNestedElementPath(idShorts) + "/" + Property.VALUE);
+ public Object invokeAsync(String idShortPath, Object... params) {
+ return getElementProvider().invokeOperation(MultiSubmodelElementProvider.ELEMENTS + "/" + idShortPath +"/" + Operation.INVOKE + OperationProvider.ASYNC, params);
}
- @SuppressWarnings("unchecked")
+ private String buildValuePathForProperty(String idShortPath) {
+ return MultiSubmodelElementProvider.ELEMENTS + "/" + idShortPath + "/" + Property.VALUE;
+ }
+
+
@Override
- public ISubmodelElement getNestedSubmodelElement(List<String> idShorts) {
- Map<String, Object> map = (Map<String, Object>) getElementProvider().getModelPropertyValue(buildNestedElementPath(idShorts));
- return SubmodelElement.createAsFacade(map);
+ public Object getOperationResult(String idShortPath, String requestId) {
+ return getElementProvider().getValue(MultiSubmodelElementProvider.ELEMENTS + "/" + idShortPath + "/" + OperationProvider.INVOCATION_LIST + "/" + requestId);
}
- /**
- * @param idShorts
- * @return
- */
- private String buildNestedElementPath(List<String> idShorts) {
- return SubmodelElementProvider.ELEMENTS + "/" + VABPathTools.concatenatePaths(idShorts.toArray(new String[1]));
- }
+
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPIFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPIFactory.java
new file mode 100644
index 0000000..a547c9c
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPIFactory.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.restapi.vab;
+
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI;
+import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPIFactory;
+import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
+
+/**
+ * Submodel API provider that provides the default VAB Submodel API
+ *
+ * @author espen
+ *
+ */
+public class VABSubmodelAPIFactory implements ISubmodelAPIFactory {
+ @Override
+ public ISubmodelAPI getSubmodelAPI(Submodel submodel) {
+ return new VABSubmodelAPI(new VABLambdaProvider(submodel));
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/DigitalNameplateSubmodel.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/DigitalNameplateSubmodel.java
new file mode 100644
index 0000000..1e76b2b
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/DigitalNameplateSubmodel.java
@@ -0,0 +1,446 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.types.digitalnameplate;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IMultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address.Address;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.assetspecificproperties.AssetSpecificProperties;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.markings.Markings;
+
+/**
+ * DigitalNameplateSubmodel as defined in the AAS Digital Nameplate Template document <br/>
+ * this contains the nameplate information attached to the product
+ *
+ * @author haque
+ *
+ */
+public class DigitalNameplateSubmodel extends Submodel {
+ public static final String MANUFACTURERNAMEID = "ManufacturerName";
+ public static final String MANUFACTURERPRODUCTDESIGNATIONID = "ManufacturerProductDesignation";
+ public static final String ADDRESSID = "Address";
+ public static final String MANUFACTURERPRODUCTFAMILYID = "ManufacturerProductFamily";
+ public static final String SERIALNUMBERID = "SerialNumber";
+ public static final String YEARSOFCONSTRUCTIONID = "YearOfConstruction";
+ public static final String MARKINGSID = "Markings";
+ public static final String ASSETSPECIFICPROPERTIESID = "AssetSpecificProperties";
+ public static final Reference SEMANTICID = new Reference(Collections.singletonList(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/zvei/nameplate/1/0/Nameplate", KeyType.IRI)));
+ public static final String SUBMODELID = "Nameplate";
+
+ private DigitalNameplateSubmodel() {}
+
+ /**
+ * Constructor with default idShort
+ * @param identifier
+ * @param manufacturerName
+ * @param manufacturerProductDesignation
+ * @param address
+ * @param manufacturerProductFamily
+ * @param yearsOfConstruction
+ */
+ public DigitalNameplateSubmodel(
+ Identifier identifier,
+ MultiLanguageProperty manufacturerName,
+ MultiLanguageProperty manufacturerProductDesignation,
+ Address address,
+ MultiLanguageProperty manufacturerProductFamily,
+ Property yearsOfConstruction
+ ) {
+ this(SUBMODELID, identifier, manufacturerName, manufacturerProductDesignation, address, manufacturerProductFamily, yearsOfConstruction);
+ }
+
+ /**
+ * Constructor with default idShort
+ * @param identifier
+ * @param manufacturerName
+ * @param manufacturerProductDesignation
+ * @param address
+ * @param manufacturerProductFamily
+ * @param yearsOfConstruction
+ */
+ public DigitalNameplateSubmodel(
+ Identifier identifier,
+ LangString manufacturerName,
+ LangString manufacturerProductDesignation,
+ Address address,
+ LangString manufacturerProductFamily,
+ String yearsOfConstruction
+ ) {
+ this(SUBMODELID, identifier, manufacturerName, manufacturerProductDesignation, address, manufacturerProductFamily, yearsOfConstruction);
+ }
+
+ /**
+ * Constructor with mandatory attributes
+ * @param idShort
+ * @param identifier
+ * @param manufacturerName
+ * @param manufacturerProductDesignation
+ * @param address
+ * @param manufacturerProductFamily
+ * @param yearsOfConstruction
+ */
+ public DigitalNameplateSubmodel(
+ String idShort,
+ Identifier identifier,
+ MultiLanguageProperty manufacturerName,
+ MultiLanguageProperty manufacturerProductDesignation,
+ Address address,
+ MultiLanguageProperty manufacturerProductFamily,
+ Property yearsOfConstruction
+ ) {
+ super(idShort, identifier);
+ setSemanticId(SEMANTICID);
+ setManufacturerName(manufacturerName);
+ setManufacturerProductDesignation(manufacturerProductDesignation);
+ setAddress(address);
+ setManufacturerProductFamily(manufacturerProductFamily);
+ setYearOfConstruction(yearsOfConstruction);
+ }
+
+ /**
+ * Constructor with mandatory attributes
+ * @param idShort
+ * @param identifier
+ * @param manufacturerName
+ * @param manufacturerProductDesignation
+ * @param address
+ * @param manufacturerProductFamily
+ * @param yearsOfConstruction
+ */
+ public DigitalNameplateSubmodel(
+ String idShort,
+ Identifier identifier,
+ LangString manufacturerName,
+ LangString manufacturerProductDesignation,
+ Address address,
+ LangString manufacturerProductFamily,
+ String yearsOfConstruction
+ ) {
+ super(idShort, identifier);
+ setSemanticId(SEMANTICID);
+ setManufacturerName(manufacturerName);
+ setManufacturerProductDesignation(manufacturerProductDesignation);
+ setAddress(address);
+ setManufacturerProductFamily(manufacturerProductFamily);
+ setYearOfConstruction(yearsOfConstruction);
+ }
+
+ /**
+ * Creates a DigitalNameplateSubmodel object from a map
+ *
+ * @param obj a DigitalNameplateSubmodel SMC object as raw map
+ * @return a DigitalNameplateSubmodel SMC object, that behaves like a facade for the given map
+ */
+ public static DigitalNameplateSubmodel createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (!isValid(obj)) {
+ throw new MetamodelConstructionException(DigitalNameplateSubmodel.class, obj);
+ }
+
+ DigitalNameplateSubmodel ret = new DigitalNameplateSubmodel();
+ ret.setMap(SubmodelElementMapCollectionConverter.mapToSM(obj));
+ return ret;
+ }
+
+ /**
+ * Creates a DigitalNameplateSubmodel object from a map without validation
+ *
+ * @param obj a DigitalNameplateSubmodel SMC object as raw map
+ * @return a DigitalNameplateSubmodel SMC object, that behaves like a facade for the given map
+ */
+ private static DigitalNameplateSubmodel createAsFacadeNonStrict(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ DigitalNameplateSubmodel ret = new DigitalNameplateSubmodel();
+ ret.setMap(SubmodelElementMapCollectionConverter.mapToSM(obj));
+ return ret;
+ }
+
+ /**
+ * Check whether all mandatory elements for DigitalNameplateSubmodel
+ * exist in the map
+ *
+ * @param obj
+ *
+ * @return true/false
+ */
+ @SuppressWarnings("unchecked")
+ public static boolean isValid(Map<String, Object> obj) {
+ DigitalNameplateSubmodel submodel = createAsFacadeNonStrict(obj);
+
+ return Submodel.isValid(obj)
+ && MultiLanguageProperty.isValid((Map<String, Object>) submodel.getManufacturerName())
+ && MultiLanguageProperty.isValid((Map<String, Object>) submodel.getManufacturerProductDesignation())
+ && Address.isValid(submodel.getAddress())
+ && MultiLanguageProperty.isValid((Map<String, Object>) submodel.getManufacturerProductFamily())
+ && Property.isValid((Map<String, Object>) submodel.getYearOfConstruction());
+ }
+
+ /**
+ * Sets manufacturerName
+ * legally valid designation of the natural or judicial person which is directly
+ * responsible for the design, production, packaging and labeling of a product
+ * in respect to its being brought into circulation
+ * Note: mandatory property according to EU Machine Directive
+ * 2006/42/EC.
+ * @param manufacturerName {@link MultiLanguageProperty}
+ */
+ public void setManufacturerName(MultiLanguageProperty manufacturerName) {
+ addSubmodelElement(manufacturerName);
+ }
+
+ /**
+ * Sets manufacturerName
+ * legally valid designation of the natural or judicial person which is directly
+ * responsible for the design, production, packaging and labeling of a product
+ * in respect to its being brought into circulation
+ * Note: mandatory property according to EU Machine Directive
+ * 2006/42/EC.
+ * @param manufacturerName {@link LangString}
+ */
+ public void setManufacturerName(LangString manufacturerName) {
+ MultiLanguageProperty manufacturerNameProp = new MultiLanguageProperty(MANUFACTURERNAMEID);
+ manufacturerNameProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO677#002", IdentifierType.IRDI)));
+ manufacturerNameProp.setValue(new LangStrings(manufacturerName));
+ setManufacturerName(manufacturerNameProp);
+ }
+
+ /**
+ *
+ * Gets manufacturerName
+ * legally valid designation of the natural or judicial person which is directly
+ * responsible for the design, production, packaging and labeling of a product
+ * in respect to its being brought into circulation
+ * Note: mandatory property according to EU Machine Directive
+ * 2006/42/EC.
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IMultiLanguageProperty getManufacturerName() {
+ return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(MANUFACTURERNAMEID));
+ }
+
+ /**
+ * Sets Short description of the product (short text)
+ * Note: mandatory property according to EU Machine Directive
+ * 2006/42/EC.
+ * @param manufacturerProductDesignation {@link MultiLanguageProperty}
+ */
+ public void setManufacturerProductDesignation(MultiLanguageProperty manufacturerProductDesignation) {
+ addSubmodelElement(manufacturerProductDesignation);
+ }
+
+ /**
+ * Sets Short description of the product (short text)
+ * Note: mandatory property according to EU Machine Directive
+ * 2006/42/EC.
+ * @param manufacturerProductDesignation {@link LangString}
+ */
+ public void setManufacturerProductDesignation(LangString manufacturerProductDesignation) {
+ MultiLanguageProperty manufacturerProductDesignationProp = new MultiLanguageProperty(MANUFACTURERPRODUCTDESIGNATIONID);
+ manufacturerProductDesignationProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAW338#001", IdentifierType.IRDI)));
+ manufacturerProductDesignationProp.setValue(new LangStrings(manufacturerProductDesignation));
+ setManufacturerProductDesignation(manufacturerProductDesignationProp);
+ }
+
+ /**
+ * Gets Short description of the product (short text)
+ * Note: mandatory property according to EU Machine Directive
+ * 2006/42/EC.
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IMultiLanguageProperty getManufacturerProductDesignation() {
+ return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(MANUFACTURERPRODUCTDESIGNATIONID));
+ }
+
+ /**
+ * Sets address information of a business partner
+ *
+ * Note: mandatory property according to EU Machine Directive
+ * 2006/42/EC.
+ * @param address
+ */
+ public void setAddress(Address address) {
+ addSubmodelElement(address);
+ }
+
+ /**
+ * Gets address information of a business partner
+ *
+ * Note: mandatory property according to EU Machine Directive
+ * 2006/42/EC.
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public Address getAddress() {
+ ISubmodelElement element = getSubmodelElement(ADDRESSID);
+ return element == null ? null : Address.createAsFacade((Map<String, Object>) element);
+ }
+
+ /**
+ * Sets 2nd level of a 3 level manufacturer specific product hierarchy
+ * Note: mandatory property according to EU Machine Directive
+ * 2006/42/EC.
+ * @param manufacturerProductFamily {@link MultiLanguageProperty}
+ */
+ public void setManufacturerProductFamily(MultiLanguageProperty manufacturerProductFamily) {
+ addSubmodelElement(manufacturerProductFamily);
+ }
+
+ /**
+ * Sets 2nd level of a 3 level manufacturer specific product hierarchy
+ * Note: mandatory property according to EU Machine Directive
+ * 2006/42/EC.
+ * @param manufacturerProductFamily {@link LangString}
+ */
+ public void setManufacturerProductFamily(LangString manufacturerProductFamily) {
+ MultiLanguageProperty manufacturerProductFamilyProp = new MultiLanguageProperty(MANUFACTURERPRODUCTFAMILYID);
+ manufacturerProductFamilyProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAU731#001", IdentifierType.IRDI)));
+ manufacturerProductFamilyProp.setValue(new LangStrings(manufacturerProductFamily));
+ setManufacturerProductFamily(manufacturerProductFamilyProp);
+ }
+
+ /**
+ * Gets 2nd level of a 3 level manufacturer specific product hierarchy
+ * Note: mandatory property according to EU Machine Directive
+ * 2006/42/EC.
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IMultiLanguageProperty getManufacturerProductFamily() {
+ return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(MANUFACTURERPRODUCTFAMILYID));
+ }
+
+ /**
+ * Sets unique combination of numbers and letters used to identify the device
+ * once it has been manufactured
+ * @param serialNumber
+ */
+ public void setSerialNumber(Property serialNumber) {
+ addSubmodelElement(serialNumber);
+ }
+
+ /**
+ * Sets unique combination of numbers and letters used to identify the device
+ * once it has been manufactured
+ * @param serialNumber
+ */
+ public void setSerialNumber(String serialNumber) {
+ Property serialNumberProp = new Property(SERIALNUMBERID, ValueType.String);
+ serialNumberProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAM556#002", IdentifierType.IRDI)));
+ serialNumberProp.setValue(serialNumber);
+ setSerialNumber(serialNumberProp);
+ }
+
+ /**
+ * Gets unique combination of numbers and letters used to identify the device
+ * once it has been manufactured
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IProperty getSerialNumber() {
+ return Property.createAsFacade((Map<String, Object>) getSubmodelElement(SERIALNUMBERID));
+ }
+
+ /**
+ * Sets year as completion date of object
+ * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+ * @param yearsOfConstruction
+ */
+ public void setYearOfConstruction(Property yearsOfConstruction) {
+ addSubmodelElement(yearsOfConstruction);
+ }
+
+ /**
+ * Sets year as completion date of object
+ * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+ * @param yearsOfConstruction
+ */
+ public void setYearOfConstruction(String yearsOfConstruction) {
+ Property yearsOfConstructionProp = new Property(YEARSOFCONSTRUCTIONID, ValueType.String);
+ yearsOfConstructionProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAP906#001", IdentifierType.IRDI)));
+ yearsOfConstructionProp.setValue(yearsOfConstruction);
+ setYearOfConstruction(yearsOfConstructionProp);
+ }
+
+ /**
+ * Gets year as completion date of object
+ * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IProperty getYearOfConstruction() {
+ return Property.createAsFacade((Map<String, Object>) getSubmodelElement(YEARSOFCONSTRUCTIONID));
+ }
+
+ /**
+ * Sets collection of product markings
+ * Note: CE marking is declared as mandatory according to EU Machine
+ * Directive 2006/42/EC.
+ * @param markings
+ */
+ public void setMarkings(Markings markings) {
+ addSubmodelElement(markings);
+ }
+
+ /**
+ * Gets collection of product markings
+ * Note: CE marking is declared as mandatory according to EU Machine
+ * Directive 2006/42/EC.
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public Markings getMarkings() {
+ ISubmodelElement element = getSubmodelElement(MARKINGSID);
+ return element == null ? null : Markings.createAsFacade((Map<String, Object>) element);
+ }
+
+ /**
+ * Sets collection of guideline specific properties
+ * @param assetSpecificProperties
+ */
+ public void setAssetSpecificProperties(AssetSpecificProperties assetSpecificProperties) {
+ addSubmodelElement(assetSpecificProperties);
+ }
+
+ /**
+ * Gets collection of guideline specific properties
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public AssetSpecificProperties getAssetSpecificProperties() {
+ ISubmodelElement element = getSubmodelElement(ASSETSPECIFICPROPERTIESID);
+ return element == null ? null : AssetSpecificProperties.createAsFacade((Map<String, Object>) element);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/FaxType.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/FaxType.java
new file mode 100644
index 0000000..74e8074
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/FaxType.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.types.digitalnameplate.enums;
+
+import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnum;
+import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnumHelper;
+
+/**
+ * characterization of the fax according its location or usage
+ * as described in the AAS Digital Nameplate template
+ * @author haque
+ *
+ */
+public enum FaxType implements StandardizedLiteralEnum {
+
+ /**
+ * (office, 0173-1#07-AAS754#001)
+ */
+ OFFICE("1"),
+
+ /**
+ * (secretary, 0173-1#07-AAS756#001)
+ */
+ SECRETARY("3"),
+
+ /**
+ * (home, 0173-1#07-AAS758#001)
+ */
+ HOME("5");
+
+ private String standardizedLiteral;
+
+ private FaxType(String standardizedLiteral) {
+ this.standardizedLiteral = standardizedLiteral;
+ }
+
+ @Override
+ public String getStandardizedLiteral() {
+ return standardizedLiteral;
+ }
+
+ @Override
+ public String toString() {
+ return standardizedLiteral;
+ }
+
+ public static FaxType fromString(String str) {
+ return StandardizedLiteralEnumHelper.fromLiteral(FaxType.class, str);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/MailType.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/MailType.java
new file mode 100644
index 0000000..9a6b1b6
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/MailType.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.types.digitalnameplate.enums;
+
+import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnum;
+import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnumHelper;
+
+/**
+ * characterization of an e-mail address according to its location or usage
+ * as described in the AAS Digital Nameplate template
+ * @author haque
+ *
+ */
+public enum MailType implements StandardizedLiteralEnum {
+ // Enum values
+
+ /**
+ * (office, 0173-1#07-AAS754#001)
+ */
+ OFFICE("1"),
+
+ /**
+ * (secretary, 0173-1#07-AAS756#001)
+ */
+ SECRETARY("3"),
+
+ /**
+ * (substitute, 0173-1#07-AAS757#001)
+ */
+ SUBSTITUTE("4"),
+
+ /**
+ * (home, 0173-1#07-AAS758#001)
+ */
+ HOME("5");
+
+ private String standardizedLiteral;
+
+ private MailType(String standardizedLiteral) {
+ this.standardizedLiteral = standardizedLiteral;
+ }
+
+ @Override
+ public String getStandardizedLiteral() {
+ return standardizedLiteral;
+ }
+
+ @Override
+ public String toString() {
+ return standardizedLiteral;
+ }
+
+ public static MailType fromString(String str) {
+ return StandardizedLiteralEnumHelper.fromLiteral(MailType.class, str);
+ }
+
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/PhoneType.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/PhoneType.java
new file mode 100644
index 0000000..b588eae
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/PhoneType.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.types.digitalnameplate.enums;
+
+import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnum;
+import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnumHelper;
+
+/**
+ * characterization of a telephone according to its location or usage
+ * as described in the AAS Digital Nameplate template
+ * @author haque
+ *
+ */
+public enum PhoneType implements StandardizedLiteralEnum {
+
+ /**
+ * (office, 0173-1#07-AAS754#001)
+ */
+ OFFICE("1"),
+
+ /**
+ * (office mobile, 0173-1#07-AAS755#001)
+ */
+ OFFICEMOBILE("2"),
+
+ /**
+ * (secretary, 0173-1#07-AAS756#001)
+ */
+ SECRETARY("3"),
+
+ /**
+ * (substitute, 0173-1#07-AAS757#001)
+ */
+ SUBSTITUTE("4"),
+
+ /**
+ * (home, 0173-1#07-AAS758#001)
+ */
+ HOME("5"),
+
+ /**
+ * (private mobile, 0173-1#07-AAS759#001)
+ */
+ PRIVATEMOBILE("6");;
+
+ private String standardizedLiteral;
+
+ private PhoneType(String standardizedLiteral) {
+ this.standardizedLiteral = standardizedLiteral;
+ }
+
+ @Override
+ public String getStandardizedLiteral() {
+ return standardizedLiteral;
+ }
+
+ @Override
+ public String toString() {
+ return standardizedLiteral;
+ }
+
+ public static PhoneType fromString(String str) {
+ return StandardizedLiteralEnumHelper.fromLiteral(PhoneType.class, str);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Address.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Address.java
new file mode 100644
index 0000000..d0ebd78
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Address.java
@@ -0,0 +1,578 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IMultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.helper.SubmodelElementRetrievalHelper;
+
+/**
+ * Address as defined in the AAS Digital Nameplate Template document <br/>
+ * It is a submodel element collection which contains
+ * The standardized SMC Address contains information
+ * about address of a partner within the value chain.
+ *
+ * @author haque
+ *
+ */
+public class Address extends SubmodelElementCollection {
+ public static final String DEPARTMENTID = "Department";
+ public static final String STREETID = "Street";
+ public static final String ZIPCODEID = "Zipcode";
+ public static final String POBOXID = "POBox";
+ public static final String ZIPCODEOFPOBOXID = "ZipCodeOfPOBox";
+ public static final String CITYTOWNID = "CityTown";
+ public static final String STATECOUNTYID = "StateCounty";
+ public static final String NATIONALCODEID = "NationalCode";
+ public static final String VATNUMBERID = "VATNumber";
+ public static final String ADDRESSREMARKSID = "AddressRemarks";
+ public static final String ADDRESSOFADDITIONALLINKID = "AddressOfAdditionalLink";
+ public static final String PHONEPREFIX = "Phone";
+ public static final String FAXPREFIX = "Fax";
+ public static final String EMAILPREFIX = "Email";
+ public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAQ832#005", KeyType.IRDI));
+ public static final String ADDRESSIDSHORT = "Address";
+
+ private Address() {
+ }
+
+ /**
+ * Constructor with default idShort
+ * @param street
+ * @param zipCode
+ * @param cityTown
+ * @param nationalCode
+ */
+ public Address(MultiLanguageProperty street, MultiLanguageProperty zipCode, MultiLanguageProperty cityTown, MultiLanguageProperty nationalCode) {
+ this(ADDRESSIDSHORT, street, zipCode, cityTown, nationalCode);
+ }
+
+ /**
+ * Constructor with default idShort
+ * @param street
+ * @param zipCode
+ * @param cityTown
+ * @param nationalCode
+ */
+ public Address(LangString street, LangString zipCode, LangString cityTown, LangString nationalCode) {
+ this(ADDRESSIDSHORT, street, zipCode, cityTown, nationalCode);
+ }
+
+ /**
+ * Constructor with mandatory attributes
+ * @param idShort
+ * @param street
+ * @param zipCode
+ * @param cityTown
+ * @param nationalCode
+ */
+ public Address(String idShort, MultiLanguageProperty street, MultiLanguageProperty zipCode, MultiLanguageProperty cityTown, MultiLanguageProperty nationalCode) {
+ super(idShort);
+ setSemanticId(SEMANTICID);
+ setStreet(street);
+ setZipCode(zipCode);
+ setCityTown(cityTown);
+ setNationalCode(nationalCode);
+ }
+
+ /**
+ * Constructor with mandatory attributes
+ * @param idShort
+ * @param street
+ * @param zipCode
+ * @param cityTown
+ * @param nationalCode
+ */
+ public Address(String idShort, LangString street, LangString zipCode, LangString cityTown, LangString nationalCode) {
+ super(idShort);
+ setSemanticId(SEMANTICID);
+ setStreet(street);
+ setZipCode(zipCode);
+ setCityTown(cityTown);
+ setNationalCode(nationalCode);
+ }
+
+ /**
+ * Creates a Address SMC object from a map
+ *
+ * @param obj a Address SMC object as raw map
+ * @return a Address SMC object, that behaves like a facade for the given map
+ */
+ public static Address createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (!isValid(obj)) {
+ throw new MetamodelConstructionException(Address.class, obj);
+ }
+
+ Address address = new Address();
+ address.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+ return address;
+ }
+
+ /**
+ * Creates a Address SMC object from a map without validation
+ *
+ * @param obj a Address SMC object as raw map
+ * @return a Address SMC object, that behaves like a facade for the given map
+ */
+ private static Address createAsFacadeNonStrict(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ Address address = new Address();
+ address.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+ return address;
+ }
+
+ /**
+ * Check whether all mandatory elements for Address SMC
+ * exist in the map
+ *
+ * @param obj
+ *
+ * @return true/false
+ */
+ @SuppressWarnings("unchecked")
+ public static boolean isValid(Map<String, Object> obj) {
+ Address address = createAsFacadeNonStrict(obj);
+
+ return SubmodelElementCollection.isValid(obj)
+ && MultiLanguageProperty.isValid((Map<String, Object>) address.getStreet())
+ && MultiLanguageProperty.isValid((Map<String, Object>) address.getZipCode())
+ && MultiLanguageProperty.isValid((Map<String, Object>) address.getCityTown())
+ && MultiLanguageProperty.isValid((Map<String, Object>) address.getNationalCode());
+ }
+
+ /**
+ * Gets administrative section within an organisation where a business partner is located
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IMultiLanguageProperty getDepartment() {
+ return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(DEPARTMENTID));
+ }
+
+ /**
+ * Sets administrative section within an organisation where a business partner is located
+ * @param department {@link MultiLanguageProperty}
+ */
+ public void setDepartment(MultiLanguageProperty department) {
+ addSubmodelElement(department);
+ }
+
+ /**
+ * Sets administrative section within an organisation where a business partner is located
+ * @param department {@link LangString}
+ */
+ public void setDepartment(LangString department) {
+ MultiLanguageProperty deptProp = new MultiLanguageProperty(DEPARTMENTID);
+ deptProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO127#003", IdentifierType.IRDI)));
+ deptProp.setValue(new LangStrings(department));
+ setDepartment(deptProp);
+ }
+
+ /**
+ * Gets street name and house number
+ * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IMultiLanguageProperty getStreet() {
+ return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(STREETID));
+ }
+
+ /**
+ * Sets street name and house number
+ * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+ * @param street {@link MultiLanguageProperty}
+ */
+ public void setStreet(MultiLanguageProperty street) {
+ addSubmodelElement(street);
+ }
+
+ /**
+ * Sets street name and house number
+ * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+ * @param street {@link LangString}
+ */
+ public void setStreet(LangString street) {
+ MultiLanguageProperty streetProp = new MultiLanguageProperty(STREETID);
+ streetProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO128#002", IdentifierType.IRDI)));
+ streetProp.setValue(new LangStrings(street));
+ setStreet(streetProp);
+ }
+
+ /**
+ * Gets ZIP code of address
+ * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IMultiLanguageProperty getZipCode() {
+ return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(ZIPCODEID));
+ }
+
+ /**
+ * Sets ZIP code of address
+ * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+ * @param zipCode {@link MultiLanguageProperty}
+ */
+ public void setZipCode(MultiLanguageProperty zipCode) {
+ addSubmodelElement(zipCode);
+ }
+
+ /**
+ * Sets ZIP code of address
+ * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+ * @param zipCode {@link LangString}
+ */
+ public void setZipCode(LangString zipCode) {
+ MultiLanguageProperty zipCodeProp = new MultiLanguageProperty(ZIPCODEID);
+ zipCodeProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO129#002", IdentifierType.IRDI)));
+ zipCodeProp.setValue(new LangStrings(zipCode));
+ setZipCode(zipCodeProp);
+ }
+
+ /**
+ * Gets P.O. box number
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IMultiLanguageProperty getPOBox() {
+ return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(POBOXID));
+ }
+
+ /**
+ * Sets P.O. box number
+ * @param poBox {@link MultiLanguageProperty}
+ */
+ public void setPOBox(MultiLanguageProperty poBox) {
+ addSubmodelElement(poBox);
+ }
+
+ /**
+ * Sets P.O. box number
+ * @param poBox {@link LangString}
+ */
+ public void setPOBox(LangString poBox) {
+ MultiLanguageProperty poBoxProp = new MultiLanguageProperty(POBOXID);
+ poBoxProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO130#002", IdentifierType.IRDI)));
+ poBoxProp.setValue(new LangStrings(poBox));
+ setPOBox(poBoxProp);
+ }
+
+ /**
+ * Gets ZIP code of P.O. box address
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IMultiLanguageProperty getZipCodeOfPOBox() {
+ return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(ZIPCODEOFPOBOXID));
+ }
+
+ /**
+ * Sets ZIP code of P.O. box address
+ * @param zipCodeOfPoBox {@link MultiLanguageProperty}
+ */
+ public void setZipCodeOfPOBox(MultiLanguageProperty zipCodeOfPoBox) {
+ addSubmodelElement(zipCodeOfPoBox);
+ }
+
+ /**
+ * Sets ZIP code of P.O. box address
+ * @param zipCodeOfPoBox {@link LangString}
+ */
+ public void setZipCodeOfPOBox(LangString zipCodeOfPoBox) {
+ MultiLanguageProperty zipCodeOfPoBoxProp = new MultiLanguageProperty(ZIPCODEOFPOBOXID);
+ zipCodeOfPoBoxProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO131#002", IdentifierType.IRDI)));
+ zipCodeOfPoBoxProp.setValue(new LangStrings(zipCodeOfPoBox));
+ setZipCodeOfPOBox(zipCodeOfPoBoxProp);
+ }
+
+ /**
+ * Gets town or city
+ * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IMultiLanguageProperty getCityTown() {
+ return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(CITYTOWNID));
+ }
+
+ /**
+ * Sets town or city
+ * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+ * @param cityTown {@link MultiLanguageProperty}
+ */
+ public void setCityTown(MultiLanguageProperty cityTown) {
+ addSubmodelElement(cityTown);
+ }
+
+ /**
+ * Sets town or city
+ * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+ * @param cityTown {@link LangString}
+ */
+ public void setCityTown(LangString cityTown) {
+ MultiLanguageProperty cityTownProp = new MultiLanguageProperty(CITYTOWNID);
+ cityTownProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO132#002", IdentifierType.IRDI)));
+ cityTownProp.setValue(new LangStrings(cityTown));
+ setCityTown(cityTownProp);
+ }
+
+ /**
+ * Gets federal state a part of a state
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IMultiLanguageProperty getStateCounty() {
+ return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(STATECOUNTYID));
+ }
+
+ /**
+ * Sets federal state a part of a state
+ * @param stateCounty {@link MultiLanguageProperty}
+ */
+ public void setStateCounty(MultiLanguageProperty stateCounty) {
+ addSubmodelElement(stateCounty);
+ }
+
+ /**
+ * Sets federal state a part of a state
+ * @param stateCounty {@link LangString}
+ */
+ public void setStateCounty(LangString stateCounty) {
+ MultiLanguageProperty stateCountyProp = new MultiLanguageProperty(STATECOUNTYID);
+ stateCountyProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO133#002", IdentifierType.IRDI)));
+ stateCountyProp.setValue(new LangStrings(stateCounty));
+ setStateCounty(stateCountyProp);
+ }
+
+ /**
+ * Gets code of a country
+ * Note: Country codes defined accord. to DIN EN ISO 3166-1
+ * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IMultiLanguageProperty getNationalCode() {
+ return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(NATIONALCODEID));
+ }
+
+ /**
+ * Sets code of a country
+ * Note: Country codes defined accord. to DIN EN ISO 3166-1
+ * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+ * @param nationalCode {@link MultiLanguageProperty}
+ */
+ public void setNationalCode(MultiLanguageProperty nationalCode) {
+ addSubmodelElement(nationalCode);
+ }
+
+ /**
+ * Sets code of a country
+ * Note: Country codes defined accord. to DIN EN ISO 3166-1
+ * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+ * @param nationalCode {@link LangString}
+ */
+ public void setNationalCode(LangString nationalCode) {
+ MultiLanguageProperty nationalCodeProp = new MultiLanguageProperty(NATIONALCODEID);
+ nationalCodeProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO134#002", IdentifierType.IRDI)));
+ nationalCodeProp.setValue(new LangStrings(nationalCode));
+ setNationalCode(nationalCodeProp);
+ }
+
+ /**
+ * Gets VAT identification number of the business partner
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IMultiLanguageProperty getVatNumber() {
+ return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(VATNUMBERID));
+ }
+
+ /**
+ * Sets VAT identification number of the business partner
+ * @param vatNumber {@link MultiLanguageProperty}
+ */
+ public void setVatNumber(MultiLanguageProperty vatNumber) {
+ addSubmodelElement(vatNumber);
+ }
+
+ /**
+ * Sets VAT identification number of the business partner
+ * @param vatNumber {@link LangString}
+ */
+ public void setVatNumber(LangString vatNumber) {
+ MultiLanguageProperty vatNumberProp = new MultiLanguageProperty(VATNUMBERID);
+ vatNumberProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO135#002", IdentifierType.IRDI)));
+ vatNumberProp.setValue(new LangStrings(vatNumber));
+ setVatNumber(vatNumberProp);
+ }
+
+ /**
+ * Gets plain text characterizing address information for which there is no property
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IMultiLanguageProperty getAddressRemarks() {
+ return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(ADDRESSREMARKSID));
+ }
+
+ /**
+ * Sets plain text characterizing address information for which there is no property
+ * @param addressRemarks {@link MultiLanguageProperty}
+ */
+ public void setAddressRemarks(MultiLanguageProperty addressRemarks) {
+ addSubmodelElement(addressRemarks);
+ }
+
+ /**
+ * Sets plain text characterizing address information for which there is no property
+ * @param addressRemarks {@link LangString}
+ */
+ public void setAddressRemarks(LangString addressRemarks) {
+ MultiLanguageProperty addressRemarksProp = new MultiLanguageProperty(ADDRESSREMARKSID);
+ addressRemarksProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO202#003", IdentifierType.IRDI)));
+ addressRemarksProp.setValue(new LangStrings(addressRemarks));
+ setAddressRemarks(addressRemarksProp);
+ }
+
+ /**
+ * Gets web site address where information about the product or contact is given
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IProperty getAddressOfAdditionalLink() {
+ return Property.createAsFacade((Map<String, Object>) getSubmodelElement(ADDRESSOFADDITIONALLINKID));
+ }
+
+ /**
+ * Sets web site address where information about the product or contact is given
+ * @param addressOfAdditionalLink {@link Property}
+ */
+ public void setAddressOfAdditionalLink(Property addressOfAdditionalLink) {
+ addSubmodelElement(addressOfAdditionalLink);
+ }
+
+ /**
+ * Sets web site address where information about the product or contact is given
+ * @param addressOfAdditionalLink {@link String}
+ */
+ public void setAddressOfAdditionalLink(String addressOfAdditionalLink) {
+ Property addressOfAdditionalLinkProp = new Property(ADDRESSOFADDITIONALLINKID, ValueType.String);
+ addressOfAdditionalLinkProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAQ326#002", IdentifierType.IRDI)));
+ addressOfAdditionalLinkProp.setValue(addressOfAdditionalLink);
+ setAddressOfAdditionalLink(addressOfAdditionalLinkProp);
+ }
+
+ /**
+ * Gets Phone number including type
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public List<Phone> getPhone() {
+ List<Phone> ret = new ArrayList<Phone>();
+ List<ISubmodelElement> elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(PHONEPREFIX, getSubmodelElements());
+
+ for (ISubmodelElement element: elements) {
+ ret.add(Phone.createAsFacade((Map<String, Object>) element));
+ }
+ return ret;
+ }
+
+ /**
+ * Sets Phone number including type
+ * @param phone
+ */
+ public void setPhone(List<Phone> phones) {
+ if (phones != null && phones.size() > 0) {
+ for (Phone phone : phones) {
+ addSubmodelElement(phone);
+ }
+ }
+ }
+
+ /**
+ * Gets fax number including type
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public List<Fax> getFax() {
+ List<Fax> ret = new ArrayList<Fax>();
+ List<ISubmodelElement> elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(FAXPREFIX, getSubmodelElements());
+
+ for (ISubmodelElement element: elements) {
+ ret.add(Fax.createAsFacade((Map<String, Object>) element));
+ }
+ return ret;
+ }
+
+ /**
+ * Sets fax number including type
+ * @param fax
+ */
+ public void setFax(List<Fax> faxes) {
+ if (faxes != null && faxes.size() > 0) {
+ for (Fax fax : faxes) {
+ addSubmodelElement(fax);
+ }
+ }
+ }
+
+ /**
+ * Gets E-mail address and encryption method
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public List<Email> getEmail() {
+ List<Email> ret = new ArrayList<Email>();
+ List<ISubmodelElement> elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(EMAILPREFIX, getSubmodelElements());
+
+ for (ISubmodelElement element: elements) {
+ ret.add(Email.createAsFacade((Map<String, Object>) element));
+ }
+ return ret;
+ }
+
+ /**
+ * Sets E-mail address and encryption method
+ * @param email
+ */
+ public void setEmail(List<Email> emails) {
+ if (emails != null && emails.size() > 0) {
+ for (Email email : emails) {
+ addSubmodelElement(email);
+ }
+ }
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Email.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Email.java
new file mode 100644
index 0000000..0f82b5a
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Email.java
@@ -0,0 +1,236 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address;
+
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IMultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.digitalnameplate.enums.MailType;
+
+/**
+ * Email as defined in the AAS Digital Nameplate Template document <br/>
+ * It is a submodel element collection which contains email address and encryption method
+ *
+ * @author haque
+ *
+ */
+public class Email extends SubmodelElementCollection {
+ public static final String EMAILADDRESSID = "EmailAddress";
+ public static final String PUBLICKEYID = "PublicKey";
+ public static final String TYPEOFEMAILADDRESSID = "TypeOfEmailAddress";
+ public static final String TYPEOFPUBLICKEYID = "TypeOfPublickKey";
+ public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAQ836#005", KeyType.IRDI));
+
+ private Email() {
+ }
+
+ /**
+ * Constructor with mandatory attributes
+ * @param idShort
+ * @param emailAddress
+ */
+ public Email(String idShort, Property emailAddress) {
+ super(idShort);
+ setSemanticId(SEMANTICID);
+ setEmailAddress(emailAddress);
+ }
+
+ /**
+ * Constructor with mandatory attributes
+ * @param idShort
+ * @param emailAddress
+ */
+ public Email(String idShort, String emailAddress) {
+ super(idShort);
+ setSemanticId(SEMANTICID);
+ setEmailAddress(emailAddress);
+ }
+
+ /**
+ * Creates a Email SMC object from a map
+ *
+ * @param obj a Email SMC object as raw map
+ * @return a Email SMC object, that behaves like a facade for the given map
+ */
+ public static Email createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (!isValid(obj)) {
+ throw new MetamodelConstructionException(Email.class, obj);
+ }
+
+ Email email = new Email();
+ email.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+ return email;
+ }
+
+ /**
+ * Creates a Email SMC object from a map without validation
+ *
+ * @param obj a Email SMC object as raw map
+ * @return a Email SMC object, that behaves like a facade for the given map
+ */
+ private static Email createAsFacadeNonStrict(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ Email email = new Email();
+ email.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+ return email;
+ }
+
+ /**
+ * Check whether all mandatory elements for Email SMC
+ * exist in the map
+ *
+ * @param obj
+ *
+ * @return true/false
+ */
+ @SuppressWarnings("unchecked")
+ public static boolean isValid(Map<String, Object> obj) {
+ Email email = createAsFacadeNonStrict(obj);
+
+ return SubmodelElementCollection.isValid(obj)
+ && Property.isValid((Map<String, Object>) email.getEmailAddress());
+ }
+
+ /**
+ * Sets electronic mail address of a business partner
+ * @param emailAddress Property
+ */
+ public void setEmailAddress(Property emailAddress) {
+ addSubmodelElement(emailAddress);
+ }
+
+ /**
+ * Sets electronic mail address of a business partner
+ * @param emailAddress String
+ */
+ public void setEmailAddress(String emailAddress) {
+ Property emailProp = new Property(EMAILADDRESSID, ValueType.String);
+ emailProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO198#002", IdentifierType.IRDI)));
+ emailProp.setValue(emailAddress);
+ setEmailAddress(emailProp);
+ }
+
+ /**
+ * Gets electronic mail address of a business partner
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IProperty getEmailAddress() {
+ return Property.createAsFacade((Map<String, Object>) getSubmodelElement(EMAILADDRESSID));
+ }
+
+ /**
+ * Sets public part of an unsymmetrical key pair to sign or encrypt text or messages
+ * @param key {@link MultiLanguageProperty}
+ */
+ public void setPublicKey(MultiLanguageProperty key) {
+ addSubmodelElement(key);
+ }
+
+ /**
+ * Sets public part of an unsymmetrical key pair to sign or encrypt text or messages
+ * @param key {@link LangString}
+ */
+ public void setPublicKey(LangString key) {
+ MultiLanguageProperty publicKey = new MultiLanguageProperty(PUBLICKEYID);
+ publicKey.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO200#002", IdentifierType.IRDI)));
+ publicKey.setValue(new LangStrings(key));
+ setPublicKey(publicKey);
+ }
+
+ /**
+ * Gets public part of an unsymmetrical key pair to sign or encrypt text or messages
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IMultiLanguageProperty getPublicKey() {
+ return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(PUBLICKEYID));
+ }
+
+ /**
+ * Sets characterization of an e-mail address according to its location or usage
+ * enumeration
+ * @param type {@link Property}
+ */
+ public void setTypeOfEmailAddress(Property type) {
+ addSubmodelElement(type);
+ }
+
+ /**
+ * Sets characterization of an e-mail address according to its location or usage
+ * enumeration
+ * @param type {@link MailType}
+ */
+ public void setTypeOfEmailAddress(MailType type) {
+ Property mailTypeProp = new Property(TYPEOFEMAILADDRESSID, ValueType.String);
+ mailTypeProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO199#003", IdentifierType.IRDI)));
+ mailTypeProp.setValue(type.toString());
+ setTypeOfEmailAddress(mailTypeProp);
+ }
+
+ /**
+ * Gets characterization of an e-mail address according to its location or usage
+ * enumeration
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IProperty getTypeOfEmailAddress() {
+ return Property.createAsFacade((Map<String, Object>) getSubmodelElement(TYPEOFEMAILADDRESSID));
+ }
+
+ /**
+ * Sets characterization of a public key according to its encryption process
+ * @param key {@link MultiLanguageProperty}
+ */
+ public void setTypeOfPublicKey(MultiLanguageProperty key) {
+ addSubmodelElement(key);
+ }
+
+ /**
+ * Sets characterization of a public key according to its encryption process
+ * @param key {@link LangString}
+ */
+ public void setTypeOfPublicKey(LangString key) {
+ MultiLanguageProperty typeOfPublicKey = new MultiLanguageProperty(TYPEOFPUBLICKEYID);
+ typeOfPublicKey.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO201#002", IdentifierType.IRDI)));
+ typeOfPublicKey.setValue(new LangStrings(key));
+ setTypeOfPublicKey(typeOfPublicKey);
+ }
+
+ /**
+ * Gets characterization of a public key according to its encryption process
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IMultiLanguageProperty getTypeOfPublicKey() {
+ return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(TYPEOFPUBLICKEYID));
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Fax.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Fax.java
new file mode 100644
index 0000000..5bcc9e5
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Fax.java
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address;
+
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IMultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.digitalnameplate.enums.FaxType;
+
+/**
+ * Fax as defined in the AAS Digital Nameplate Template document <br/>
+ * It is a submodel element collection which contains a fax number including type
+ *
+ * @author haque
+ *
+ */
+public class Fax extends SubmodelElementCollection {
+ public static final String FAXNUMBERID = "FaxNumber";
+ public static final String TYPEOFFAXID = "TypeOfFaxNumber";
+ public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAQ834#005", KeyType.IRDI));
+
+ private Fax() {
+ }
+
+ /**
+ * Constructor with mandatory attributes
+ * @param idShort
+ * @param faxNumber
+ */
+ public Fax(String idShort, LangString faxNumber) {
+ super(idShort);
+ setSemanticId(SEMANTICID);
+ setFaxNumber(faxNumber);
+ }
+
+ /**
+ * Constructor with mandatory attributes
+ * @param idShort
+ * @param faxNumber
+ */
+ public Fax(String idShort, MultiLanguageProperty faxNumber) {
+ super(idShort);
+ setSemanticId(SEMANTICID);
+ setFaxNumber(faxNumber);
+ }
+
+ /**
+ * Creates a Fax SMC object from a map
+ *
+ * @param obj a Fax SMC object as raw map
+ * @return a Fax SMC object, that behaves like a facade for the given map
+ */
+ public static Fax createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (!isValid(obj)) {
+ throw new MetamodelConstructionException(Fax.class, obj);
+ }
+
+ Fax fax = new Fax();
+ fax.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+ return fax;
+ }
+
+ /**
+ * Creates a Fax SMC object from a map without validation
+ *
+ * @param obj a Fax SMC object as raw map
+ * @return a Fax SMC object, that behaves like a facade for the given map
+ */
+ private static Fax createAsFacadeNonStrict(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ Fax fax = new Fax();
+ fax.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+ return fax;
+ }
+
+ /**
+ * Check whether all mandatory elements for Fax SMC
+ * exist in the map
+ *
+ * @param obj
+ *
+ * @return true/false
+ */
+ @SuppressWarnings("unchecked")
+ public static boolean isValid(Map<String, Object> obj) {
+ Fax fax = createAsFacadeNonStrict(obj);
+ return SubmodelElementCollection.isValid(obj)
+ && MultiLanguageProperty.isValid((Map<String, Object>) fax.getFaxNumber());
+ }
+
+ /**
+ * Sets complete telephone number to be called to reach a
+ * business partner's fax machine
+ * @param faxNumber {@link MultiLanguageProperty}
+ */
+ public void setFaxNumber(MultiLanguageProperty faxNumber) {
+ addSubmodelElement(faxNumber);
+ }
+
+ /**
+ * Sets complete telephone number to be called to reach a
+ * business partner's fax machine
+ * @param faxNumber {@link LangString}
+ */
+ public void setFaxNumber(LangString faxNumber) {
+ MultiLanguageProperty faxProp = new MultiLanguageProperty(FAXNUMBERID);
+ faxProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO195#002", IdentifierType.IRDI)));
+ faxProp.setValue(new LangStrings(faxNumber));
+ setFaxNumber(faxProp);
+ }
+
+ /**
+ * Sets characterization of the fax according its location or usage
+ * @param type {@link Property}
+ */
+ public void setTypeOfFaxNumber(Property type) {
+ addSubmodelElement(type);
+ }
+
+ /**
+ * Sets characterization of the fax according its location or usage
+ * @param type {@link FaxType}
+ */
+ public void setTypeOfFaxNumber(FaxType type) {
+ Property faxTypeProp = new Property(TYPEOFFAXID, ValueType.String);
+ faxTypeProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO196#003", IdentifierType.IRDI)));
+ faxTypeProp.setValue(type.toString());
+ setTypeOfFaxNumber(faxTypeProp);
+ }
+
+ /**
+ * Gets characterization of the fax according its location or usage
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IProperty getTypeOfFaxNumber() {
+ return Property.createAsFacade((Map<String, Object>) getSubmodelElement(TYPEOFFAXID));
+ }
+
+ /**
+ * Gets complete telephone number to be called to reach a
+ * business partner's fax machine
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IMultiLanguageProperty getFaxNumber() {
+ return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(FAXNUMBERID));
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Phone.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Phone.java
new file mode 100644
index 0000000..7ee01f2
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Phone.java
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address;
+
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IMultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.digitalnameplate.enums.PhoneType;
+
+/**
+ * Phone as defined in the AAS Digital Nameplate Template document <br/>
+ * It is a submodel element collection which contains a phone number including type
+ *
+ * @author haque
+ *
+ */
+public class Phone extends SubmodelElementCollection {
+ public static final String TELEPHONENUMBERID = "TelephoneNumber";
+ public static final String TYPEOFTELEPHONEID = "TypeOfTelephone";
+ public static final String PHONEID = "Phone";
+ public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAQ833#005", KeyType.IRDI));
+
+ private Phone() {}
+
+ /**
+ * Constructor with mandatory attributes
+ * @param idShort
+ * @param telephoneNumber
+ */
+ public Phone(String idShort, LangString telephoneNumber) {
+ super(idShort);
+ setSemanticId(SEMANTICID);
+ setTelephoneNumber(telephoneNumber);
+ }
+
+ /**
+ * Constructor with mandatory attributes
+ * @param idShort
+ * @param telephoneNumber
+ */
+ public Phone(String idShort, MultiLanguageProperty telephoneNumber) {
+ super(idShort);
+ setSemanticId(SEMANTICID);
+ setTelephoneNumber(telephoneNumber);
+ }
+
+ /**
+ * Creates a Phone SMC object from a map
+ *
+ * @param obj a Phone SMC object as raw map
+ * @return a Phone SMC object, that behaves like a facade for the given map
+ */
+ public static Phone createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (!isValid(obj)) {
+ throw new MetamodelConstructionException(Phone.class, obj);
+ }
+
+ Phone phone = new Phone();
+ phone.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+ return phone;
+ }
+
+ /**
+ * Creates a Phone SMC object from a map without checking validity
+ *
+ * @param obj a Phone SMC object as raw map
+ * @return a Phone SMC object, that behaves like a facade for the given map
+ */
+ private static Phone createAsFacadeNonStrict(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ Phone phone = new Phone();
+ phone.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+ return phone;
+ }
+
+ /**
+ * Check whether all mandatory elements for Phone SMC
+ * exist in the map
+ *
+ * @param obj
+ *
+ * @return true/false
+ */
+ @SuppressWarnings("unchecked")
+ public static boolean isValid(Map<String, Object> obj) {
+ Phone phone = createAsFacadeNonStrict(obj);
+
+ return SubmodelElementCollection.isValid(obj)
+ && MultiLanguageProperty.isValid((Map<String, Object>) phone.getTelephoneNumber());
+ }
+
+ /**
+ * Sets complete telephone number to be called to reach a business partner
+ * @param telephoneNumber {@link MultiLanguageProperty}
+ */
+ public void setTelephoneNumber(MultiLanguageProperty telephoneNumber) {
+ addSubmodelElement(telephoneNumber);
+ }
+
+ /**
+ * Sets complete telephone number to be called to reach a business partner
+ * @param telephoneNumber {@link LangString}
+ */
+ public void setTelephoneNumber(LangString telephoneNumber) {
+ MultiLanguageProperty phoneProp = new MultiLanguageProperty(TELEPHONENUMBERID);
+ phoneProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO136#002", IdentifierType.IRDI)));
+ phoneProp.setValue(new LangStrings(telephoneNumber));
+ setTelephoneNumber(phoneProp);
+ }
+
+ /**
+ * Sets characterization of a telephone according to its location or usage enumeration
+ * @param type {@link Property}
+ */
+ public void setTypeOfTelephone(Property type) {
+ addSubmodelElement(type);
+ }
+
+ /**
+ * Sets characterization of a telephone according to its location or usage enumeration
+ * @param type {@link PhoneType}
+ */
+ public void setTypeOfTelephone(PhoneType type) {
+ Property phoneTypeProp = new Property(TYPEOFTELEPHONEID, ValueType.String);
+ phoneTypeProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO137#003", IdentifierType.IRDI)));
+ phoneTypeProp.setValue(type.toString());
+ setTypeOfTelephone(phoneTypeProp);
+ }
+
+ /**
+ * Gets characterization of a telephone according to its location or usage enumeration
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IProperty getTypeOfTelephone() {
+ return Property.createAsFacade((Map<String, Object>) getSubmodelElement(TYPEOFTELEPHONEID));
+ }
+
+ /**
+ * Gets complete telephone number to be called to reach a business partner
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IMultiLanguageProperty getTelephoneNumber() {
+ return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(TELEPHONENUMBERID));
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/AssetSpecificProperties.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/AssetSpecificProperties.java
new file mode 100644
index 0000000..03f504d
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/AssetSpecificProperties.java
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.assetspecificproperties;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.types.helper.SubmodelElementRetrievalHelper;
+
+/**
+ * AssetSpecificProperties as defined in the AAS Digital Nameplate Template document <br/>
+ * It is a submodel element collection which contains collection of guideline specific properties
+ *
+ * @author haque
+ *
+ */
+public class AssetSpecificProperties extends SubmodelElementCollection {
+ public static final String ASSETSPECIFICPROPERTIESID = "AssetSpecificProperties";
+ public static final String GUIDELINESPECIFICPROPERTYPREFIX = "GuidelineSpecificProperties";
+ public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/zvei/nameplate/1/0/Nameplate/AssetSpecificProperties", KeyType.IRI));
+
+ private AssetSpecificProperties() {
+ }
+
+ /**
+ * Constructor with default idShort
+ * @param guidelineSpecificProperties
+ */
+ public AssetSpecificProperties(List<GuidelineSpecificProperties> guidelineSpecificProperties) {
+ this (ASSETSPECIFICPROPERTIESID, guidelineSpecificProperties);
+ }
+
+ /**
+ * Constructor with mandatory attributes
+ *
+ * @param idShort
+ * @param guidelineSpecificProperties
+ */
+ public AssetSpecificProperties(String idShort, List<GuidelineSpecificProperties> guidelineSpecificProperties) {
+ super(idShort);
+ setSemanticId(SEMANTICID);
+ setGuidelineSpecificProperties(guidelineSpecificProperties);
+ }
+
+ /**
+ * Creates a AssetSpecificProperties SMC object from a map
+ *
+ * @param obj a AssetSpecificProperties SMC object as raw map
+ * @return a AssetSpecificProperties SMC object, that behaves like a facade for the given map
+ */
+ public static AssetSpecificProperties createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (!isValid(obj)) {
+ throw new MetamodelConstructionException(AssetSpecificProperties.class, obj);
+ }
+
+ AssetSpecificProperties assetSpecificProperties = new AssetSpecificProperties();
+ assetSpecificProperties.setMap((Map<String, Object>)SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+ return assetSpecificProperties;
+ }
+
+ /**
+ * Creates a AssetSpecificProperties SMC object from a map without validation
+ *
+ * @param obj a AssetSpecificProperties SMC object as raw map
+ * @return a AssetSpecificProperties SMC object, that behaves like a facade for the given map
+ */
+ private static AssetSpecificProperties createAsFacadeNonStrict(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ AssetSpecificProperties assetSpecificProperties = new AssetSpecificProperties();
+ assetSpecificProperties.setMap((Map<String, Object>)SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+ return assetSpecificProperties;
+ }
+
+ /**
+ * Check whether all mandatory elements for AssetSpecificProperties SMC
+ * exist in the map
+ *
+ * @param obj
+ *
+ * @return true/false
+ */
+ public static boolean isValid(Map<String, Object> obj) {
+ AssetSpecificProperties props = createAsFacadeNonStrict(obj);
+
+ if (SubmodelElementCollection.isValid(obj)
+ && props.getGuidelineSpecificProperties() != null
+ && props.getGuidelineSpecificProperties().size() > 0) {
+ for (GuidelineSpecificProperties prop : props.getGuidelineSpecificProperties()) {
+ if (!GuidelineSpecificProperties.isValid((Map<String, Object>) prop)) {
+ return false;
+ }
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public void setGuidelineSpecificProperties(List<GuidelineSpecificProperties> properties) {
+ if (properties != null & properties.size() > 0) {
+ for (GuidelineSpecificProperties prop : properties) {
+ addSubmodelElement(prop);
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public List<GuidelineSpecificProperties> getGuidelineSpecificProperties() {
+ List<GuidelineSpecificProperties> ret = new ArrayList<GuidelineSpecificProperties>();
+ List<ISubmodelElement> elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(GUIDELINESPECIFICPROPERTYPREFIX, getSubmodelElements());
+
+ for (ISubmodelElement element: elements) {
+ ret.add(GuidelineSpecificProperties.createAsFacade((Map<String, Object>) element));
+ }
+ return ret;
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/GuidelineSpecificProperties.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/GuidelineSpecificProperties.java
new file mode 100644
index 0000000..b60d5a1
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/GuidelineSpecificProperties.java
@@ -0,0 +1,195 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.assetspecificproperties;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+
+/**
+ * GuidelineSpecificProperties as defined in the AAS Digital Nameplate Template document <br/>
+ * It is a submodel element collection which contains Asset specific nameplate
+ * information required by guideline, stipulation or legislation.
+ *
+ * @author haque
+ *
+ */
+public class GuidelineSpecificProperties extends SubmodelElementCollection {
+ public static final String GUIDELINEFORCONFORMITYDECLARATIONID = "GuidelineForConformityDeclaration";
+ public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://adminshell.io/zvei/nameplate/1/0/Nameplate/AssetSpecificProperties/GuidelineSpecificProperties", KeyType.IRI));
+
+ private GuidelineSpecificProperties() {
+ }
+
+ /**
+ * Constructor with mandatory attributes
+ *
+ * @param idShort
+ * @param declaration
+ * @param arbitrary
+ */
+ public GuidelineSpecificProperties(String idShort, Property declaration, List<Property> arbitrary) {
+ super(idShort);
+ setSemanticId(SEMANTICID);
+ setGuidelineForConformityDeclaration(declaration);
+ setArbitrary(arbitrary);
+ }
+
+ /**
+ * Constructor with mandatory attributes
+ *
+ * @param idShort
+ * @param declaration
+ * @param arbitrary
+ */
+ public GuidelineSpecificProperties(String idShort, String declaration, List<Property> arbitrary) {
+ super(idShort);
+ setSemanticId(SEMANTICID);
+ setGuidelineForConformityDeclaration(declaration);
+ setArbitrary(arbitrary);
+ }
+
+ /**
+ * Creates a GuidelineSpecificProperties SMC object from a map
+ *
+ * @param obj a GuidelineSpecificProperties SMC object as raw map
+ * @return a GuidelineSpecificProperties SMC object, that behaves like a facade for the given map
+ */
+ public static GuidelineSpecificProperties createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (!isValid(obj)) {
+ throw new MetamodelConstructionException(GuidelineSpecificProperties.class, obj);
+ }
+
+ GuidelineSpecificProperties guidelineSpecificProperties = new GuidelineSpecificProperties();
+ guidelineSpecificProperties.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+ return guidelineSpecificProperties;
+ }
+
+ /**
+ * Creates a GuidelineSpecificProperties SMC object from a map without validation
+ *
+ * @param obj a GuidelineSpecificProperties SMC object as raw map
+ * @return a GuidelineSpecificProperties SMC object, that behaves like a facade for the given map
+ */
+ private static GuidelineSpecificProperties createAsFacadeNonStrict(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ GuidelineSpecificProperties guidelineSpecificProperties = new GuidelineSpecificProperties();
+ guidelineSpecificProperties.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+ return guidelineSpecificProperties;
+ }
+
+ /**
+ * Check whether all mandatory elements for GuidelineSpecificProperties SMC
+ * exist in the map
+ *
+ * @param obj
+ *
+ * @return true/false
+ */
+ @SuppressWarnings("unchecked")
+ public static boolean isValid(Map<String, Object> obj) {
+ GuidelineSpecificProperties props = createAsFacadeNonStrict(obj);
+
+ if (SubmodelElementCollection.isValid(obj)
+ && Property.isValid((Map<String, Object>) props.getGuidelineForConformityDeclaration())
+ && props.getArbitrary() != null
+ && props.getArbitrary().size() > 0) {
+ for (IProperty arbitrary: props.getArbitrary()) {
+ if (!Property.isValid((Map<String, Object>) arbitrary)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ /**
+ * Sets guideline, stipulation or legislation used for determining conformity
+ *
+ * @param declaration {@link Property}
+ */
+ public void setGuidelineForConformityDeclaration(Property declaration) {
+ addSubmodelElement(declaration);
+ }
+
+ /**
+ * Sets guideline, stipulation or legislation used for determining conformity
+ *
+ * @param declaration {@link String}
+ */
+ public void setGuidelineForConformityDeclaration(String declaration) {
+ Property declarationProp = new Property(GUIDELINEFORCONFORMITYDECLARATIONID, ValueType.String);
+ declarationProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO856#002", IdentifierType.IRDI)));
+ declarationProp.setValue(declaration);
+ setGuidelineForConformityDeclaration(declarationProp);
+ }
+
+ /**
+ * Gets guideline, stipulation or legislation used for determining conformity
+ *
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IProperty getGuidelineForConformityDeclaration() {
+ return Property.createAsFacade((Map<String, Object>) getSubmodelElement(GUIDELINEFORCONFORMITYDECLARATIONID));
+ }
+
+ /**
+ * Gets arbitrary, representing information required by further standards
+ * @return
+ */
+ public List<IProperty> getArbitrary() {
+ List<IProperty> ret = new ArrayList<IProperty>();
+ Map<String, ISubmodelElement> elemMap = getSubmodelElements();
+ if (elemMap != null && elemMap.size() > 0) {
+ for (Map.Entry<String, ISubmodelElement> singleElement: elemMap.entrySet()) {
+ if (!singleElement.getKey().equals(GUIDELINEFORCONFORMITYDECLARATIONID)) {
+ ret.add((IProperty) singleElement.getValue());
+ }
+ }
+ }
+ return ret;
+ }
+
+ /**
+ * Sets arbitrary, representing information required by further standards
+ * @param arbitraries
+ */
+ public void setArbitrary(List<Property> arbitraries) {
+ if (arbitraries != null & arbitraries.size() > 0) {
+ for (Property prop : arbitraries) {
+ addSubmodelElement(prop);
+ }
+ }
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/markings/Marking.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/markings/Marking.java
new file mode 100644
index 0000000..7afd9e8
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/markings/Marking.java
@@ -0,0 +1,218 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.markings;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IFile;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.helper.SubmodelElementRetrievalHelper;
+
+/**
+ * Marking as defined in the AAS Digital Nameplate Template document <br/>
+ * It is a submodel element collection which
+ * contains information about the marking labelled on the device
+ *
+ * @author haque
+ *
+ */
+public class Marking extends SubmodelElementCollection {
+ public static final String MARKINGNAMEID = "MarkingName";
+ public static final String MARKINGFILEID = "MarkingFile";
+ public static final String MARKINGADDITIONALTEXTPREFIX = "MarkingAdditionalText";
+ public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/zvei/nameplate/0/1/Nameplate/Markings/Marking", KeyType.IRI));
+
+ private Marking() {
+ }
+
+ /**
+ * Constructor with mandatory attributes
+ *
+ * @param idShort
+ * @param markingName
+ * @param markingFile
+ */
+ public Marking(String idShort, Property markingName, File markingFile) {
+ super(idShort);
+ setSemanticId(SEMANTICID);
+ setMarkingAdditionalText(new ArrayList<Property>());
+ setMarkingName(markingName);
+ setMarkingFile(markingFile);
+ }
+
+ /**
+ * Constructor with mandatory attributes
+ *
+ * @param idShort
+ * @param markingName
+ * @param markingFile
+ */
+ public Marking(String idShort, String markingName, File markingFile) {
+ super(idShort);
+ setSemanticId(SEMANTICID);
+ setMarkingAdditionalText(new ArrayList<Property>());
+ setMarkingName(markingName);
+ setMarkingFile(markingFile);
+ }
+
+ /**
+ * Creates a Marking SMC object from a map
+ *
+ * @param obj a Marking SMC object as raw map
+ * @return a Marking SMC object, that behaves like a facade for the given map
+ */
+ public static Marking createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (!isValid(obj)) {
+ throw new MetamodelConstructionException(Marking.class, obj);
+ }
+
+ Marking marking = new Marking();
+ marking.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+ return marking;
+ }
+
+ /**
+ * Creates a Marking SMC object from a map without validation
+ *
+ * @param obj a Marking SMC object as raw map
+ * @return a Marking SMC object, that behaves like a facade for the given map
+ */
+ private static Marking createAsFacadeNonStrict(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ Marking marking = new Marking();
+ marking.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+ return marking;
+ }
+
+ /**
+ * Check whether all mandatory elements for Marking SMC
+ * exist in the map
+ *
+ * @param obj
+ *
+ * @return true/false
+ */
+ @SuppressWarnings("unchecked")
+ public static boolean isValid(Map<String, Object> obj) {
+ Marking marking = createAsFacadeNonStrict(obj);
+ return SubmodelElementCollection.isValid(obj)
+ && Property.isValid((Map<String, Object>) marking.getMarkingName())
+ && File.isValid((Map<String, Object>) marking.getMarkingFile());
+ }
+
+ /**
+ * Sets common name of the marking
+ *
+ * Note: CE marking is declared as mandatory according to EU
+ * Machine Directive 2006/42/EC.
+ * @param markingName
+ */
+ public void setMarkingName(Property markingName) {
+ addSubmodelElement(markingName);
+ }
+
+ /**
+ * Sets common name of the marking
+ *
+ * Note: CE marking is declared as mandatory according to EU
+ * Machine Directive 2006/42/EC.
+ * @param markingName
+ */
+ public void setMarkingName(String markingName) {
+ Property markingNameProp = new Property(MARKINGNAMEID, ValueType.String);
+ markingNameProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/zvei/nameplate/1/0/Nameplate/Markings/Marking/MarkingName", IdentifierType.IRDI)));
+ markingNameProp.setValue(markingName);
+ setMarkingName(markingNameProp);
+ }
+
+ /**
+ * Gets common name of the marking
+ *
+ * Note: CE marking is declared as mandatory according to EU
+ * Machine Directive 2006/42/EC.
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IProperty getMarkingName() {
+ return Property.createAsFacade((Map<String, Object>) getSubmodelElement(MARKINGNAMEID));
+ }
+
+ /**
+ * Sets picture of the marking
+ *
+ * Note: CE marking is declared as mandatory according to EU
+ * Machine Directive 2006/42/EC.
+ * @param markingFile
+ */
+ public void setMarkingFile(File markingFile) {
+ addSubmodelElement(markingFile);
+ }
+
+ /**
+ * Gets picture of the marking
+ *
+ * Note: CE marking is declared as mandatory according to EU
+ * Machine Directive 2006/42/EC.
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IFile getMarkingFile() {
+ return File.createAsFacade((Map<String, Object>) getSubmodelElement(MARKINGFILEID));
+ }
+
+ /**
+ * Sets where applicable, additional information on the marking in
+ * plain text
+ * @param markingAdditionalText
+ */
+ public void setMarkingAdditionalText(List<Property> markingAdditionalText) {
+ if (markingAdditionalText != null && markingAdditionalText.size() > 0) {
+ for (Property markingAdditionalSingle : markingAdditionalText) {
+ addSubmodelElement(markingAdditionalSingle);
+ }
+ }
+ }
+
+ /**
+ * Gets where applicable, additional information on the marking in
+ * plain text
+ * @return
+ */
+ public List<IProperty> getMarkingAdditionalText() {
+ List<IProperty> ret = new ArrayList<IProperty>();
+ List<ISubmodelElement> elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(MARKINGADDITIONALTEXTPREFIX, getSubmodelElements());
+
+ for (ISubmodelElement element: elements) {
+ ret.add((IProperty) element);
+ }
+ return ret;
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/markings/Markings.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/markings/Markings.java
new file mode 100644
index 0000000..4123443
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/markings/Markings.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.markings;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.types.helper.SubmodelElementRetrievalHelper;
+
+/**
+ * Markings as defined in the AAS Digital Nameplate Template document <br/>
+ * It is a submodel element collection which contains a collection of product markings
+ *
+ * Note: CE marking is declared as mandatory according to EU Machine Directive 2006/42/EC.
+ *
+ * @author haque
+ *
+ */
+public class Markings extends SubmodelElementCollection {
+ public static final String IDSHORT = "Markings";
+ public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/zvei/nameplate/1/0/Nameplate/Markings", KeyType.IRI));
+ public static final String MARKINGPREFIX = "Marking";
+
+ private Markings() {
+ }
+
+ /**
+ * Constructor with default idShort
+ * @param markings
+ */
+ public Markings(List<Marking> markings) {
+ this(IDSHORT, markings);
+ }
+
+ /**
+ * Constructor with mandatory attributes
+ *
+ * @param idShort
+ * @param markings
+ */
+ public Markings(String idShort, List<Marking> markings) {
+ super(idShort);
+ setSemanticId(SEMANTICID);
+ setMarking(markings);
+ }
+
+ /**
+ * Creates a Markings SMC object from a map
+ *
+ * @param obj a Markings SMC object as raw map
+ * @return a Markings SMC object, that behaves like a facade for the given map
+ */
+ public static Markings createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (!isValid(obj)) {
+ throw new MetamodelConstructionException(Markings.class, obj);
+ }
+
+ Markings markings = new Markings();
+ markings.setMap((Map<String, Object>)SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+ return markings;
+ }
+
+ /**
+ * Creates a Markings SMC object from a map without validation
+ *
+ * @param obj a Markings SMC object as raw map
+ * @return a Markings SMC object, that behaves like a facade for the given map
+ */
+ private static Markings createAsFacadeNonStrict(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ Markings markings = new Markings();
+ markings.setMap((Map<String, Object>)SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+ return markings;
+ }
+
+ /**
+ * Check whether all mandatory elements for Markings SMC
+ * exist in the map
+ *
+ * @param obj
+ *
+ * @return true/false
+ */
+ public static boolean isValid(Map<String, Object> obj) {
+ Markings markings = createAsFacadeNonStrict(obj);
+
+ if (SubmodelElementCollection.isValid(obj)
+ && markings.getMarking() != null
+ && markings.getMarking().size() > 0) {
+ for (Marking marking : markings.getMarking()) {
+ if (!Marking.isValid((Map<String, Object>) marking)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ /**
+ * Sets information about the marking labelled on the device
+
+ * Note: CE marking is declared as mandatory according to EU Machine
+ * Directive 2006/42/EC.
+ * @param markingName
+ */
+ public void setMarking(List<Marking> markings) {
+ if (markings != null && markings.size() > 0) {
+ for (Marking prop : markings) {
+ addSubmodelElement(prop);
+ }
+ }
+ }
+
+ /**
+ * Gets information about the marking labelled on the device
+
+ * Note: CE marking is declared as mandatory according to EU Machine
+ * Directive 2006/42/EC.
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public List<Marking> getMarking() {
+ List<Marking> ret = new ArrayList<Marking>();
+ List<ISubmodelElement> elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(MARKINGPREFIX, getSubmodelElements());
+
+ for (ISubmodelElement element: elements) {
+ ret.add(Marking.createAsFacade((Map<String, Object>) element));
+ }
+ return ret;
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/helper/SubmodelElementRetrievalHelper.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/helper/SubmodelElementRetrievalHelper.java
new file mode 100644
index 0000000..a5fccbd
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/helper/SubmodelElementRetrievalHelper.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.types.helper;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+
+public class SubmodelElementRetrievalHelper {
+
+ public static List<ISubmodelElement> getSubmodelElementsByIdPrefix(String prefix, Map<String, ISubmodelElement> elemMap) {
+ if (elemMap != null && elemMap.size() > 0) {
+ return elemMap.values().stream().filter(s -> s.getIdShort().startsWith(prefix)).collect(Collectors.toList());
+ }
+ return new ArrayList<ISubmodelElement>();
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/TechnicalDataSubmodel.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/TechnicalDataSubmodel.java
new file mode 100644
index 0000000..8f61c9d
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/TechnicalDataSubmodel.java
@@ -0,0 +1,223 @@
+/*******************************************************************************
+* Copyright (C) 2021 the Eclipse BaSyx Authors
+*
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+
+*
+* SPDX-License-Identifier: EPL-2.0
+******************************************************************************/
+
+package org.eclipse.basyx.submodel.types.technicaldata;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.furtherinformation.FurtherInformation;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.generalinformation.GeneralInformation;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.productclassifications.ProductClassifications;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.technicalproperties.TechnicalProperties;
+
+/**
+ * TechnicalDataSubmodel as described in the Submodel Template AAS Technical Data Document
+ *
+ * this contains Submodel containing technical data of the asset and associated product classifications.
+ *
+ * @author haque
+ *
+ */
+public class TechnicalDataSubmodel extends Submodel {
+ public static final String GENERALINFORMATIONID = "GeneralInformation";
+ public static final String PRODUCTCLASSIFICATIONSID = "ProductClassifications";
+ public static final String TECHNICALPROPERTIESID = "TechnicalProperties";
+ public static final String FURTHERINFORMATIONID = "FurtherInformation";
+ public static final Reference SEMANTICID = new Reference(Collections.singletonList(new Key(KeyElements.CONCEPTDESCRIPTION, false, "http://admin-shell.io/ZVEI/TechnicalData/Submodel/1/1", KeyType.IRI)));
+ public static final String SUBMODELID = "TechnicalData";
+
+ private TechnicalDataSubmodel() {}
+
+ /**
+ * Constructor with default idShort
+ * @param identifier
+ * @param generalInformation
+ * @param productClassifications
+ * @param properties
+ * @param furtherInformation
+ */
+ public TechnicalDataSubmodel(
+ Identifier identifier,
+ GeneralInformation generalInformation,
+ ProductClassifications productClassifications,
+ TechnicalProperties properties,
+ FurtherInformation furtherInformation
+ ) {
+ this(SUBMODELID, identifier, generalInformation, productClassifications, properties, furtherInformation);
+ }
+
+ /**
+ * Constructor with mandatory attributes
+ * @param idShort
+ * @param identifier
+ * @param manufacturerName
+ * @param manufacturerProductDesignation
+ * @param address
+ * @param manufacturerProductFamily
+ * @param yearsOfConstruction
+ */
+ public TechnicalDataSubmodel(
+ String idShort,
+ Identifier identifier,
+ GeneralInformation generalInformation,
+ ProductClassifications productClassifications,
+ TechnicalProperties properties,
+ FurtherInformation furtherInformation
+ ) {
+ super(idShort, identifier);
+ setSemanticId(SEMANTICID);
+ setGeneralInformation(generalInformation);
+ setProductClassifications(productClassifications);
+ setTechnicalProperties(properties);
+ setFurtherInformation(furtherInformation);
+ }
+
+ /**
+ * Creates a TechnicalDataSubmodel object from a map
+ *
+ * @param obj a TechnicalDataSubmodel SMC object as raw map
+ * @return a TechnicalDataSubmodel SMC object, that behaves like a facade for the given map
+ */
+ public static TechnicalDataSubmodel createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (!isValid(obj)) {
+ throw new MetamodelConstructionException(TechnicalDataSubmodel.class, obj);
+ }
+
+ TechnicalDataSubmodel ret = new TechnicalDataSubmodel();
+ ret.setMap((Map<String, Object>)SubmodelElementMapCollectionConverter.mapToSM(obj));
+ return ret;
+ }
+
+ /**
+ * Creates a TechnicalDataSubmodel object from a map without validation
+ *
+ * @param obj a TechnicalDataSubmodel SMC object as raw map
+ * @return a TechnicalDataSubmodel SMC object, that behaves like a facade for the given map
+ */
+ private static TechnicalDataSubmodel createAsFacadeNonStrict(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ TechnicalDataSubmodel ret = new TechnicalDataSubmodel();
+ ret.setMap((Map<String, Object>)SubmodelElementMapCollectionConverter.mapToSM(obj));
+ return ret;
+ }
+
+ /**
+ * Check whether all mandatory elements for TechnicalDataSubmodel
+ * exist in the map
+ *
+ * @param obj
+ *
+ * @return true/false
+ */
+ public static boolean isValid(Map<String, Object> obj) {
+ TechnicalDataSubmodel submodel = createAsFacadeNonStrict(obj);
+
+ return Submodel.isValid(obj)
+ && GeneralInformation.isValid((Map<String, Object>) submodel.getGeneralInformation())
+ && TechnicalProperties.isValid((Map<String, Object>) submodel.getTechnicalProperties());
+ }
+
+ /**
+ * Sets general information, for example ordering and manufacturer information.
+ *
+ * @param information
+ */
+ public void setGeneralInformation(GeneralInformation information) {
+ addSubmodelElement(information);
+ }
+
+ /**
+ *
+ * Gets general information, for example ordering and manufacturer information.
+ *
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public GeneralInformation getGeneralInformation() {
+ return GeneralInformation.createAsFacade((Map<String, Object>) getSubmodelElement(GENERALINFORMATIONID));
+ }
+
+ /**
+ * Sets product classifications by association of product classes with common classification systems.
+ *
+ * @param classifications
+ */
+ public void setProductClassifications(ProductClassifications classifications) {
+ addSubmodelElement(classifications);
+ }
+
+ /**
+ *
+ * Gets product classifications by association of product classes with common classification systems.
+ *
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public ProductClassifications getProductClassifications() {
+ return ProductClassifications.createAsFacade((Map<String, Object>) getSubmodelElement(PRODUCTCLASSIFICATIONSID));
+ }
+
+ /**
+ * Sets technical and product properties. Individual characteristics that describe the product and its technical properties.
+ *
+ * @param properties
+ */
+ public void setTechnicalProperties(TechnicalProperties properties) {
+ addSubmodelElement(properties);
+ }
+
+ /**
+ *
+ * Gets technical and product properties. Individual characteristics that describe the product and its technical properties.
+ *
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public TechnicalProperties getTechnicalProperties() {
+ return TechnicalProperties.createAsFacade((Map<String, Object>) getSubmodelElement(TECHNICALPROPERTIESID));
+ }
+
+ /**
+ * Sets further information on the product, the validity of the information provided and this data record.
+ *
+ * @param information
+ */
+ public void setFurtherInformation(FurtherInformation information) {
+ addSubmodelElement(information);
+ }
+
+ /**
+ *
+ * Gets further information on the product, the validity of the information provided and this data record.
+ *
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public FurtherInformation getFurtherInformation() {
+ return FurtherInformation.createAsFacade((Map<String, Object>) getSubmodelElement(FURTHERINFORMATIONID));
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/furtherinformation/FurtherInformation.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/furtherinformation/FurtherInformation.java
new file mode 100644
index 0000000..7b355ca
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/furtherinformation/FurtherInformation.java
@@ -0,0 +1,225 @@
+/*******************************************************************************
+* Copyright (C) 2021 the Eclipse BaSyx Authors
+*
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+
+*
+* SPDX-License-Identifier: EPL-2.0
+******************************************************************************/
+
+package org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.furtherinformation;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IMultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.helper.SubmodelElementRetrievalHelper;
+
+/**
+ * FurtherInformation as described in the Submodel Template AAS Technical Data Document
+ * It contains Further information on the product, the validity of the information provided and this data record.
+ *
+ * @author haque
+ *
+ */
+public class FurtherInformation extends SubmodelElementCollection {
+ public static final String IDSHORT = "FurtherInformation";
+ public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/FurtherInformation/1/1", KeyType.IRI));
+ public static final String TEXTSTATEMENTPREFIX = "TextStatement";
+ public static final String VALIDDATEID = "ValidDate";
+
+ private FurtherInformation() {
+ }
+
+ /**
+ * Constructor with default idShort
+ * @param validDate
+ */
+ public FurtherInformation(Property validDate) {
+ this(IDSHORT, validDate);
+ }
+
+ /**
+ * Constructor with default idShort
+ * @param validDate
+ */
+ public FurtherInformation(XMLGregorianCalendar validDate) {
+ this(IDSHORT, validDate);
+ }
+
+ /**
+ * Constructor with mandatory attributes
+ *
+ * @param idShort
+ * @param validDate
+ */
+ public FurtherInformation(String idShort, Property validDate) {
+ super(idShort);
+ setSemanticId(SEMANTICID);
+ setValidDate(validDate);
+ setTextStatements(new ArrayList<MultiLanguageProperty>());
+ }
+
+ /**
+ * Constructor with mandatory attributes
+ *
+ * @param idShort
+ * @param validDate
+ */
+ public FurtherInformation(String idShort, XMLGregorianCalendar validDate) {
+ super(idShort);
+ setSemanticId(SEMANTICID);
+ setValidDate(validDate);
+ setTextStatements(new ArrayList<MultiLanguageProperty>());
+ }
+
+ /**
+ * Creates a FurtherInformation SMC object from a map
+ *
+ * @param obj a FurtherInformation SMC object as raw map
+ * @return a FurtherInformation SMC object, that behaves like a facade for the given map
+ */
+ public static FurtherInformation createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (!isValid(obj)) {
+ throw new MetamodelConstructionException(FurtherInformation.class, obj);
+ }
+
+ FurtherInformation furtherInformation = new FurtherInformation();
+ furtherInformation.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+ return furtherInformation;
+ }
+
+ /**
+ * Creates a FurtherInformation SMC object from a map without validation
+ *
+ * @param obj a FurtherInformation SMC object as raw map
+ * @return a FurtherInformation SMC object, that behaves like a facade for the given map
+ */
+ private static FurtherInformation createAsFacadeNonStrict(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ FurtherInformation furtherInformation = new FurtherInformation();
+ furtherInformation.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+ return furtherInformation;
+ }
+
+ /**
+ * Check whether all mandatory elements for FurtherInformation SMC
+ * exist in the map
+ *
+ * @param obj
+ *
+ * @return true/false
+ */
+ @SuppressWarnings("unchecked")
+ public static boolean isValid(Map<String, Object> obj) {
+ FurtherInformation furtherInformation = createAsFacadeNonStrict(obj);
+
+ return SubmodelElementCollection.isValid(obj)
+ && Property.isValid((Map<String, Object>) furtherInformation.getValidDate());
+ }
+
+ /**
+ * Sets statement by the manufacturer in text form,
+ * e.g. scope of validity of the statements, scopes of application,
+ * conditions of operation.
+ *
+ * Note: Whenever possible, a multi-language definition is preferred.
+ *
+ * @param statements
+ */
+ public void setTextStatements(List<MultiLanguageProperty> statements) {
+ if (statements != null && statements.size() > 0) {
+ for (MultiLanguageProperty statement: statements) {
+ addSubmodelElement(statement);
+ }
+ }
+ }
+
+ /**
+ * Gets statement by the manufacturer in text form,
+ * e.g. scope of validity of the statements, scopes of application,
+ * conditions of operation.
+ *
+ * Note: Whenever possible, a multi-language definition is preferred.
+ *
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public List<IMultiLanguageProperty> getStatements() {
+ List<IMultiLanguageProperty> ret = new ArrayList<IMultiLanguageProperty>();
+ List<ISubmodelElement> elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(TEXTSTATEMENTPREFIX, getSubmodelElements());
+
+ for (ISubmodelElement element: elements) {
+ ret.add(MultiLanguageProperty.createAsFacade((Map<String, Object>) element));
+ }
+ return ret;
+ }
+
+ /**
+ * Sets a date on which the data specified in the Submodel was valid from for the associated asset.
+ *
+ * Note: Often this date will be the date of the last update of the
+ * corresponding data, that are the source for the technical properties
+ * section in the master data system.
+ *
+ * @param validDate
+ */
+ public void setValidDate(Property validDate) {
+ addSubmodelElement(validDate);
+ }
+
+ /**
+ * Sets a date on which the data specified in the Submodel was valid from for the associated asset.
+ *
+ * Note: Often this date will be the date of the last update of the
+ * corresponding data, that are the source for the technical properties
+ * section in the master data system.
+ *
+ * @param validDate
+ */
+ public void setValidDate(XMLGregorianCalendar validDate) {
+ Property validDateProp = new Property(VALIDDATEID, ValueType.DateTime);
+ validDateProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/ValidDate/1/1", IdentifierType.IRI)));
+ validDateProp.setValue(validDate);
+ setValidDate(validDateProp);
+ }
+
+ /**
+ * Gets a date on which the data specified in the Submodel was valid from for the associated asset.
+ *
+ * Note: Often this date will be the date of the last update of the
+ * corresponding data, that are the source for the technical properties
+ * section in the master data system.
+ *
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IProperty getValidDate() {
+ return Property.createAsFacade((Map<String, Object>) getSubmodelElement(VALIDDATEID));
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/generalinformation/GeneralInformation.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/generalinformation/GeneralInformation.java
new file mode 100644
index 0000000..b7533ad
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/generalinformation/GeneralInformation.java
@@ -0,0 +1,352 @@
+/*******************************************************************************
+* Copyright (C) 2021 the Eclipse BaSyx Authors
+*
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+
+*
+* SPDX-License-Identifier: EPL-2.0
+******************************************************************************/
+
+package org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.generalinformation;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IFile;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IMultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.helper.SubmodelElementRetrievalHelper;
+
+/**
+ * GeneralInformation as described in the Submodel Template AAS Technical Data Document
+ *
+ * It is a submodel element collection which contains General information, for example ordering and manufacturer information.
+ *
+ * @author haque
+ *
+ */
+public class GeneralInformation extends SubmodelElementCollection{
+ public static final String IDSHORT = "GeneralInformation";
+ public static final String MANUFACTURERNAMEID = "ManufacturerName";
+ public static final String MANUFACTURERLOGOID = "ManufacturerLogo";
+ public static final String MANUFACTURERPRODUCTDESIGNATIONID = "ManufacturerProductDesignation";
+ public static final String MANUFACTURERPARTNUMBERID = "ManufacturerPartNumber";
+ public static final String MANUFACTURERORDERCODEID = "ManufacturerOrderCode";
+ public static final String PRODUCTIMAGEPREFIX = "ProductImage";
+ public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/GeneralInformation/1/1", KeyType.IRI));
+
+ private GeneralInformation() {
+ }
+
+ /**
+ * Constructor with default idShort
+ *
+ * @param manufacturerName
+ * @param manufacturerProductDesignation
+ * @param manufacturerPartNumber
+ * @param manufacturerOrderCode
+ */
+ public GeneralInformation(Property manufacturerName, MultiLanguageProperty manufacturerProductDesignation, Property manufacturerPartNumber, Property manufacturerOrderCode) {
+ this(IDSHORT, manufacturerName, manufacturerProductDesignation, manufacturerPartNumber, manufacturerOrderCode);
+ }
+
+ /**
+ * Constructor with default idShort
+ *
+ * @param manufacturerName
+ * @param manufacturerProductDesignation
+ * @param manufacturerPartNumber
+ * @param manufacturerOrderCode
+ */
+ public GeneralInformation(String manufacturerName, LangString manufacturerProductDesignation, String manufacturerPartNumber, String manufacturerOrderCode) {
+ this(IDSHORT, manufacturerName, manufacturerProductDesignation, manufacturerPartNumber, manufacturerOrderCode);
+ }
+
+ /**
+ * Constructor with mandatory attributes
+ *
+ * @param idShort
+ * @param manufacturerName
+ * @param manufacturerProductDesignation
+ * @param manufacturerPartNumber
+ * @param manufacturerOrderCode
+ */
+ public GeneralInformation(String idShort, Property manufacturerName, MultiLanguageProperty manufacturerProductDesignation, Property manufacturerPartNumber, Property manufacturerOrderCode) {
+ super(idShort);
+ setSemanticId(SEMANTICID);
+ setManufacturerName(manufacturerName);
+ setManufacturerProductDesignation(manufacturerProductDesignation);
+ setManufacturerPartNumber(manufacturerPartNumber);
+ setManufacturerOrderCode(manufacturerOrderCode);
+ }
+
+ /**
+ * Constructor with mandatory attributes
+ *
+ * @param idShort
+ * @param manufacturerName
+ * @param manufacturerProductDesignation
+ * @param manufacturerPartNumber
+ * @param manufacturerOrderCode
+ */
+ public GeneralInformation(String idShort, String manufacturerName, LangString manufacturerProductDesignation, String manufacturerPartNumber, String manufacturerOrderCode) {
+ super(idShort);
+ setSemanticId(SEMANTICID);
+ setManufacturerName(manufacturerName);
+ setManufacturerProductDesignation(manufacturerProductDesignation);
+ setManufacturerPartNumber(manufacturerPartNumber);
+ setManufacturerOrderCode(manufacturerOrderCode);
+ }
+
+ /**
+ * Creates a GeneralInformation SMC object from a map
+ *
+ * @param obj a GeneralInformation SMC object as raw map
+ * @return a GeneralInformation SMC object, that behaves like a facade for the given map
+ */
+ public static GeneralInformation createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (!isValid(obj)) {
+ throw new MetamodelConstructionException(GeneralInformation.class, obj);
+ }
+
+ GeneralInformation generalInformation = new GeneralInformation();
+ generalInformation.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+ return generalInformation;
+ }
+
+ /**
+ * Creates a GeneralInformation SMC object from a map without validation
+ *
+ * @param obj a GeneralInformation SMC object as raw map
+ * @return a GeneralInformation SMC object, that behaves like a facade for the given map
+ */
+ private static GeneralInformation createAsFacadeNonStrict(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ GeneralInformation generalInformation = new GeneralInformation();
+ generalInformation.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+ return generalInformation;
+ }
+
+ /**
+ * Check whether all mandatory elements for GeneralInformation SMC
+ * exist in the map
+ *
+ * @param obj
+ *
+ * @return true/false
+ */
+ @SuppressWarnings("unchecked")
+ public static boolean isValid(Map<String, Object> obj) {
+ GeneralInformation generalInformation = createAsFacadeNonStrict(obj);
+ return SubmodelElementCollection.isValid(obj)
+ && Property.isValid((Map<String, Object>) generalInformation.getManufacturerName())
+ && MultiLanguageProperty.isValid((Map<String, Object>) generalInformation.getManufacturerProductDesignation())
+ && Property.isValid((Map<String, Object>) generalInformation.getManufacturerPartNumber())
+ && Property.isValid((Map<String, Object>) generalInformation.getManufacturerOrderCode());
+ }
+
+ /**
+ * Sets legally valid designation of the natural or judicial body which is directly responsible for the design, production, packaging and labeling of a product in respect to its being brought into the market.
+ *
+ * @param name
+ */
+ public void setManufacturerName(Property name) {
+ addSubmodelElement(name);
+ }
+
+ /**
+ * Sets legally valid designation of the natural or judicial body which is directly responsible for the design, production, packaging and labeling of a product in respect to its being brought into the market.
+ *
+ * @param name
+ */
+ public void setManufacturerName(String name) {
+ Property nameProp = new Property(MANUFACTURERNAMEID, ValueType.String);
+ nameProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/ManufacturerName/1/1", IdentifierType.IRI)));
+ nameProp.setValue(name);
+ setManufacturerName(nameProp);
+ }
+
+ /**
+ * Gets legally valid designation of the natural or judicial body which is directly responsible for the design, production, packaging and labeling of a product in respect to its being brought into the market.
+ *
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IProperty getManufacturerName() {
+ return Property.createAsFacade((Map<String, Object>) getSubmodelElement(MANUFACTURERNAMEID));
+ }
+
+ /**
+ * Sets imagefile for logo of manufacturer provided in common format (.png, .jpg).
+ *
+ * @param logo
+ */
+ public void setManufacturerLogo(File logo) {
+ addSubmodelElement(logo);
+ }
+
+ /**
+ * Gets imagefile for logo of manufacturer provided in common format (.png, .jpg).
+ *
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IFile getManufacturerLogo() {
+ return File.createAsFacade((Map<String, Object>) getSubmodelElement(MANUFACTURERLOGOID));
+ }
+
+ /**
+ * Sets product designation as given by the mnaufacturer. Short description of the product, product group or function (short text) in common language.
+ *
+ * Note: Whenever possible, a multi-language definition is preferred.
+ *
+ * @param designation {@link MultiLanguageProperty}
+ */
+ public void setManufacturerProductDesignation(MultiLanguageProperty designation) {
+ addSubmodelElement(designation);
+ }
+
+ /**
+ * Sets product designation as given by the mnaufacturer. Short description of the product, product group or function (short text) in common language.
+ *
+ * Note: Whenever possible, a multi-language definition is preferred.
+ *
+ * @param designation {@link LangString}
+ */
+ public void setManufacturerProductDesignation(LangString designation) {
+ MultiLanguageProperty designationProp = new MultiLanguageProperty(MANUFACTURERPRODUCTDESIGNATIONID);
+ designationProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/ManufacturerProductDesignation/1/1", IdentifierType.IRI)));
+ designationProp.setValue(new LangStrings(designation));
+ setManufacturerProductDesignation(designationProp);
+ }
+
+ /**
+ * Gets product designation as given by the mnaufacturer. Short description of the product, product group or function (short text) in common language.
+ *
+ * Note: Whenever possible, a multi-language definition is preferred.
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IMultiLanguageProperty getManufacturerProductDesignation() {
+ return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(MANUFACTURERPRODUCTDESIGNATIONID));
+ }
+
+ /**
+ * Sets unique product identifier of the manufacturer for the product type respective the type designation of the industrial equipemnt.
+ *
+ * Note: The Manufacturer part number is represented as a string, although often a numerical id.
+ * @param partNumber
+ */
+ public void setManufacturerPartNumber(Property partNumber) {
+ addSubmodelElement(partNumber);
+ }
+
+ /**
+ * Sets unique product identifier of the manufacturer for the product type respective the type designation of the industrial equipemnt.
+ *
+ * Note: The Manufacturer part number is represented as a string, although often a numerical id.
+ * @param partNumber
+ */
+ public void setManufacturerPartNumber(String partNumber) {
+ Property partNumberProp = new Property(MANUFACTURERPARTNUMBERID, ValueType.String);
+ partNumberProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/ManufacturerPartNumber/1/1", IdentifierType.IRI)));
+ partNumberProp.setValue(partNumber);
+ setManufacturerPartNumber(partNumberProp);
+ }
+
+ /**
+ * Gets unique product identifier of the manufacturer for the product type respective the type designation of the industrial equipemnt.
+ *
+ * Note: The Manufacturer part number is represented as a string, although often a numerical id.
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IProperty getManufacturerPartNumber() {
+ return Property.createAsFacade((Map<String, Object>) getSubmodelElement(MANUFACTURERPARTNUMBERID));
+ }
+
+ /**
+ * Sets unique product identifier of the manufacturer sufficient to order the exact same product.
+ *
+ * @param orderCode
+ */
+ public void setManufacturerOrderCode(Property orderCode) {
+ addSubmodelElement(orderCode);
+ }
+
+ /**
+ * Sets unique product identifier of the manufacturer sufficient to order the exact same product.
+ *
+ * @param orderCode
+ */
+ public void setManufacturerOrderCode(String orderCode) {
+ Property orderCodeProp = new Property(MANUFACTURERORDERCODEID, ValueType.String);
+ orderCodeProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/ManufacturerOrderCode/1/1", IdentifierType.IRI)));
+ orderCodeProp.setValue(orderCode);
+ setManufacturerOrderCode(orderCodeProp);
+ }
+
+ /**
+ * Gets unique product identifier of the manufacturer sufficient to order the exact same product.
+ *
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IProperty getManufacturerOrderCode() {
+ return Property.createAsFacade((Map<String, Object>) getSubmodelElement(MANUFACTURERORDERCODEID));
+ }
+
+ /**
+ * Sets image file for associated product provided in common format (.png, .jpg).
+ *
+ * @param image
+ */
+ public void setProductImages(List<File> images) {
+ if (images != null && images.size() > 0) {
+ for (File image : images) {
+ addSubmodelElement(image);
+ }
+ }
+ }
+
+ /**
+ * Gets image file for associated product provided in common format (.png, .jpg).
+ *
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public List<IFile> getProductImages() {
+ List<IFile> ret = new ArrayList<IFile>();
+ List<ISubmodelElement> elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(PRODUCTIMAGEPREFIX, getSubmodelElements());
+
+ for (ISubmodelElement element: elements) {
+ ret.add(File.createAsFacade((Map<String, Object>) element));
+ }
+ return ret;
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/productclassifications/ProductClassificationItem.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/productclassifications/ProductClassificationItem.java
new file mode 100644
index 0000000..647e9a0
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/productclassifications/ProductClassificationItem.java
@@ -0,0 +1,228 @@
+/*******************************************************************************
+* Copyright (C) 2021 the Eclipse BaSyx Authors
+*
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+
+*
+* SPDX-License-Identifier: EPL-2.0
+******************************************************************************/
+
+package org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.productclassifications;
+
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+
+/**
+ * ProductClassificationItem as described in the Submodel Template AAS Technical Data Document
+ *
+ * It is a submodel element collection which contains Single product
+ * classification by association with product class in a particular
+ * classification system or property dictionary.
+ *
+ * @author haque
+ *
+ */
+public class ProductClassificationItem extends SubmodelElementCollection {
+ public static final String PRODUCTCLASSIFICATIONSYSTEMID = "ProductClassificationSystem";
+ public static final String CLASSIFICATIONSYSTEMVERSIONID = "ClassificationSystemVersion";
+ public static final String PRODUCTCLASSID = "ProductClassId";
+ public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/ProductClassificationItem/1/1", KeyType.IRI));
+
+ private ProductClassificationItem() {
+ }
+
+ /**
+ * Constructor with mandatory attributes
+ *
+ * @param idShort
+ * @param productClassificationSystem
+ * @param productClassId
+ */
+ public ProductClassificationItem(String idShort, Property productClassificationSystem, Property productClassId) {
+ super(idShort);
+ setSemanticId(SEMANTICID);
+ setProductClassificationSystem(productClassificationSystem);
+ setProductClassId(productClassId);
+ }
+
+ /**
+ * Constructor with mandatory attributes
+ *
+ * @param idShort
+ * @param productClassificationSystem
+ * @param productClassId
+ */
+ public ProductClassificationItem(String idShort, String productClassificationSystem, String productClassId) {
+ super(idShort);
+ setSemanticId(SEMANTICID);
+ setProductClassificationSystem(productClassificationSystem);
+ setProductClassId(productClassId);
+ }
+
+ /**
+ * Creates a ProductClassificationItem SMC object from a map
+ *
+ * @param obj a ProductClassificationItem SMC object as raw map
+ * @return a ProductClassificationItem SMC object, that behaves like a facade for the given map
+ */
+ public static ProductClassificationItem createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (!isValid(obj)) {
+ throw new MetamodelConstructionException(ProductClassificationItem.class, obj);
+ }
+
+ ProductClassificationItem productClassificationItem = new ProductClassificationItem();
+ productClassificationItem.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+ return productClassificationItem;
+ }
+
+ /**
+ * Creates a ProductClassificationItem SMC object from a map without validation
+ *
+ * @param obj a ProductClassificationItem SMC object as raw map
+ * @return a ProductClassificationItem SMC object, that behaves like a facade for the given map
+ */
+ private static ProductClassificationItem createAsFacadeNonStrict(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ ProductClassificationItem productClassificationItem = new ProductClassificationItem();
+ productClassificationItem.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+ return productClassificationItem;
+ }
+
+ /**
+ * Check whether all mandatory elements for ProdictClassificationSystem SMC
+ * exist in the map
+ *
+ * @param obj
+ *
+ * @return true/false
+ */
+ @SuppressWarnings("unchecked")
+ public static boolean isValid(Map<String, Object> obj) {
+ ProductClassificationItem productClassificationItem = createAsFacadeNonStrict(obj);
+ return SubmodelElementCollection.isValid(obj)
+ && Property.isValid((Map<String, Object>) productClassificationItem.getProductClassificationSystem())
+ && Property.isValid((Map<String, Object>) productClassificationItem.getProductClassId());
+ }
+
+ /**
+ * Sets common name of the classification system.
+ *
+ * Note: Examples for common names for classification systems are "ECLASS" or "IEC CDD".
+ * @param system
+ */
+ public void setProductClassificationSystem(Property system) {
+ addSubmodelElement(system);
+ }
+
+ /**
+ * Sets common name of the classification system.
+ *
+ * Note: Examples for common names for classification systems are "ECLASS" or "IEC CDD".
+ * @param system
+ */
+ public void setProductClassificationSystem(String system) {
+ Property productClassificationSystemProp = new Property(PRODUCTCLASSIFICATIONSYSTEMID, ValueType.String);
+ productClassificationSystemProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/ProductClassificationSystem/1/1", IdentifierType.IRI)));
+ productClassificationSystemProp.setValue(system);
+ setProductClassificationSystem(productClassificationSystemProp);
+ }
+
+ /**
+ * Gets common name of the classification system.
+ *
+ * Note: Examples for common names for classification systems are "ECLASS" or "IEC CDD".
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IProperty getProductClassificationSystem() {
+ return Property.createAsFacade((Map<String, Object>) getSubmodelElement(PRODUCTCLASSIFICATIONSYSTEMID));
+ }
+
+ /**
+ * Sets common version identifier of the used classification system, in order to distinguish different version of the property dictionary.
+ *
+ * Note: Casing is to be ignored.
+ * @param version
+ */
+ public void setClassificationSystemVersion(Property version) {
+ addSubmodelElement(version);
+ }
+
+ /**
+ * Sets common version identifier of the used classification system, in order to distinguish different version of the property dictionary.
+ *
+ * Note: Casing is to be ignored.
+ * @param system
+ */
+ public void setClassificationSystemVersion(String version) {
+ Property versionProp = new Property(CLASSIFICATIONSYSTEMVERSIONID, ValueType.String);
+ versionProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/ClassificationSystemVersion/1/1", IdentifierType.IRI)));
+ versionProp.setValue(version);
+ setClassificationSystemVersion(versionProp);
+ }
+
+ /**
+ * Gets common version identifier of the used classification system, in order to distinguish different version of the property dictionary.
+ *
+ * Note: Casing is to be ignored.
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IProperty getClassificationSystemVersion() {
+ return Property.createAsFacade((Map<String, Object>) getSubmodelElement(CLASSIFICATIONSYSTEMVERSIONID));
+ }
+
+ /**
+ * Sets class of the associated product or industrial equipment in the classification system. According to the notation of the system.
+ *
+ * Note: Ideally, the Property/valueId is used to reference the IRI/ IRDI of the product class.
+ * @param id
+ */
+ public void setProductClassId(Property id) {
+ addSubmodelElement(id);
+ }
+
+ /**
+ * Sets class of the associated product or industrial equipment in the classification system. According to the notation of the system.
+ *
+ * Note: Ideally, the Property/valueId is used to reference the IRI/ IRDI of the product class.
+ * @param id
+ */
+ public void setProductClassId(String id) {
+ Property idProp = new Property(PRODUCTCLASSID, ValueType.String);
+ idProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/ProductClassId/1/1", IdentifierType.IRI)));
+ idProp.setValue(id);
+ setProductClassId(idProp);
+ }
+
+ /**
+ * Gets class of the associated product or industrial equipment in the classification system. According to the notation of the system.
+ *
+ * Note: Ideally, the Property/valueId is used to reference the IRI/ IRDI of the product class.
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public IProperty getProductClassId() {
+ return Property.createAsFacade((Map<String, Object>) getSubmodelElement(PRODUCTCLASSID));
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/productclassifications/ProductClassifications.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/productclassifications/ProductClassifications.java
new file mode 100644
index 0000000..955c34a
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/productclassifications/ProductClassifications.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+* Copyright (C) 2021 the Eclipse BaSyx Authors
+*
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+
+*
+* SPDX-License-Identifier: EPL-2.0
+******************************************************************************/
+
+package org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.productclassifications;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.types.helper.SubmodelElementRetrievalHelper;
+
+/**
+ * ProductClassifications as described in the Submodel Template AAS Technical Data Document
+ * It is a submodel element collection which contains Product classifications by association with product classes in common classification systems.
+ *
+ * @author haque
+ *
+ */
+public class ProductClassifications extends SubmodelElementCollection {
+ public static final String IDSHORT = "ProductClassifications";
+ public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/ProductClassifications/1/1", KeyType.IRI));
+ public static final String PRODUCTCLASSIFICATIONITEMPREFIX = "ProductClassificationItem";
+
+ /**
+ * Constructor with default idshort
+ */
+ public ProductClassifications() {
+ this(IDSHORT);
+ }
+
+ /**
+ * Constructor with mandatory attributes
+ *
+ * @param idShort
+ */
+ public ProductClassifications(String idShort) {
+ super(idShort);
+ setProductClassificationItems(new ArrayList<ProductClassificationItem>());
+ }
+
+ /**
+ * Creates a ProductClassifications SMC object from a map
+ *
+ * @param obj a ProductClassifications SMC object as raw map
+ * @return a ProductClassifications SMC object, that behaves like a facade for the given map
+ */
+ public static ProductClassifications createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (!isValid(obj)) {
+ throw new MetamodelConstructionException(ProductClassifications.class, obj);
+ }
+
+ ProductClassifications productClassifications = new ProductClassifications();
+ productClassifications.setMap((Map<String, Object>)SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+ return productClassifications;
+ }
+
+ /**
+ * Check whether all mandatory elements for ProductClassifications SMC
+ * exist in the map
+ *
+ * @param obj
+ *
+ * @return true/false
+ */
+ public static boolean isValid(Map<String, Object> obj) {
+ return SubmodelElementCollection.isValid(obj);
+ }
+
+ /**
+ * Sets single product classification item by association with product class in a particular classification system or property dictionary
+ *
+ * @param items
+ */
+ public void setProductClassificationItems(List<ProductClassificationItem> items) {
+ if (items != null && items.size() > 0) {
+ for (ProductClassificationItem item: items) {
+ addSubmodelElement(item);
+ }
+ }
+ }
+
+ /**
+ * Gets single product classification item by association with product class in a particular classification system or property dictionary
+ *
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public List<ProductClassificationItem> getProductClassificationItems() {
+ List<ProductClassificationItem> ret = new ArrayList<ProductClassificationItem>();
+ List<ISubmodelElement> elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(PRODUCTCLASSIFICATIONITEMPREFIX, getSubmodelElements());
+
+ for (ISubmodelElement element: elements) {
+ ret.add(ProductClassificationItem.createAsFacade((Map<String, Object>) element));
+ }
+ return ret;
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/technicalproperties/TechnicalProperties.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/technicalproperties/TechnicalProperties.java
new file mode 100644
index 0000000..78185f2
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/technicalproperties/TechnicalProperties.java
@@ -0,0 +1,229 @@
+/*******************************************************************************
+* Copyright (C) 2021 the Eclipse BaSyx Authors
+*
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+
+*
+* SPDX-License-Identifier: EPL-2.0
+******************************************************************************/
+
+package org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.technicalproperties;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.types.helper.SubmodelElementRetrievalHelper;
+
+/**
+ * TechnicalProperties as described in the Submodel Template AAS Technical Data Document
+ *
+ * It is a submodel element collection which contains Individual characteristics that describe the product (industrial equipment) and its technical properties.
+ *
+ * @author haque
+ *
+ */
+public class TechnicalProperties extends SubmodelElementCollection {
+ public static final String IDSHORT = "TechnicalProperties";
+ public static final String MAINSECTIONPREFIX = "MainSection";
+ public static final String SUBSECTIONPREFIX = "SubSection";
+ public static final String SMENOTDESCRIBEDID = "https://admin-shell.io/SemanticIdNotAvailable/1/1";
+ public static final String MAINSECTIONID = "https://admin-shell.io/ZVEI/TechnicalData/MainSection/1/1";
+ public static final String SUBSECTIONID = "https://admin-shell.io/ZVEI/TechnicalData/SubSection/1/1";
+ public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/TechnicalProperties/1/1", KeyType.IRI));
+
+ /**
+ * Constructor with default idShort
+ */
+ public TechnicalProperties() {
+ this(IDSHORT);
+ }
+
+ /**
+ * Constructor with mandatory attributes
+ * @param idShort
+ */
+ public TechnicalProperties(String idShort) {
+ super(idShort);
+ }
+
+ /**
+ * Creates a TechnicalProperties SMC object from a map
+ *
+ * @param obj a TechnicalProperties SMC object as raw map
+ * @return a TechnicalProperties SMC object, that behaves like a facade for the given map
+ */
+ public static TechnicalProperties createAsFacade(Map<String, Object> obj) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (!isValid(obj)) {
+ throw new MetamodelConstructionException(TechnicalProperties.class, obj);
+ }
+
+ TechnicalProperties technicalProperties = new TechnicalProperties();
+ technicalProperties.setMap((Map<String, Object>)SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+ return technicalProperties;
+ }
+
+ /**
+ * Check whether all mandatory elements for TechnicalProperties SMC
+ * exist in the map
+ *
+ * @param obj
+ *
+ * @return true/false
+ */
+ public static boolean isValid(Map<String, Object> obj) {
+ return SubmodelElementCollection.isValid(obj);
+ }
+
+ /**
+ * Sets arbitrary semanticId but defined in a classification system
+ *
+ * Arbitrary SubmodelElement with semanticId possibly referring to a ConceptDescription can be used within the Technical Properties.
+ *
+ * @param elements
+ */
+ public void setArbitrary(List<SubmodelElement> elements) {
+ if (elements != null && elements.size() > 0) {
+ for (SubmodelElement elem: elements) {
+ addSubmodelElement(elem);
+ }
+ }
+ }
+
+ /**
+ * Gets arbitrary semanticId but defined in a classification system
+ *
+ * Arbitrary SubmodelElement with semanticId possibly referring to a ConceptDescription can be used within the Technical Properties.
+ *
+ * @return
+ */
+ public List<ISubmodelElement> getArbitrary() {
+ return getSubmodelElements()
+ .values().stream()
+ .filter(x -> {
+ String id = x.getSemanticId().getKeys().get(0).getValue();
+ if (id.equals(MAINSECTIONID) || id.equals(SUBSECTIONID) || id.equals(SMENOTDESCRIBEDID)) {
+ return false;
+ } else {
+ return true;
+ }
+ })
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * Set arbitrary
+ *
+ * Represents a SubmodelElement that is not described using a common classification system, a consortium specification, an open community standard, a published manufacturer specification or such.
+ *
+ * Note: The idShort of the SubmodelElement can be named accordingly. Constraints concerning the usable characters for idShort shall be respected.
+ * Note: Only perceivable by human understanding.
+ * Note: The special case of SME being a SMC is accepted, will be rendered as MainSection/ SubSection accordingly.
+ * @param elements
+ */
+ public void setSMENotDescribedBySemanticId(List<SubmodelElement> elements) {
+ if (elements != null && elements.size() > 0) {
+ for (SubmodelElement elem: elements) {
+ addSubmodelElement(elem);
+ }
+ }
+ }
+
+ /**
+ * Get arbitrary
+ * Represents a SubmodelElement that is not described using a common classification system, a consortium specification, an open community standard, a published manufacturer specification or such.
+ *
+ * Note: The idShort of the SubmodelElement can be named accordingly. Constraints concerning the usable characters for idShort shall be respected.
+ * Note: Only perceivable by human understanding.
+ * Note: The special case of SME being a SMC is accepted, will be rendered as MainSection/ SubSection accordingly.
+ * @return
+ */
+ public List<ISubmodelElement> getSMENotDescribedBySemanticId() {
+ return getSubmodelElements()
+ .values().stream()
+ .filter(x -> x.getSemanticId().getKeys().get(0).getValue()
+ .equals(SMENOTDESCRIBEDID))
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * Sets main subdivision possibility for properties.
+ *
+ * Note: Each Main Section SMC may contain arbitray sets of SubmodelElements, SemanticIdNotAvailable, SubSection.
+ * @param mainSections
+ */
+ public void setMainSections(List<SubmodelElementCollection> mainSections) {
+ if (mainSections != null && mainSections.size() > 0) {
+ for (SubmodelElementCollection section: mainSections) {
+ addSubmodelElement(section);
+ }
+ }
+ }
+
+ /**
+ * Gets main subdivision possibility for properties.
+ *
+ * Note: Each Main Section SMC may contain arbitray sets of SubmodelElements, SemanticIdNotAvailable, SubSection.
+ *
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public List<ISubmodelElementCollection> getMainSections() {
+ List<ISubmodelElementCollection> ret = new ArrayList<ISubmodelElementCollection>();
+ List<ISubmodelElement> elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(MAINSECTIONPREFIX, getSubmodelElements());
+
+ for (ISubmodelElement element: elements) {
+ ret.add(SubmodelElementCollection.createAsFacade((Map<String, Object>) element));
+ }
+ return ret;
+ }
+
+ /**
+ * Sets subordinate subdivision possibility for properties.
+ *
+ * Note: Each Sub Section SMC may contain arbitray sets of SubmodelElements, SemanticIdNotAvailable, SubSection.
+ * @param mainSections
+ */
+ public void setSubSections(List<SubmodelElementCollection> subSections) {
+ if (subSections != null && subSections.size() > 0) {
+ for (SubmodelElementCollection section: subSections) {
+ addSubmodelElement(section);
+ }
+ }
+ }
+
+ /**
+ * Gets subordinate subdivision possibility for properties.
+ *
+ * Note: Each Sub Section SMC may contain arbitray sets of SubmodelElements, SemanticIdNotAvailable, SubSection.
+ *
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public List<ISubmodelElementCollection> getSubSections() {
+ List<ISubmodelElementCollection> ret = new ArrayList<ISubmodelElementCollection>();
+ List<ISubmodelElement> elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(SUBSECTIONPREFIX, getSubmodelElements());
+
+ for (ISubmodelElement element: elements) {
+ ret.add(SubmodelElementCollection.createAsFacade((Map<String, Object>) element));
+ }
+ return ret;
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/connector/JSONConnector.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/connector/JSONConnector.java
index 4b0abcc..6fc5eaa 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/connector/JSONConnector.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/connector/JSONConnector.java
@@ -1,8 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.coder.json.connector;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Arrays;
+import java.util.UUID;
+import org.eclipse.basyx.submodel.restapi.operation.InvocationRequest;
import org.eclipse.basyx.vab.coder.json.metaprotocol.IMetaProtocolHandler;
import org.eclipse.basyx.vab.coder.json.metaprotocol.MetaprotocolHandler;
import org.eclipse.basyx.vab.coder.json.serialization.DefaultTypeFactory;
@@ -12,6 +22,8 @@
import org.eclipse.basyx.vab.modelprovider.VABPathTools;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
import org.eclipse.basyx.vab.protocol.api.IBaSyxConnector;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
@@ -24,6 +36,9 @@
*/
public class JSONConnector implements IModelProvider {
+ private static final Logger LOGGER_DEFAULT = LoggerFactory.getLogger(JSONConnector.class);
+ private static final Logger LOGGER_COMMUNICATION = LoggerFactory.getLogger(LOGGER_DEFAULT.getName() + ".MALFORMED");
+
/**
* Reference to Connector backend
@@ -76,24 +91,34 @@
@Override
- public Object getModelPropertyValue(String path) throws ProviderException {
+ public Object getValue(String path) throws ProviderException {
VABPathTools.checkPathForNull(path);
// Get element from server
- String message = provider.getModelPropertyValue(path);
+ String message = provider.getValue(path);
// De-serialize and verify
- return metaProtocolHandler.deserialize(message);
+ try {
+ return metaProtocolHandler.deserialize(message);
+ } catch (ProviderException e) {
+ throw e;
+ } catch (RuntimeException e) {
+ String messageCorrelation = UUID.randomUUID().toString();
+ String msg = "Failed to deserialize request for '" + provider.getEndpointRepresentation(path) + "' (" + messageCorrelation + ")";
+ LOGGER_DEFAULT.warn(msg);
+ LOGGER_COMMUNICATION.warn(msg + ": " + message);
+ throw new ProviderException(msg, e);
+ }
}
@Override
- public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
+ public void setValue(String path, Object newValue) throws ProviderException {
VABPathTools.checkPathForNull(path);
// Serialize value Object
String jsonString = serializer.serialize(newValue);
- String message = provider.setModelPropertyValue(path, jsonString);
+ String message = provider.setValue(path, jsonString);
// De-serialize and verify
metaProtocolHandler.deserialize(message);
@@ -140,16 +165,16 @@
VABPathTools.checkPathForNull(path);
// Serialize parameter
- List<Object> params = new ArrayList<>();
- for (Object o : parameter) {
- params.add(o);
+ String jsonString;
+ if (parameter.length == 1 && parameter[0] instanceof InvocationRequest) {
+ jsonString = serializer.serialize(parameter[0]);
+ } else {
+ jsonString = serializer.serialize(Arrays.asList(parameter));
}
- String jsonString = serializer.serialize(params);
-
String message = provider.invokeOperation(path, jsonString);
// De-serialize and verify
return metaProtocolHandler.deserialize(message);
}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/IMetaProtocolHandler.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/IMetaProtocolHandler.java
index 3c28b2e..634c4b5 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/IMetaProtocolHandler.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/IMetaProtocolHandler.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.coder.json.metaprotocol;
import org.eclipse.basyx.vab.exception.provider.ProviderException;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/Message.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/Message.java
index d3c036d..a11de57 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/Message.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/Message.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.coder.json.metaprotocol;
import java.util.HashMap;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/MessageType.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/MessageType.java
index c27d293..fe6cce7 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/MessageType.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/MessageType.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.coder.json.metaprotocol;
/**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/MetaprotocolHandler.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/MetaprotocolHandler.java
index 60b832d..09195e3 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/MetaprotocolHandler.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/MetaprotocolHandler.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.coder.json.metaprotocol;
import java.util.Collection;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/Result.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/Result.java
index 40d0291..4fa9bc0 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/Result.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/Result.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.coder.json.metaprotocol;
import java.util.Arrays;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/provider/JSONProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/provider/JSONProvider.java
index e1376ec..1d3c2f7 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/provider/JSONProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/provider/JSONProvider.java
@@ -1,6 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.coder.json.provider;
-import java.io.PrintWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
import java.util.Collection;
import org.eclipse.basyx.vab.coder.json.metaprotocol.Result;
@@ -112,12 +123,15 @@
* @param path
* @param resp
*/
- private void sendException(PrintWriter resp, Exception e) throws ProviderException {
+ private void sendException(OutputStream resp, Exception e) throws ProviderException {
// Serialize Exception
String jsonString = serialize(e);
-
- resp.write(jsonString);
+ try {
+ resp.write(jsonString.getBytes(StandardCharsets.UTF_8));
+ } catch(IOException innerE) {
+ throw new ProviderException("Failed to send Exception '" + e.getMessage() + "' to client", innerE);
+ }
//If the Exception is a ProviderException, just rethrow it
if(e instanceof ProviderException) {
@@ -141,7 +155,7 @@
* @throws LostHTTPRequestParameterException
* @throws ProviderException
*/
- private Object extractParameter(String path, String serializedJSONValue, PrintWriter outputStream) throws MalformedRequestException {
+ private Object extractParameter(String path, String serializedJSONValue, OutputStream outputStream) throws MalformedRequestException {
// Return value
Object result = null;
@@ -161,17 +175,17 @@
* Process a BaSys get operation, return JSON serialized result
* @throws ProviderException
*/
- public void processBaSysGet(String path, PrintWriter outputStream) throws ProviderException {
+ public void processBaSysGet(String path, OutputStream outputStream) throws ProviderException {
try {
// Get requested value from provider backend
- Object value = providerBackend.getModelPropertyValue(path);
+ Object value = providerBackend.getValue(path);
// Serialize as json string - any messages?
String jsonString = serializer.serialize(value);
// Send response
- outputStream.write(jsonString);
+ outputStream.write(jsonString.getBytes(StandardCharsets.UTF_8));
} catch (Exception e) {
sendException(outputStream, e);
}
@@ -186,7 +200,7 @@
* @param outputStream
* @throws ProviderException
*/
- public void processBaSysSet(String path, String serializedJSONValue, PrintWriter outputStream) throws ProviderException {
+ public void processBaSysSet(String path, String serializedJSONValue, OutputStream outputStream) throws ProviderException {
// Try to set value of BaSys VAB element
try {
@@ -195,10 +209,10 @@
Object parameter = extractParameter(path, serializedJSONValue, outputStream);
// Set the value of the element
- providerBackend.setModelPropertyValue(path, parameter);
+ providerBackend.setValue(path, parameter);
// Send response
- outputStream.write("");
+ outputStream.write("".getBytes(StandardCharsets.UTF_8));
} catch (Exception e) {
sendException(outputStream, e);
@@ -211,7 +225,7 @@
* @throws ProviderException
*/
@SuppressWarnings("unchecked")
- public void processBaSysInvoke(String path, String serializedJSONValue, PrintWriter outputStream) throws ProviderException {
+ public void processBaSysInvoke(String path, String serializedJSONValue, OutputStream outputStream) throws ProviderException {
try {
@@ -244,7 +258,7 @@
String jsonString = serializer.serialize(result);
// Send response
- outputStream.write(jsonString);
+ outputStream.write(jsonString.getBytes(StandardCharsets.UTF_8));
} catch (Exception e) {
sendException(outputStream, e);
@@ -260,7 +274,7 @@
* @param outputStream
* @throws ProviderException
*/
- public void processBaSysDelete(String path, String serializedJSONValue, PrintWriter outputStream) throws ProviderException {
+ public void processBaSysDelete(String path, String serializedJSONValue, OutputStream outputStream) throws ProviderException {
try {
@@ -275,7 +289,7 @@
}
// Send response
- outputStream.write("");
+ outputStream.write("".getBytes(StandardCharsets.UTF_8));
} catch (Exception e) {
sendException(outputStream, e);
@@ -291,7 +305,7 @@
* @param outputStream
* @throws ProviderException
*/
- public void processBaSysCreate(String path, String serializedJSONValue, PrintWriter outputStream) throws ProviderException {
+ public void processBaSysCreate(String path, String serializedJSONValue, OutputStream outputStream) throws ProviderException {
try {
// Deserialize json body.
@@ -301,7 +315,7 @@
providerBackend.createValue(path, parameter);
// Send response
- outputStream.write("");
+ outputStream.write("".getBytes(StandardCharsets.UTF_8));
} catch (Exception e) {
sendException(outputStream, e);
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/DefaultTypeFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/DefaultTypeFactory.java
index c7fcd3f..3066bf8 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/DefaultTypeFactory.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/DefaultTypeFactory.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.coder.json.serialization;
import java.util.ArrayList;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/GSONTools.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/GSONTools.java
index 34f1eec..fde9ef9 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/GSONTools.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/GSONTools.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.coder.json.serialization;
import java.io.ByteArrayInputStream;
@@ -7,6 +16,7 @@
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
+import java.math.BigInteger;
import java.util.Base64;
import java.util.Collection;
import java.util.Map;
@@ -19,6 +29,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
@@ -59,6 +70,16 @@
* Type factory
*/
protected GSONToolsFactory toolsFactory = null;
+
+ /**
+ * Flag to remove null values from serialized JSON
+ */
+ private boolean removeNull = true;
+
+ /**
+ * Flag to remove empty arrays from serialized JSON
+ */
+ private boolean removeEmpty = false;
/**
* Constructor
@@ -67,6 +88,15 @@
// Store factory reference
toolsFactory = factory;
}
+
+ /**
+ * Constructor
+ */
+ public GSONTools(GSONToolsFactory factory, boolean removeNull, boolean removeEmpty) {
+ this(factory);
+ this.removeNull = removeNull;
+ this.removeEmpty = removeEmpty;
+ }
/**
* Set factory instance
@@ -85,7 +115,14 @@
@Override
public String serialize(Object obj) {
JsonElement elem = serializeObject(obj);
- return elem.toString();
+ // Removing null value if the removeNull flag is on
+ if (removeNull) {
+ // Gson#toJson removes null automatically
+ Gson gson = new Gson();
+ return gson.toJson(elem);
+ } else {
+ return elem.toString();
+ }
}
/**
@@ -98,7 +135,7 @@
private JsonElement serializeObject(Object obj) {
if (obj == null) {
return JsonNull.INSTANCE;
- } else if (obj.getClass().isPrimitive() || isWrapperType(obj.getClass()) || obj instanceof String) {
+ } else if (obj.getClass().isPrimitive() || isWrapperType(obj.getClass()) || obj instanceof String || obj instanceof Number) {
return serializePrimitive(obj);
} else if (obj instanceof Map<?, ?>) {
return serializeMap((Map<String, Object>) obj);
@@ -149,7 +186,19 @@
if (primitive.getAsString().contains(".")) {
return primitive.getAsDouble();
} else {
- return primitive.getAsInt();
+ // Get value as Big integer
+ BigInteger tmp= primitive.getAsBigInteger();
+ if (BigInteger.valueOf(Integer.MAX_VALUE).compareTo(tmp) >= 0 && BigInteger.valueOf(Integer.MIN_VALUE).compareTo(tmp) <= 0) {
+ // convert to int
+ return primitive.getAsInt();
+ } else if (BigInteger.valueOf(Long.MAX_VALUE).compareTo(tmp) >= 0 && BigInteger.valueOf(Long.MIN_VALUE).compareTo(tmp) <= 0) {
+ // convert to long
+ return primitive.getAsLong();
+ } else {
+ // for types NonNegativeInteger, NonPositiveInteger, NegativeInteger,
+ // PositiveInteger
+ return tmp;
+ }
}
} else if (primitive.isBoolean()) {
return primitive.getAsBoolean();
@@ -158,6 +207,7 @@
}
}
+
/**
* Serializes either string, number or boolean to a JsonPrimitive
*
@@ -219,7 +269,11 @@
private JsonObject serializeMap(Map<String, Object> map) {
JsonObject obj = new JsonObject();
for (Entry<String, Object> entry : map.entrySet()) {
- obj.add(entry.getKey(), serializeObject(entry.getValue()));
+ Object value = entry.getValue();
+ // Remove empty list if removeEmpty flag is on
+ if (!removeEmpty || !(value instanceof Collection<?> && ((Collection<?>)value).isEmpty())) {
+ obj.add(entry.getKey(), serializeObject(value));
+ }
}
return obj;
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/GSONToolsFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/GSONToolsFactory.java
index 31dd4b6..ee0685b 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/GSONToolsFactory.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/GSONToolsFactory.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.coder.json.serialization;
import java.util.Collection;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/Serializer.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/Serializer.java
index 523387f..1ea9f8b 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/Serializer.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/Serializer.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.coder.json.serialization;
/**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/directory/api/IVABDirectoryService.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/directory/api/IVABDirectoryService.java
deleted file mode 100644
index 17d51a8..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/directory/api/IVABDirectoryService.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package org.eclipse.basyx.vab.directory.api;
-
-/**
- * Directory service SDK interface.
- *
- * @author kuhn
- *
- */
-public interface IVABDirectoryService {
-
-
- /**
- * Add a mapping to directory
- */
- public IVABDirectoryService addMapping(String key, String value);
-
-
- /**
- * Remove a mapping from directory
- */
- public void removeMapping(String key);
-
-
- /**
- * Lookup method maps key "id" to value
- */
- public String lookup(String id);
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/directory/memory/InMemoryDirectory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/directory/memory/InMemoryDirectory.java
deleted file mode 100644
index a3ee350..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/directory/memory/InMemoryDirectory.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package org.eclipse.basyx.vab.directory.memory;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.basyx.vab.directory.api.IVABDirectoryService;
-import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
-
-
-
-/**
- * Implement a in memory directory
- *
- * @author kuhn
- *
- */
-public class InMemoryDirectory implements IVABDirectoryService {
-
-
- /**
- * Map that stores key/value mappings
- */
- protected Map<String, Object> keyToValue = new HashMap<>();
-
-
-
-
- /**
- * Default constructor
- */
- public InMemoryDirectory() {
- // Do nothing
- }
-
-
- /**
- * Constructor that accepts initial entries
- */
- public InMemoryDirectory(Map<String, String> addedValues) {
- keyToValue.putAll(addedValues);
- }
-
-
-
- /**
- * Add a mapping to directory
- */
- @Override
- public IVABDirectoryService addMapping(String key, String value) {
- keyToValue.put(key, value);
-
- // Return 'this' instance
- return this;
- }
-
- /**
- * Add several mappings to directory
- */
- public void addMappings(Map<String, String> mappings) {
- keyToValue.putAll(mappings);
- }
-
- /**
- * Remove a mapping from directory
- */
- @Override
- public void removeMapping(String key) {
- keyToValue.remove(key);
- }
-
- /**
- * Lookup method
- */
- @Override
- public String lookup(String id) {
- if(keyToValue.containsKey(id)) {
- return (String) keyToValue.get(id);
- } else {
- throw new ResourceNotFoundException("No entry exists for key " + id);
- }
- }
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/directory/proxy/VABDirectoryProxy.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/directory/proxy/VABDirectoryProxy.java
deleted file mode 100644
index 9741496..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/directory/proxy/VABDirectoryProxy.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package org.eclipse.basyx.vab.directory.proxy;
-
-import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
-import org.eclipse.basyx.vab.directory.api.IVABDirectoryService;
-import org.eclipse.basyx.vab.exception.provider.ProviderException;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnector;
-
-public class VABDirectoryProxy implements IVABDirectoryService {
- /**
- * Store the URL of the registry of this proxy
- */
- protected IModelProvider provider;
-
- /**
- * Constructor for a generic VAB directory proxy based on a HTTP connection
- *
- * @param directoryUrl
- * The endpoint of the registry with a HTTP-REST interface
- */
- public VABDirectoryProxy(String directoryUrl) {
- this(new VABElementProxy("", new JSONConnector(new HTTPConnector(directoryUrl))));
- }
-
- /**
- * Constructor for a generic VAB directory based on the registry model provider
- *
- * @param provider
- * A model provider for the actual registry
- */
- public VABDirectoryProxy(IModelProvider provider) {
- this.provider = provider;
- }
-
- /**
- * Adds a single entry to the directory
- */
- @Override
- public IVABDirectoryService addMapping(String key, String value) {
- provider.createValue(key, value);
- return this;
- }
-
- /**
- * Deletes an entry from the directory
- */
- @Override
- public void removeMapping(String key) {
- provider.deleteValue(key);
- }
-
- /**
- * Returns a single entry in the directory
- */
- @Override
- public String lookup(String id) {
- Object response = provider.getModelPropertyValue(id);
-
- if (response instanceof String) {
- return (String) response;
- } else {
- throw new ProviderException("Lookup returned unexpected object: " + response);
- }
- }
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/directory/restapi/DirectoryModelProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/directory/restapi/DirectoryModelProvider.java
deleted file mode 100644
index 0d06c5c..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/directory/restapi/DirectoryModelProvider.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package org.eclipse.basyx.vab.directory.restapi;
-
-import org.eclipse.basyx.vab.directory.api.IVABDirectoryService;
-import org.eclipse.basyx.vab.directory.memory.InMemoryDirectory;
-import org.eclipse.basyx.vab.exception.provider.ProviderException;
-import org.eclipse.basyx.vab.modelprovider.VABPathTools;
-import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-
-/**
- * Connects an arbitrary IVABDirectoryService implementation to the VAB
- *
- * @author schnicke
- */
-
-public class DirectoryModelProvider implements IModelProvider {
-
- private IVABDirectoryService directory;
-
- /**
- * Creates a DirectoryModelProvider wrapping an IVABDirectoryService
- *
- * @param directory
- */
- public DirectoryModelProvider(IVABDirectoryService directory) {
- super();
- this.directory = directory;
- }
-
- /**
- * Creates a default DirectoryModelProvider wrapping an InMemoryDirectory
- */
- public DirectoryModelProvider() {
- this(new InMemoryDirectory());
- }
-
- @Override
- public Object getModelPropertyValue(String path) throws ProviderException {
- path = VABPathTools.stripSlashes(path);
- return directory.lookup(path);
- }
-
- @Override
- public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
- throw new RuntimeException("Set not supported by VAB Directory");
- }
-
- @Override
- public void createValue(String path, Object newEntity) throws ProviderException {
- path = VABPathTools.stripSlashes(path);
- directory.addMapping(path, (String) newEntity);
- }
-
- @Override
- public void deleteValue(String path) throws ProviderException {
- path = VABPathTools.stripSlashes(path);
- directory.removeMapping(path);
- }
-
- @Override
- public void deleteValue(String path, Object obj) throws ProviderException {
- throw new RuntimeException("Delete with parameter not supported by VAB Directory");
- }
-
- @Override
- public Object invokeOperation(String path, Object... parameter) throws ProviderException {
- throw new RuntimeException("Invoke not supported by VAB Directory");
- }
-
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/AtomicTransactionFailedException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/AtomicTransactionFailedException.java
index 8e5a003..07ac87d 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/AtomicTransactionFailedException.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/AtomicTransactionFailedException.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.exception;
public class AtomicTransactionFailedException extends Exception {
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/FeatureNotImplementedException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/FeatureNotImplementedException.java
index 27f0dcc..5690bf0 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/FeatureNotImplementedException.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/FeatureNotImplementedException.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.exception;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/LostHTTPRequestParameterException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/LostHTTPRequestParameterException.java
index 63d1b72..35130dd 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/LostHTTPRequestParameterException.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/LostHTTPRequestParameterException.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.exception;
public class LostHTTPRequestParameterException extends Exception {
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/ReadOnlyException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/ReadOnlyException.java
index 498bfca..e9b3dc6 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/ReadOnlyException.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/ReadOnlyException.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.exception;
public class ReadOnlyException extends Exception {
@@ -12,7 +21,7 @@
*/
public ReadOnlyException(String name) {
// Store message
- message = "The SubModel "+name+" is frozen.";
+ message = "The Submodel "+name+" is frozen.";
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/TypeMismatchException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/TypeMismatchException.java
index c9e36da..01a4808 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/TypeMismatchException.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/TypeMismatchException.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.exception;
public class TypeMismatchException extends Exception {
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/UnknownElementTypeException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/UnknownElementTypeException.java
index 7114694..4e6fbf6 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/UnknownElementTypeException.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/UnknownElementTypeException.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.exception;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/MalformedRequestException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/MalformedRequestException.java
index 02f92a0..1137cd3 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/MalformedRequestException.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/MalformedRequestException.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.exception.provider;
/**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/NotAnInvokableException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/NotAnInvokableException.java
index 58f54d5..62d87fe 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/NotAnInvokableException.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/NotAnInvokableException.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.exception.provider;
/**
@@ -26,4 +35,4 @@
public NotAnInvokableException(Exception e) {
super(e);
}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/ProviderException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/ProviderException.java
index 4544210..8eb45b2 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/ProviderException.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/ProviderException.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.exception.provider;
/**
@@ -35,6 +44,12 @@
}
+ public ProviderException(String message, Throwable cause) {
+ super(cause);
+ this.message = message;
+ }
+
+
/**
* Return detailed message
*/
@@ -42,4 +57,4 @@
public String getMessage() {
return message;
}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/ResourceAlreadyExistsException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/ResourceAlreadyExistsException.java
index 5289ae0..6b6a589 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/ResourceAlreadyExistsException.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/ResourceAlreadyExistsException.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.exception.provider;
/**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/ResourceNotFoundException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/ResourceNotFoundException.java
index 9c58147..07e64e2 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/ResourceNotFoundException.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/ResourceNotFoundException.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.exception.provider;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/WrongNumberOfParametersException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/WrongNumberOfParametersException.java
new file mode 100644
index 0000000..32bff37
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/WrongNumberOfParametersException.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab.exception.provider;
+
+import java.util.Collection;
+
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperationVariable;
+
+public class WrongNumberOfParametersException extends MalformedRequestException {
+ /**
+ * Version information for serialized instances
+ */
+ private static final long serialVersionUID = 1L;
+ public WrongNumberOfParametersException(String operationIdShort, Collection<IOperationVariable> expected, Object... actual) {
+ super(constructErrorMessage(operationIdShort, expected, actual));
+ }
+
+ private static String constructErrorMessage(String operationIdShort, Collection<IOperationVariable> expected, Object... actual) {
+ return "Operation with idShort " + operationIdShort + " was called using the wrong number of parameters. Expected size: " + expected.size() + ", actual: " + actual.length;
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/factory/java/ModelProxyFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/factory/java/ModelProxyFactory.java
index 7c33ed7..705571a 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/factory/java/ModelProxyFactory.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/factory/java/ModelProxyFactory.java
@@ -1,9 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.factory.java;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
import org.eclipse.basyx.vab.modelprovider.VABPathTools;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-import org.eclipse.basyx.vab.protocol.api.IConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
/**
* A factory for creating model providers out of addresses with multiple endpoints included.
@@ -12,10 +21,10 @@
*
*/
public class ModelProxyFactory {
- private IConnectorProvider connectorProvider;
+ private IConnectorFactory connectorFactory;
- public ModelProxyFactory(IConnectorProvider connectorProvider) {
- this.connectorProvider = connectorProvider;
+ public ModelProxyFactory(IConnectorFactory connectorFactory) {
+ this.connectorFactory = connectorFactory;
}
/**
@@ -27,7 +36,7 @@
public VABElementProxy createProxy(String path) {
// Create a model provider for the first endpoint
String addressEntry = VABPathTools.getFirstEndpoint(path);
- IModelProvider provider = connectorProvider.getConnector(addressEntry);
+ IModelProvider provider = connectorFactory.getConnector(addressEntry);
// Return a proxy for the whole path using the connector to the first endpoint
String subPath = VABPathTools.removeFirstEndpoint(path);
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/factory/xml/VABXmlProviderFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/factory/xml/VABXmlProviderFactory.java
index 4036244..4391edf 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/factory/xml/VABXmlProviderFactory.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/factory/xml/VABXmlProviderFactory.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.factory.xml;
import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/factory/xml/XmlParser.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/factory/xml/XmlParser.java
index ac14dc2..adef422 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/factory/xml/XmlParser.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/factory/xml/XmlParser.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.factory.xml;
import java.io.IOException;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/gateway/ConnectorProviderMapper.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/gateway/ConnectorProviderMapper.java
index d90db4a..35fd2ab 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/gateway/ConnectorProviderMapper.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/gateway/ConnectorProviderMapper.java
@@ -1,10 +1,19 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.gateway;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-import org.eclipse.basyx.vab.protocol.api.IConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
/**
* Maps an incoming address to an IConnectorProvider based on the protocol used
@@ -15,9 +24,9 @@
* @author schnicke
*
*/
-public class ConnectorProviderMapper implements IConnectorProvider {
+public class ConnectorProviderMapper implements IConnectorFactory {
- private Map<String, IConnectorProvider> providerMap = new HashMap<>();
+ private Map<String, IConnectorFactory> providerMap = new HashMap<>();
/**
*
@@ -26,7 +35,7 @@
* <i>basyx://</i>
* @param provider
*/
- public void addConnectorProvider(String prefix, IConnectorProvider provider) {
+ public void addConnectorProvider(String prefix, IConnectorFactory provider) {
providerMap.put(prefix, provider);
}
@@ -47,7 +56,7 @@
*/
private String getPrefix(String addr) {
String prefix = addr.split("//")[0];
- return prefix.replace(":", "");
+ return prefix.replaceFirst(":", "");
}
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/gateway/DelegatingModelProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/gateway/DelegatingModelProvider.java
index deff24d..c055d63 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/gateway/DelegatingModelProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/gateway/DelegatingModelProvider.java
@@ -1,9 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.gateway;
import org.eclipse.basyx.vab.exception.provider.ProviderException;
import org.eclipse.basyx.vab.factory.java.ModelProxyFactory;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-import org.eclipse.basyx.vab.protocol.api.IConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
/**
* IModelProvider that delegates all calls to a Connector to enable gateway
@@ -17,19 +26,19 @@
// Provider that provides the connectors
private ModelProxyFactory proxyFactory;
- public DelegatingModelProvider(IConnectorProvider connectorProvider) {
+ public DelegatingModelProvider(IConnectorFactory connectorFactory) {
super();
- this.proxyFactory = new ModelProxyFactory(connectorProvider);
+ this.proxyFactory = new ModelProxyFactory(connectorFactory);
}
@Override
- public Object getModelPropertyValue(String path) throws ProviderException {
- return getProvider(path).getModelPropertyValue("");
+ public Object getValue(String path) throws ProviderException {
+ return getProvider(path).getValue("");
}
@Override
- public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
- getProvider(path).setModelPropertyValue("", newValue);
+ public void setValue(String path, Object newValue) throws ProviderException {
+ getProvider(path).setValue("", newValue);
}
@Override
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/manager/VABConnectionManager.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/manager/VABConnectionManager.java
index 9781e42..9760e34 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/manager/VABConnectionManager.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/manager/VABConnectionManager.java
@@ -1,9 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.manager;
-import org.eclipse.basyx.vab.directory.api.IVABDirectoryService;
import org.eclipse.basyx.vab.factory.java.ModelProxyFactory;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.api.IConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
+import org.eclipse.basyx.vab.registry.api.IVABRegistryService;
@@ -18,13 +27,13 @@
/**
* Directory service reference
*/
- protected IVABDirectoryService directoryService = null;
+ protected IVABRegistryService directoryService = null;
/**
* Store connection providers
*/
- protected IConnectorProvider connectorProvider = null;
+ protected IConnectorFactory connectorFactory = null;
/**
* Factory for creating proxies for addresses with multiple endpoints
@@ -38,12 +47,12 @@
* @param providerProvider
* used to get the appropriate connector for the selected address
*/
- public VABConnectionManager(IVABDirectoryService networkDirectoryService, IConnectorProvider providerProvider) {
+ public VABConnectionManager(IVABRegistryService networkDirectoryService, IConnectorFactory providerProvider) {
// Set directory service reference
directoryService = networkDirectoryService;
// Set connector reference
- this.connectorProvider = providerProvider;
+ this.connectorFactory = providerProvider;
// Set proxy factory
this.proxyFactory = new ModelProxyFactory(providerProvider);
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/model/VABModelMap.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/model/VABModelMap.java
index c5cb3aa..7acec69 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/model/VABModelMap.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/model/VABModelMap.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.model;
import java.util.Collection;
@@ -5,6 +14,7 @@
import java.util.Map;
import java.util.Set;
+import org.eclipse.basyx.submodel.metamodel.connected.ConnectedElement;
import org.eclipse.basyx.vab.support.TypeDestroyer;
/**
@@ -23,7 +33,7 @@
*/
public class VABModelMap<V extends Object> implements Map<String, V> {
- Map<String, V> map;
+ protected Map<String, V> map;
/**
* Default constructor
@@ -183,6 +193,12 @@
return result;
}
+ /**
+ * VABModelMaps are assumed to be equal iff they are containing the same data
+ * independent of the used containers. <br>
+ * In consequence, it does not matter if a collection is represented as Set or
+ * as List, as long as the same elements are contained.
+ */
@SuppressWarnings("unchecked")
@Override
public boolean equals(Object obj) {
@@ -190,6 +206,9 @@
return true;
if (obj == null)
return false;
+ if (obj instanceof ConnectedElement) {
+ obj = ((ConnectedElement) obj).getElemLive();
+ }
if (!Map.class.isAssignableFrom(obj.getClass()))
return false;
@@ -199,14 +218,15 @@
Map<String, Object> otherMap = TypeDestroyer.destroyType(otherVAB);
if (map == null) {
- if (otherMap != null)
- return false;
+ return otherMap == null;
} else {
Map<String, Object> thisMap = TypeDestroyer.destroyType((Map<String, Object>) map);
- if (!thisMap.equals(otherMap)) {
- return false;
- }
+ return thisMap.equals(otherMap);
}
- return true;
+ }
+
+ @Override
+ public String toString() {
+ return map.toString();
}
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/VABElementProxy.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/VABElementProxy.java
index 8750768..c70f149 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/VABElementProxy.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/VABElementProxy.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.modelprovider;
import org.eclipse.basyx.vab.exception.provider.ProviderException;
@@ -47,10 +56,10 @@
* Read VAB element value
*/
@Override
- public Object getModelPropertyValue(String elementPath) throws ProviderException {
+ public Object getValue(String elementPath) throws ProviderException {
// Get element from server
try {
- return provider.getModelPropertyValue(constructPath(elementPath));
+ return provider.getValue(constructPath(elementPath));
} catch (ProviderException e) {
throw e;
} catch (Exception e) {
@@ -65,11 +74,11 @@
* If the element does not exist it will be created<br />
*/
@Override
- public void setModelPropertyValue(String elementPath, Object newValue) throws ProviderException {
+ public void setValue(String elementPath, Object newValue) throws ProviderException {
// Set property value
try {
// Change element on server
- provider.setModelPropertyValue(constructPath(elementPath), newValue);
+ provider.setValue(constructPath(elementPath), newValue);
} catch (ProviderException e) {
throw e;
} catch (Exception e) {
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/VABPathTools.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/VABPathTools.java
index 720b5b7..6657bba 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/VABPathTools.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/VABPathTools.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.modelprovider;
import java.io.UnsupportedEncodingException;
@@ -6,6 +15,7 @@
import java.util.ArrayList;
import java.util.List;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
/**
@@ -229,10 +239,10 @@
}
/**
- * Check if the path to an VAB elements leads to an operation. In this case, the
- * element path conforms to /aas/submodels/{subModelId}/operations
+ * Check if the path to an VAB elements leads to the invocation of an operation. In this case, the
+ * element path conforms to /aas/submodels/{subModelId}/submodelElements/{operationId}/invoke
*/
- public static boolean isOperationPath(String path) {
+ public static boolean isOperationInvokationPath(String path) {
// null-Paths are no operation paths
if (path == null) {
return false;
@@ -240,16 +250,18 @@
// Split path
String[] pathElements = splitPath(path);
-
- // Look for the 'operation' element inside the path
- for (String s : pathElements) {
- if (s.equals("operations")) {
- return true;
- }
+
+ if(pathElements.length == 0) {
+ return false;
}
- // No operation
- return false;
+ // Check if last path element is "invoke" or "operations" is contained anywhere
+ return pathElements[pathElements.length - 1].startsWith(Operation.INVOKE) || isOperationPath(path);
+ }
+
+ private static boolean isOperationPath(String path) {
+ String lowerCasePath = path.toLowerCase();
+ return lowerCasePath.startsWith("operations/") || path.toLowerCase().contains("/operations/");
}
/**
@@ -361,4 +373,77 @@
throw new MalformedRequestException("Path is not allowed to be null");
}
}
+
+ /**
+ * Strips the last path element if it is "invoke"
+ *
+ * @param path
+ * @return path without last element "invoke" or unchanged path
+ */
+ public static String stripInvokeFromPath(String path) {
+
+ if(path == null)
+ return null;
+
+ if(getLastElement(path).startsWith(Operation.INVOKE)) {
+ return getParentPath(path);
+ }
+
+ return path;
+ }
+
+ /**
+ * Gets the path from a URL
+ * e.g "http://localhost:8080/path/to/test.file" results in "/path/to/test.file"
+ *
+ * @param url
+ * @return the path from the URL
+ */
+ public static String getPathFromURL(String url) {
+ if(url == null) {
+ return null;
+ }
+
+ if(url.contains("://")) {
+
+ // Find the ":" and and remove the "http://" from the url
+ int index = url.indexOf(":") + 3;
+ url = url.substring(index);
+
+ // Find the first "/" from the URL (now without the "http://") and remove everything before that
+ index = url.indexOf("/");
+ url = url.substring(index);
+
+ // Recursive call to deal with more than one server parts
+ // (e.g. basyx://127.0.0.1:6998//https://localhost/test/)
+ return getPathFromURL(url);
+ } else {
+ // Make sure the path has a / at the start
+ if(!url.startsWith("/")) {
+ url = "/" + url;
+ }
+ return url;
+ }
+ }
+
+ /**
+ * Harmonizes a path so that it will always and with the suffix and no ending
+ * slash (even if the suffix contains one).
+ *
+ * @param path
+ * to harmonize
+ * @param suffix
+ * to check for existance and append if necessary
+ * @return harmonized path
+ */
+ public static String harmonizePathWithSuffix(String path, String suffix) {
+ String strippedPath = stripSlashes(path);
+ String strippedSuffix = stripSlashes(suffix);
+
+ if (strippedPath.endsWith("/" + strippedSuffix)) {
+ return strippedPath;
+ } else {
+ return VABPathTools.concatenatePaths(strippedPath, strippedSuffix);
+ }
+ }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/api/IModelProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/api/IModelProvider.java
index 4d98c75..36c89be 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/api/IModelProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/api/IModelProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.modelprovider.api;
import org.eclipse.basyx.vab.exception.provider.ProviderException;
@@ -17,7 +26,7 @@
* Path to the requested value
* @return Object type is assumed to be [Integer | ... | Collection]
*/
- public Object getModelPropertyValue(String path) throws ProviderException;
+ public Object getValue(String path) throws ProviderException;
/**
* Sets or overrides existing value in a given path
@@ -27,7 +36,7 @@
* @param newValue
* Updated value
*/
- public void setModelPropertyValue(String path, Object newValue) throws ProviderException;
+ public void setValue(String path, Object newValue) throws ProviderException;
/**
* Create a new value under the given path
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/consistency/ConsistencyProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/consistency/ConsistencyProvider.java
index 1875d48..04b3a3f 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/consistency/ConsistencyProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/consistency/ConsistencyProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.modelprovider.consistency;
import org.eclipse.basyx.vab.exception.provider.ProviderException;
@@ -50,14 +59,14 @@
}
@Override
- public Object getModelPropertyValue(String path) throws ProviderException {
+ public Object getValue(String path) throws ProviderException {
if (path.endsWith("/frozen")) {
return this.frozen;
} else if (path.endsWith("/clock")) {
return this.clock;
} else {
- return providerBackend.getModelPropertyValue(path);
+ return providerBackend.getValue(path);
}
}
@@ -70,7 +79,7 @@
* @throws Exception
*/
@Override
- public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
+ public void setValue(String path, Object newValue) throws ProviderException {
if (path.endsWith("/frozen")) {
@@ -83,7 +92,7 @@
incrementClock();
// Set the value of the element
- providerBackend.setModelPropertyValue(path, newValue);
+ providerBackend.setValue(path, newValue);
} else {
throw new ProviderException("Value " + path + " is read only");
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/FileSystemProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/FileSystemProvider.java
index bf25e8a..9006681 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/FileSystemProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/FileSystemProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.modelprovider.filesystem;
import java.io.IOException;
@@ -324,7 +333,7 @@
}
@Override
- public synchronized Object getModelPropertyValue(String path) throws ProviderException {
+ public synchronized Object getValue(String path) throws ProviderException {
path = unifyPath(path);
String directory = VABPathTools.getParentPath(path);
String fileName = VABPathTools.getLastElement(path);
@@ -375,7 +384,7 @@
*/
@Override
@SuppressWarnings("unchecked")
- public synchronized void setModelPropertyValue(String path, Object newValue) throws ProviderException {
+ public synchronized void setValue(String path, Object newValue) throws ProviderException {
path = unifyPath(path);
String fileName = VABPathTools.getLastElement(path);
String fullPath = rootDir + "/" + path;
@@ -566,4 +575,4 @@
throw new MalformedRequestException("Invoke not supported by filesystem");
}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/TimeProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/TimeProvider.java
index 2cb1ac9..6f3045d 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/TimeProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/TimeProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.modelprovider.filesystem;
import java.time.LocalDateTime;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/File.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/File.java
index 20792f9..828832d 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/File.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/File.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.modelprovider.filesystem.filesystem;
/**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/FileSystem.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/FileSystem.java
index 880795f..0fe54b1 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/FileSystem.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/FileSystem.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.modelprovider.filesystem.filesystem;
import java.io.IOException;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/FileType.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/FileType.java
index 395b3c0..635ce2b 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/FileType.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/FileType.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.modelprovider.filesystem.filesystem;
/**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/GenericFileSystem.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/GenericFileSystem.java
index 62ad620..772e3c2 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/GenericFileSystem.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/GenericFileSystem.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.modelprovider.filesystem.filesystem;
import java.io.FileWriter;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/generic/IVABElementHandler.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/generic/IVABElementHandler.java
index 34a885d..01a2273 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/generic/IVABElementHandler.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/generic/IVABElementHandler.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.modelprovider.generic;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/generic/VABModelProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/generic/VABModelProvider.java
index 03f1c9e..f1dc60b 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/generic/VABModelProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/generic/VABModelProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.modelprovider.generic;
import java.util.function.Function;
@@ -30,13 +39,13 @@
}
@Override
- public Object getModelPropertyValue(String path) {
+ public Object getValue(String path) {
Object element = getTargetElement(path);
return handler.postprocessObject(element);
}
@Override
- public void setModelPropertyValue(String path, Object newValue) {
+ public void setValue(String path, Object newValue) {
VABPathTools.checkPathForNull(path);
if (VABPathTools.isEmptyPath(path)) {
// Empty path => parent element == null => replace root, if it exists
@@ -99,7 +108,10 @@
@SuppressWarnings("unchecked")
@Override
public Object invokeOperation(String path, Object... parameters) {
- Object childElement = getModelPropertyValue(path);
+
+ path = VABPathTools.stripInvokeFromPath(path);
+
+ Object childElement = getValue(path);
// Invoke operation for function interfaces
if (childElement instanceof Function<?, ?>) {
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaHandler.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaHandler.java
index 27cc661..815783a 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaHandler.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaHandler.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.modelprovider.lambda;
import java.util.ArrayList;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaProvider.java
index a5b3649..0e67bc8 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.modelprovider.lambda;
import java.util.Map;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaProviderHelper.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaProviderHelper.java
index 74e75ce..b2a95b9 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaProviderHelper.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaProviderHelper.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.modelprovider.lambda;
import java.util.HashMap;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/map/VABMapHandler.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/map/VABMapHandler.java
index f46ffc0..1da707c 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/map/VABMapHandler.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/map/VABMapHandler.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.modelprovider.map;
import java.util.Collection;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/map/VABMapProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/map/VABMapProvider.java
index 3922309..1a90239 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/map/VABMapProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/map/VABMapProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.modelprovider.map;
import java.util.Map;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/ConnectorFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/ConnectorFactory.java
new file mode 100644
index 0000000..11b7db5
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/ConnectorFactory.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab.protocol.api;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+
+/**
+ * ConnectorProvider that caches connectors for addresses to save resources
+ *
+ * @author schnicke
+ *
+ */
+public abstract class ConnectorFactory implements IConnectorFactory {
+
+ private Map<String, IModelProvider> providerMap = new HashMap<>();
+
+ @Override
+ public IModelProvider getConnector(String addr) {
+ if (!providerMap.containsKey(addr)) {
+ providerMap.put(addr, createProvider(addr));
+ }
+ return providerMap.get(addr);
+ }
+
+ /**
+ * Creates a new provider for the given address
+ *
+ * @param addr
+ * @return
+ */
+ protected abstract IModelProvider createProvider(String addr);
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/ConnectorProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/ConnectorProvider.java
deleted file mode 100644
index 769e788..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/ConnectorProvider.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.eclipse.basyx.vab.protocol.api;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-
-/**
- * ConnectorProvider that caches connectors for addresses to save resources
- *
- * @author schnicke
- *
- */
-public abstract class ConnectorProvider implements IConnectorProvider {
-
- private Map<String, IModelProvider> providerMap = new HashMap<>();
-
- @Override
- public IModelProvider getConnector(String addr) {
- if (!providerMap.containsKey(addr)) {
- providerMap.put(addr, createProvider(addr));
- }
- return providerMap.get(addr);
- }
-
- /**
- * Creates a new provider for the given address
- *
- * @param addr
- * @return
- */
- protected abstract IModelProvider createProvider(String addr);
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/IBaSyxConnector.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/IBaSyxConnector.java
index 1d1f9fb..f4582bf 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/IBaSyxConnector.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/IBaSyxConnector.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.protocol.api;
import org.eclipse.basyx.vab.exception.provider.ProviderException;
@@ -19,7 +28,7 @@
* @return Property value. Object type is assumed to be [Integer | ... |
* Collection]
*/
- public String getModelPropertyValue(String path) throws ProviderException;
+ public String getValue(String path) throws ProviderException;
/**
* Sets or overrides existing property, operation or event.
@@ -29,7 +38,7 @@
* @param newValue
* Updated value
*/
- public String setModelPropertyValue(String path, String newValue) throws ProviderException;
+ public String setValue(String path, String newValue) throws ProviderException;
/**
* Create a new property, operation, event submodel or aas under the given path
@@ -67,4 +76,11 @@
* @return Return value
*/
public String invokeOperation(String path, String jsonObject) throws ProviderException;
+
+ /**
+ * Get string representation of endpoint for given path for debugging.
+ * @param path Requested path
+ * @return String representing requested endpoint
+ */
+ public String getEndpointRepresentation(String path);
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/IConnectorFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/IConnectorFactory.java
new file mode 100644
index 0000000..b0065e8
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/IConnectorFactory.java
@@ -0,0 +1,29 @@
+/**
+ *
+ */
+package org.eclipse.basyx.vab.protocol.api;
+
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+
+/**
+ * Base interface for factories that return IModelProviders that connects to
+ * specific addresses
+ *
+ * @author schnicke
+ *
+ */
+public interface IConnectorFactory {
+
+ /**
+ * Gets an IModelProvider connecting the specific address.
+ *
+ * @param addr
+ * The address for which a provider is returned. Must be an address limited to one included endpoint.
+ * For example, it does NOT support basyx://localhost:6998//http://localhost/a/b/c, but http://localhost/a/b/c
+ * @return
+ * A provider that directly points to the element referenced by the given address.
+ * E.g. the returned model provider for http://localhost/a/b/c directly points to the element c. Therefore,
+ * getConnector("http://localhost/a/b/c").getModelPropertyValue(""); returns the value of the element c.
+ */
+ public IModelProvider getConnector(String addr);
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/IConnectorProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/IConnectorProvider.java
deleted file mode 100644
index 9d1f49d..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/IConnectorProvider.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- *
- */
-package org.eclipse.basyx.vab.protocol.api;
-
-import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-
-/**
- * Base interface for providers that return IModelProviders that connects to
- * specific addresses
- *
- * @author schnicke
- *
- */
-public interface IConnectorProvider {
-
- /**
- * Gets an IModelProvider connecting the specific address.
- *
- * @param addr
- * The address for which a provider is returned. Must be an address limited to one included endpoint.
- * For example, it does NOT support basyx://localhost:6998//http://localhost/a/b/c, but http://localhost/a/b/c
- * @return
- * A provider that directly points to the element referenced by the given address.
- * E.g. the returned model provider for http://localhost/a/b/c directly points to the element c. Therefore,
- * getConnector("http://localhost/a/b/c").getModelPropertyValue(""); returns the value of the element c.
- */
- public IModelProvider getConnector(String addr);
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/CoderTools.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/CoderTools.java
index 92f676d..100c304 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/CoderTools.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/CoderTools.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.protocol.basyx;
import java.nio.charset.StandardCharsets;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/connector/BaSyxConnector.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/connector/BaSyxConnector.java
index bb0f851..0d0dbc7 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/connector/BaSyxConnector.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/connector/BaSyxConnector.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.protocol.basyx.connector;
import java.io.IOException;
@@ -143,7 +152,7 @@
* Invoke a BaSys get operation via HTTP
*/
@Override
- public String getModelPropertyValue(String servicePath) {
+ public String getValue(String servicePath) {
byte[] call = createCall(servicePath, VABBaSyxTCPInterface.BASYX_GET);
@@ -160,7 +169,7 @@
* that carries the Exceptions thrown on the server
*/
@Override
- public String setModelPropertyValue(String servicePath, String newValue) {
+ public String setValue(String servicePath, String newValue) {
byte[] call = createCall(servicePath, newValue, VABBaSyxTCPInterface.BASYX_SET);
@@ -278,4 +287,14 @@
return call;
}
+
+ /**
+ * Get string representation of endpoint for given path for debugging.
+ * @param path Requested path
+ * @return String representing requested endpoint
+ */
+ @Override
+ public String getEndpointRepresentation(String path) {
+ return "basyx://" + serverSocketAddress.getHostString() + ":" + serverSocketAddress.getPort() + "/" + path;
+ }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/connector/BaSyxConnectorFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/connector/BaSyxConnectorFactory.java
new file mode 100644
index 0000000..0b9846c
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/connector/BaSyxConnectorFactory.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab.protocol.basyx.connector;
+
+import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.protocol.api.ConnectorFactory;
+
+
+/**
+ * A connector provider for TCP/BaSyx protocol
+ *
+ * @author schnicke, kuhn
+ *
+ */
+public class BaSyxConnectorFactory extends ConnectorFactory {
+
+
+ /**
+ * Create the provider
+ */
+ @Override
+ protected IModelProvider createProvider(String address) {
+ // Create address
+ address = VABPathTools.getFirstEndpoint(address);
+ address = address.replaceFirst("basyx://", "");
+ String hostName = address.substring(0, address.indexOf(':'));
+ String[] splitted = address.split("/");
+ int hostPort = Integer.parseInt(splitted[0].substring(address.indexOf(':') + 1));
+
+ // Create connector, connect
+ IModelProvider provider = new JSONConnector(new BaSyxConnector(hostName, hostPort));
+
+ // Create a proxy, if necessary
+ String path = address.replaceFirst(hostName + ":" + hostPort, "");
+ if (!path.isEmpty() && !path.equals("/")) {
+ provider = new VABElementProxy(path, provider);
+ }
+
+ return provider;
+ }
+
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/connector/BaSyxConnectorProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/connector/BaSyxConnectorProvider.java
deleted file mode 100644
index 81476ad..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/connector/BaSyxConnectorProvider.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package org.eclipse.basyx.vab.protocol.basyx.connector;
-
-import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.modelprovider.VABPathTools;
-import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-import org.eclipse.basyx.vab.protocol.api.ConnectorProvider;
-
-
-/**
- * A connector provider for TCP/BaSyx protocol
- *
- * @author schnicke, kuhn
- *
- */
-public class BaSyxConnectorProvider extends ConnectorProvider {
-
-
- /**
- * Create the provider
- */
- @Override
- protected IModelProvider createProvider(String address) {
- // Create address
- address = VABPathTools.getFirstEndpoint(address);
- address = address.replace("basyx://", "");
- String hostName = address.substring(0, address.indexOf(':'));
- String[] splitted = address.split("/");
- int hostPort = Integer.parseInt(splitted[0].substring(address.indexOf(':') + 1));
-
- // Create connector, connect
- IModelProvider provider = new JSONConnector(new BaSyxConnector(hostName, hostPort));
-
- // Create a proxy, if necessary
- String path = address.replace(hostName + ":" + hostPort, "");
- if (!path.isEmpty() && !path.equals("/")) {
- provider = new VABElementProxy(path, provider);
- }
-
- return provider;
- }
-
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/server/BaSyxTCPServer.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/server/BaSyxTCPServer.java
index 2ee4d10..4af9d10 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/server/BaSyxTCPServer.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/server/BaSyxTCPServer.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.protocol.basyx.server;
import java.io.IOException;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/server/VABBaSyxTCPInterface.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/server/VABBaSyxTCPInterface.java
index a33e8da..b67c0b0 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/server/VABBaSyxTCPInterface.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/server/VABBaSyxTCPInterface.java
@@ -1,8 +1,16 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.protocol.basyx.server;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.io.PrintWriter;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SocketChannel;
@@ -81,8 +89,7 @@
*/
public void processInputFrame(byte[] rxFrame) throws IOException {
// Create output streams
- ByteArrayOutputStream byteArrayOutput = new ByteArrayOutputStream();
- PrintWriter output = new PrintWriter(byteArrayOutput);
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
// Get command
switch (rxFrame[0]) {
@@ -107,7 +114,7 @@
// Send response frame
output.flush();
- sendResponseFrame(byteArrayOutput);
+ sendResponseFrame(output);
break;
}
@@ -133,7 +140,7 @@
// Send response frame
output.flush();
- sendResponseFrame(byteArrayOutput);
+ sendResponseFrame(output);
break;
}
@@ -159,7 +166,7 @@
// Send response frame
output.flush();
- sendResponseFrame(byteArrayOutput);
+ sendResponseFrame(output);
break;
}
@@ -194,7 +201,7 @@
// Send response frame
output.flush();
- sendResponseFrame(byteArrayOutput);
+ sendResponseFrame(output);
break;
}
@@ -219,7 +226,7 @@
// Send response frame
output.flush();
- sendResponseFrame(byteArrayOutput);
+ sendResponseFrame(output);
break;
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/HTTPConnector.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/HTTPConnector.java
index 87cf852..83f39cf 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/HTTPConnector.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/HTTPConnector.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.protocol.http.connector;
import javax.ws.rs.client.Client;
@@ -7,14 +16,18 @@
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
import org.eclipse.basyx.vab.exception.provider.ProviderException;
import org.eclipse.basyx.vab.modelprovider.VABPathTools;
import org.eclipse.basyx.vab.protocol.api.IBaSyxConnector;
+import org.eclipse.basyx.vab.protocol.http.server.ExceptionToHTTPCodeMapper;
import org.glassfish.jersey.client.HttpUrlConnectorProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import io.netty.handler.codec.http.HttpMethod;
+
/**
* HTTP connector class
*
@@ -27,7 +40,7 @@
private String address;
private String mediaType;
- private Client client;
+ protected Client client;
/**
* Invoke a BaSys get operation via HTTP GET
@@ -39,12 +52,12 @@
* @return the requested object
*/
@Override
- public String getModelPropertyValue(String servicePath) {
+ public String getValue(String servicePath) {
return httpGet(servicePath);
}
public HTTPConnector(String address) {
- this(address, MediaType.APPLICATION_JSON);
+ this(address, MediaType.APPLICATION_JSON + ";charset=UTF-8");
}
public HTTPConnector(String address, String mediaType) {
@@ -69,7 +82,7 @@
* should be an IElement of type Property, Operation or Event
*/
@Override
- public String setModelPropertyValue(String servicePath, String newValue) throws ProviderException {
+ public String setValue(String servicePath, String newValue) throws ProviderException {
return httpPut(servicePath, newValue);
}
@@ -125,7 +138,6 @@
// Build request, set JSON encoding
Builder request = resource.request();
request.accept(mediaType);
-
// Return JSON request
return request;
}
@@ -159,7 +171,14 @@
Builder request = retrieveBuilder(servicePath);
// Perform request
- Response rsp = request.get();
+ Response rsp = null;
+ try {
+ rsp = request.get();
+ } finally {
+ if (!isRequestSuccess(rsp)) {
+ throw this.handleProcessingException(HttpMethod.GET, getStatusCode(rsp));
+ }
+ }
// Return response message (header)
return rsp.readEntity(String.class);
@@ -171,7 +190,14 @@
Builder request = retrieveBuilder(servicePath);
// Perform request
- Response rsp = request.put(Entity.entity(newValue, mediaType));
+ Response rsp = null;
+ try {
+ rsp = request.put(Entity.entity(newValue, mediaType));
+ } finally {
+ if (!isRequestSuccess(rsp)) {
+ throw this.handleProcessingException(HttpMethod.PUT, getStatusCode(rsp));
+ }
+ }
// Return response message (header)
return rsp.readEntity(String.class);
@@ -181,11 +207,15 @@
private String httpPatch(String servicePath, String newValue) throws ProviderException {
logger.trace("[HTTP Patch] {} {}", VABPathTools.concatenatePaths(address, servicePath), newValue);
- // Invoke service call via web services
- Client client = ClientBuilder.newClient();
-
// Create and invoke HTTP PATCH request
- Response rsp = client.target(VABPathTools.concatenatePaths(address, servicePath)).request().build("PATCH", Entity.text(newValue)).property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true).invoke();
+ Response rsp = null;
+ try {
+ rsp = this.client.target(VABPathTools.concatenatePaths(address, servicePath)).request().build("PATCH", Entity.text(newValue)).property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true).invoke();
+ } finally {
+ if (!isRequestSuccess(rsp)) {
+ throw this.handleProcessingException(HttpMethod.PATCH, getStatusCode(rsp));
+ }
+ }
// Return response message (header)
return rsp.readEntity(String.class);
@@ -197,7 +227,14 @@
Builder request = retrieveBuilder(servicePath);
// Perform request
- Response rsp = request.post(Entity.entity(parameter, mediaType));
+ Response rsp = null;
+ try {
+ rsp = request.post(Entity.entity(parameter, mediaType));
+ } finally {
+ if (!isRequestSuccess(rsp)) {
+ throw this.handleProcessingException(HttpMethod.POST, getStatusCode(rsp));
+ }
+ }
// Return response message (header)
return rsp.readEntity(String.class);
@@ -209,7 +246,14 @@
Builder request = retrieveBuilder(servicePath);
// Perform request
- Response rsp = request.delete();
+ Response rsp = null;
+ try {
+ rsp = request.delete();
+ } finally {
+ if (!isRequestSuccess(rsp)) {
+ throw this.handleProcessingException(HttpMethod.DELETE, getStatusCode(rsp));
+ }
+ }
// Return response message (header)
return rsp.readEntity(String.class);
@@ -231,4 +275,35 @@
return buildRequest(client, VABPathTools.concatenatePaths(address, servicePath));
}
+ private ProviderException handleProcessingException(HttpMethod method, int statusCode) {
+ return ExceptionToHTTPCodeMapper.mapToException(statusCode, "[HTTP " + method.name() + "] Failed to request " + this.address + " with mediatype " + this.mediaType);
+ }
+
+ /**
+ * Get status code from HTTP Response
+ * @param rsp
+ * @return
+ */
+ private int getStatusCode(Response rsp) {
+ return rsp != null ? rsp.getStatus() : 0;
+ }
+
+ /**
+ * Returns true if the response is succeeded
+ * @param rsp
+ * @return
+ */
+ private boolean isRequestSuccess(Response rsp) {
+ return rsp != null && rsp.getStatusInfo().getFamily() == Status.Family.SUCCESSFUL;
+ }
+
+ /**
+ * Get string representation of endpoint for given path for debugging.
+ * @param path Requested path
+ * @return String representing requested endpoint
+ */
+ @Override
+ public String getEndpointRepresentation(String path) {
+ return VABPathTools.concatenatePaths(address, path);
+ }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/HTTPConnectorFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/HTTPConnectorFactory.java
new file mode 100644
index 0000000..38971ee
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/HTTPConnectorFactory.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab.protocol.http.connector;
+
+import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.protocol.api.ConnectorFactory;
+
+public class HTTPConnectorFactory extends ConnectorFactory {
+
+ /**
+ * returns HTTPConnetor wrapped with ConnectedHashmapProvider that handles
+ * message header information
+ */
+ @Override
+ protected IModelProvider createProvider(String addr) {
+
+ return new JSONConnector(new HTTPConnector(addr));
+ }
+
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/HTTPConnectorProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/HTTPConnectorProvider.java
deleted file mode 100644
index fb86647..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/HTTPConnectorProvider.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.eclipse.basyx.vab.protocol.http.connector;
-
-import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
-import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-import org.eclipse.basyx.vab.protocol.api.ConnectorProvider;
-
-public class HTTPConnectorProvider extends ConnectorProvider {
-
- /**
- * returns HTTPConnetor wrapped with ConnectedHashmapProvider that handles
- * message header information
- */
- @Override
- protected IModelProvider createProvider(String addr) {
-
- return new JSONConnector(new HTTPConnector(addr));
- }
-
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/AASHTTPServer.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/AASHTTPServer.java
deleted file mode 100644
index 712de52..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/AASHTTPServer.java
+++ /dev/null
@@ -1,130 +0,0 @@
-package org.eclipse.basyx.vab.protocol.http.server;
-
-import java.io.File;
-import java.util.Iterator;
-import java.util.Map.Entry;
-
-import javax.servlet.http.HttpServlet;
-
-import org.apache.catalina.Context;
-import org.apache.catalina.LifecycleEvent;
-import org.apache.catalina.LifecycleException;
-import org.apache.catalina.LifecycleListener;
-import org.apache.catalina.LifecycleState;
-import org.apache.catalina.startup.Tomcat;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Starter Class for Apache Tomcat 8.0.53 HTTP server that adds the provided servlets and respective mappings on startup.
- *
- * @author pschorn, espen
- *
- */
-public class AASHTTPServer {
-
- private static Logger logger = LoggerFactory.getLogger(AASHTTPServer.class);
-
- private Tomcat tomcat;
-
- static {
- // Enable coding of forward slash in tomcat
- System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
- }
-
- /**
- * Constructor
- *
- * Create new Tomcat instance and add the provided servlet mappings
- *
- * @param context
- * Basyx context with of url mappings to HTTPServlet
- */
- public AASHTTPServer(BaSyxContext context) {
- // Instantiate and setup Tomcat server
- tomcat = new Tomcat();
- tomcat.setPort(context.port);
- tomcat.setHostname(context.hostname);
- tomcat.getHost().setAppBase(".");
-
- // Create servlet context
- // - Base path for resource files
- File docBase = new File(context.docBasePath); // System.getProperty("java.io.tmpdir"));
- // - Create context for servlets
- Context rootCtx = tomcat.addContext(context.contextPath, docBase.getAbsolutePath());
-
- // Iterate all servlets in context
- Iterator<Entry<String, HttpServlet>> it = context.entrySet().iterator();
- while (it.hasNext()) {
- // Servlet entry
- Entry<String, HttpServlet> entry = it.next();
-
- // Servlet mapping
- String mapping = entry.getKey();
- HttpServlet servlet = entry.getValue();
-
- // Add new Servlet and Mapping to tomcat environment
- Tomcat.addServlet(rootCtx, Integer.toString(servlet.hashCode()), servlet);
- rootCtx.addServletMappingDecoded(mapping, Integer.toString(servlet.hashCode()));
- }
- }
-
- /**
- * Starts the server in a new thread to avoid blocking the main thread
- */
- public void start() {
- logger.trace("Starting Tomcat.....");
-
- Thread serverThread = new Thread(() -> {
- try {
- tomcat.stop();
-
- // Adds listener that notifies the tomcat object when the server has started
- tomcat.getServer().addLifecycleListener(new LifecycleListener() {
- @Override
- public void lifecycleEvent(LifecycleEvent event) {
- if (event.getLifecycle().getState() == LifecycleState.STARTED) {
- synchronized (tomcat) {
- tomcat.notifyAll();
- }
- }
- }
- });
-
- tomcat.start();
-
- // Keeps the server thread alive until the server is shut down
- tomcat.getServer().await();
- } catch (LifecycleException e) {
- logger.error("Exception in start", e);
- }
- });
- serverThread.start();
-
- synchronized (tomcat) {
- try {
- tomcat.wait();
- } catch (InterruptedException e) {
- logger.error("Exception in start", e);
- }
- }
- }
-
- /**
- * This Method stops and destroys the tomcat instance. This is important since Tomcat would be already
- * bound to port 8080 when new tests are run that require a start of tomcat
- */
- public void shutdown() {
- logger.trace("Shutting down BaSyx HTTP Server...");
-
- try {
- tomcat.stop();
- tomcat.destroy();
- } catch (LifecycleException e) {
- // TODO Auto-generated catch block
- logger.error("Exception in shutdown", e);
- }
- }
-
-
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxContext.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxContext.java
index 387f3ce..9b77690 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxContext.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxContext.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.protocol.http.server;
import java.util.HashMap;
@@ -10,7 +19,7 @@
/**
* BaSyx context that contains an Industrie 4.0 Servlet infrastructure
*
- * @author kuhn
+ * @author kuhn, haque
*
*/
public class BaSyxContext extends HashMap<String, HttpServlet> {
@@ -43,6 +52,20 @@
*/
protected int port;
+ /**
+ * Indicates whether the connection is secures or not
+ */
+ private boolean isSecuredConnection;
+
+ /**
+ * Password of the SSL key
+ */
+ private String keyPassword;
+
+ /**
+ * Path to the certificate
+ */
+ private String certificatePath;
/**
* Servlet parameter
@@ -62,7 +85,11 @@
/**
- * Constructor
+ * Initiates a BasyxContext
+ * @param reqContextPath context path
+ * @param reqDocBasePath base path of doc
+ * @param hostn host name
+ * @param reqPort connection port
*/
public BaSyxContext(String reqContextPath, String reqDocBasePath, String hostn, int reqPort) {
// Store context path and doc base path
@@ -70,8 +97,26 @@
docBasePath = reqDocBasePath;
hostname = hostn;
port = reqPort;
+ isSecuredConnection = false;
}
+ /**
+ * Initiates a BasyxContext. this constructor can indicate whether
+ * the connection is secured or not
+ * @param reqContextPath context path
+ * @param reqDocBasePath base path of doc
+ * @param hostn host name
+ * @param reqPort connection port
+ * @param isSecuredCon boolean value indicating the connection is secured or not
+ * @param keyPass password of the SSL key
+ * @param keyPath path to the SSL certificate
+ */
+ public BaSyxContext(String reqContextPath, String reqDocBasePath, String hostn, int reqPort, boolean isSecuredCon, String keyPath, String keyPass) {
+ this(reqContextPath, reqDocBasePath, hostn, reqPort);
+ this.isSecuredConnection = isSecuredCon;
+ this.certificatePath = keyPath;
+ this.keyPassword = keyPass;
+ }
/**
@@ -131,5 +176,48 @@
public int getPort() {
return port;
}
+
+ /**
+ * Returns whether the secured connection enabled or not
+ * @return
+ */
+ public boolean isSecuredConnectionEnabled() {
+ return this.isSecuredConnection;
+ }
+
+ /**
+ * Returns password of the SSL key
+ * @return
+ */
+ public String getKeyPassword() {
+ return keyPassword;
+ }
+
+
+ /**
+ * Sets password of the SSL key
+ * @param keyPassword
+ */
+ public void setKeyPassword(String keyPassword) {
+ this.keyPassword = keyPassword;
+ }
+
+
+ /**
+ * Returns Path to the certificate
+ * @return
+ */
+ public String getCertificatePath() {
+ return certificatePath;
+ }
+
+
+ /**
+ * Sets Certificate Path
+ * @param certificatePath
+ */
+ public void setCertificatePath(String certificatePath) {
+ this.certificatePath = certificatePath;
+ }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxHTTPServer.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxHTTPServer.java
new file mode 100644
index 0000000..a5eb5cc
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxHTTPServer.java
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab.protocol.http.server;
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.Map.Entry;
+import java.util.UUID;
+
+import javax.servlet.http.HttpServlet;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.LifecycleEvent;
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.LifecycleListener;
+import org.apache.catalina.LifecycleState;
+import org.apache.catalina.connector.Connector;
+import org.apache.catalina.startup.Tomcat;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Starter Class for Apache Tomcat 8.0.53 HTTP server that adds the provided servlets and respective mappings on startup.
+ *
+ * @author pschorn, espen, haque
+ *
+ */
+public class BaSyxHTTPServer {
+
+ private static Logger logger = LoggerFactory.getLogger(BaSyxHTTPServer.class);
+
+ private Tomcat tomcat;
+
+ static {
+ // Enable coding of forward slash in tomcat
+ System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
+ }
+
+ /**
+ * Constructor
+ *
+ * Create new Tomcat instance and add the provided servlet mappings
+ *
+ * @param context
+ * Basyx context with of url mappings to HTTPServlet
+ */
+
+ public BaSyxHTTPServer(BaSyxContext context) {
+ // Instantiate and setup Tomcat server
+ tomcat = new Tomcat();
+
+ // Set random name to prevent lifecycle expections during shutdown of multiple
+ // instances
+ tomcat.getEngine().setName(UUID.randomUUID().toString());
+
+ if (context.isSecuredConnectionEnabled()) {
+ Connector httpsConnector = tomcat.getConnector();
+ configureSslConnector(context, httpsConnector);
+ } else {
+ tomcat.setPort(context.port);
+ }
+
+ tomcat.setHostname(context.hostname);
+ tomcat.getHost().setAppBase(".");
+
+ // Create servlet context
+ // - Base path for resource files
+ File docBase = new File(context.docBasePath); // System.getProperty("java.io.tmpdir"));
+ // - Create context for servlets
+ Context rootCtx = tomcat.addContext(context.contextPath, docBase.getAbsolutePath());
+
+ // Iterate all servlets in context
+ Iterator<Entry<String, HttpServlet>> it = context.entrySet().iterator();
+ while (it.hasNext()) {
+ // Servlet entry
+ Entry<String, HttpServlet> entry = it.next();
+
+ // Servlet mapping
+ String mapping = entry.getKey();
+ HttpServlet servlet = entry.getValue();
+
+ // Add new Servlet and Mapping to tomcat environment
+ Tomcat.addServlet(rootCtx, Integer.toString(servlet.hashCode()), servlet);
+ rootCtx.addServletMappingDecoded(mapping, Integer.toString(servlet.hashCode()));
+ }
+ }
+
+ /**
+ * SSL Configuration for SSL connector
+ * @param context
+ * @param httpsConnector
+ */
+ private void configureSslConnector(BaSyxContext context, Connector httpsConnector) {
+ httpsConnector.setPort(context.port);
+ httpsConnector.setSecure(true);
+ httpsConnector.setScheme("https");
+ httpsConnector.setAttribute("keystoreFile", context.getCertificatePath());
+ httpsConnector.setAttribute("clientAuth", "false");
+ httpsConnector.setAttribute("sslProtocol", "TLS");
+ httpsConnector.setAttribute("SSLEnabled", true);
+ httpsConnector.setAttribute("protocol", "HTTP/1.1");
+ httpsConnector.setAttribute("keystorePass", context.getKeyPassword());
+
+ httpsConnector.setAttribute("keyAlias", "tomcat");
+
+ httpsConnector.setAttribute("maxThreads", "200");
+ httpsConnector.setAttribute("protocol", "org.apache.coyote.http11.Http11AprProtocol");
+ }
+
+ /**
+ * Starts the server in a new thread to avoid blocking the main thread
+ */
+ public void start() {
+ logger.trace("Starting Tomcat.....");
+
+ Thread serverThread = new Thread(() -> {
+ try {
+ tomcat.stop();
+
+ // Adds listener that notifies the tomcat object when the server has started
+ tomcat.getServer().addLifecycleListener(new LifecycleListener() {
+ @Override
+ public void lifecycleEvent(LifecycleEvent event) {
+ if (event.getLifecycle().getState() == LifecycleState.STARTED) {
+ synchronized (tomcat) {
+ tomcat.notifyAll();
+ }
+ }
+ }
+ });
+
+ tomcat.start();
+
+ // Keeps the server thread alive until the server is shut down
+ tomcat.getServer().await();
+ } catch (LifecycleException e) {
+ logger.error("Exception in start", e);
+ }
+ });
+ serverThread.start();
+
+ synchronized (tomcat) {
+ try {
+ tomcat.wait();
+ } catch (InterruptedException e) {
+ logger.error("Exception in start", e);
+ }
+ }
+ }
+
+ /**
+ * This Method stops and destroys the tomcat instance. This is important since Tomcat would be already
+ * bound to port 8080 when new tests are run that require a start of tomcat
+ */
+ public void shutdown() {
+ logger.trace("Shutting down BaSyx HTTP Server...");
+
+ try {
+ tomcat.stop();
+ tomcat.destroy();
+ } catch (LifecycleException e) {
+ // TODO Auto-generated catch block
+ logger.error("Exception in shutdown", e);
+ }
+ }
+
+
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BasysHTTPServlet.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BasysHTTPServlet.java
index 92d3a90..be0af71 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BasysHTTPServlet.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BasysHTTPServlet.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.protocol.http.server;
import java.io.IOException;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/ExceptionToHTTPCodeMapper.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/ExceptionToHTTPCodeMapper.java
index 4f58027..bcc23ea 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/ExceptionToHTTPCodeMapper.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/ExceptionToHTTPCodeMapper.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.protocol.http.server;
import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/VABHTTPInterface.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/VABHTTPInterface.java
index 692305b..00900ae 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/VABHTTPInterface.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/VABHTTPInterface.java
@@ -1,6 +1,16 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.protocol.http.server;
import java.io.IOException;
+import java.io.InputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
@@ -9,7 +19,6 @@
import java.util.StringJoiner;
import javax.servlet.ServletException;
-import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -21,6 +30,9 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Charsets;
+import com.google.common.io.ByteSource;
+
/**
* VAB provider class that enables access to an IModelProvider via HTTP REST
@@ -91,8 +103,6 @@
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- PrintWriter responseWriter = resp.getWriter();
-
try {
String path = extractPath(req);
@@ -103,12 +113,10 @@
resp.setStatus(200);
// Process get request
- providerBackend.processBaSysGet(path, responseWriter);
- responseWriter.flush();
+ providerBackend.processBaSysGet(path, resp.getOutputStream());
} catch(ProviderException e) {
int httpCode = ExceptionToHTTPCodeMapper.mapFromException(e);
resp.setStatus(httpCode);
- responseWriter.flush();
logger.debug("Exception in HTTP-GET. Response-code: " + httpCode, e);
}
@@ -120,21 +128,19 @@
*/
@Override
protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- PrintWriter responseWriter = resp.getWriter();
-
try {
String path = extractPath(req);
String serValue = extractSerializedValue(req);
logger.trace("DoPut: {}", serValue);
+ resp.setContentType("application/json");
+ resp.setCharacterEncoding("UTF-8");
resp.setStatus(200);
- providerBackend.processBaSysSet(path, serValue.toString(), responseWriter);
- responseWriter.flush();
+ providerBackend.processBaSysSet(path, serValue.toString(), resp.getOutputStream());
} catch(ProviderException e) {
int httpCode = ExceptionToHTTPCodeMapper.mapFromException(e);
resp.setStatus(httpCode);
- responseWriter.flush();
logger.debug("Exception in HTTP-PUT. Response-code: " + httpCode, e);
}
}
@@ -147,8 +153,6 @@
*/
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- PrintWriter responseWriter = resp.getWriter();
-
try {
String path = extractPath(req);
String serValue = extractSerializedValue(req);
@@ -161,21 +165,18 @@
resp.setCharacterEncoding("UTF-8");
// Check if request is for property creation or operation invoke
- if (VABPathTools.isOperationPath(path)) {
+ if (VABPathTools.isOperationInvokationPath(path)) {
// Invoke BaSys VAB 'invoke' primitive
- providerBackend.processBaSysInvoke(path, serValue, responseWriter);
- responseWriter.flush();
+ providerBackend.processBaSysInvoke(path, serValue, resp.getOutputStream());
} else {
// Invoke the BaSys 'create' primitive
- providerBackend.processBaSysCreate(path, serValue, responseWriter);
- responseWriter.flush();
+ providerBackend.processBaSysCreate(path, serValue, resp.getOutputStream());
}
} catch (ProviderException e) {
int httpCode = ExceptionToHTTPCodeMapper.mapFromException(e);
resp.setStatus(httpCode);
- responseWriter.flush();
logger.debug("Exception in HTTP-POST. Response-code: " + httpCode, e);
}
}
@@ -187,7 +188,6 @@
*/
@Override
protected void doPatch(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- PrintWriter responseWriter = resp.getWriter();
try {
String path = extractPath(req);
String serValue = extractSerializedValue(req);
@@ -195,12 +195,10 @@
resp.setStatus(200);
- providerBackend.processBaSysDelete(path, serValue, responseWriter);
- responseWriter.flush();
+ providerBackend.processBaSysDelete(path, serValue, resp.getOutputStream());
} catch(ProviderException e) {
int httpCode = ExceptionToHTTPCodeMapper.mapFromException(e);
resp.setStatus(httpCode);
- responseWriter.flush();
logger.debug("Exception in HTTP-PATCH. Response-code: " + httpCode, e);
}
}
@@ -211,8 +209,6 @@
*/
@Override
protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- PrintWriter responseWriter = resp.getWriter();
-
try {
String path = extractPath(req);
@@ -222,12 +218,10 @@
resp.setStatus(200);
- providerBackend.processBaSysDelete(path, nullParam, responseWriter);
- responseWriter.flush();
+ providerBackend.processBaSysDelete(path, nullParam, resp.getOutputStream());
} catch(ProviderException e) {
int httpCode = ExceptionToHTTPCodeMapper.mapFromException(e);
resp.setStatus(httpCode);
- responseWriter.flush();
logger.debug("Exception in HTTP-DELETE. Response-code: " + httpCode, e);
}
}
@@ -305,14 +299,14 @@
* @throws IOException
*/
private String extractSerializedValue(HttpServletRequest req) throws IOException {
- // Read request body
- ServletInputStream is = req.getInputStream();
- StringBuilder serValue = new StringBuilder();
-
- // This seems kind of slow...
- while (!is.isFinished()) {
- serValue.append(String.valueOf((char) (byte) is.read()));
- }
- return serValue.toString();
+ // https://www.baeldung.com/convert-input-stream-to-string#guava
+ ByteSource byteSource = new ByteSource() {
+ @Override
+ public InputStream openStream() throws IOException {
+ return req.getInputStream();
+ }
+ };
+
+ return byteSource.asCharSource(Charsets.UTF_8).read();
}
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/OpcUaConnector.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/OpcUaConnector.java
index 9ce47d3..c315e3f 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/OpcUaConnector.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/OpcUaConnector.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.protocol.opcua.connector;
import java.util.ArrayList;
@@ -45,24 +54,25 @@
* @throws Exception
*/
@Override
- public String getModelPropertyValue(String servicePath) {
+ public String getValue(String servicePath) {
try {
clientRunner = new BaSyxOpcUaClientRunner(address);
clientRunner.run();
} catch (Exception e) {
logger.error("Exception in getModelPropertyValue", e);
+ throw new RuntimeException(e);
}
return opcUaRead(translateBrowsePathToNodeId(servicePath)[1]);
}
@Override
- public void setModelPropertyValue(String servicePath, Object newValue) throws ProviderException {
+ public void setValue(String servicePath, Object newValue) throws ProviderException {
try {
clientRunner = new BaSyxOpcUaClientRunner(address);
clientRunner.run();
} catch (Exception e) {
- // TODO Auto-generated catch block
logger.error("Exception in setModelPropertyValue", e);
+ throw new RuntimeException(e);
}
opcUaWrite(translateBrowsePathToNodeId(servicePath)[1], newValue);
}
@@ -89,6 +99,7 @@
clientRunner.run();
} catch (Exception e) {
logger.error("Exception in invokeOperation", e);
+ throw new RuntimeException(e);
}
return opcUaMethodCall(translateBrowsePathToNodeId(servicePath), parameters);
}
@@ -182,20 +193,20 @@
CompletableFuture<TranslateBrowsePathsToNodeIdsResponse> result_parent = clientRunner
.translate(bp_parent_list);
if (result_node.get().getResults().length == 0) {
- logger.warn("TranslateBrowsePathsToNodeIdsResponse result size = 0, checkthe browse path!");
+ logger.warn("TranslateBrowsePathsToNodeIdsResponse result size = 0, check the browse path!");
return null;
}
if (result_node.get().getResults().length > 1) {
logger.warn("TranslateBrowsePathsToNodeIdsResponse result size > 1, the method returns only the first one!");
}
+ if (result_node.get().getResults()[0].getTargets() == null || result_node.get().getResults()[0].getTargets().length == 0) {
+ logger.warn("TranslateBrowsePathsToNodeIdsResponse targets size = 0, check the browse path!");
+ logger.trace(result_node.get().getResults()[0].getStatusCode().toString());
+ return null;
+ }
if (result_node.get().getResults()[0].getTargets().length > 1) {
logger.warn("TranslateBrowsePathsToNodeIdsResponse targets size > 1, the method returns only the first one!");
}
- if (result_node.get().getResults()[0].getTargets().length == 0) {
- logger.warn("TranslateBrowsePathsToNodeIdsResponse targets size = 0, check the browse path!");
- logger.trace(result_node.get().getResults()[0].getStatusCode().toString());
- return null;
- }
Object nodeIdentifier = result_node.get().getResults()[0].getTargets()[0].getTargetId().getIdentifier();
Object parentIdentifier = result_parent.get().getResults()[0].getTargets()[0].getTargetId().getIdentifier();
UShort nodeNsIdx = result_node.get().getResults()[0].getTargets()[0].getTargetId().getNamespaceIndex();
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/OpcUaConnectorProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/OpcUaConnectorProvider.java
index 450f534..c5c6477 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/OpcUaConnectorProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/OpcUaConnectorProvider.java
@@ -1,7 +1,16 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.protocol.opcua.connector;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-import org.eclipse.basyx.vab.protocol.api.ConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.ConnectorFactory;
/**
* OPC UA connector provider class
@@ -9,7 +18,7 @@
* @author kdorofeev
*
*/
-public class OpcUaConnectorProvider extends ConnectorProvider {
+public class OpcUaConnectorProvider extends ConnectorFactory {
/**
* returns HTTPConnetor wrapped with ConnectedHashmapProvider that handles
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/BaSyxOpcUaClient.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/BaSyxOpcUaClient.java
index 14aa223..f08a453 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/BaSyxOpcUaClient.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/BaSyxOpcUaClient.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.protocol.opcua.server;
import java.util.concurrent.CompletableFuture;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/BaSyxOpcUaClientRunner.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/BaSyxOpcUaClientRunner.java
index 616df4c..8c38c1f 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/BaSyxOpcUaClientRunner.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/BaSyxOpcUaClientRunner.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.protocol.opcua.server;
import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.uint;
@@ -115,7 +124,7 @@
try {
Thread.sleep(1000);
- System.exit(0);
+ throw new RuntimeException("Could not disconnect from server '" + endpointUrl + "'");
} catch (InterruptedException e) {
logger.error("Exception in run", e);
}
@@ -128,7 +137,7 @@
try {
Thread.sleep(1000);
- System.exit(0);
+ throw new RuntimeException("Could not connect to server '" + endpointUrl + "'");
} catch (InterruptedException e) {
logger.error("Exception in run", e);
}
@@ -153,4 +162,4 @@
return client.translateBrowsePaths(browsePaths);
}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/KeyStoreLoaderClient.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/KeyStoreLoaderClient.java
index 4c45abd..535c994 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/KeyStoreLoaderClient.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/KeyStoreLoaderClient.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.protocol.opcua.server;
import java.io.InputStream;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/registry/api/IVABRegistryService.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/registry/api/IVABRegistryService.java
new file mode 100644
index 0000000..dccdfd0
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/registry/api/IVABRegistryService.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab.registry.api;
+
+/**
+ * Directory service SDK interface.
+ *
+ * @author kuhn
+ *
+ */
+public interface IVABRegistryService {
+
+
+ /**
+ * Add a mapping to directory
+ */
+ public IVABRegistryService addMapping(String key, String value);
+
+
+ /**
+ * Remove a mapping from directory
+ */
+ public void removeMapping(String key);
+
+
+ /**
+ * Lookup method maps key "id" to value
+ */
+ public String lookup(String id);
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/registry/memory/VABInMemoryRegistry.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/registry/memory/VABInMemoryRegistry.java
new file mode 100644
index 0000000..08bc30e
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/registry/memory/VABInMemoryRegistry.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab.registry.memory;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.registry.api.IVABRegistryService;
+
+
+
+/**
+ * Implement a in memory directory
+ *
+ * @author kuhn
+ *
+ */
+public class VABInMemoryRegistry implements IVABRegistryService {
+
+
+ /**
+ * Map that stores key/value mappings
+ */
+ protected Map<String, Object> keyToValue = new HashMap<>();
+
+
+
+
+ /**
+ * Default constructor
+ */
+ public VABInMemoryRegistry() {
+ // Do nothing
+ }
+
+
+ /**
+ * Constructor that accepts initial entries
+ */
+ public VABInMemoryRegistry(Map<String, String> addedValues) {
+ keyToValue.putAll(addedValues);
+ }
+
+
+
+ /**
+ * Add a mapping to directory
+ */
+ @Override
+ public IVABRegistryService addMapping(String key, String value) {
+ keyToValue.put(key, value);
+
+ // Return 'this' instance
+ return this;
+ }
+
+ /**
+ * Add several mappings to directory
+ */
+ public void addMappings(Map<String, String> mappings) {
+ keyToValue.putAll(mappings);
+ }
+
+ /**
+ * Remove a mapping from directory
+ */
+ @Override
+ public void removeMapping(String key) {
+ keyToValue.remove(key);
+ }
+
+ /**
+ * Lookup method
+ */
+ @Override
+ public String lookup(String id) {
+ if(keyToValue.containsKey(id)) {
+ return (String) keyToValue.get(id);
+ } else {
+ throw new ResourceNotFoundException("No entry exists for key " + id);
+ }
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/registry/proxy/VABRegistryProxy.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/registry/proxy/VABRegistryProxy.java
new file mode 100644
index 0000000..16cdb08
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/registry/proxy/VABRegistryProxy.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab.registry.proxy;
+
+import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnector;
+import org.eclipse.basyx.vab.registry.api.IVABRegistryService;
+
+public class VABRegistryProxy implements IVABRegistryService {
+ /**
+ * Store the URL of the registry of this proxy
+ */
+ protected IModelProvider provider;
+
+ /**
+ * Constructor for a generic VAB directory proxy based on a HTTP connection
+ *
+ * @param directoryUrl
+ * The endpoint of the registry with a HTTP-REST interface
+ */
+ public VABRegistryProxy(String directoryUrl) {
+ this(new VABElementProxy("", new JSONConnector(new HTTPConnector(directoryUrl))));
+ }
+
+ /**
+ * Constructor for a generic VAB directory based on the registry model provider
+ *
+ * @param provider
+ * A model provider for the actual registry
+ */
+ public VABRegistryProxy(IModelProvider provider) {
+ this.provider = provider;
+ }
+
+ /**
+ * Adds a single entry to the directory
+ */
+ @Override
+ public IVABRegistryService addMapping(String key, String value) {
+ provider.createValue(key, value);
+ return this;
+ }
+
+ /**
+ * Deletes an entry from the directory
+ */
+ @Override
+ public void removeMapping(String key) {
+ provider.deleteValue(key);
+ }
+
+ /**
+ * Returns a single entry in the directory
+ */
+ @Override
+ public String lookup(String id) {
+ Object response = provider.getValue(id);
+
+ if (response instanceof String) {
+ return (String) response;
+ } else {
+ throw new ProviderException("Lookup returned unexpected object: " + response);
+ }
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/registry/restapi/VABRegistryModelProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/registry/restapi/VABRegistryModelProvider.java
new file mode 100644
index 0000000..1540570
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/registry/restapi/VABRegistryModelProvider.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab.registry.restapi;
+
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.registry.api.IVABRegistryService;
+import org.eclipse.basyx.vab.registry.memory.VABInMemoryRegistry;
+
+/**
+ * Connects an arbitrary IVABDirectoryService implementation to the VAB
+ *
+ * @author schnicke
+ */
+
+public class VABRegistryModelProvider implements IModelProvider {
+
+ private IVABRegistryService directory;
+
+ /**
+ * Creates a DirectoryModelProvider wrapping an IVABDirectoryService
+ *
+ * @param directory
+ */
+ public VABRegistryModelProvider(IVABRegistryService directory) {
+ super();
+ this.directory = directory;
+ }
+
+ /**
+ * Creates a default DirectoryModelProvider wrapping an InMemoryDirectory
+ */
+ public VABRegistryModelProvider() {
+ this(new VABInMemoryRegistry());
+ }
+
+ @Override
+ public Object getValue(String path) throws ProviderException {
+ path = VABPathTools.stripSlashes(path);
+ return directory.lookup(path);
+ }
+
+ @Override
+ public void setValue(String path, Object newValue) throws ProviderException {
+ throw new RuntimeException("Set not supported by VAB Directory");
+ }
+
+ @Override
+ public void createValue(String path, Object newEntity) throws ProviderException {
+ path = VABPathTools.stripSlashes(path);
+ directory.addMapping(path, (String) newEntity);
+ }
+
+ @Override
+ public void deleteValue(String path) throws ProviderException {
+ path = VABPathTools.stripSlashes(path);
+ directory.removeMapping(path);
+ }
+
+ @Override
+ public void deleteValue(String path, Object obj) throws ProviderException {
+ throw new RuntimeException("Delete with parameter not supported by VAB Directory");
+ }
+
+ @Override
+ public Object invokeOperation(String path, Object... parameter) throws ProviderException {
+ throw new RuntimeException("Invoke not supported by VAB Directory");
+ }
+
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/service/api/BaSyxService.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/service/api/BaSyxService.java
index bd5dbbe..5e08d68 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/service/api/BaSyxService.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/service/api/BaSyxService.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.service.api;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/support/TypeDestroyer.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/support/TypeDestroyer.java
index c142792..0e3c2fd 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/support/TypeDestroyer.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/support/TypeDestroyer.java
@@ -1,8 +1,16 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.support;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -10,6 +18,9 @@
/**
* Removes type information similar to what a communication over VAB would do
+ * <br>
+ * Additionally, Sets are changed to Lists
+ *
* @author rajashek
*
*/
@@ -40,8 +51,8 @@
}
}
- private static Set<Object> handleSet(Set<Object> set) {
- Set<Object> ret = new HashSet<>();
+ private static List<Object> handleSet(Set<Object> set) {
+ List<Object> ret = new ArrayList<>();
for (Object o : set) {
ret.add(handle(o));
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/support/TypeDestroyingProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/support/TypeDestroyingProvider.java
index 443da13..90ba2bf 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/support/TypeDestroyingProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/support/TypeDestroyingProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.vab.support;
import org.eclipse.basyx.vab.exception.provider.ProviderException;
@@ -19,13 +28,13 @@
}
@Override
- public Object getModelPropertyValue(String path) throws ProviderException {
- return TypeDestroyer.handle(provider.getModelPropertyValue(path));
+ public Object getValue(String path) throws ProviderException {
+ return TypeDestroyer.handle(provider.getValue(path));
}
@Override
- public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
- provider.setModelPropertyValue(path, newValue);
+ public void setValue(String path, Object newValue) throws ProviderException {
+ provider.setValue(path, newValue);
}
@Override
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorSuite.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorSuite.java
index 69ada6b..db54503 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorSuite.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorSuite.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.aas.aggregator;
import static org.junit.Assert.assertEquals;
@@ -8,10 +17,15 @@
import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -25,7 +39,9 @@
public abstract class AASAggregatorSuite {
protected AssetAdministrationShell aas1;
- private static final String aas1Id = "aas1";
+
+ // Choose AAS Id that needs encoding due to '/'
+ private static final String aas1Id = "aas1/s";
private static final LangStrings description1 = new LangStrings("en", "This is test AAS 1");
private static final String aas1Category = "TestCategory1";
private static final String aas1AltCategory = "OtherTestCategory1";
@@ -38,21 +54,22 @@
// initializing dummy test data
@Before
public void initAASDummies() {
- aas1 = new AssetAdministrationShell();
- aas1.setIdentification(IdentifierType.CUSTOM, aas1Id);
- aas1.setIdShort(aas1Id);
+ aas1 = new AssetAdministrationShell(aas1Id, new Identifier(IdentifierType.CUSTOM, aas1Id), new Asset("asset1IdShort", new Identifier(IdentifierType.CUSTOM, "asset1"), AssetKind.INSTANCE));
aas1.setDescription(description1);
aas1.setCategory(aas1Category);
- aas2 = new AssetAdministrationShell();
- aas2.setIdentification(IdentifierType.CUSTOM, aas2Id);
- aas2.setIdShort(aas2Id);
+ aas2 = new AssetAdministrationShell(aas2Id, new Identifier(IdentifierType.CUSTOM, aas2Id), new Asset("asset2IdShort", new Identifier(IdentifierType.CUSTOM, "asset2"), AssetKind.INSTANCE));
aas2.setDescription(description2);
aas2.setCategory(aas2Category);
}
protected abstract IAASAggregator getAggregator();
+ @Before
+ public void clearAASAggregator() {
+ IAASAggregator aggregator = getAggregator();
+ aggregator.getAASList().stream().map(a -> a.getIdentification()).forEach(id -> aggregator.deleteAAS(id));
+ }
@Test
public void testCreateAndGetAAS() {
@@ -62,7 +79,8 @@
aggregator.createAAS(aas1);
//get and check the created AAS
- checkAAS1(aggregator.getAAS(new ModelUrn(aas1Id)));
+ IAssetAdministrationShell retrieved = aggregator.getAAS(aas1.getIdentification());
+ checkAAS1(retrieved);
}
@Test
@@ -140,10 +158,34 @@
}
}
+ @Test(expected = ResourceNotFoundException.class)
+ public void deleteNotExistingAAS() {
+ getAggregator().getAAS(new Identifier(IdentifierType.CUSTOM, "IDontExist"));
+ }
+
+ @After
+ public void deleteExistingAAS() {
+ IAASAggregator aggregator = getAggregator();
+
+ // Delete aas1 if exists
+ try {
+ aggregator.deleteAAS(new ModelUrn(aas1Id));
+ } catch (ResourceNotFoundException e) {
+ // do nothing
+ }
+
+ // Delete aas2 if exists
+ try {
+ aggregator.deleteAAS(new ModelUrn(aas2Id));
+ } catch (ResourceNotFoundException e) {
+ // do nothing
+ }
+ }
+
// Methods to verify, that AAS objects contain the correct test data
private void checkAAS1(Object o) {
- assertTrue(o instanceof AssetAdministrationShell);
- AssetAdministrationShell aas = (AssetAdministrationShell) o;
+ assertTrue(o instanceof IAssetAdministrationShell);
+ IAssetAdministrationShell aas = (IAssetAdministrationShell) o;
assertEquals(aas1Id, aas.getIdShort());
assertEquals(aas1Id, aas.getIdentification().getId());
@@ -152,8 +194,8 @@
}
private void checkAAS2(Object o) {
- assertTrue(o instanceof AssetAdministrationShell);
- AssetAdministrationShell aas = (AssetAdministrationShell) o;
+ assertTrue(o instanceof IAssetAdministrationShell);
+ IAssetAdministrationShell aas = (IAssetAdministrationShell) o;
assertEquals(aas2Id, aas.getIdShort());
assertEquals(aas2Id, aas.getIdentification().getId());
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregator.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregator.java
index bc1a757..3e838b1 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregator.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregator.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.aas.aggregator;
import org.eclipse.basyx.aas.aggregator.AASAggregator;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregatorProvider.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregatorProvider.java
deleted file mode 100644
index 42706ec..0000000
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregatorProvider.java
+++ /dev/null
@@ -1,111 +0,0 @@
-package org.eclipse.basyx.testsuite.regression.aas.aggregator;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.Map;
-
-import org.eclipse.basyx.aas.aggregator.AASAggregator;
-import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
-import org.eclipse.basyx.aas.aggregator.proxy.AASAggregatorProxy;
-import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
-import org.eclipse.basyx.vab.modelprovider.VABPathTools;
-import org.junit.Test;
-
-/**
- * Test for the AASAggregationProvider
- *
- * @author conradi, schnicke
- *
- */
-public class TestAASAggregatorProvider extends AASAggregatorSuite {
-
- @Override
- protected IAASAggregator getAggregator() {
- return new AASAggregatorProxy(new AASAggregatorProvider(new AASAggregator()));
- }
-
- /**
- * Requests like /aasList/${aasId}/aas need to be fed through correctly. This
- * behaviour is tested here.
- */
- @SuppressWarnings("unchecked")
- @Test
- public void testFeedThrough() {
- AASAggregator aggregator = new AASAggregator();
- aggregator.createAAS(aas1);
- AASAggregatorProvider provider = new AASAggregatorProvider(aggregator);
-
- // Test feedthrough of GET
- String aasPath = "/aasList/" + aas1.getIdentification().getId() + "/aas";
- AssetAdministrationShell retrievedAAS = retrieveAAS(provider, aasPath);
- assertEquals(aas1.getIdentification(), retrievedAAS.getIdentification());
-
- // Test feedthrough of CREATE
- SubModel sm = new SubModel();
- sm.setIdentification(IdentifierType.CUSTOM, "smId");
- sm.setIdShort("smIdShort");
- Operation op = new Operation((o) -> {
- return true;
- });
- op.setIdShort("op");
- sm.addSubModelElement(op);
-
- Property prop = new Property(5);
- prop.setIdShort("prop");
- sm.addSubModelElement(prop);
-
- provider.createValue(aasPath + "/submodels", sm);
-
- // Check if it was created
- String smPath = aasPath + "/submodels/smIdShort";
- SubModel retrievedSm = SubModel.createAsFacade((Map<String, Object>) provider.getModelPropertyValue(smPath));
- assertEquals(sm.getIdShort(), retrievedSm.getIdShort());
-
- // Test feedthrough of SET
- String propValuePath = VABPathTools.concatenatePaths(smPath, SubmodelElementProvider.PROPERTIES, prop.getIdShort(), "value");
- int expectedPropValue = 20;
- provider.setModelPropertyValue(propValuePath, expectedPropValue);
-
- Map<String, Object> value = (Map<String, Object>) provider.getModelPropertyValue(propValuePath);
- assertEquals(expectedPropValue, value.get(Property.VALUE));
-
- // Test feedthrough of INVOKE
- assertTrue((boolean) provider.invokeOperation(smPath + "/operations/op"));
-
- // Test feedthrough of DELETE
- provider.deleteValue(smPath);
-
- // Ensure only the submodel has been deleted
- retrievedAAS = retrieveAAS(provider, aasPath);
- assertEquals(aas1.getIdentification(), retrievedAAS.getIdentification());
-
- try {
- provider.getModelPropertyValue(smPath);
- fail();
- } catch (ResourceNotFoundException e) {
- // Expected
- }
-
- }
-
- /**
- * Retrieves the AAS given residing in the passed path on the passed provider
- *
- * @param provider
- * @param aasPath
- * @return
- */
- @SuppressWarnings("unchecked")
- private AssetAdministrationShell retrieveAAS(AASAggregatorProvider provider, String aasPath) {
- return AssetAdministrationShell.createAsFacade((Map<String, Object>) provider.getModelPropertyValue(aasPath));
- }
-}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregatorProxy.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregatorProxy.java
new file mode 100644
index 0000000..00a6fc5
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregatorProxy.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.aas.aggregator;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.basyx.aas.aggregator.AASAggregator;
+import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
+import org.eclipse.basyx.aas.aggregator.proxy.AASAggregatorProxy;
+import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.junit.Test;
+
+/**
+ * Test for the AASAggregationProvider
+ *
+ * @author conradi, schnicke
+ *
+ */
+public class TestAASAggregatorProxy extends AASAggregatorSuite {
+
+ @Override
+ protected IAASAggregator getAggregator() {
+ return new AASAggregatorProxy(new VABElementProxy("/shells", new AASAggregatorProvider(new AASAggregator())));
+ }
+
+ /**
+ * Requests like /shells/${aasId}/aas need to be fed through correctly. This
+ * behaviour is tested here.
+ */
+ @Test
+ public void testFeedThrough() throws Exception {
+ IAASAggregator aggregator = getAggregator();
+ aggregator.createAAS(aas1);
+
+ // Test feedthrough of GET
+ IAssetAdministrationShell retrievedAAS = aggregator.getAAS(aas1.getIdentification());
+ assertEquals(aas1.getIdentification(), retrievedAAS.getIdentification());
+
+ // Test feedthrough of CREATE
+ Submodel sm = new Submodel();
+ sm.setIdentification(IdentifierType.CUSTOM, "smId");
+ sm.setIdShort("smIdShort");
+ Operation op = new Operation((o) -> {
+ return true;
+ });
+ op.setIdShort("op");
+ sm.addSubmodelElement(op);
+
+ Property prop = new Property(5);
+ prop.setIdShort("prop");
+ sm.addSubmodelElement(prop);
+
+ retrievedAAS.addSubmodel(sm);
+
+ // Check if it was created
+ ISubmodel retrievedSm = retrievedAAS.getSubmodels().get(sm.getIdShort());
+ assertEquals(sm.getIdShort(), retrievedSm.getIdShort());
+
+ // Test feedthrough of SET
+ int expectedPropValue = 20;
+ IProperty connectedProp = (IProperty) retrievedSm.getSubmodelElement(prop.getIdShort());
+
+ connectedProp.setValue(expectedPropValue);
+ assertEquals(expectedPropValue, connectedProp.getValue());
+
+ // Test feedthrough of INVOKE
+ // Use short form of invoke with operation variable matching and no parameters (empty object array)
+ assertTrue((boolean) ((IOperation) sm.getSubmodelElement(op.getIdShort())).invoke(new Object[0]));
+
+ // Test feedthrough of DELETE
+ retrievedAAS.removeSubmodel(sm.getIdentification());
+
+ // Ensure only the submodel has been deleted
+ assertEquals(aas1.getIdentification(), retrievedAAS.getIdentification());
+
+ assertFalse(retrievedAAS.getSubmodels().containsKey(sm.getIdShort()));
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/AASXFactoryTest.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/AASXFactoryTest.java
new file mode 100644
index 0000000..6a6925c
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/AASXFactoryTest.java
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.aas.factory.aasx;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.eclipse.basyx.aas.factory.aasx.AASXFactory;
+import org.eclipse.basyx.aas.factory.aasx.InMemoryFile;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.parts.IConceptDescription;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test for the AASXFactory
+ *
+ * @author conradi
+ *
+ */
+public class AASXFactoryTest {
+
+ private static final String XML_PATH = "aasx/xml/content.xml";
+ private static final String ORIGIN_PATH = "aasx/aasx-origin";
+
+
+ private AssetAdministrationShell aas;
+ private Submodel sm1;
+ private Submodel sm2;
+
+ private List<IAssetAdministrationShell> aasList = new ArrayList<>();
+ private List<ISubmodel> submodelList = new ArrayList<>();
+ private List<IAsset> assetList = new ArrayList<>();
+ private List<IConceptDescription> conceptDescriptionList = new ArrayList<>();
+
+ private List<InMemoryFile> fileList = new ArrayList<>();
+
+
+
+ @Before
+ public void setup() throws IOException {
+ Asset asset = new Asset("asset-id", new ModelUrn("ASSET_IDENTIFICATION"), AssetKind.TYPE);
+ aas = new AssetAdministrationShell("aas-id", new ModelUrn("AAS_IDENTIFICATION"), asset);
+
+ sm1 = new Submodel("sm1", new ModelUrn("SM1_ID"));
+ sm2 = new Submodel("sm2", new ModelUrn("SM2_ID"));
+
+ File file1 = new File("http://localhost:8080/image.png", "image/png");
+ file1.setIdShort("file1");
+ File file2 = new File("aasx/Document/docu.pdf", "application/pdf");
+ file2.setIdShort("file2");
+ File file3 = new File("/aasx/Document/docu2.pdf", "application/pdf");
+ file3.setIdShort("file3");
+
+
+
+ SubmodelElementCollection collection = new SubmodelElementCollection("collection");
+ collection.addSubmodelElement(file2);
+
+ sm1.addSubmodelElement(file1);
+ sm1.addSubmodelElement(collection);
+ sm2.addSubmodelElement(file3);
+
+ aas.addSubmodel(sm1);
+ aas.addSubmodel(sm2);
+
+ aasList.add(aas);
+ submodelList.add(sm1);
+ submodelList.add(sm2);
+ assetList.add(asset);
+
+
+ byte[] content1 = {0,1,2,3,4};
+ InMemoryFile file = new InMemoryFile(content1, "/image.png");
+ fileList.add(file);
+
+ byte[] content2 = {5,6,7,8,9};
+ file = new InMemoryFile(content2, "/aasx/Document/docu.pdf");
+ fileList.add(file);
+
+ byte[] content3 = {10,11,12,13,14};
+ file = new InMemoryFile(content3, "aasx/Document/docu2.pdf");
+ fileList.add(file);
+ }
+
+
+ @Test
+ public void testBuildAASX() throws IOException, TransformerException, ParserConfigurationException {
+
+ // This stream can be used to write the .aasx directly to a file
+ // FileOutputStream out = new FileOutputStream("path/to/test.aasx");
+
+ // This stream keeps the output of the AASXFactory only in memory
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ AASXFactory.buildAASX(aasList, assetList, conceptDescriptionList, submodelList, fileList, out);
+
+ validateAASX(out);
+
+ }
+
+
+ private void validateAASX(ByteArrayOutputStream byteStream) throws IOException {
+ ZipInputStream in = new ZipInputStream(new ByteArrayInputStream(byteStream.toByteArray()));
+ ZipEntry zipEntry = null;
+
+ ArrayList<String> filePaths = new ArrayList<>();
+
+ while((zipEntry = in.getNextEntry()) != null) {
+ if(zipEntry.getName().equals(XML_PATH)) {
+
+ // Read the first 5 bytes of the XML file to make sure it is in fact XML file
+ // No further test of XML file necessary as XML-Converter is tested separately
+ byte[] buf = new byte[5];
+ in.read(buf);
+ assertEquals("<?xml", new String(buf));
+
+ }
+
+ // Write the paths of all files contained in the .aasx into filePaths
+ filePaths.add(zipEntry.getName());
+ }
+
+ assertTrue(filePaths.contains(XML_PATH));
+ assertTrue(filePaths.contains(ORIGIN_PATH));
+
+ // Check if all expected files are present
+ // Needs to strip the first slash of the paths, as ZipEntry gives paths without it
+ for(InMemoryFile file: fileList) {
+ assertTrue(filePaths.contains(VABPathTools.stripSlashes(file.getPath())));
+ }
+
+ }
+
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/json/TestJSONConverter.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/json/TestJSONConverter.java
new file mode 100644
index 0000000..b72744c
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/json/TestJSONConverter.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.aas.factory.json;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.List;
+
+import org.eclipse.basyx.aas.factory.json.JSONToMetamodelConverter;
+import org.eclipse.basyx.aas.factory.json.MetamodelToJSONConverter;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.parts.ConceptDescription;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test for MetamodelToJSONConverter and JSONToMetamodelConverter
+ *
+ * @author conradi
+ *
+ */
+public class TestJSONConverter {
+
+ private String jsonPath = "src/test/resources/aas/factory/json/aasJsonSchemaV2.0.1_Example.json";
+
+ private JSONToMetamodelConverter converter;
+
+ @Before
+ public void buildConverter() throws IOException {
+ String json = new String(Files.readAllBytes(Paths.get(jsonPath)));
+ converter = new JSONToMetamodelConverter(json);
+ }
+
+ @Test
+ public void testParseAAS() {
+ checkAASs(converter.parseAAS());
+ }
+
+ @Test
+ public void testParseSubmodels() {
+ checkSubmodels(converter.parseSubmodels());
+ }
+
+ @Test
+ public void testParseAssets() {
+ checkAssets(converter.parseAssets());
+ }
+
+ @Test
+ public void testParseConceptDescriptions() {
+ checkConceptDescriptions(converter.parseConceptDescriptions());
+ }
+
+ @Test
+ public void testBuildJSON() {
+
+ // Read Metamodel-Objects from JSON-File
+ List<AssetAdministrationShell> aasList = converter.parseAAS();
+ List<Asset> assetList = converter.parseAssets();
+ List<ConceptDescription> conceptDescriptionList = converter.parseConceptDescriptions();
+ List<Submodel> submodelList = converter.parseSubmodels();
+
+ // Convert Metamodel-Objects to JSON
+ String json = MetamodelToJSONConverter.convertToJSON(aasList, assetList, conceptDescriptionList, submodelList);
+
+ // Convert new JSON back to Metamodel-Objects to check them
+ JSONToMetamodelConverter converter2 = new JSONToMetamodelConverter(json);
+
+ // Check if the Metamodel-Objects are still correct
+ checkAASs(converter2.parseAAS());
+ checkAssets(converter2.parseAssets());
+ checkConceptDescriptions(converter2.parseConceptDescriptions());
+ checkSubmodels(converter2.parseSubmodels());
+ }
+
+
+
+ private void checkAASs(List<AssetAdministrationShell> aasList) {
+ assertEquals(1, aasList.size());
+ AssetAdministrationShell aas = aasList.get(0);
+
+ assertEquals("ExampleMotor", aas.getIdShort());
+ assertEquals(3, aas.getSubmodelReferences().size());
+ assertEquals("http://customer.com/aas/9175_7013_7091_9168", aas.getIdentification().getId());
+ }
+
+ private void checkSubmodels(List<Submodel> smList) {
+ assertEquals(3, smList.size());
+
+ Submodel sm = smList.stream().filter(c -> c.getIdShort().equals("TechnicalData")).findAny().get();
+
+ assertEquals(1, sm.getSubmodelElements().size());
+
+ Property smElement = (Property) sm.getSubmodelElements().get("MaxRotationSpeed");
+ assertEquals("5000", smElement.getValue());
+ }
+
+ private void checkAssets(List<Asset> assetList) {
+ assertEquals(1, assetList.size());
+ Asset asset = assetList.get(0);
+
+ assertEquals("ServoDCMotor", asset.getIdShort());
+ assertEquals("http://customer.com/assets/KHBVZJSQKIY", asset.getIdentification().getId());
+ }
+
+ private void checkConceptDescriptions(List<ConceptDescription> conceptDescriptionList) {
+ assertEquals(5, conceptDescriptionList.size());
+
+ ConceptDescription cd = conceptDescriptionList.stream()
+ .filter(c -> c.getIdShort().equals("DigitalFile")).findAny().get();
+
+ assertEquals("www.vdi2770.com/blatt1/Entwurf/Okt18/cd/StoredDocumentRepresentation/DigitalFile",
+ cd.getIdentification().getId());
+ }
+
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/xml/TestXMLConverter.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/xml/TestXMLConverter.java
index 087dd33..47ce3c5 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/xml/TestXMLConverter.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/xml/TestXMLConverter.java
@@ -1,16 +1,23 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.aas.factory.xml;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
import java.io.StringWriter;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
-import java.util.Base64;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -25,7 +32,7 @@
import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IDataSpecificationContent;
import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IEmbeddedDataSpecification;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
@@ -37,9 +44,10 @@
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IDataElement;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.entity.EntityType;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperationVariable;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
import org.eclipse.basyx.submodel.metamodel.map.dataspecification.DataSpecificationIEC61360Content;
import org.eclipse.basyx.submodel.metamodel.map.parts.ConceptDescription;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
@@ -47,12 +55,14 @@
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Blob;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Range;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.ReferenceElement;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.Range;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.entity.Entity;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.event.BasicEvent;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.AnnotatedRelationshipElement;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElement;
import org.eclipse.basyx.vab.model.VABModelMap;
import org.eclipse.basyx.vab.support.TypeDestroyer;
@@ -66,101 +76,70 @@
private XMLToMetamodelConverter converter;
@Before
- public void buildConverter() {
- try {
- String xml = new String(Files.readAllBytes(Paths.get(xmlInPath)));
- converter = new XMLToMetamodelConverter(xml);
- } catch (Exception e) {
- e.printStackTrace();
- fail();
- }
+ public void buildConverter() throws Exception {
+ String xml = new String(Files.readAllBytes(Paths.get(xmlInPath)));
+ converter = new XMLToMetamodelConverter(xml);
}
@Test
- public void testParseAAS() {
- try {
- checkAASs(converter.parseAAS());
- } catch (Exception e) {
- e.printStackTrace();
- fail();
- }
+ public void testParseAAS() throws Exception {
+ checkAASs(converter.parseAAS());
}
@Test
- public void testParseAssets() {
- try {
- checkAssets(converter.parseAssets());
- } catch (Exception e) {
- e.printStackTrace();
- fail();
- }
+ public void testParseAssets() throws Exception {
+ checkAssets(converter.parseAssets());
}
@Test
public void testParseConceptDescriptions() {
- try {
- checkConceptDescriptions(converter.parseConceptDescriptions());
- } catch (Exception e) {
- e.printStackTrace();
- fail();
- }
+ checkConceptDescriptions(converter.parseConceptDescriptions());
}
@Test
public void testParseSubmodels() {
- try {
- checkSubmodels(converter.parseSubmodels());
- } catch (Exception e) {
- e.printStackTrace();
- fail();
- }
+ checkSubmodels(converter.parseSubmodels());
}
@Test
- public void testBuildXML() {
- try {
- //Convert the in.xml to Objects
- List<IAssetAdministrationShell> assetAdministrationShellList = converter.parseAAS();
- List<IAsset> assetList = converter.parseAssets();
- List<IConceptDescription> conceptDescriptionList = converter.parseConceptDescriptions();
- List<ISubModel> submodelList = converter.parseSubmodels();
-
- //Build XML-File from the Objects and write it to a StringWriter
- StringWriter resultWithTypes = new StringWriter();
- MetamodelToXMLConverter.convertToXML(assetAdministrationShellList, assetList, conceptDescriptionList, submodelList, new StreamResult(resultWithTypes));
-
-
- //Read the content of the StringWriter, convert it into Objects and check them
- XMLToMetamodelConverter converterWithTypes = new XMLToMetamodelConverter(resultWithTypes.toString());
-
- checkAASs(converterWithTypes.parseAAS());
- checkAssets(converterWithTypes.parseAssets());
- checkConceptDescriptions(converterWithTypes.parseConceptDescriptions());
- checkSubmodels(converterWithTypes.parseSubmodels());
-
- //erase the types of the Objects, that they are plain Maps as if they were transferred over the VAB
- List<IAssetAdministrationShell> iAssetAdministrationShellList = destroyAASTypes(assetAdministrationShellList);
- List<IAsset> iAssetList = destroyAssetTypes(assetList);
- List<IConceptDescription> iConceptDescriptionList = destroyConceptDescriptionTypes(conceptDescriptionList);
- List<ISubModel> iSubmodelList = destroySubmodelTypes(submodelList);
-
- //Build XML-File from the Objects and write it to a StringWriter
- StringWriter resultWithoutTypes = new StringWriter();
- MetamodelToXMLConverter.convertToXML(iAssetAdministrationShellList, iAssetList, iConceptDescriptionList, iSubmodelList, new StreamResult(resultWithoutTypes));
-
-
- //Read the content of the StringWriter, convert it into Objects and check them
- XMLToMetamodelConverter converterWithoutTypes = new XMLToMetamodelConverter(resultWithoutTypes.toString());
-
- checkAASs(converterWithoutTypes.parseAAS());
- checkAssets(converterWithoutTypes.parseAssets());
- checkConceptDescriptions(converterWithoutTypes.parseConceptDescriptions());
- checkSubmodels(converterWithoutTypes.parseSubmodels());
-
- } catch (Exception e) {
- e.printStackTrace();
- fail();
- }
+ public void testBuildXML() throws Exception {
+ //Convert the in.xml to Objects
+ List<IAssetAdministrationShell> assetAdministrationShellList = converter.parseAAS();
+ List<IAsset> assetList = converter.parseAssets();
+ List<IConceptDescription> conceptDescriptionList = converter.parseConceptDescriptions();
+ List<ISubmodel> submodelList = converter.parseSubmodels();
+
+ //Build XML-File from the Objects and write it to a StringWriter
+ StringWriter resultWithTypes = new StringWriter();
+ MetamodelToXMLConverter.convertToXML(assetAdministrationShellList, assetList, conceptDescriptionList, submodelList, new StreamResult(resultWithTypes));
+
+
+ //Read the content of the StringWriter, convert it into Objects and check them
+ XMLToMetamodelConverter converterWithTypes = new XMLToMetamodelConverter(resultWithTypes.toString());
+
+ checkAASs(converterWithTypes.parseAAS());
+ checkAssets(converterWithTypes.parseAssets());
+ checkConceptDescriptions(converterWithTypes.parseConceptDescriptions());
+ checkSubmodels(converterWithTypes.parseSubmodels());
+
+ //erase the types of the Objects, that they are plain Maps as if they were transferred over the VAB
+ List<IAssetAdministrationShell> iAssetAdministrationShellList = destroyAASTypes(assetAdministrationShellList);
+ List<IAsset> iAssetList = destroyAssetTypes(assetList);
+ List<IConceptDescription> iConceptDescriptionList = destroyConceptDescriptionTypes(conceptDescriptionList);
+ List<ISubmodel> iSubmodelList = destroySubmodelTypes(submodelList);
+
+ //Build XML-File from the Objects and write it to a StringWriter
+ StringWriter resultWithoutTypes = new StringWriter();
+ MetamodelToXMLConverter.convertToXML(iAssetAdministrationShellList, iAssetList, iConceptDescriptionList, iSubmodelList, new StreamResult(resultWithoutTypes));
+
+
+ //Read the content of the StringWriter, convert it into Objects and check them
+ XMLToMetamodelConverter converterWithoutTypes = new XMLToMetamodelConverter(resultWithoutTypes.toString());
+
+ checkAASs(converterWithoutTypes.parseAAS());
+ checkAssets(converterWithoutTypes.parseAssets());
+ checkConceptDescriptions(converterWithoutTypes.parseConceptDescriptions());
+ checkSubmodels(converterWithoutTypes.parseSubmodels());
}
private void checkAASs(List<IAssetAdministrationShell> aasList) {
@@ -320,7 +299,7 @@
assertEquals("3s7plfdrs35_asset1", asset.getIdShort());
assertEquals("asset1_Description", asset.getDescription().get("EN"));
assertEquals(IdentifierType.IRI, asset.getIdentification().getIdType());
- assertEquals("Instance", asset.getAssetKind().toString());
+ assertEquals("Type", asset.getAssetKind().toString());
assertEquals("www.festo.com/dic/08111234", asset.getAssetIdentificationModel().getKeys().get(0).getValue());
}
@@ -340,12 +319,12 @@
assertEquals(1, refs.size());
}
- private void checkSubmodels(List<ISubModel> submodels) {
+ private void checkSubmodels(List<ISubmodel> submodels) {
assertEquals(2, submodels.size());
- ISubModel submodel = null;
+ ISubmodel submodel = null;
- //select the SubModel with a specific ID form the list
- for(ISubModel s: submodels) {
+ //select the Submodel with a specific ID form the list
+ for(ISubmodel s: submodels) {
if(s.getIdShort().equals("3s7plfdrs35_submodel1")) {
submodel = s;
break;
@@ -355,34 +334,37 @@
assertNotNull(submodel);
checkDefaultEmbeddedDataSpecification(submodel);
assertEquals("3s7plfdrs35_submodel1", submodel.getIdShort());
- Collection<IConstraint> constraints = submodel.getQualifier();
- assertEquals(2, constraints.size());
+ Collection<IConstraint> constraints = submodel.getQualifiers();
+ assertEquals(4, constraints.size());
checkSubmodelElements(submodel);
}
@SuppressWarnings("unchecked")
- private void checkSubmodelElements(ISubModel submodel) {
+ private void checkSubmodelElements(ISubmodel submodel) {
Map<String, ISubmodelElement> submodelElements = (Map<String, ISubmodelElement>)
- ((Map<String, Object>)submodel).get(SubModel.SUBMODELELEMENT);
- assertEquals(12, submodelElements.size());
+ ((Map<String, Object>)submodel).get(Submodel.SUBMODELELEMENT);
+ assertEquals(13, submodelElements.size());
ISubmodelElement element = submodelElements.get("rotationSpeed");
assertTrue(element instanceof Property);
Property property = (Property) element;
checkDefaultEmbeddedDataSpecification(property);
- assertEquals("2000", property.get());
- assertEquals("double", property.getValueType());
+ List<IKey> keys = property.getValueId().getKeys();
+ assertEquals(1, keys.size());
+ assertEquals("0173-1#05-AAA650#002", keys.get(0).getValue());
+ assertEquals(2000.0, property.getValue());
+ assertEquals(ValueType.Double, property.getValueType());
assertEquals("rotationSpeed", property.getIdShort());
element = submodelElements.get("emptyDouble");
assertTrue(element instanceof Property);
property = (Property) element;
- assertEquals("double", property.getValueType());
+ assertEquals(ValueType.Double, property.getValueType());
element = submodelElements.get("basic_event_id");
assertTrue(element instanceof BasicEvent);
BasicEvent basicEvent = (BasicEvent) element;
- List<IKey> keys = basicEvent.getObserved().getKeys();
+ keys = basicEvent.getObserved().getKeys();
assertEquals(1, keys.size());
assertEquals("http://www.zvei.de/demo/submodelDefinitions/87654346", keys.get(0).getValue());
@@ -408,7 +390,7 @@
element = submodelElements.get("range_id");
assertTrue(element instanceof Range);
Range range = (Range) element;
- assertEquals("int", range.getValueType());
+ assertEquals(ValueType.Integer, range.getValueType());
assertEquals("1", range.getMin());
assertEquals("10", range.getMax());
@@ -422,7 +404,7 @@
assertTrue(element instanceof Blob);
Blob blob = (Blob) element;
assertEquals("blob_mimetype", blob.getMimeType());
- assertEquals("YmxvYit2YWx1ZQ==", Base64.getEncoder().encodeToString(blob.getValue()));
+ assertEquals("YmxvYit2YWx1ZQ==", blob.getValue());
element = submodelElements.get("reference_ELE_ID");
assertTrue(element instanceof ReferenceElement);
@@ -449,6 +431,21 @@
assertEquals(1, keys.size());
assertEquals("0173-1#05-AAA650#002", keys.get(0).getValue());
+ element = submodelElements.get("annotatedRelationshipElement_ID");
+ assertTrue(element instanceof AnnotatedRelationshipElement);
+ AnnotatedRelationshipElement annotatedElem = (AnnotatedRelationshipElement) element;
+ keys = annotatedElem.getFirst().getKeys();
+ assertEquals(1, keys.size());
+ assertEquals("0173-1#05-AAA650#003", keys.get(0).getValue());
+ keys = annotatedElem.getSecond().getKeys();
+ assertEquals(1, keys.size());
+ assertEquals("0173-1#05-AAA650#004", keys.get(0).getValue());
+ Collection<IDataElement> annotations = annotatedElem.getValue().getAnnotations();
+ assertEquals(2, annotations.size());
+ for(IDataElement annotationElement: annotations) {
+ assertTrue(annotationElement instanceof Property);
+ }
+
element = submodelElements.get("operation_ID");
assertTrue(element instanceof Operation);
Operation op = (Operation) element;
@@ -474,10 +471,10 @@
}
@SuppressWarnings("unchecked")
- private List<ISubModel> destroySubmodelTypes(List<ISubModel> submodelList) {
- List<ISubModel> ret = new ArrayList<>();
- for(ISubModel submodel: submodelList) {
- ret.add(SubModel.createAsFacade(new VABModelMap<>(TypeDestroyer.destroyType((Map<String, Object>) submodel))));
+ private List<ISubmodel> destroySubmodelTypes(List<ISubmodel> submodelList) {
+ List<ISubmodel> ret = new ArrayList<>();
+ for(ISubmodel submodel: submodelList) {
+ ret.add(Submodel.createAsFacade(new VABModelMap<>(TypeDestroyer.destroyType((Map<String, Object>) submodel))));
}
return ret;
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/manager/TestAASHTTP.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/manager/TestAASHTTP.java
index 4bb1648..fff8642 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/manager/TestAASHTTP.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/manager/TestAASHTTP.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.aas.manager;
import static org.junit.Assert.assertEquals;
@@ -10,15 +19,15 @@
import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
import org.eclipse.basyx.testsuite.regression.aas.restapi.StubAASServlet;
import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
-import org.eclipse.basyx.vab.directory.memory.InMemoryDirectory;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
+import org.eclipse.basyx.vab.registry.memory.VABInMemoryRegistry;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
@@ -49,10 +58,10 @@
@Before
public void build() {
// Fill directory stub
- InMemoryDirectory directory = new InMemoryDirectory();
+ VABInMemoryRegistry directory = new VABInMemoryRegistry();
directory.addMapping(StubAASServlet.AASURN.getId(), "http://localhost:8080/basys.sdk/Testsuite/StubAAS/aas");
directory.addMapping(StubAASServlet.SMURN.getId(),
- "http://localhost:8080/basys.sdk/Testsuite/StubAAS/aas/submodels/" + StubAASServlet.SMIDSHORT);
+ "http://localhost:8080/basys.sdk/Testsuite/StubAAS/aas/submodels/" + StubAASServlet.SMIDSHORT + "/submodel");
InMemoryRegistry registry = new InMemoryRegistry();
@@ -62,7 +71,7 @@
// Create the submodel descriptor
SubmodelDescriptor submodelDescriptor = new SubmodelDescriptor(StubAASServlet.SMIDSHORT, StubAASServlet.SMURN,
- "http://localhost:8080/basys.sdk/Testsuite/StubAAS/aas/submodels/" + StubAASServlet.SMIDSHORT);
+ "http://localhost:8080/basys.sdk/Testsuite/StubAAS/aas/submodels/" + StubAASServlet.SMIDSHORT + "/submodel");
// add submodel descriptor to the aas descriptor
aasDescriptor.addSubmodelDescriptor(submodelDescriptor);
@@ -71,7 +80,7 @@
registry.register(aasDescriptor);
// Create manager using the directory stub an the HTTPConnectorProvider
- manager = new ConnectedAssetAdministrationShellManager(registry, new HTTPConnectorProvider());
+ manager = new ConnectedAssetAdministrationShellManager(registry, new HTTPConnectorFactory());
}
/**
@@ -88,7 +97,7 @@
assertEquals(StubAASServlet.AASIDSHORT, shell.getIdShort());
// Retrieve submodels
- Map<String, ISubModel> submodels = shell.getSubModels();
+ Map<String, ISubmodel> submodels = shell.getSubmodels();
// Check content of submodels
assertEquals(1, submodels.size());
@@ -101,9 +110,9 @@
* @throws Exception
*/
@Test
- public void testSubModel() throws Exception {
- // Retrieve SubModel
- ISubModel sm = manager.retrieveSubModel(StubAASServlet.AASURN, StubAASServlet.SMURN);
+ public void testSubmodel() throws Exception {
+ // Retrieve Submodel
+ ISubmodel sm = manager.retrieveSubmodel(StubAASServlet.AASURN, StubAASServlet.SMURN);
// Check id
assertEquals(StubAASServlet.SMIDSHORT, sm.getIdShort());
@@ -112,10 +121,9 @@
// - retrieve properties and operations
Map<String, IProperty> properties = sm.getProperties();
- // 2 properties -> SMElementCollections don't count
assertEquals(3, properties.size());
IProperty prop = properties.get("integerProperty");
- assertEquals(123, prop.get());
+ assertEquals(123, prop.getValue());
Map<String, IOperation> operations = sm.getOperations();
assertEquals(4, operations.size());
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/manager/TestConnectedAssetAdministrationShellManager.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/manager/TestConnectedAssetAdministrationShellManager.java
index b2fc2bb..5b9d9bf 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/manager/TestConnectedAssetAdministrationShellManager.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/manager/TestConnectedAssetAdministrationShellManager.java
@@ -1,25 +1,42 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.aas.manager;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.fail;
import org.eclipse.basyx.aas.aggregator.AASAggregator;
import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
import org.eclipse.basyx.aas.metamodel.connected.ConnectedAssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
import org.eclipse.basyx.aas.restapi.AASModelProvider;
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.aas.restapi.MultiSubmodelProvider;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
import org.eclipse.basyx.testsuite.regression.vab.gateway.ConnectorProviderStub;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
import org.junit.Before;
import org.junit.Test;
@@ -33,7 +50,7 @@
public class TestConnectedAssetAdministrationShellManager {
ConnectedAssetAdministrationShellManager manager;
ConnectorProviderStub connectorProvider;
- IAASRegistryService registry;
+ IAASRegistry registry;
/**
* Create infrastructure
@@ -57,17 +74,16 @@
// Register AAS at directory
IIdentifier aasId = new Identifier(IdentifierType.CUSTOM, "aasId");
String aasIdShort = "aasName";
- connectorProvider.addMapping("", new AASAggregatorProvider(new AASAggregator()));
-
- // Create an AAS containing a reference to the created SubModel
- AssetAdministrationShell aas = new AssetAdministrationShell();
- aas.setIdentification(aasId);
- aas.setIdShort(aasIdShort);
- manager.createAAS(aas, aasId, "");
+ IModelProvider provider = new AASAggregatorProvider(new AASAggregator());
+ prepareConnectorProvider(provider);
+
+ // Create an AAS containing a reference to the created Submodel
+ AssetAdministrationShell aas = createTestAAS(aasId, aasIdShort);
+ manager.createAAS(aas, "/shells");
// Check descriptor for correct endpoint
String endpoint = registry.lookupAAS(aasId).getFirstEndpoint();
- assertEquals("/aasList/" + aasId.getId() + "/aas", endpoint);
+ assertEquals(AASAggregatorProvider.PREFIX + "/" + aasId.getId() + "/aas", endpoint);
// Retrieve it
ConnectedAssetAdministrationShell connectedAAS = manager.retrieveAAS(aasId);
@@ -76,8 +92,9 @@
assertEquals(aasId.getIdType(), connectedAAS.getIdentification().getIdType());
}
+
@Test
- public void testCreateSubModel() throws Exception {
+ public void testCreateSubmodel() throws Exception {
IIdentifier aasId = new Identifier(IdentifierType.CUSTOM, "aasId");
IIdentifier smId = new Identifier(IdentifierType.CUSTOM, "smId");
String smIdShort = "smName";
@@ -85,26 +102,26 @@
// Register AAS at directory
AASDescriptor desc = new AASDescriptor(aasId, "/aas");
registry.register(desc);
- IModelProvider provider = new VABMultiSubmodelProvider(new AASModelProvider(new AssetAdministrationShell()));
+ IModelProvider provider = new MultiSubmodelProvider(new AASModelProvider(new AssetAdministrationShell()));
connectorProvider.addMapping("", provider);
// Create sub model
- SubModel submodel = new SubModel();
+ Submodel submodel = new Submodel();
submodel.setIdShort(smIdShort);
submodel.setIdentification(smId.getIdType(), smId.getId());
// - Add example properties to sub model
Property prop1 = new Property(7);
prop1.setIdShort("prop1");
- submodel.addSubModelElement(prop1);
+ submodel.addSubmodelElement(prop1);
Property prop2 = new Property("myStr");
prop2.setIdShort("prop2");
- submodel.addSubModelElement(prop2);
+ submodel.addSubmodelElement(prop2);
// - Retrieve submodel using the SDK connector
- manager.createSubModel(aasId, submodel);
- ISubModel sm = manager.retrieveSubModel(aasId, smId);
+ manager.createSubmodel(aasId, submodel);
+ ISubmodel sm = manager.retrieveSubmodel(aasId, smId);
// - check id and properties
IProperty prop1Connected = sm.getProperties().get("prop1");
@@ -114,9 +131,123 @@
assertEquals(smId.getId(), sm.getIdentification().getId());
assertEquals(smId.getIdType(), sm.getIdentification().getIdType());
assertEquals("prop1", prop1Connected.getIdShort());
- assertEquals(7, prop1Connected.get());
+ assertEquals(7, prop1Connected.getValue());
assertEquals("prop2", prop2Connected.getIdShort());
- assertEquals("myStr", prop2Connected.get());
+ assertEquals("myStr", prop2Connected.getValue());
}
+ @Test
+ public void testDeleteSubmodel() {
+ IIdentifier aasId = new Identifier(IdentifierType.CUSTOM, "aasId");
+ String aasIdShort = "aasName";
+
+ IIdentifier smId = new Identifier(IdentifierType.CUSTOM, "smId");
+ String smIdShort = "smName";
+
+ IModelProvider provider = new AASAggregatorProvider(new AASAggregator());
+ prepareConnectorProvider(provider);
+
+ AssetAdministrationShell aas = createTestAAS(aasId, aasIdShort);
+ manager.createAAS(aas, "/shells");
+
+ Submodel sm = new Submodel(smIdShort, smId);
+ manager.createSubmodel(aasId, sm);
+
+ // Assert everything was created correctly
+ IAssetAdministrationShell connectedAAS = manager.retrieveAAS(aasId);
+ ISubmodel connectedSm = connectedAAS.getSubmodels().get(sm.getIdShort());
+
+ assertEquals(sm.getIdShort(), connectedSm.getIdShort());
+
+ manager.deleteSubmodel(aasId, smId);
+ assertFalse(connectedAAS.getSubmodels().containsKey(smIdShort));
+ }
+
+ @Test
+ public void testDeleteAAS() {
+ IIdentifier aasId = new Identifier(IdentifierType.CUSTOM, "aasId");
+ String aasIdShort = "aasName";
+
+ IModelProvider provider = new AASAggregatorProvider(new AASAggregator());
+ prepareConnectorProvider(provider);
+
+ AssetAdministrationShell aas = createTestAAS(aasId, aasIdShort);
+ manager.createAAS(aas, "/shells");
+ manager.deleteAAS(aas.getIdentification());
+ try {
+ manager.retrieveAAS(aas.getIdentification());
+ fail();
+ } catch (ResourceNotFoundException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * Tries to retrieve a nonexistent AAS
+ */
+ @Test
+ public void testRetrieveNonexistentAAS() {
+ IModelProvider provider = new AASAggregatorProvider(new AASAggregator());
+ prepareConnectorProvider(provider);
+
+ IIdentifier nonexistentAASId = new Identifier(IdentifierType.CUSTOM, "nonexistentAAS");
+
+ // Try to retrieve a nonexistent AAS
+ try {
+ manager.retrieveAAS(nonexistentAASId);
+ fail();
+ } catch (ResourceNotFoundException e) {
+ }
+ }
+
+ /**
+ * Tries to retrieve a nonexistent Submodel from a nonexistent AAS
+ */
+ @Test
+ public void testRetrieveNonexistentSMFromNonexistentSM() {
+ IModelProvider provider = new AASAggregatorProvider(new AASAggregator());
+ prepareConnectorProvider(provider);
+
+ IIdentifier nonexistentAASId = new Identifier(IdentifierType.CUSTOM, "nonexistentAAS");
+ IIdentifier nonexistentSMId = new Identifier(IdentifierType.CUSTOM, "nonexistentSM");
+
+ // Try to retrieve a nonexistent Submodel from a nonexistent AAS
+ try {
+ manager.retrieveSubmodel(nonexistentAASId, nonexistentSMId);
+ fail();
+ } catch (ResourceNotFoundException e) {
+ }
+ }
+
+ /**
+ * Tries to retrieve a nonexistent Submodel from an existing AAS
+ */
+ @Test
+ public void testRetrieveNonexistentSMFromExistentAAS() {
+ IModelProvider provider = new AASAggregatorProvider(new AASAggregator());
+ prepareConnectorProvider(provider);
+
+ IIdentifier aasId = new Identifier(IdentifierType.CUSTOM, "aasId");
+ IIdentifier nonexistentSMId = new Identifier(IdentifierType.CUSTOM, "nonexistentSM");
+
+ // Try to retrieve a nonexistent Submodel from an existing AAS
+ try {
+ manager.retrieveSubmodel(aasId, nonexistentSMId);
+ fail();
+ } catch (ResourceNotFoundException e) {
+ }
+ }
+
+ /**
+ * @param provider
+ */
+ private void prepareConnectorProvider(IModelProvider provider) {
+ connectorProvider.addMapping("", new VABElementProxy("", provider));
+ connectorProvider.addMapping("shells", new VABElementProxy("shells", provider));
+ }
+
+ private AssetAdministrationShell createTestAAS(IIdentifier aasId, String aasIdShort) {
+ AssetAdministrationShell aas = new AssetAdministrationShell(aasIdShort, aasId, new Asset("assetIdShort", new ModelUrn("assetId"), AssetKind.INSTANCE));
+ return aas;
+ }
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/AssetAdministrationShellSuite.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/AssetAdministrationShellSuite.java
index 6c1d626..d8aa3b3 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/AssetAdministrationShellSuite.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/AssetAdministrationShellSuite.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.aas.metamodel;
import static org.junit.Assert.assertEquals;
@@ -5,12 +14,15 @@
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.List;
import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.CustomId;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
import org.eclipse.basyx.submodel.metamodel.api.qualifier.IAdministrativeInformation;
@@ -19,12 +31,13 @@
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.AdministrativeInformation;
import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
import org.junit.Test;
@@ -71,11 +84,9 @@
* setters, additional tests for setters are needed. Currently, this is tested
* implicitly
*/
- // Create an AAS containing a reference to the created SubModel
- AssetAdministrationShell aas = new AssetAdministrationShell();
- aas.setIdShort(AASIDSHORT);
- aas.setIdentification(AASID);
- aas.addSubModel(retrieveBaselineSM());
+ // Create an AAS containing a reference to the created Submodel
+ AssetAdministrationShell aas = new AssetAdministrationShell(AASIDSHORT, AASID, new Asset("assetIdShort", new CustomId("assetId"), AssetKind.INSTANCE));
+ aas.addSubmodel(retrieveBaselineSM());
aas.setAssetReference(EXPECTED_ASSETREF);
aas.setDerivedFrom(EXPECTED_DERIVEDFROMREF);
aas.setAdministration(EXPECTED_ADMINISTRATIVEINFORMATION);
@@ -89,21 +100,19 @@
*
* @return
*/
- protected static SubModel retrieveBaselineSM() {
+ protected static Submodel retrieveBaselineSM() {
/*
* ! Caution: If the Submodel is constructed in any way that is not using the
* setters, additional tests for setters are needed. Currently, this is tested
* implicitly
*/
- // Create a SubModel containing no operations and one property
+ // Create a Submodel containing no operations and one property
Property p = new Property(PROPVAL);
p.setIdShort(PROPID);
- SubModel sm = new SubModel();
- sm.addSubModelElement(p);
- sm.setIdShort(SMIDSHORT);
- sm.setIdentification(SMID.getIdType(), SMID.getId());
+ Submodel sm = new Submodel(SMIDSHORT, SMID);
+ sm.addSubmodelElement(p);
return sm;
}
@@ -125,7 +134,7 @@
}
/**
- * Tests retrieving the contained SubModels
+ * Tests retrieving the contained Submodels
*
* @throws Exception
*/
@@ -133,16 +142,16 @@
public void testGetSubmodel() throws Exception {
IAssetAdministrationShell shell = retrieveShell();
- // Check if the number of SubModels is as expected
- assertEquals(1, shell.getSubModels().size());
+ // Check if the number of Submodels is as expected
+ assertEquals(1, shell.getSubmodels().size());
- // Check if the contained SubModel id is as expected
- assertTrue(shell.getSubModels().containsKey(SMIDSHORT));
+ // Check if the contained Submodel id is as expected
+ assertTrue(shell.getSubmodels().containsKey(SMIDSHORT));
// Check if the submodel has been retrieved correctly
- ISubModel sm = shell.getSubModels().get(SMIDSHORT);
+ ISubmodel sm = shell.getSubmodels().get(SMIDSHORT);
IProperty prop = sm.getProperties().get(PROPID);
- assertEquals(PROPVAL, prop.get());
+ assertEquals(PROPVAL, prop.getValue());
}
/**
@@ -167,13 +176,14 @@
// Create a submodel
String smId = "newSubmodelId";
String testId = "smIdTest";
- SubModel subModel = new SubModel(Collections.singletonList(new Property("testProperty")));
- subModel.setIdentification(IdentifierType.CUSTOM, testId);
- subModel.setIdShort(smId);
+ Submodel subModel = new Submodel(smId, new ModelUrn(testId));
+ Property prop = new Property("prop1", ValueType.String);
+ prop.setValue("testProperty");
+ subModel.addSubmodelElement(prop);
//Retrieve the aas
IAssetAdministrationShell shell = retrieveShell();
- shell.addSubModel(subModel);
+ shell.addSubmodel(subModel);
// Create the expected reference for assertion
List<IKey> expected1Keys = new ArrayList<>();
@@ -184,7 +194,7 @@
List<IKey> expected2Keys = new ArrayList<>();
expected2Keys.add(new Key(KeyElements.ASSETADMINISTRATIONSHELL, true, AASID.getId(), AASID.getIdType()));
- expected2Keys.add(new Key(KeyElements.SUBMODEL, true, testId, IdentifierType.CUSTOM));
+ expected2Keys.add(new Key(KeyElements.SUBMODEL, true, testId, IdentifierType.IRI));
Reference expected2 = new Reference(expected2Keys);
Collection<IReference> smReferences = shell.getSubmodelReferences();
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/connected/TestConnectedAssetAdministrationShell.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/connected/TestConnectedAssetAdministrationShell.java
index b9ee20b..6c2ffca 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/connected/TestConnectedAssetAdministrationShell.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/connected/TestConnectedAssetAdministrationShell.java
@@ -1,21 +1,36 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.aas.metamodel.connected;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.connected.ConnectedAssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
import org.eclipse.basyx.aas.restapi.AASModelProvider;
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
+import org.eclipse.basyx.aas.restapi.MultiSubmodelProvider;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
import org.eclipse.basyx.testsuite.regression.aas.metamodel.AssetAdministrationShellSuite;
import org.eclipse.basyx.testsuite.regression.vab.gateway.ConnectorProviderStub;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
import org.eclipse.basyx.vab.support.TypeDestroyer;
import org.junit.Before;
+import org.junit.Test;
/**
* Tests the connected implementation of {@link IAssetAdministrationShell} based
@@ -30,20 +45,20 @@
@Before
public void build() throws Exception {
- VABMultiSubmodelProvider provider = new VABMultiSubmodelProvider();
+ MultiSubmodelProvider provider = new MultiSubmodelProvider();
AssetAdministrationShell shell = retrieveBaselineShell();
provider.setAssetAdministrationShell(new AASModelProvider(AssetAdministrationShell.createAsFacade(TypeDestroyer.destroyType(shell))));
- SubModel sm = retrieveBaselineSM();
+ Submodel sm = retrieveBaselineSM();
sm.setParent(shell.getReference());
- provider.addSubmodel(SMIDSHORT, new SubModelProvider(SubModel.createAsFacade(TypeDestroyer.destroyType(sm))));
+ provider.addSubmodel(new SubmodelProvider(Submodel.createAsFacade(TypeDestroyer.destroyType(sm))));
// Create AAS registry
- IAASRegistryService registry = new InMemoryRegistry();
+ IAASRegistry registry = new InMemoryRegistry();
// Create AAS Descriptor
AASDescriptor aasDescriptor = new AASDescriptor(AASID, "/aas");
// Create Submodel Descriptor
- SubmodelDescriptor smDescriptor2 = new SubmodelDescriptor(SMIDSHORT, SMID, "/aas/submodels/" + SMIDSHORT);
+ SubmodelDescriptor smDescriptor2 = new SubmodelDescriptor(SMIDSHORT, SMID, "/aas/submodels/" + SMIDSHORT + "/submodel");
// Add Submodel descriptor to aas descriptor
aasDescriptor.addSubmodelDescriptor(smDescriptor2);
@@ -65,4 +80,24 @@
protected ConnectedAssetAdministrationShell retrieveShell() {
return connectedAAS;
}
+
+ @Test
+ public void testGetSpecificSubmodel() {
+ ISubmodel sm = retrieveShell().getSubmodel(SMID);
+ assertEquals(SMIDSHORT, sm.getIdShort());
+ }
+
+ @Test
+ public void testDeleteSubmodel() {
+ retrieveShell().removeSubmodel(SMID);
+ assertFalse(retrieveShell().getSubmodels().containsKey(SMIDSHORT));
+ }
+
+ @Test
+ public void testGetLocalCopy() {
+ AASModelProvider aasProvider = new AASModelProvider(retrieveBaselineShell());
+ ConnectedAssetAdministrationShell localCAAS = new ConnectedAssetAdministrationShell(new VABElementProxy("", aasProvider));
+
+ assertEquals(retrieveBaselineShell(), localCAAS.getLocalCopy());
+ }
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/TestAasEnv.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/TestAasEnv.java
new file mode 100644
index 0000000..eb658bb
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/TestAasEnv.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.aas.metamodel.map;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
+import org.eclipse.basyx.aas.metamodel.map.AasEnv;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
+import org.eclipse.basyx.submodel.metamodel.map.parts.ConceptDescription;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.junit.Test;
+
+public class TestAasEnv {
+
+
+ @Test
+ public void testAssetsGetSet() {
+ AasEnv env = new AasEnv();
+ Asset asset = new Asset();
+ asset.setIdShort("TestAasEnv");
+ env.setAssets(Arrays.asList(asset));
+ assertEquals(asset, env.getAssets().toArray()[0]);
+ }
+
+ @Test
+ public void testAssetAdministrationShellGetSet() {
+ AasEnv env = new AasEnv();
+ AssetAdministrationShell ass = new AssetAdministrationShell();
+ ass.setIdShort("TestAasEnv");
+ env.setAssetAdministrationShells(Arrays.asList(ass));
+ assertEquals(ass, env.getAssetAdministrationShells().toArray()[0]);
+ }
+
+ @Test
+ public void testConceptDescriptionsGetSet() {
+ AasEnv env = new AasEnv();
+ ConceptDescription conceptDescriptions = new ConceptDescription();
+ conceptDescriptions.setIdShort("TestAasEnv");
+ env.setConceptDescriptions(Arrays.asList(conceptDescriptions));
+ assertEquals(conceptDescriptions, env.getConceptDescriptions().toArray()[0]);
+ }
+
+ @Test
+ public void testSubmodelsGetSet() {
+ AasEnv env = new AasEnv();
+ Submodel submodels = new Submodel();
+ submodels.setIdShort("TestAasEnv");
+ env.setSubmodels(Arrays.asList(submodels));
+ assertEquals(submodels, env.getSubmodels().toArray()[0]);
+ }
+
+ @Test
+ public void testCreateAsFacade() {
+ Map<String, Object> asset = new HashMap<>();
+ asset.put(ModelType.MODELTYPE, Asset.MODELTYPE);
+ asset.put(Referable.IDSHORT, "TestAsset");
+ asset.put(Asset.KIND, AssetKind.INSTANCE);
+ asset.put(Identifiable.IDENTIFICATION, new Identifier(IdentifierType.IRI, "testAssetIdShort"));
+
+ Map<String, Object> assetAdministrationShell = new HashMap<>();
+ assetAdministrationShell.put(ModelType.MODELTYPE, AssetAdministrationShell.MODELTYPE);
+ assetAdministrationShell.put(Referable.IDSHORT, "TestAssetAdministrationShell");
+ assetAdministrationShell.put(AssetAdministrationShell.ASSET, asset);
+ assetAdministrationShell.put(Identifiable.IDENTIFICATION, new Identifier(IdentifierType.IRI, "testAASIdShort"));
+
+
+ Map<String, Object> submodel = new HashMap<>();
+ submodel.put(ModelType.MODELTYPE, Submodel.MODELTYPE);
+ submodel.put(Referable.IDSHORT, "TestSubmodel");
+ submodel.put(Submodel.SUBMODELELEMENT, new ArrayList<Object>());
+ submodel.put(Identifiable.IDENTIFICATION, new Identifier(IdentifierType.IRI, "testSubmodelIdShort"));
+
+ Map<String, Object> conceptDescription = new HashMap<>();
+ conceptDescription.put(ModelType.MODELTYPE, ConceptDescription.MODELTYPE);
+ conceptDescription.put(Referable.IDSHORT, "TestConceptDescription");
+ conceptDescription.put(Identifiable.IDENTIFICATION, new Identifier(IdentifierType.IRI, "testConceptDesIdShort"));
+
+
+ Map<String, Object> aasEnvAsMap = new HashMap<>();
+ aasEnvAsMap.put(AasEnv.ASSETS, Arrays.asList(asset));
+ aasEnvAsMap.put(AasEnv.ASSETADMINISTRATIONSHELLS, Arrays.asList(assetAdministrationShell));
+ aasEnvAsMap.put(AasEnv.SUBMODELS, Arrays.asList(submodel));
+ aasEnvAsMap.put(AasEnv.CONCEPTDESCRIPTIONS, Arrays.asList(conceptDescription));
+
+ AasEnv aasEnv = AasEnv.createAsFacade(aasEnvAsMap);
+
+ Asset assetObj = (Asset)aasEnv.getAssets().toArray()[0];
+ assertEquals(assetObj.getIdShort(), asset.get(Referable.IDSHORT));
+ AssetAdministrationShell assetAdministrationShellObj = (AssetAdministrationShell)aasEnv.getAssetAdministrationShells().toArray()[0];
+ assertEquals(assetAdministrationShellObj.getIdShort(), assetAdministrationShell.get(Referable.IDSHORT));
+ Submodel submodelObj = (Submodel)aasEnv.getSubmodels().toArray()[0];
+ assertEquals(submodelObj.getIdShort(), submodel.get(Referable.IDSHORT));
+ ConceptDescription conceptDescriptionObj = (ConceptDescription)aasEnv.getConceptDescriptions().toArray()[0];
+ assertEquals(conceptDescriptionObj.getIdShort(), conceptDescription.get(Referable.IDSHORT));
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/TestAssetAdministrationShell.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/TestAssetAdministrationShell.java
index 80fb134..e663d24 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/TestAssetAdministrationShell.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/TestAssetAdministrationShell.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.aas.metamodel.map;
import static org.junit.Assert.assertEquals;
@@ -6,7 +15,6 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -20,12 +28,14 @@
import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
import org.eclipse.basyx.submodel.metamodel.map.dataspecification.EmbeddedDataSpecification;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
import org.eclipse.basyx.submodel.metamodel.map.parts.ConceptDescription;
import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
import org.eclipse.basyx.testsuite.regression.aas.metamodel.AssetAdministrationShellSuite;
import org.junit.Before;
import org.junit.Test;
@@ -63,17 +73,6 @@
}
@Test
- public void testSetEndpoint() {
- String endpoint = "testEndpoint.com";
- String endpointType = "http";
- shell.setEndpoint(endpoint, endpointType);
- List<HashMap<String, String>> endPoints = shell.getEndpoints();
- HashMap<String, String> map = endPoints.iterator().next();
- assertTrue(map.containsValue(endpoint));
- assertTrue(map.containsValue(endpointType));
- }
-
- @Test
public void testSetDataSpecificationReferences() {
Collection<IReference> refs = Collections.singleton(REFERENCE);
shell.setDataSpecificationReferences(refs);
@@ -111,6 +110,7 @@
shell.addConceptDescription(description);
Collection<IConceptDictionary> dictionaries = new HashSet<IConceptDictionary>();
ConceptDictionary dictionary = new ConceptDictionary();
+ dictionary.setIdShort("defaultConceptDictionary");
dictionary.addConceptDescription(description);
dictionaries.add(dictionary);
assertEquals(dictionaries, shell.getConceptDictionary());
@@ -119,19 +119,22 @@
@Test
public void testSetSubmodels() {
// Create submodels
- SubModel subModel1 = new SubModel(Collections.singletonList(new Property("testProperty1")));
- subModel1.setIdShort("newSubmodelId1");
- subModel1.setIdentification(IdentifierType.CUSTOM, "smId1");
- SubModel subModel2 = new SubModel(Collections.singletonList(new Property("testProperty2")));
- subModel2.setIdShort("newSubmodelId2");
- subModel2.setIdentification(IdentifierType.CUSTOM, "smId2");
+ Submodel subModel1 = new Submodel("newSubmodelId1", new Identifier(IdentifierType.CUSTOM, "smId1"));
+ Property prop1 = new Property("prop1Id", ValueType.String);
+ prop1.setValue("testProperty1");
+ subModel1.addSubmodelElement(prop1);
+
+ Submodel subModel2 = new Submodel("newSubmodelId2", new Identifier(IdentifierType.CUSTOM, "smId2"));
+ Property prop2 = new Property("prop2Id", ValueType.String);
+ prop2.setValue("testProperty2");
+ subModel2.addSubmodelElement(prop2);
// create a collection of descriptors and add the above descriptors
- Collection<SubModel> submodels = new ArrayList<SubModel>();
+ Collection<Submodel> submodels = new ArrayList<Submodel>();
submodels.add(subModel1);
submodels.add(subModel2);
- shell.setSubModels(submodels);
+ shell.setSubmodels(submodels);
// expect references to be set according to the descriptors
Collection<IReference> smReferences = shell.getSubmodelReferences();
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestAASDescriptor.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestAASDescriptor.java
index 2720210..25782cc 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestAASDescriptor.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestAASDescriptor.java
@@ -1,11 +1,32 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.aas.metamodel.map.descriptor;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelDescriptor;
import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.junit.Before;
import org.junit.Test;
/**
@@ -15,24 +36,107 @@
*
*/
public class TestAASDescriptor {
+
+ private Map<String, Object> map;
+
+ @Before
+ public void initialize() {
+ map = new HashMap<String, Object>();
+ map.put(Referable.IDSHORT, "123");
+ map.put(Identifiable.IDENTIFICATION, new Identifier(IdentifierType.IRDI, "123"));
+ map.put(ModelDescriptor.ENDPOINTS, Arrays.asList(new HashMap<String, String>()));
+ map.put(AssetAdministrationShell.SUBMODELS, new HashSet<SubmodelDescriptor>());
+ }
/**
* Tests retrieval of all registered submodel descriptors
*/
@Test
- public void testGetAllSubModels() {
+ public void testGetAllSubmodels() {
// Setup descriptor and add one submodel descriptor
AASDescriptor descriptor = new AASDescriptor(new Identifier(IdentifierType.CUSTOM, "Test"), "http://a.b/c/aas");
descriptor.addSubmodelDescriptor(new SubmodelDescriptor("SM1", new Identifier(IdentifierType.CUSTOM, "SM1"), "http://a.b/c/aas/submodels/SM1"));
// Assert correct retrieval
- assertEquals(1, descriptor.getSubModelDescriptors().size());
- assertEquals("SM1", descriptor.getSubModelDescriptors().iterator().next().getIdentifier().getId());
+ assertEquals(1, descriptor.getSubmodelDescriptors().size());
+ assertEquals("SM1", descriptor.getSubmodelDescriptors().iterator().next().getIdentifier().getId());
// Add a second descriptor
descriptor.addSubmodelDescriptor(new SubmodelDescriptor("SM2", new Identifier(IdentifierType.CUSTOM, "SM2"), "http://a.b/c/aas/submodels/SM2"));
// Assert correct retrieval
- assertEquals(2, descriptor.getSubModelDescriptors().size());
+ assertEquals(2, descriptor.getSubmodelDescriptors().size());
+ }
+
+ @Test(expected = MalformedRequestException.class)
+ public void testValidateNoIdShort() {
+ map.remove(Referable.IDSHORT);
+ new AASDescriptor(map);
+ }
+
+ @Test(expected = MalformedRequestException.class)
+ public void testValidateNullIdShort() {
+ map.put(Referable.IDSHORT, null);
+ new AASDescriptor(map);
+ }
+
+ @Test(expected = MalformedRequestException.class)
+ public void testValidateWrongIdShort() {
+ map.put(Referable.IDSHORT, 0);
+ new AASDescriptor(map);
+ }
+
+ @Test(expected = MalformedRequestException.class)
+ public void testValidateNoIdentification() {
+ map.remove(Identifiable.IDENTIFICATION);
+ new AASDescriptor(map);
+ }
+
+ @Test(expected = MalformedRequestException.class)
+ public void testValidateNullIdentification() {
+ map.put(Identifiable.IDENTIFICATION, null);
+ new AASDescriptor(map);
+ }
+
+ @Test(expected = MalformedRequestException.class)
+ public void testValidateWrongdentification() {
+ map.put(Identifiable.IDENTIFICATION, "testId");
+ new AASDescriptor(map);
+ }
+
+ @Test(expected = MalformedRequestException.class)
+ public void testValidateNoEndpoints() {
+ map.remove(ModelDescriptor.ENDPOINTS);
+ new AASDescriptor(map);
+ }
+
+ @Test(expected = MalformedRequestException.class)
+ public void testValidateNullEndpoints() {
+ map.put(ModelDescriptor.ENDPOINTS, null);
+ new AASDescriptor(map);
+ }
+
+ @Test(expected = MalformedRequestException.class)
+ public void testValidateWrongEndpoints() {
+ map.put(ModelDescriptor.ENDPOINTS, "testEndpoint");
+ new AASDescriptor(map);
+ }
+
+ @Test
+ public void testValidateNoSubmodels() {
+ map.remove(AssetAdministrationShell.SUBMODELS);
+ assertNotNull(new AASDescriptor(map).getSubmodelDescriptors());
+ }
+
+ @Test(expected = MalformedRequestException.class)
+ public void testValidateNullSubmodels() {
+ map.put(AssetAdministrationShell.SUBMODELS, null);
+ new AASDescriptor(map).getSubmodelDescriptors();
+ }
+
+ @Test(expected = MalformedRequestException.class)
+ public void testValidateWrongSubmodels() {
+ map.put(AssetAdministrationShell.SUBMODELS, "testSubmodel");
+ new AASDescriptor(map).getSubmodelDescriptors();
}
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestModelUrn.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestModelUrn.java
index 5e31d2a..044ec7d 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestModelUrn.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestModelUrn.java
@@ -1,8 +1,20 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.aas.metamodel.map.descriptor;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
import org.junit.Test;
/**
@@ -25,7 +37,7 @@
public void testConstructor2() {
String legalEntity = "testLegalEntity";
String subUnit = "testSubUnit";
- String subModel = "testSubModel";
+ String subModel = "testSubmodel";
String version = "1.0";
String revision = "5";
String elementId = "testId";
@@ -34,6 +46,7 @@
ModelUrn modelUrn = new ModelUrn(legalEntity, subUnit, subModel, version, revision, elementId, elementInstance);
String appendedString = "urn:" + legalEntity + ":" + subUnit + ":" + subModel + ":" + version + ":" + revision + ":" + elementId + "#"+ elementInstance;
assertEquals(appendedString, modelUrn.getURN());
+ assertEquals(IdentifierType.IRI, modelUrn.getIdType());
}
@Test
@@ -43,4 +56,10 @@
ModelUrn newModelUrn = modelUrn.append(suffix);
assertEquals(rawURN + suffix, newModelUrn.getURN());
}
+
+ @Test
+ public void testValidIdentifier() {
+ ModelUrn modelUrn = new ModelUrn(rawURN);
+ assertTrue(Identifier.isValid(modelUrn));
+ }
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestSubmodelDescriptor.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestSubmodelDescriptor.java
index 55adcb4..e62df53 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestSubmodelDescriptor.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestSubmodelDescriptor.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.aas.metamodel.map.descriptor;
import static org.junit.Assert.assertEquals;
@@ -9,7 +18,7 @@
import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
@@ -31,7 +40,7 @@
*/
public class TestSubmodelDescriptor {
private static final IdentifierType ID_TYPE = IdentifierType.CUSTOM;
- private static final String HTTP_ENDPOINT = "testEnd";
+ private static final String HTTP_ENDPOINT = "testEnd/submodel";
private static final String ID_SHORT_STRING = "testIdShort";
private static final Identifier IDENTIFIER = new Identifier(ID_TYPE, ID_SHORT_STRING);
@@ -51,7 +60,7 @@
Formula formula = new Formula(Collections.singleton(new Reference(new Key(KeyElements.BLOB, true, "TestValue", IdentifierType.IRI))));
Qualifiable qualifiable = new Qualifiable(formula);
HasDataSpecification hasDataSpecification = new HasDataSpecification(new ArrayList<>(), Collections.singleton(reference));
- SubModel subModel = new SubModel(hasSemantics, identifiable, qualifiable, hasDataSpecification, hasKind);
+ Submodel subModel = new Submodel(hasSemantics, identifiable, qualifiable, hasDataSpecification, hasKind);
SubmodelDescriptor descriptor = new SubmodelDescriptor(subModel, HTTP_ENDPOINT);
assertEquals(HTTP_ENDPOINT, descriptor.getFirstEndpoint());
@@ -66,4 +75,4 @@
assertEquals(ID_SHORT_STRING, descriptor.getIdShort());
assertEquals(IDENTIFIER, descriptor.getIdentifier());
}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestAsset.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestAsset.java
index 54dcbde..4062b94 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestAsset.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestAsset.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.aas.metamodel.map.parts;
import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestConceptDictionary.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestConceptDictionary.java
index 51db72e..17737d7 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestConceptDictionary.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestConceptDictionary.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.aas.metamodel.map.parts;
import static org.junit.Assert.assertEquals;
@@ -39,7 +48,8 @@
public void buildConceptDictionary() {
List<IReference> refs = new ArrayList<>();
refs.add(REFERENCE);
- dictionary = new ConceptDictionary(refs);
+ dictionary = new ConceptDictionary("testIdShort");
+ dictionary.setConceptDescriptionReferences(refs);
}
@Test
@@ -86,9 +96,9 @@
@Test
public void testSetConceptDescriptions() {
- ConceptDescription description1 = new ConceptDescription();
+ ConceptDescription description1 = new ConceptDescription("testIdShort1", new Identifier(IdentifierType.IRDI, "testIdShort1"));
description1.setCategory("cat1");
- ConceptDescription description2 = new ConceptDescription();
+ ConceptDescription description2 = new ConceptDescription("testIdShort2", new Identifier(IdentifierType.IRDI, "testIdShort2"));
description2.setCategory("cat2");
Collection<IConceptDescription> descriptions = new ArrayList<IConceptDescription>();
descriptions.add(description1);
@@ -101,8 +111,7 @@
public void testAddConceptDescription() {
IdentifierType idType = IdentifierType.IRI;
String id = "testId";
- ConceptDescription description = new ConceptDescription();
- description.setIdentification(idType, id);
+ ConceptDescription description = new ConceptDescription("testIdShort", new Identifier(idType, id));
description.setCategory("testCategory");
dictionary.addConceptDescription(description);
assertEquals(Collections.singletonList(description), dictionary.getConceptDescriptions());
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestView.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestView.java
index 669472a..eb5fd09 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestView.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestView.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.aas.metamodel.map.parts;
import static org.junit.Assert.assertEquals;
@@ -34,7 +43,8 @@
@Before
public void buildConceptDictionary() {
- view = new View(Collections.singleton(REFERENCE));
+ view = new View("testIdShort");
+ view.setContainedElement(Collections.singleton(REFERENCE));
references = new HashSet<IReference>();
references.add(REFERENCE);
references.add(REFERENCE2);
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/policypoints/TestAccessControlPolicyPoints.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/policypoints/TestAccessControlPolicyPoints.java
index a7bebae..ef52a64 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/policypoints/TestAccessControlPolicyPoints.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/policypoints/TestAccessControlPolicyPoints.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.aas.metamodel.map.policypoints;
import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/security/TestSecurity.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/security/TestSecurity.java
index e116091..d83bf01 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/security/TestSecurity.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/security/TestSecurity.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.aas.metamodel.map.security;
import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/TestRegistryProviderSuite.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/TestRegistryProviderSuite.java
index 7829405..57e3a43 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/TestRegistryProviderSuite.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/TestRegistryProviderSuite.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.aas.registration;
import static org.junit.Assert.assertEquals;
@@ -12,7 +21,7 @@
import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
@@ -32,7 +41,7 @@
*/
public abstract class TestRegistryProviderSuite {
// The registry proxy that is used to access the sql servlet
- protected final IAASRegistryService proxy = getRegistryService();
+ protected final IAASRegistry proxy = getRegistryService();
// Ids, shortIds and endpoints for registered AAS and submodel
protected IIdentifier aasId1 = new ModelUrn("urn:de.FHG:devices.es.iese/test:aas:1.0:1:registryAAS#001");
@@ -45,15 +54,15 @@
protected String smIdShort2 = "smIdShort2";
protected String aasEndpoint1 = "http://www.registrytest.de/aas01/aas";
protected String aasEndpoint2 = "http://www.registrytest.de/aas02/aas";
- protected String smEndpoint1 = "http://www.registrytest.de/aas01/aas/submodels/" + smIdShort1;
- protected String smEndpoint2 = "http://www.registrytest.de/aas01/aas/submodels/" + smIdShort2;
+ protected String smEndpoint1 = "http://www.registrytest.de/aas01/aas/submodels/" + smIdShort1 + "/submodel";
+ protected String smEndpoint2 = "http://www.registrytest.de/aas01/aas/submodels/" + smIdShort2 + "/submodel";
protected Asset asset1;
protected Asset asset2;
/**
* Getter for the tested registry provider. Tests for actual registry provider
* have to realize this method.
*/
- protected abstract IAASRegistryService getRegistryService();
+ protected abstract IAASRegistry getRegistryService();
/**
* Before each test, clean entries are created in the registry using a proxy
@@ -63,8 +72,10 @@
// Create assets
asset1 = new Asset(new Reference(new Identifier(IdentifierType.CUSTOM, "asset001"), KeyElements.ASSET, false));
asset1.setIdentification(IdentifierType.CUSTOM, "asset001");
+ asset1.setIdShort("asset001");
asset2 = new Asset(new Reference(new Identifier(IdentifierType.CUSTOM, "asset002"), KeyElements.ASSET, false));
asset2.setIdentification(IdentifierType.CUSTOM, "asset002");
+ asset2.setIdShort("asset002");
// Create descriptors for AAS and submodels
AASDescriptor aasDesc1 = new AASDescriptor(aasIdShort1, aasId1, asset1, aasEndpoint1);
aasDesc1.addSubmodelDescriptor(new SubmodelDescriptor(smIdShort1, smId1, smEndpoint1));
@@ -125,7 +136,7 @@
* Checks, if the given descriptor is valid. Should contain the values of the first descriptor
* as given by the test setup
*/
- private void validateDescriptor1(AASDescriptor descriptor) {
+ protected void validateDescriptor1(AASDescriptor descriptor) {
assertEquals(aasId1.getId(), descriptor.getIdentifier().getId());
assertEquals(aasId1.getIdType(), descriptor.getIdentifier().getIdType());
IAsset asset = descriptor.getAsset();
@@ -133,7 +144,7 @@
assertEquals(aasEndpoint1, descriptor.getFirstEndpoint());
// Check, if the SM descriptor in the AASDescriptor is correct
- SubmodelDescriptor smDescriptor = descriptor.getSubModelDescriptorFromIdentifierId(smId1.getId());
+ SubmodelDescriptor smDescriptor = descriptor.getSubmodelDescriptorFromIdentifierId(smId1.getId());
assertEquals(smId1.getId(), smDescriptor.getIdentifier().getId());
assertEquals(smId1.getIdType(), smDescriptor.getIdentifier().getIdType());
assertEquals(smIdShort1, smDescriptor.get(Referable.IDSHORT));
@@ -144,7 +155,7 @@
* Checks, if the given descriptor is valid. Should contain the values of the second descriptor
* as given by the test setup
*/
- private void validateDescriptor2(AASDescriptor descriptor) {
+ protected void validateDescriptor2(AASDescriptor descriptor) {
assertEquals(aasId2.getId(), descriptor.getIdentifier().getId());
assertEquals(aasId2.getIdType(), descriptor.getIdentifier().getIdType());
IAsset asset = descriptor.getAsset();
@@ -152,6 +163,42 @@
assertEquals(aasEndpoint2, descriptor.getFirstEndpoint());
}
+ @Test
+ public void testDeleteWithAssetExtension() {
+ // After the setup, both AAS should have been inserted to the registry
+ assertNotNull(proxy.lookupAAS(aasId1));
+ assertNotNull(proxy.lookupAAS(aasId2));
+
+ proxy.delete(aasId2);
+
+ // After aas2 has been deleted, only aas1 should be registered
+ assertNotNull(proxy.lookupAAS(asset1.getIdentification()));
+
+ // Reference of asset-id to the AAS descriptor should also to deleted
+ try {
+ proxy.lookupAAS(asset2.getIdentification());
+ fail();
+ } catch (ResourceNotFoundException e) {
+ // expected
+ }
+
+ proxy.delete(aasId1);
+
+ // Reference of both asset-ids to the AAS descriptors should also to deleted
+ try {
+ proxy.lookupAAS(asset1.getIdentification());
+ fail();
+ } catch (ResourceNotFoundException e) {
+ // expected
+ }
+ try {
+ proxy.lookupAAS(asset2.getIdentification());
+ fail();
+ } catch (ResourceNotFoundException e) {
+ // expected
+ }
+ }
+
/**
* Tests deletion for aas entries
*/
@@ -165,7 +212,6 @@
// After aas2 has been deleted, only aas1 should be registered
assertNotNull(proxy.lookupAAS(aasId1));
- assertNotNull(proxy.lookupAAS(asset1.getIdentification()));
try {
proxy.lookupAAS(aasId2);
fail();
@@ -173,14 +219,6 @@
// expected
}
- // Reference of asset-id to the AAS descriptor should also to deleted
- try {
- proxy.lookupAAS(asset2.getIdentification());
- fail();
- } catch (ResourceNotFoundException e) {
- // expected
- }
-
proxy.delete(aasId1);
// After aas1 has been deleted, both should not be registered any more
@@ -196,16 +234,27 @@
} catch (ResourceNotFoundException e) {
// expected
}
+ }
- // Reference of both asset-ids to the AAS descriptors should also to deleted
+ /**
+ * Tests deletion for aas entries
+ */
+ @Test
+ public void testDeleteByAssetIdCall() {
+ proxy.delete(asset1.getIdentification());
+
+ // After aas1 has been deleted, only aas2 should be registered
+ assertNotNull(proxy.lookupAAS(aasId2));
+ assertNotNull(proxy.lookupAAS(asset2.getIdentification()));
try {
- proxy.lookupAAS(asset1.getIdentification());
+ proxy.lookupAAS(aasId1);
fail();
} catch (ResourceNotFoundException e) {
// expected
}
+
try {
- proxy.lookupAAS(asset2.getIdentification());
+ proxy.lookupAAS(asset1.getIdentification());
fail();
} catch (ResourceNotFoundException e) {
// expected
@@ -214,12 +263,12 @@
@Test(expected = ResourceNotFoundException.class)
public void testDeleteNotExistingSubmodelFromNotExistingAAS() {
- proxy.delete(new Identifier(IdentifierType.CUSTOM, "nonExistent"), "nonExistentSubModelId");
+ proxy.delete(new Identifier(IdentifierType.CUSTOM, "nonExistent"), new Identifier(IdentifierType.CUSTOM, "nonExistentSubmodelId"));
}
@Test(expected = ResourceNotFoundException.class)
- public void testDeleteNotExistingSubModel() {
- proxy.delete(aasId1, "nonExistentSubModelId");
+ public void testDeleteNotExistingSubmodel() {
+ proxy.delete(aasId1, new Identifier(IdentifierType.CUSTOM, "nonExistentSubmodelId"));
}
@Test(expected = ResourceNotFoundException.class)
@@ -227,12 +276,25 @@
proxy.delete(new Identifier(IdentifierType.CUSTOM, "nonExistent"));
}
+ @Test
+ public void testRetrieveSubmodelDescriptors() {
+ List<SubmodelDescriptor> descs = proxy.lookupSubmodels(aasId1);
+ assertEquals(1, descs.size());
+ assertEquals(smIdShort1, descs.get(0).getIdShort());
+ }
+
+ @Test
+ public void testRetrieveSpecificSubmodelDescriptor() {
+ SubmodelDescriptor desc = proxy.lookupSubmodel(aasId1, smId1);
+ assertEquals(smIdShort1, desc.getIdShort());
+ }
+
/**
* Tests overwriting the descriptor of an AAS
*/
@Test
public void testOverwritingAASDescriptor() {
- AASDescriptor aasDesc2 = new AASDescriptor(aasIdShort2, aasId2, asset2, "TestEndpoint");
+ AASDescriptor aasDesc2 = new AASDescriptor(aasIdShort2, aasId2, asset2, "http://testendpoint2/");
proxy.register(aasDesc2);
AASDescriptor retrieved = proxy.lookupAAS(aasId2);
assertEquals(aasDesc2.getFirstEndpoint(), retrieved.getFirstEndpoint());
@@ -252,17 +314,22 @@
assertEquals(smDesc, aasDesc.getSubmodelDescriptorFromIdShort(smIdShort2));
// Test overwriting an SM descriptor
- SubmodelDescriptor smDescNew = new SubmodelDescriptor(smIdShort2, smId2, "TestEndpoint");
+ SubmodelDescriptor smDescNew = new SubmodelDescriptor(smIdShort2, smId2, "http://testendpoint2/submodel/");
proxy.register(aasId1, smDescNew);
AASDescriptor aasDescNew = proxy.lookupAAS(aasId1);
assertEquals(smDescNew.getFirstEndpoint(), aasDescNew.getSubmodelDescriptorFromIdShort(smIdShort2).getFirstEndpoint());
// Remove Submodel
- proxy.delete(aasId1, smIdShort2);
+ proxy.delete(aasId1, smId2);
// Ensure that the submodel was correctly removed
aasDesc = proxy.lookupAAS(aasId1);
assertNotNull(aasDesc.getSubmodelDescriptorFromIdShort(smIdShort1));
assertNull(aasDesc.getSubmodelDescriptorFromIdShort(smIdShort2));
}
+
+ @Test(expected = ResourceNotFoundException.class)
+ public void testRegisterSubmodelToNotExistingAAS() {
+ proxy.register(new Identifier(IdentifierType.CUSTOM, "nonExistent"), new SubmodelDescriptor(smIdShort1, smId1, smEndpoint1));
+ }
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/memory/TestMapRegistry.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/memory/TestMapRegistry.java
index 9cb8f07..3ef1f3e 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/memory/TestMapRegistry.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/memory/TestMapRegistry.java
@@ -1,12 +1,21 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.aas.registration.memory;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
-import org.eclipse.basyx.aas.registration.memory.MapRegistry;
+import org.eclipse.basyx.aas.registration.memory.MapRegistryHandler;
import org.eclipse.basyx.testsuite.regression.aas.registration.TestRegistryProviderSuite;
/**
- * Tests functionalities of {@link MapRegistry} for their correctness
+ * Tests functionalities of {@link MapRegistryHandler} for their correctness
* Includes test cases for exceptions
*
* @author haque
@@ -15,7 +24,7 @@
public class TestMapRegistry extends TestRegistryProviderSuite {
@Override
- protected IAASRegistryService getRegistryService() {
+ protected IAASRegistry getRegistryService() {
return new InMemoryRegistry();
}
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/AASRegistryServlet.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/AASRegistryServlet.java
new file mode 100644
index 0000000..495db3f
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/AASRegistryServlet.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.aas.registration.restapi;
+
+import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
+import org.eclipse.basyx.aas.registration.restapi.AASRegistryModelProvider;
+import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
+
+/**
+ * A registry servlet based on an InMemory Registry. The servlet therefore provides an implementation
+ * for the IAASRegistryService interface without a permanent storage capability.
+ *
+ * @author espen
+ */
+public class AASRegistryServlet extends VABHTTPInterface<AASRegistryModelProvider> {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructor with ModelProvider based on an InMemoryRegistry
+ */
+ public AASRegistryServlet() {
+ super(new AASRegistryModelProvider(new InMemoryRegistry()));
+
+ }
+}
+
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/DirectoryProviderServlet.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/DirectoryProviderServlet.java
deleted file mode 100644
index b8ac0ec..0000000
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/DirectoryProviderServlet.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package org.eclipse.basyx.testsuite.regression.aas.registration.restapi;
-
-import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
-import org.eclipse.basyx.aas.registration.restapi.DirectoryModelProvider;
-import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
-
-/**
- * A registry servlet based on an InMemory Registry. The servlet therefore provides an implementation
- * for the IAASRegistryService interface without a permanent storage capability.
- *
- * @author espen
- */
-public class DirectoryProviderServlet extends VABHTTPInterface<DirectoryModelProvider> {
- private static final long serialVersionUID = 1L;
-
- /**
- * Constructor with ModelProvider based on an InMemoryRegistry
- */
- public DirectoryProviderServlet() {
- super(new DirectoryModelProvider(new InMemoryRegistry()));
-
- }
-}
-
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/TestDirectoryModelProvider.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/TestDirectoryModelProvider.java
index a4b001b..868b8b5 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/TestDirectoryModelProvider.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/TestDirectoryModelProvider.java
@@ -1,8 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.aas.registration.restapi;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
-import org.eclipse.basyx.aas.registration.restapi.DirectoryModelProvider;
+import org.eclipse.basyx.aas.registration.restapi.AASRegistryModelProvider;
import org.eclipse.basyx.testsuite.regression.aas.registration.TestRegistryProviderSuite;
/**
@@ -14,8 +23,8 @@
*/
public class TestDirectoryModelProvider extends TestRegistryProviderSuite {
@Override
- protected IAASRegistryService getRegistryService() {
- DirectoryModelProvider provider = new DirectoryModelProvider();
+ protected IAASRegistry getRegistryService() {
+ AASRegistryModelProvider provider = new AASRegistryModelProvider();
return new AASRegistryProxy(provider);
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/TestDirectoryModelProviderServlet.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/TestDirectoryModelProviderServlet.java
index 6bb8403..0fbc2fc 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/TestDirectoryModelProviderServlet.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/TestDirectoryModelProviderServlet.java
@@ -1,6 +1,15 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.aas.registration.restapi;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
import org.eclipse.basyx.testsuite.regression.aas.registration.TestRegistryProviderSuite;
import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
@@ -21,10 +30,10 @@
@Rule
public AASHTTPServerResource res = new AASHTTPServerResource(
new BaSyxContext("/basys.sdk", System.getProperty("java.io.tmpdir"))
- .addServletMapping("/Testsuite/directory/*", new DirectoryProviderServlet()));
+ .addServletMapping("/Testsuite/directory/*", new AASRegistryServlet()));
@Override
- protected IAASRegistryService getRegistryService() {
+ protected IAASRegistry getRegistryService() {
return new AASRegistryProxy("http://localhost:8080/basys.sdk/Testsuite/directory");
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiAASProviderTest.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiAASProviderTest.java
deleted file mode 100644
index a37c034..0000000
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiAASProviderTest.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/**
- *
- */
-package org.eclipse.basyx.testsuite.regression.aas.restapi;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
-
-import java.util.Map;
-
-import org.eclipse.basyx.aas.restapi.MultiAASProvider;
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.testsuite.regression.submodel.restapi.SimpleAASSubmodel;
-import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
-import org.eclipse.basyx.vab.exception.provider.ProviderException;
-import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Tests the capability to multiplex of a VABMultiAASProvider
- *
- * @author espen
- *
- */
-public class MultiAASProviderTest {
- VABElementProxy proxy;
- MultiAASProvider provider;
-
- @Before
- public void build() {
- VABConnectionManagerStub stub = new VABConnectionManagerStub();
- String urn = "urn:fhg:es.iese:aas:1:1:submodel";
- VABMultiSubmodelProvider aasProvider = new VABMultiSubmodelProvider();
- aasProvider.addSubmodel("SimpleAASSubmodel", new SubModelProvider(new SimpleAASSubmodel()));
- provider = new MultiAASProvider();
- provider.addMultiSubmodelProvider("a1", aasProvider);
- stub.addProvider(urn, "", provider);
- proxy = stub.connectToVABElement(urn);
- }
-
- @Test
- public void clearTest() {
- provider.clear();
- Object result = proxy.getModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/");
- assertNull(result);
- }
-
- @SuppressWarnings("unchecked")
- @Test
- public void getTest() {
- // test reading from a valid aas
- Map<String, Object> result = (Map<String, Object>) proxy
- .getModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty/value");
- assertEquals(123, result.get(Property.VALUE));
-
- // test reading from an invalid aas
- assertNull(proxy.getModelPropertyValue("A1/aas/submodels/SimpleAASSubmodel/"));
- }
-
- @SuppressWarnings("unchecked")
- @Test
- public void setTest() {
- // test setting in a valid aas
- proxy.setModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty/value", 100);
-
- // test setting in an invalid aas
- proxy.setModelPropertyValue("A1/aas/submodels/SimpleAASSubmodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty/value", 200);
-
- // retrieving property
- Map<String, Object> result = (Map<String, Object>) proxy
- .getModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty/value");
- assertEquals(100, result.get(Property.VALUE));
- }
-
- @SuppressWarnings("unchecked")
- @Test
- public void removeTest() {
- // test deleting from an invalid aas
- proxy.deleteValue("A1/aas/submodels/SimpleAASSubmodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty/value");
- Map<String, Object> result = (Map<String, Object>) proxy
- .getModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty/value");
- assertEquals(123, result.get(Property.VALUE));
-
- // test deleting from a valid aas
- proxy.deleteValue("a1/aas/submodels/SimpleAASSubmodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty");
- try {
- proxy.getModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty/");
- fail();
- } catch (ResourceNotFoundException e) {
- }
- }
-
- @Test
- public void invokeExceptionTest() {
- // Invoke exception1
- try {
- proxy.invokeOperation("a1/aas/submodels/SimpleAASSubmodel/operations/exception1");
- fail();
- } catch (ProviderException e) {
- assertEquals(NullPointerException.class, e.getCause().getClass());
- }
- // Invoke exception2
- try {
- proxy.invokeOperation("a1/aas/submodels/SimpleAASSubmodel/operations/exception2", "prop1");
- fail();
- } catch (ProviderException e) {
- assertEquals("Exception description", e.getMessage());
- }
- }
-
- @Test
- public void invokeTest() {
- // test invoking from an invalid aas
- assertNull(proxy.invokeOperation("A1/aas/submodels/SimpleAASSubmodel/operations/complex", 10, 3));
-
- // test invoking with return value
- assertEquals(7, proxy.invokeOperation("a1/aas/submodels/SimpleAASSubmodel/operations/complex", 10, 3));
- assertEquals(true, proxy.invokeOperation("a1/aas/submodels/SimpleAASSubmodel/operations/simple"));
- }
-}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiSubmodelProviderRemoteInvocationTest.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiSubmodelProviderRemoteInvocationTest.java
new file mode 100644
index 0000000..73ca6af
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiSubmodelProviderRemoteInvocationTest.java
@@ -0,0 +1,224 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.aas.restapi;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
+import org.eclipse.basyx.aas.restapi.AASModelProvider;
+import org.eclipse.basyx.aas.restapi.MultiSubmodelProvider;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
+import org.eclipse.basyx.testsuite.regression.submodel.restapi.SimpleAASSubmodel;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnectorFactory;
+import org.eclipse.basyx.vab.protocol.basyx.server.BaSyxTCPServer;
+import org.eclipse.basyx.vab.service.api.BaSyxService;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests the capability remote submodel invocation from registry
+ * in VABMultiSubmodelProvider
+ *
+ * @author haque
+ */
+public class MultiSubmodelProviderRemoteInvocationTest {
+ private static final IIdentifier AASID1 = new ModelUrn("aas");
+ private static final String AASIDSHORT1 = "aasIdShort1";
+
+ private static final IIdentifier REMOTESMID = new ModelUrn("remoteSm");
+ private static final String REMOTESMIDSHORT = "remoteSmIdShort";
+
+ private static final IIdentifier LOCALSMID = new ModelUrn("localSm");
+ private static final String LOCALSMIDSHORT = "localSmIdShort";
+
+ private static final String REMOTEPATH = "/aas/submodels/" + REMOTESMIDSHORT + "/" + SubmodelProvider.SUBMODEL;
+
+ private List<BaSyxService> services = new ArrayList<>();
+
+ private MultiSubmodelProvider provider;
+
+ // Creating a new AAS Registry
+ private IAASRegistry registry = new InMemoryRegistry();
+
+ @Before
+ public void init() {
+
+
+ // Create descriptors for AAS and submodels
+ String aasEndpoint = "basyx://localhost:8000/aas";
+ String remoteSmEndpoint = "basyx://localhost:8001/submodel";
+ String localSmEndpoint = "basyx://localhost:8000/aas/submodels/" + LOCALSMIDSHORT;
+
+ AASDescriptor aasDesc = new AASDescriptor(AASIDSHORT1, AASID1, aasEndpoint);
+ aasDesc.addSubmodelDescriptor(new SubmodelDescriptor(REMOTESMIDSHORT, REMOTESMID, remoteSmEndpoint));
+ aasDesc.addSubmodelDescriptor(new SubmodelDescriptor(LOCALSMIDSHORT, LOCALSMID, localSmEndpoint));
+
+ // Register Asset Administration Shells
+ registry.register(aasDesc);
+
+
+ // Create a VABMultiSubmodelProvider using the registry and a http connector
+ provider = new MultiSubmodelProvider(registry, new BaSyxConnectorFactory());
+
+ // Create and add an AAS to the provider with same id as the AAS in the registry
+ AssetAdministrationShell aas = new AssetAdministrationShell();
+ aas.setIdShort(AASIDSHORT1);
+ aas.setIdentification(AASID1);
+ provider.setAssetAdministrationShell(new AASModelProvider(aas));
+
+ // Create the local SM
+ Submodel localSM = new Submodel(LOCALSMIDSHORT, LOCALSMID);
+ provider.addSubmodel(new SubmodelProvider(localSM));
+
+ // Create the remote SM
+ Submodel remoteSm = new SimpleAASSubmodel(REMOTESMIDSHORT);
+ remoteSm.setIdentification(REMOTESMID.getIdType(), REMOTESMID.getId());
+
+ // Setup and start the BaSyx TCP servers
+ services.add(new BaSyxTCPServer<>(provider, 8000));
+ services.add(new BaSyxTCPServer<>(new SubmodelProvider(remoteSm), 8001));
+
+ services.forEach(b -> b.start());
+ }
+
+ /**
+ * Checks if GET is correctly forwarded by checking if the Id of the remote
+ * submodel can be retrieved
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testGetModelPropertyValue() throws Exception {
+ Submodel sm = getRemoteSubmodel();
+ assertEquals(sm.getIdentification().getId(), REMOTESMID.getId());
+ }
+
+ /**
+ * Checks if a call to "/aas/submodels" correctly includes the remote submodels
+ */
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testGetAllSubmodels() {
+ Collection<Map<String, Object>> collection = (Collection<Map<String, Object>>) provider.getValue("/aas/submodels");
+ Collection<String> smIdShorts = collection.stream().map(m -> Submodel.createAsFacade(m)).map(sm -> sm.getIdShort()).collect(Collectors.toList());
+ assertTrue(smIdShorts.contains(REMOTESMIDSHORT));
+ assertTrue(smIdShorts.contains(LOCALSMIDSHORT));
+ assertTrue(smIdShorts.size() == 2);
+ }
+
+ /**
+ * Tries to register a Submodel, not actually push it to the server and try to request all Submodels
+ * This will result in an endless loop if not handled correctly
+ */
+ @Test
+ public void testGetRegisteredButNotExistentSM() {
+ // Create a Descriptor for a Submodel (with a local Endpoint), that is not present on the server
+ SubmodelDescriptor smDescriptor = new SubmodelDescriptor("nonexist", new ModelUrn("nonexisting"), "basyx://localhost:8000/aas/submodels/nonexist");
+
+ // Register this SubmodelDescriptor
+ registry.register(AASID1, smDescriptor);
+
+ // Try to request all Submodels from the server
+ try {
+ provider.getValue("/aas/submodels");
+ fail();
+ } catch (ResourceNotFoundException e) {
+ }
+ }
+
+ /**
+ * Checks if SET is correctly forwarded by checking if a property value of the
+ * remote submodel can be changed
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testSetModelPropertyValue() throws Exception {
+ int newVal = 0;
+ String path = VABPathTools.concatenatePaths(REMOTEPATH, Submodel.SUBMODELELEMENT, SimpleAASSubmodel.INTPROPIDSHORT, Property.VALUE);
+ provider.setValue(path, newVal);
+
+ Submodel sm = getRemoteSubmodel();
+ assertEquals(newVal, sm.getProperties().get(SimpleAASSubmodel.INTPROPIDSHORT).getValue());
+ }
+
+ /**
+ * Checks if CREATE is correctly forwarded by checking if a new property can be
+ * created in the remote submodel
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testCreateModelPropertyValue() throws Exception {
+ Property p = new Property(5);
+ String testPropIdShort = "testProperty";
+ p.setIdShort(testPropIdShort);
+
+ provider.setValue(REMOTEPATH + "/submodelElements/" + testPropIdShort, p);
+
+ assertTrue(getRemoteSubmodel().getProperties().containsKey(testPropIdShort));
+ }
+
+ /**
+ * Checks if DELETE is correctly forwarded by checking if a property can be
+ * deleted in the remote submodel
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testDeleteModelPropertyValue() throws Exception {
+ String path = VABPathTools.concatenatePaths(REMOTEPATH, Submodel.SUBMODELELEMENT, SimpleAASSubmodel.INTPROPIDSHORT);
+ provider.deleteValue(path);
+ assertFalse(getRemoteSubmodel().getProperties().containsKey(SimpleAASSubmodel.INTPROPIDSHORT));
+ }
+
+ /**
+ * Checks if INVOKE is correctly forwarded by checking if an operation can be
+ * called in the remote submodel
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testInvoke() throws Exception {
+ String path = VABPathTools.concatenatePaths(REMOTEPATH, Submodel.SUBMODELELEMENT, SimpleAASSubmodel.OPERATIONSIMPLEIDSHORT, Operation.INVOKE);
+ assertTrue((Boolean) provider.invokeOperation(path));
+ }
+
+ @SuppressWarnings("unchecked")
+ private Submodel getRemoteSubmodel() {
+ return Submodel.createAsFacade((Map<String, Object>) provider.getValue(REMOTEPATH));
+ }
+
+ @After
+ public void tearDown() {
+ services.forEach(b -> b.stop());
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiSubmodelProviderTest.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiSubmodelProviderTest.java
index 9c59cfc..87c1b84 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiSubmodelProviderTest.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiSubmodelProviderTest.java
@@ -10,17 +10,20 @@
import java.util.Collection;
import java.util.Map;
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
import org.eclipse.basyx.aas.metamodel.connected.ConnectedAssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
import org.eclipse.basyx.aas.restapi.AASModelProvider;
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
+import org.eclipse.basyx.aas.restapi.MultiSubmodelProvider;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
import org.eclipse.basyx.testsuite.regression.submodel.restapi.SimpleAASSubmodel;
import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
import org.eclipse.basyx.vab.exception.provider.ProviderException;
@@ -47,13 +50,12 @@
public void build() {
VABConnectionManagerStub stub = new VABConnectionManagerStub();
String urn = "urn:fhg:es.iese:aas:1:1:submodel";
- VABMultiSubmodelProvider provider = new VABMultiSubmodelProvider();
+ MultiSubmodelProvider provider = new MultiSubmodelProvider();
+
// set dummy aas
- AssetAdministrationShell aas = new AssetAdministrationShell();
- aas.setIdShort(AASIDSHORT);
- aas.setIdentification(AASURN);
+ AssetAdministrationShell aas = new AssetAdministrationShell(AASIDSHORT, AASURN, new Asset("assetIdShort", new Identifier(IdentifierType.CUSTOM, "assetId"), AssetKind.INSTANCE));
provider.setAssetAdministrationShell(new AASModelProvider(aas));
- provider.addSubmodel("SimpleAASSubmodel", new SubModelProvider(new SimpleAASSubmodel()));
+ provider.addSubmodel(new SubmodelProvider(new SimpleAASSubmodel()));
stub.addProvider(urn, "", provider);
proxy = stub.connectToVABElement(urn);
}
@@ -65,13 +67,13 @@
public void invokeExceptionTest() {
// Invoke operationEx1
try {
- proxy.invokeOperation("/aas/submodels/SimpleAASSubmodel/operations/exception1/invokable");
+ proxy.invokeOperation("/aas/submodels/SimpleAASSubmodel/submodel/submodelElements/exception1/invokable/invoke");
fail();
} catch (ProviderException e) {}
// Invoke operationEx2
try {
- proxy.invokeOperation("/aas/submodels/SimpleAASSubmodel/operations/exception2/invokable", "prop1");
+ proxy.invokeOperation("/aas/submodels/SimpleAASSubmodel/submodel/submodelElements/exception2/invokable/invoke", "prop1");
fail();
} catch (ProviderException e) {}
}
@@ -79,29 +81,44 @@
@Test
public void invokeTest() {
// Invoke operation
- assertEquals(7, proxy.invokeOperation("/aas/submodels/SimpleAASSubmodel/operations/complex", 10, 3));
- assertEquals(true, proxy.invokeOperation("/aas/submodels/SimpleAASSubmodel/operations/simple"));
+ assertEquals(7, proxy.invokeOperation("/aas/submodels/SimpleAASSubmodel/submodel/submodelElements/complex/" + Operation.INVOKE, 10, 3));
+ assertEquals(true, proxy.invokeOperation("/aas/submodels/SimpleAASSubmodel/submodel/submodelElements/simple/" + Operation.INVOKE));
}
@SuppressWarnings("unchecked")
@Test
public void getTest() {
- AssetAdministrationShell aas = AssetAdministrationShell.createAsFacade((Map<String, Object>) proxy.getModelPropertyValue("/aas"));
+ AssetAdministrationShell aas = AssetAdministrationShell.createAsFacade((Map<String, Object>) proxy.getValue("/aas"));
assertEquals(AASIDSHORT, aas.getIdShort());
getTestRunner("SimpleAASSubmodel");
}
@Test
- public void createDeleteSubmodelTest() {
- SubModel sm = new SimpleAASSubmodel("TestSM");
+ public void updateSubmodelTest() {
+ Submodel sm = new SimpleAASSubmodel("TestSM");
sm.setIdentification(IdentifierType.CUSTOM, "TestId");
- proxy.createValue("/aas/submodels", sm);
+ proxy.setValue("/aas/submodels/" + sm.getIdShort(), sm);
+
+ Submodel sm2 = new SimpleAASSubmodel("TestSM");
+ sm2.setIdentification(IdentifierType.CUSTOM, "TestId2");
+ proxy.setValue("/aas/submodels/" + sm.getIdShort(), sm2);
+
+ ConnectedAssetAdministrationShell shell = new ConnectedAssetAdministrationShell(proxy.getDeepProxy("/aas"));
+ String newId = shell.getSubmodels().get("TestSM").getIdentification().getId();
+ assertEquals("TestId2", newId);
+ }
+
+ @Test
+ public void createDeleteSubmodelTest() {
+ Submodel sm = new SimpleAASSubmodel("TestSM");
+ sm.setIdentification(IdentifierType.CUSTOM, "TestId");
+ proxy.setValue("/aas/submodels/" + sm.getIdShort(), sm);
getTestRunner("TestSM");
- // Ensure that the Submodel References where updated
- ConnectedAssetAdministrationShell shell = new ConnectedAssetAdministrationShell(proxy.getDeepProxy("/aas"), null);
+ // Ensure that the Submodel References were updated
+ ConnectedAssetAdministrationShell shell = new ConnectedAssetAdministrationShell(proxy.getDeepProxy("/aas"));
Collection<IReference> refs = shell.getSubmodelReferences();
assertEquals(2, refs.size());
assertEquals(sm.getReference(), refs.iterator().next());
@@ -113,22 +130,21 @@
assertFalse(shell.getSubmodelReferences().contains(sm.getReference()));
try {
- proxy.getModelPropertyValue("/aas/submodels/TestSM");
+ proxy.getValue("/aas/submodels/TestSM");
fail();
} catch (ProviderException e) {
// Expected
}
}
- @SuppressWarnings("unchecked")
- void getTestRunner(String smId) {
+ private void getTestRunner(String smId) {
// Get property value
- Map<String, Object> value = (Map<String, Object>) proxy
- .getModelPropertyValue("/aas/submodels/" + smId + "/" + SubmodelElementProvider.PROPERTIES + "/integerProperty/value");
- assertEquals(123, value.get(Property.VALUE));
+ Integer value = (Integer) proxy
+ .getValue("/aas/submodels/" + smId + "/" + SubmodelProvider.SUBMODEL + "/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty/value");
+ assertEquals(123, value.intValue());
// Get property value with /submodel suffix
- value = (Map<String, Object>) proxy.getModelPropertyValue("/aas/submodels/" + smId + "/submodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty/value");
- assertEquals(123, value.get(Property.VALUE));
+ value = (Integer) proxy.getValue("/aas/submodels/" + smId + "/" + SubmodelProvider.SUBMODEL + "/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty/value");
+ assertEquals(123, value.intValue());
}
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/StubAASServlet.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/StubAASServlet.java
index 62d0640..178f6d4 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/StubAASServlet.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/StubAASServlet.java
@@ -1,15 +1,24 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.aas.restapi;
import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
import org.eclipse.basyx.aas.restapi.AASModelProvider;
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
+import org.eclipse.basyx.aas.restapi.MultiSubmodelProvider;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
import org.eclipse.basyx.testsuite.regression.submodel.restapi.SimpleAASSubmodel;
import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
-public class StubAASServlet extends VABHTTPInterface<VABMultiSubmodelProvider> {
+public class StubAASServlet extends VABHTTPInterface<MultiSubmodelProvider> {
private static final long serialVersionUID = 8859337501045845823L;
// Used short ids
@@ -21,18 +30,18 @@
public static final ModelUrn SMURN = new ModelUrn("urn:fhg:es.iese:aas:1:1:mySM#001");
public StubAASServlet() {
- super(new VABMultiSubmodelProvider());
+ super(new MultiSubmodelProvider());
- SubModel sm = new SubModel();
+ Submodel sm = new Submodel();
sm.setIdentification(SMURN.getIdType(), SMURN.getId());
sm.setIdShort(SMIDSHORT);
AssetAdministrationShell aas = new AssetAdministrationShell();
- aas.addSubModel(sm);
+ aas.addSubmodel(sm);
aas.setIdShort(AASIDSHORT);
aas.setIdentification(AASURN);
getModelProvider().setAssetAdministrationShell(new AASModelProvider(aas));
- getModelProvider().addSubmodel(SMIDSHORT, new SubModelProvider(new SimpleAASSubmodel(SMIDSHORT)));
+ getModelProvider().addSubmodel(new SubmodelProvider(new SimpleAASSubmodel(SMIDSHORT)));
}
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/enumhelper/StandardizedLiteralEnumHelperTests.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/enumhelper/StandardizedLiteralEnumHelperTests.java
index f28728f..0917f4c 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/enumhelper/StandardizedLiteralEnumHelperTests.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/enumhelper/StandardizedLiteralEnumHelperTests.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.enumhelper;
import static org.junit.Assert.assertTrue;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/mqtt/TestMqttAASAggregator.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/mqtt/TestMqttAASAggregator.java
new file mode 100644
index 0000000..9ffca3b
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/mqtt/TestMqttAASAggregator.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.extensions.aas.aggregator.mqtt;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+
+import org.eclipse.basyx.aas.aggregator.AASAggregator;
+import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.extensions.aas.aggregator.mqtt.MqttAASAggregator;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.testsuite.regression.extensions.shared.mqtt.MqttTestListener;
+import org.eclipse.paho.client.mqttv3.MqttException;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import io.moquette.broker.Server;
+import io.moquette.broker.config.ClasspathResourceLoader;
+import io.moquette.broker.config.IConfig;
+import io.moquette.broker.config.IResourceLoader;
+import io.moquette.broker.config.ResourceLoaderConfig;
+
+/**
+ * Tests events emitting with the MqttAASAggregator
+ *
+ * @author haque
+ *
+ */
+public class TestMqttAASAggregator {
+ protected AssetAdministrationShell shell;
+ private static final String AASID = "aasid1";
+ private static final Identifier AASIDENTIFIER = new Identifier(IdentifierType.IRI, AASID);
+
+ private static Server mqttBroker;
+ private static MqttAASAggregator eventAPI;
+ private MqttTestListener listener;
+
+ /**
+ * Sets up the MQTT broker and AASAggregator for tests
+ */
+ @BeforeClass
+ public static void setUpClass() throws MqttException, IOException {
+ // Start MQTT broker
+ mqttBroker = new Server();
+ IResourceLoader classpathLoader = new ClasspathResourceLoader();
+ final IConfig classPathConfig = new ResourceLoaderConfig(classpathLoader);
+ mqttBroker.startServer(classPathConfig);
+
+ // Create underlying aas aggregator
+ IAASAggregator aggregator = new AASAggregator();
+
+ eventAPI = new MqttAASAggregator(aggregator, "tcp://localhost:1884", "testClient");
+ }
+
+ @AfterClass
+ public static void tearDownClass() {
+ mqttBroker.stopServer();
+ }
+
+ @Before
+ public void setUp() {
+ shell = new AssetAdministrationShell(AASID, AASIDENTIFIER, new Asset("assetid1", new Identifier(IdentifierType.IRI, "assetid1"), AssetKind.INSTANCE));
+ eventAPI.createAAS(shell);
+
+ listener = new MqttTestListener();
+ mqttBroker.addInterceptHandler(listener);
+ }
+
+ @After
+ public void tearDown() {
+ mqttBroker.removeInterceptHandler(listener);
+ }
+
+ @Test
+ public void testCreateAAS() {
+ String aasId2 = "aas2";
+ Identifier identifier2 = new Identifier(IdentifierType.IRDI, aasId2);
+ AssetAdministrationShell shell2 = new AssetAdministrationShell(aasId2, identifier2, new Asset("assetid2", new Identifier(IdentifierType.IRI, "assetid2"), AssetKind.INSTANCE));
+ eventAPI.createAAS(shell2);
+
+ assertEquals(aasId2, listener.lastPayload);
+ assertEquals(MqttAASAggregator.TOPIC_CREATEAAS, listener.lastTopic);
+ }
+
+ @Test
+ public void testUpdateAAS() {
+ shell.setCategory("newCategory");
+ eventAPI.updateAAS(shell);
+
+ assertEquals(AASID, listener.lastPayload);
+ assertEquals(MqttAASAggregator.TOPIC_UPDATEAAS, listener.lastTopic);
+ }
+
+ @Test
+ public void testDeleteAAS() {
+ eventAPI.deleteAAS(AASIDENTIFIER);
+
+ assertEquals(AASID, listener.lastPayload);
+ assertEquals(MqttAASAggregator.TOPIC_DELETEAAS, listener.lastTopic);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/TestTaggedDirectorySuite.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/TestTaggedDirectorySuite.java
index acc5e24..1d83683 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/TestTaggedDirectorySuite.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/TestTaggedDirectorySuite.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.extensions.aas.directory.tagged;
import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/map/TestMapTaggedDirectory.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/map/TestMapTaggedDirectory.java
index 51f89fb..9545598 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/map/TestMapTaggedDirectory.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/map/TestMapTaggedDirectory.java
@@ -1,8 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.extensions.aas.directory.tagged.map;
import java.util.HashMap;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
import org.eclipse.basyx.extensions.aas.directory.tagged.api.IAASTaggedDirectory;
import org.eclipse.basyx.extensions.aas.directory.tagged.map.MapTaggedDirectory;
import org.eclipse.basyx.testsuite.regression.extensions.aas.directory.tagged.TestTaggedDirectorySuite;
@@ -21,7 +30,7 @@
}
@Override
- protected IAASRegistryService getRegistryService() {
+ protected IAASRegistry getRegistryService() {
return getDirectory();
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/proxy/TestProxyTaggedDirectory.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/proxy/TestProxyTaggedDirectory.java
index 1f8edef..2e9470d 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/proxy/TestProxyTaggedDirectory.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/proxy/TestProxyTaggedDirectory.java
@@ -1,6 +1,15 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.extensions.aas.directory.tagged.proxy;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
import org.eclipse.basyx.extensions.aas.directory.tagged.api.IAASTaggedDirectory;
import org.eclipse.basyx.extensions.aas.directory.tagged.proxy.TaggedDirectoryProxy;
import org.eclipse.basyx.extensions.aas.directory.tagged.restapi.TaggedDirectoryProvider;
@@ -14,7 +23,7 @@
}
@Override
- protected IAASRegistryService getRegistryService() {
+ protected IAASRegistry getRegistryService() {
return getDirectory();
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/servlet/TestTaggedDirectoryProviderHTTP.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/servlet/TestTaggedDirectoryProviderHTTP.java
index 137c187..dd90a15 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/servlet/TestTaggedDirectoryProviderHTTP.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/servlet/TestTaggedDirectoryProviderHTTP.java
@@ -1,6 +1,15 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.extensions.aas.directory.tagged.servlet;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
import org.eclipse.basyx.extensions.aas.directory.tagged.api.IAASTaggedDirectory;
import org.eclipse.basyx.extensions.aas.directory.tagged.proxy.TaggedDirectoryProxy;
import org.eclipse.basyx.extensions.aas.directory.tagged.restapi.TaggedDirectoryProvider;
@@ -32,7 +41,7 @@
public AASHTTPServerResource res = new AASHTTPServerResource(new BaSyxContext("/basys.sdk", System.getProperty("java.io.tmpdir")).addServletMapping("/Testsuite/directory/*", new TaggedDirectoryProviderServlet()));
@Override
- protected IAASRegistryService getRegistryService() {
+ protected IAASRegistry getRegistryService() {
return getDirectory();
}
@@ -41,4 +50,4 @@
return new TaggedDirectoryProxy("http://localhost:8080/basys.sdk/Testsuite/directory");
}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/registration/mqtt/TestMqttAASRegistryService.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/registration/mqtt/TestMqttAASRegistryService.java
new file mode 100644
index 0000000..e6f3ac3
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/registration/mqtt/TestMqttAASRegistryService.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.extensions.aas.registration.mqtt;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
+import org.eclipse.basyx.extensions.aas.registration.mqtt.MqttAASRegistryService;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.testsuite.regression.extensions.shared.mqtt.MqttTestListener;
+import org.eclipse.paho.client.mqttv3.MqttException;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import io.moquette.broker.Server;
+import io.moquette.broker.config.ClasspathResourceLoader;
+import io.moquette.broker.config.IConfig;
+import io.moquette.broker.config.IResourceLoader;
+import io.moquette.broker.config.ResourceLoaderConfig;
+
+/**
+ * Tests events emitting with the MqttAASRegistryService
+ *
+ * @author haque
+ *
+ */
+public class TestMqttAASRegistryService {
+
+ private static final String AASID = "aasid1";
+ private static final String SUBMODELID = "submodelid1";
+ private static final String AASENDPOINT = "http://localhost:8080/aasList/" + AASID + "/aas";
+ private static final Identifier AASIDENTIFIER = new Identifier(IdentifierType.IRI, AASID);
+ private static final Identifier SUBMODELIDENTIFIER = new Identifier(IdentifierType.IRI, SUBMODELID);
+
+ private static Server mqttBroker;
+ private static MqttAASRegistryService eventAPI;
+ private MqttTestListener listener;
+
+ /**
+ * Sets up the MQTT broker and AASRegistryService for tests
+ */
+ @BeforeClass
+ public static void setUpClass() throws MqttException, IOException {
+ // Start MQTT broker
+ mqttBroker = new Server();
+ IResourceLoader classpathLoader = new ClasspathResourceLoader();
+ final IConfig classPathConfig = new ResourceLoaderConfig(classpathLoader);
+ mqttBroker.startServer(classPathConfig);
+
+ // Create underlying registry service
+ IAASRegistry registryService = new InMemoryRegistry();
+
+ eventAPI = new MqttAASRegistryService(registryService, "tcp://localhost:1884", "testClient");
+ }
+
+ @AfterClass
+ public static void tearDownClass() {
+ mqttBroker.stopServer();
+ }
+
+ @Before
+ public void setUp() {
+ AssetAdministrationShell shell = new AssetAdministrationShell(AASID, AASIDENTIFIER, new Asset("assetid1", new Identifier(IdentifierType.IRI, "assetid1"), AssetKind.INSTANCE));
+ AASDescriptor aasDescriptor = new AASDescriptor(shell, AASENDPOINT);
+ eventAPI.register(aasDescriptor);
+
+ Submodel submodel = new Submodel(SUBMODELID, SUBMODELIDENTIFIER);
+ String submodelEndpoint = AASENDPOINT + "/submodels/" + SUBMODELID + "/submodel";
+ SubmodelDescriptor submodelDescriptor = new SubmodelDescriptor(submodel, submodelEndpoint);
+ eventAPI.register(AASIDENTIFIER, submodelDescriptor);
+
+ listener = new MqttTestListener();
+ mqttBroker.addInterceptHandler(listener);
+ }
+
+ @After
+ public void tearDown() {
+ mqttBroker.removeInterceptHandler(listener);
+ }
+
+ @Test
+ public void testRegisterAAS() {
+ String newAASId = "aasid2";
+ Identifier newIdentifier = new Identifier(IdentifierType.IRI, newAASId);
+ AssetAdministrationShell shell = new AssetAdministrationShell(newAASId, newIdentifier, new Asset("assetid1", new Identifier(IdentifierType.IRI, "assetid2"), AssetKind.INSTANCE));
+ String aasEndpoint = "http://localhost:8080/aasList/" + newAASId + "/aas";
+
+ AASDescriptor aasDescriptor = new AASDescriptor(shell, aasEndpoint);
+ eventAPI.register(aasDescriptor);
+
+ assertEquals(newAASId, listener.lastPayload);
+ assertEquals(MqttAASRegistryService.TOPIC_REGISTERAAS, listener.lastTopic);
+ }
+
+ @Test
+ public void testRegisterSubmodel() {
+ String submodelid = "submodelid2";
+ Identifier newSubmodelIdentifier = new Identifier(IdentifierType.IRI, submodelid);
+ Submodel submodel = new Submodel(submodelid, newSubmodelIdentifier);
+ String submodelEndpoint = AASENDPOINT + "/submodels/" + submodelid + "/submodel";
+ SubmodelDescriptor submodelDescriptor = new SubmodelDescriptor(submodel, submodelEndpoint);
+
+ eventAPI.register(AASIDENTIFIER, submodelDescriptor);
+
+ assertEquals(MqttAASRegistryService.concatAasSmId(AASIDENTIFIER, newSubmodelIdentifier), listener.lastPayload);
+ assertEquals(MqttAASRegistryService.TOPIC_REGISTERSUBMODEL, listener.lastTopic);
+ }
+
+ @Test
+ public void testDeleteAAS() {
+ eventAPI.delete(AASIDENTIFIER);
+
+ assertEquals(AASID, listener.lastPayload);
+ assertEquals(MqttAASRegistryService.TOPIC_DELETEAAS, listener.lastTopic);
+ }
+
+ @Test
+ public void testDeleteSubmodel() {
+ eventAPI.delete(AASIDENTIFIER, SUBMODELIDENTIFIER);
+
+ assertEquals(MqttAASRegistryService.concatAasSmId(AASIDENTIFIER, SUBMODELIDENTIFIER), listener.lastPayload);
+ assertEquals(MqttAASRegistryService.TOPIC_DELETESUBMODEL, listener.lastTopic);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/shared/mqtt/MqttTestListener.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/shared/mqtt/MqttTestListener.java
new file mode 100644
index 0000000..ab2d192
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/shared/mqtt/MqttTestListener.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.extensions.shared.mqtt;
+
+import java.nio.charset.StandardCharsets;
+
+import io.moquette.interception.InterceptHandler;
+import io.moquette.interception.messages.InterceptAcknowledgedMessage;
+import io.moquette.interception.messages.InterceptConnectMessage;
+import io.moquette.interception.messages.InterceptConnectionLostMessage;
+import io.moquette.interception.messages.InterceptDisconnectMessage;
+import io.moquette.interception.messages.InterceptPublishMessage;
+import io.moquette.interception.messages.InterceptSubscribeMessage;
+import io.moquette.interception.messages.InterceptUnsubscribeMessage;
+
+/**
+ * Very simple MQTT broker listener for testing Submodel API events.
+ * Stores the last received event and makes its topic and payload available for reading.
+ *
+ * @author espen
+ *
+ */
+public class MqttTestListener implements InterceptHandler {
+ // Topic and payload of the most recent event
+ public String lastTopic;
+ public String lastPayload;
+
+ @Override
+ public String getID() {
+ return null;
+ }
+
+ @Override
+ public Class<?>[] getInterceptedMessageTypes() {
+ return null;
+ }
+
+ @Override
+ public void onConnect(InterceptConnectMessage arg0) {
+ }
+
+ @Override
+ public void onConnectionLost(InterceptConnectionLostMessage arg0) {
+ }
+
+ @Override
+ public void onDisconnect(InterceptDisconnectMessage arg0) {
+ }
+
+ @Override
+ public void onMessageAcknowledged(InterceptAcknowledgedMessage arg0) {
+ }
+
+ @Override
+ public void onPublish(InterceptPublishMessage msg) {
+ lastTopic = msg.getTopicName();
+ lastPayload = msg.getPayload().toString(StandardCharsets.UTF_8);
+ }
+
+ @Override
+ public void onSubscribe(InterceptSubscribeMessage arg0) {
+ }
+
+ @Override
+ public void onUnsubscribe(InterceptUnsubscribeMessage arg0) {
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/mqtt/TestMqttSubmodelAPIEvents.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/mqtt/TestMqttSubmodelAPIEvents.java
new file mode 100644
index 0000000..87bbad5
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/mqtt/TestMqttSubmodelAPIEvents.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.extensions.submodel.mqtt;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import java.io.IOException;
+
+import org.eclipse.basyx.extensions.submodel.mqtt.MqttSubmodelAPI;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.restapi.vab.VABSubmodelAPI;
+import org.eclipse.basyx.testsuite.regression.extensions.shared.mqtt.MqttTestListener;
+import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
+import org.eclipse.paho.client.mqttv3.MqttException;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import io.moquette.broker.Server;
+import io.moquette.broker.config.ClasspathResourceLoader;
+import io.moquette.broker.config.IConfig;
+import io.moquette.broker.config.IResourceLoader;
+import io.moquette.broker.config.ResourceLoaderConfig;
+
+/**
+ * Tests events emitting with the MqttSubmodelAPI
+ *
+ * @author espen
+ *
+ */
+public class TestMqttSubmodelAPIEvents {
+ private static final String AASID = "testaasid";
+ private static final String SUBMODELID = "testsubmodelid";
+
+ private static Server mqttBroker;
+ private static MqttSubmodelAPI eventAPI;
+ private MqttTestListener listener;
+
+ /**
+ * Sets up the MQTT broker and submodelAPI for tests
+ */
+ @BeforeClass
+ public static void setUpClass() throws MqttException, IOException {
+ // Start MQTT broker
+ mqttBroker = new Server();
+ IResourceLoader classpathLoader = new ClasspathResourceLoader();
+ final IConfig classPathConfig = new ResourceLoaderConfig(classpathLoader);
+ mqttBroker.startServer(classPathConfig);
+
+ // Create submodel
+ Submodel sm = new Submodel(SUBMODELID, new Identifier(IdentifierType.CUSTOM, SUBMODELID));
+ Reference parentRef = new Reference(new Key(KeyElements.ASSETADMINISTRATIONSHELL, true, AASID, IdentifierType.IRDI));
+ sm.setParent(parentRef);
+
+ VABSubmodelAPI vabAPI = new VABSubmodelAPI(new VABMapProvider(sm));
+ eventAPI = new MqttSubmodelAPI(vabAPI, "tcp://localhost:1884", "testClient");
+ }
+
+ @AfterClass
+ public static void tearDownClass() {
+ mqttBroker.stopServer();
+ }
+
+ @Before
+ public void setUp() {
+ listener = new MqttTestListener();
+ mqttBroker.addInterceptHandler(listener);
+ }
+
+ @After
+ public void tearDown() {
+ mqttBroker.removeInterceptHandler(listener);
+ }
+
+ @Test
+ public void testAddSubmodelElement() throws InterruptedException {
+ String elemIdShort = "testAddProp";
+ Property prop = new Property(true);
+ prop.setIdShort(elemIdShort);
+ eventAPI.addSubmodelElement(prop);
+
+ assertEquals(MqttSubmodelAPI.getCombinedMessage(AASID, SUBMODELID, elemIdShort), listener.lastPayload);
+ assertEquals(MqttSubmodelAPI.TOPIC_ADDELEMENT, listener.lastTopic);
+ }
+
+ @Test
+ public void testAddNestedSubmodelElement() {
+ String idShortPath = "/testColl/testAddProp/";
+ SubmodelElementCollection coll = new SubmodelElementCollection();
+ coll.setIdShort("testColl");
+ eventAPI.addSubmodelElement(coll);
+
+ Property prop = new Property(true);
+ prop.setIdShort("testAddProp");
+ eventAPI.addSubmodelElement(idShortPath, prop);
+
+ assertEquals(MqttSubmodelAPI.getCombinedMessage(AASID, SUBMODELID, idShortPath), listener.lastPayload);
+ assertEquals(MqttSubmodelAPI.TOPIC_ADDELEMENT, listener.lastTopic);
+ }
+
+ @Test
+ public void testDeleteSubmodelElement() {
+ String idShortPath = "/testDeleteProp";
+ Property prop = new Property(true);
+ prop.setIdShort("testDeleteProp");
+ eventAPI.addSubmodelElement(prop);
+ eventAPI.deleteSubmodelElement(idShortPath);
+
+ assertEquals(MqttSubmodelAPI.getCombinedMessage(AASID, SUBMODELID, idShortPath), listener.lastPayload);
+ assertEquals(MqttSubmodelAPI.TOPIC_DELETEELEMENT, listener.lastTopic);
+ }
+
+ @Test
+ public void testUpdateSubmodelElement() {
+ String idShortPath = "testUpdateProp";
+ Property prop = new Property(true);
+ prop.setIdShort(idShortPath);
+ eventAPI.addSubmodelElement(prop);
+ eventAPI.updateSubmodelElement(idShortPath, false);
+
+ assertFalse((boolean) eventAPI.getSubmodelElementValue(idShortPath));
+ assertEquals(MqttSubmodelAPI.getCombinedMessage(AASID, SUBMODELID, idShortPath), listener.lastPayload);
+ assertEquals(MqttSubmodelAPI.TOPIC_UPDATEELEMENT, listener.lastTopic);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/TestSubmodelSuite.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/TestSubmodelSuite.java
new file mode 100644
index 0000000..63f0540
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/TestSubmodelSuite.java
@@ -0,0 +1,408 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.metamodel;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.math.BigInteger;
+import java.time.Duration;
+import java.time.LocalDate;
+import java.time.Month;
+import java.time.Period;
+import java.util.ArrayList;
+import java.util.Base64;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IDataElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Blob;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.ReferenceElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.Range;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.RangeValue;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.AnnotatedRelationshipElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElement;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Test;
+
+/**
+ * Abstract Submodel Testsuite to be reused by different implementations of
+ * {@link ISubmodel}
+ *
+ * @author schnicke
+ *
+ */
+public abstract class TestSubmodelSuite {
+ // String constants used in this test case
+ private final static String PROP = "prop1";
+ private final static String ID = "TestId";
+
+ private final String PROPERTY_ID = "property_id";
+ private final String BLOB_ID = "blob_id";
+ private final String RELATIONSHIP_ELEM_ID = "relElem_id";
+ private final String ANNOTATED_RELATIONSHIP_ELEM_ID = "annotatedRelElem_id";
+ private final String SUBMODEL_ELEM_COLLECTION_ID = "elemCollection_id";
+ private final String PROPERTY_CONTAINED_ID = "containedProp";
+ private final String RANGE_ID = "range_id";
+ private final String FILE_ID = "file_id";
+ private final String MULTI_LANG_PROP_ID = "multi_lang_prop_id";
+ private final String REFERENCE_ELEMENT_ID = "reference_element_id";
+ private final String PROPERTY_ID2 = "property_id2";
+
+
+ private final static Reference testSemanticIdRef = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "testVal", IdentifierType.CUSTOM));
+
+ public Submodel getReferenceSubmodel() {
+
+ // Create a simple value property
+ Property propertyMeta = new Property(PROP, ValueType.Integer);
+ propertyMeta.setValue(100);
+
+ // Create the Submodel using the created property and operation
+ IIdentifier submodelId = new ModelUrn("testUrn");
+ Submodel localSubmodel = new Submodel(ID, submodelId);
+ localSubmodel.addSubmodelElement(propertyMeta);
+ localSubmodel.setSemanticId(testSemanticIdRef);
+
+ return localSubmodel;
+ }
+
+ protected abstract ISubmodel getSubmodel();
+
+ /**
+ * Tests if a Submodel's id can be retrieved correctly
+ */
+ @Test
+ public void getIdTest() {
+ ISubmodel submodel = getSubmodel();
+ assertEquals(ID, submodel.getIdShort());
+ }
+
+ /**
+ * Tests if a Submodel's properties can be used correctly
+ */
+ @Test
+ public void propertiesTest() throws Exception {
+ ISubmodel submodel = getSubmodel();
+ // Retrieve all properties
+ Map<String, IProperty> props = submodel.getProperties();
+
+ // Check if number of properties is as expected
+ assertEquals(1, props.size());
+
+ // Check the value of the property
+ IProperty prop = props.get(PROP);
+ assertEquals(100, prop.getValue());
+ }
+
+
+ @Test
+ public void saveAndLoadPropertyTest() throws Exception {
+ ISubmodel submodel = getSubmodel();
+
+ // Get sample DataElements and save them into Submodel
+ Map<String, IProperty> testData = getTestDataProperty();
+ for (ISubmodelElement element : testData.values()) {
+ submodel.addSubmodelElement(element);
+ }
+
+ // Load it
+ Map<String, IProperty> map = submodel.getProperties();
+
+ // Check if it loaded correctly
+ checkProperties(map);
+ }
+
+ @Test
+ public void saveAndLoadSubmodelElementTest() throws Exception {
+ ISubmodel submodel = getSubmodel();
+
+ // Get sample DataElements and save them into Submodel
+ Map<String, IProperty> testDataElements = getTestDataProperty();
+ for (ISubmodelElement element : testDataElements.values()) {
+ submodel.addSubmodelElement(element);
+ }
+
+
+ // Get sample SubmodelElements and save them into Submodel
+ Map<String, ISubmodelElement> testSMElements = getTestSubmodelElements();
+ for (ISubmodelElement element : testSMElements.values()) {
+ submodel.addSubmodelElement(element);
+ }
+
+ // Load it
+ Map<String, ISubmodelElement> map = submodel.getSubmodelElements();
+
+ // Check if it loaded correctly
+ // Including DataElements and Operations as they are also SubmodelElements
+ checkProperties(map);
+ checkSubmodelElements(map);
+ }
+
+ /**
+ * Tests if the semantic Id can be retrieved correctly
+ */
+ @Test
+ public void semanticIdRetrievalTest() {
+ ISubmodel submodel = getSubmodel();
+ IReference ref = submodel.getSemanticId();
+ assertEquals(testSemanticIdRef, ref);
+ }
+
+ /**
+ * Tests if the adding a submodel element is correctly done Also checks the
+ * addition of parent reference to the submodel
+ */
+ @Test
+ public void addSubmodelElementTest() throws Exception {
+ ISubmodel submodel = getSubmodel();
+ Property property = new Property("testProperty");
+ property.setIdShort("testIdShort");
+ submodel.addSubmodelElement(property);
+
+ IProperty connectedProperty = (IProperty) submodel.getSubmodelElements().get("testIdShort");
+ assertEquals(property.getIdShort(), connectedProperty.getIdShort());
+ assertEquals(property.getValue(), connectedProperty.getValue());
+
+ // creates an expected reference for assertion
+ IReference expected = submodel.getReference();
+ assertEquals(expected, property.getParent());
+ }
+
+ @Test
+ public void testGetSubmodelElement() {
+ ISubmodel submodel = getSubmodel();
+ ISubmodelElement element = submodel.getSubmodelElement(PROP);
+ assertEquals(PROP, element.getIdShort());
+ }
+
+ @Test(expected = ResourceNotFoundException.class)
+ public void testDeleteSubmodelElement() {
+
+ ISubmodel submodel = getSubmodel();
+ submodel.deleteSubmodelElement(PROP);
+ submodel.getSubmodelElement(PROP);
+ }
+
+ /**
+ * Tests getValues function
+ */
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testGetValues() {
+ ISubmodel submodel = getSubmodel();
+
+ // Add elements to the Submodel
+ Map<String, ISubmodelElement> testSMElements = getTestSubmodelElements();
+ for (ISubmodelElement element : testSMElements.values()) {
+ submodel.addSubmodelElement(element);
+ }
+
+ Map<String, Object> values = submodel.getValues();
+
+ assertEquals(10, values.size());
+
+ // Check if all expected Values are present
+ assertEquals(100, values.get(PROP));
+ assertEquals(Base64.getEncoder().encodeToString(new byte[] { 1, 2, 3 }), values.get(BLOB_ID));
+
+ assertTrue(values.containsKey(RELATIONSHIP_ELEM_ID));
+ assertTrue(values.containsKey(SUBMODEL_ELEM_COLLECTION_ID));
+ Map<String, Object> collection = (Map<String, Object>) values.get(SUBMODEL_ELEM_COLLECTION_ID);
+ assertTrue(collection.containsKey(PROPERTY_CONTAINED_ID));
+ assertTrue(values.containsKey(PROPERTY_ID2));
+ assertTrue(values.containsKey(BLOB_ID));
+ assertTrue(values.containsKey(RANGE_ID));
+ assertTrue(values.containsKey(MULTI_LANG_PROP_ID));
+ assertTrue(values.containsKey(FILE_ID));
+ assertTrue(values.containsKey(REFERENCE_ELEMENT_ID));
+ }
+
+ /**
+ * Generates test IDataElements
+ */
+ private Map<String, IProperty> getTestDataProperty() {
+ Map<String, IProperty> ret = new HashMap<>();
+
+ Property property = new Property();
+ property.setIdShort(PROPERTY_ID);
+ property.setValue("test2");
+ ret.put(property.getIdShort(), property);
+
+ Property byteProp = new Property();
+ byteProp.setIdShort("byte_prop01");
+ Byte byteNumber = Byte.parseByte("2");
+ byteProp.setValue(byteNumber);
+ ret.put(byteProp.getIdShort(), byteProp);
+
+ Property durationProp = new Property();
+ durationProp.setIdShort("duration_prop01");
+ Duration duration = Duration.ofSeconds(10);
+ durationProp.setValue(duration);
+ ret.put(durationProp.getIdShort(), durationProp);
+
+ Property periodProp = new Property();
+ periodProp.setIdShort("period_prop01");
+ LocalDate today = LocalDate.now();
+ LocalDate birthday = LocalDate.of(1960, Month.JANUARY, 1);
+ Period p = Period.between(birthday, today);
+ periodProp.setValue(p);
+ ret.put(periodProp.getIdShort(), periodProp);
+
+ Property bigNumberProp = new Property();
+ bigNumberProp.setIdShort("bignumber_prop01");
+ BigInteger bignumber = new BigInteger("9223372036854775817");
+ property.setValue(bignumber);
+ ret.put(bigNumberProp.getIdShort(), bigNumberProp);
+
+ return ret;
+ }
+ /**
+ * Generates test ISubmodelElements
+ */
+ private Map<String, ISubmodelElement> getTestSubmodelElements() {
+ Map<String, ISubmodelElement> ret = new HashMap<>();
+
+ SubmodelElementCollection smECollection = new SubmodelElementCollection();
+ smECollection.setIdShort(SUBMODEL_ELEM_COLLECTION_ID);
+
+ // Create a Property to use as Value for smECollection
+ List<ISubmodelElement> values = new ArrayList<>();
+ Property contained = new Property(PROPERTY_CONTAINED_ID, true);
+ values.add(contained);
+
+
+ smECollection.setValue(values);
+ ret.put(smECollection.getIdShort(), smECollection);
+
+ Blob blob = new Blob(BLOB_ID, "text/json");
+ blob.setByteArrayValue(new byte[] { 1, 2, 3 });
+ ret.put(blob.getIdShort(), blob);
+
+ Reference first = new Reference(new Key(KeyElements.BASICEVENT, true, "testFirst", IdentifierType.CUSTOM));
+ Reference second = new Reference(new Key(KeyElements.BASICEVENT, true, "testSecond", IdentifierType.CUSTOM));
+
+ RelationshipElement relElement = new RelationshipElement(RELATIONSHIP_ELEM_ID, first, second);
+ ret.put(relElement.getIdShort(), relElement);
+
+ AnnotatedRelationshipElement annotatedRelElement = new AnnotatedRelationshipElement(ANNOTATED_RELATIONSHIP_ELEM_ID, first, second);
+ List<IDataElement> annotations = new ArrayList<>();
+ Property annotationProperty = new Property("id", 10);
+ annotations.add(annotationProperty);
+ annotatedRelElement.setAnnotation(annotations);
+ ret.put(annotatedRelElement.getIdShort(), annotatedRelElement);
+
+ Property property = new Property(PROPERTY_ID2, ValueType.AnySimpleType);
+ ret.put(property.getIdShort(), property);
+
+ Range range = new Range(RANGE_ID, ValueType.Integer);
+ range.setValue(new RangeValue(-100, +100));
+ ret.put(range.getIdShort(), range);
+
+ File file = new File("text/plain");
+ file.setIdShort(FILE_ID);
+ file.setValue("fileUrl");
+ ret.put(file.getIdShort(), file);
+
+ MultiLanguageProperty languageProperty = new MultiLanguageProperty(MULTI_LANG_PROP_ID);
+ languageProperty.setValue(new LangStrings(new LangString("en-en", "TestDescription")));
+ ret.put(languageProperty.getIdShort(), languageProperty);
+
+ ReferenceElement referenceElement = new ReferenceElement(REFERENCE_ELEMENT_ID, first);
+ ret.put(referenceElement.getIdShort(), referenceElement);
+
+ return ret;
+ }
+
+ /**
+ * Checks if the given Map contains all expected IDataElements
+ */
+ private void checkProperties(Map<String, ? extends ISubmodelElement> actual) throws Exception {
+ assertNotNull(actual);
+
+ Map<String, IProperty> expected = getTestDataProperty();
+
+ // Check value and type of each property in the submodel
+ expected.forEach((id, prop) -> {
+ IProperty expectedProperty = expected.get(PROPERTY_ID);
+ IProperty actualProperty = (IProperty) actual.get(PROPERTY_ID);
+ assertNotNull(actualProperty);
+ try {
+ assertEquals(expectedProperty.getValue(), actualProperty.getValue());
+ assertEquals(expectedProperty.getValueType(), actualProperty.getValueType());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ });
+ }
+
+ /**
+ * Checks if the given Map contains all expected ISubmodelElements
+ */
+ private void checkSubmodelElements(Map<String, ISubmodelElement> actual) throws Exception {
+ assertNotNull(actual);
+
+ Map<String, ISubmodelElement> expected = getTestSubmodelElements();
+
+ ISubmodelElementCollection expectedCollection = (ISubmodelElementCollection) expected.get(SUBMODEL_ELEM_COLLECTION_ID);
+ ISubmodelElementCollection actualCollection = (ISubmodelElementCollection) actual.get(SUBMODEL_ELEM_COLLECTION_ID);
+
+ assertNotNull(actualCollection);
+
+ Collection<ISubmodelElement> elements = actualCollection.getSubmodelElements().values();
+
+
+ // Check for correct Type
+ assertEquals(1, elements.size());
+ assertTrue(elements.iterator().next() instanceof IProperty);
+
+ assertEquals(expectedCollection.getSubmodelElements().size(), elements.size());
+
+ // Check value of all submodel elements
+ for (ISubmodelElement elem : expected.values()) {
+ // Equality of Ids is implicitly checked by this retrieval
+ ISubmodelElement actualElem = actual.get(elem.getIdShort());
+ assertNotNull(actualElem);
+
+ assertEquals(elem.getValue(), actualElem.getValue());
+ }
+ }
+
+ /**
+ * This method tests deleteSubmodelElement method of Submodel class with non
+ * existing element id
+ */
+ @Test(expected = ResourceNotFoundException.class)
+ public void testDeleteSubmodelElementNotExist() {
+ getSubmodel().deleteSubmodelElement("Id_Which_Does_Not_Exist");
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/api/qualifier/TestIdShortValidator.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/api/qualifier/TestIdShortValidator.java
new file mode 100644
index 0000000..0ef7980
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/api/qualifier/TestIdShortValidator.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.metamodel.api.qualifier;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.IdShortValidator;
+import org.junit.Test;
+
+/**
+ * Tests the IdShortValidator's capability to validate IdShorts
+ *
+ * @author schnicke
+ *
+ */
+public class TestIdShortValidator {
+
+ @Test
+ public void testValidator() {
+ String[] accepted = {"abc", "AbC"};
+ String[] notAccepted = { ":", " test", "1Test", "äTest", null, "" };
+
+ for (String s : accepted) {
+ assertTrue(s + " was not tested valid", IdShortValidator.isValid(s));
+ }
+
+ for (String s : notAccepted) {
+ assertFalse(s + " was not tested invalid", IdShortValidator.isValid(s));
+ }
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/api/submodelelement/TestSubmodelElementIdShortBlacklist.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/api/submodelelement/TestSubmodelElementIdShortBlacklist.java
new file mode 100644
index 0000000..95602e2
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/api/submodelelement/TestSubmodelElementIdShortBlacklist.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.metamodel.api.submodelelement;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.SubmodelElementIdShortBlacklist;
+import org.junit.Test;
+
+/**
+ * Tests if the SubmodelElementIdShortBlacklist works as intended
+ *
+ * @author schnicke
+ *
+ */
+public class TestSubmodelElementIdShortBlacklist {
+
+ @Test
+ public void testIsBlacklisted() {
+ String allowed[] = { "test", "values", "invocations" };
+
+ for (String s : SubmodelElementIdShortBlacklist.BLACKLIST) {
+ assertTrue(s + " was incorrectly allowed", SubmodelElementIdShortBlacklist.isBlacklisted(s));
+ }
+
+ for (String s : allowed) {
+ assertFalse(s + " was incorrectly blacklisted", SubmodelElementIdShortBlacklist.isBlacklisted(s));
+ }
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedProperty.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedProperty.java
index 5fceb14..8b24e4e 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedProperty.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedProperty.java
@@ -1,14 +1,27 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected;
import static org.junit.Assert.assertEquals;
import java.util.Map;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedProperty;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDef;
-import org.eclipse.basyx.submodel.restapi.PropertyProvider;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
import org.eclipse.basyx.vab.support.TypeDestroyer;
@@ -25,25 +38,27 @@
IProperty prop;
private static final int VALUE = 10;
+ private static final Reference VALUEID = new Reference(new Key(KeyElements.ACCESSPERMISSIONRULE, true, "testValue", IdentifierType.CUSTOM));
@Before
public void build() {
// Create PropertySingleValued containing the simple value
- Property propertyMeta = new Property(VALUE);
+ Property propertyMeta = new Property("testProp", VALUE);
+ propertyMeta.setValueId(VALUEID);
Map<String, Object> destroyType = TypeDestroyer.destroyType(propertyMeta);
- prop = new ConnectedProperty(new VABConnectionManagerStub(new PropertyProvider(new VABMapProvider(destroyType))).connectToVABElement(""));
+ prop = new ConnectedProperty(new VABConnectionManagerStub(new SubmodelElementProvider(new VABMapProvider(destroyType))).connectToVABElement(""));
}
@Test
public void testEmptyProperty() throws Exception {
- Property propertyMeta = new Property();
- propertyMeta.setValueType(PropertyValueTypeDef.String);
+ Property propertyMeta = new Property("testIdShort", ValueType.String);
+ propertyMeta.setValue(null);
Map<String, Object> destroyType = TypeDestroyer.destroyType(propertyMeta);
prop = new ConnectedProperty(
- new VABConnectionManagerStub(new PropertyProvider(new VABMapProvider(destroyType)))
+ new VABConnectionManagerStub(new SubmodelElementProvider(new VABMapProvider(destroyType)))
.connectToVABElement(""));
- prop.set("content");
- assertEquals("content", prop.get());
+ prop.setValue("content");
+ assertEquals("content", prop.getValue());
}
/**
@@ -53,7 +68,7 @@
*/
@Test
public void testGet() throws Exception {
- int val = (int) prop.get();
+ int val = (int) prop.getValue();
assertEquals(VALUE, val);
}
@@ -64,8 +79,8 @@
*/
@Test
public void testValueTypeRetrieval() {
- String valueType = prop.getValueType();
- assertEquals(PropertyValueTypeDef.Integer.toString(), valueType);
+ ValueType valueType = prop.getValueType();
+ assertEquals(ValueType.Integer, valueType);
}
/**
@@ -75,9 +90,14 @@
*/
@Test
public void testSet() throws Exception {
- prop.set(123);
- int val = (int) prop.get();
+ prop.setValue(123);
+ int val = (int) prop.getValue();
assertEquals(123, val);
}
+ @Test
+ public void testGetValueId() {
+ assertEquals(VALUEID, prop.getValueId());
+ }
+
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedSubModel.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedSubModel.java
deleted file mode 100644
index 3a1580e..0000000
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedSubModel.java
+++ /dev/null
@@ -1,331 +0,0 @@
-package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Function;
-
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
-import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
-import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IBlob;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.relationship.IRelationshipElement;
-import org.eclipse.basyx.submodel.metamodel.connected.ConnectedSubModel;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
-import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Blob;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElement;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
-import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
-import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
-import org.eclipse.basyx.vab.support.TypeDestroyingProvider;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Tests if a SubModel can be created and used correctly
- *
- * @author schnicke
- *
- */
-public class TestConnectedSubModel {
-
- // String constants used in this test case
- private final static String OP = "add";
- private final static String PROP = "prop1";
- private final static String ID = "TestId";
-
- private final String OPERATION_ID = "operation_id";
- private final String PROPERTY_ID = "property_id";
- private final String BLOB_ID = "blob_id";
- private final String RELATIONSHIP_ELEM_ID = "relElem_id";
- private final String SUBMODEL_ELEM_COLLECTION_ID = "elemCollection_id";
-
- private final static Reference testSemanticIdRef = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "testVal", IdentifierType.CUSTOM));
-
- ConnectedSubModel submodel;
-
- @Before
- public void build() {
- // Create a simple value property
- Property propertyMeta = new Property(100);
- propertyMeta.setIdShort(PROP);
-
- // Create an operation
- Operation op = new Operation((Function<Object[], Object> & Serializable) obj -> {
- return (int) obj[0] + (int) obj[1];
- });
- op.setIdShort(OP);
-
- // Create the SubModel using the created property and operation
- SubModel sm = new SubModel();
- sm.addSubModelElement(propertyMeta);
- sm.addSubModelElement(op);
- sm.setIdShort(ID);
- sm.setSemanticId(testSemanticIdRef);
-
- SubModelProvider provider = new SubModelProvider(new TypeDestroyingProvider(new VABLambdaProvider(sm)));
-
- // Create the ConnectedSubModel based on the manager
- submodel = new ConnectedSubModel(new VABConnectionManagerStub(provider).connectToVABElement(""));
- }
-
- /**
- * Tests if a SubModel's id can be retrieved correctly
- */
- @Test
- public void getIdTest() {
- assertEquals(ID, submodel.getIdShort());
- }
-
- /**
- * Tests if a SubModel's properties can be used correctly
- */
- @Test
- public void propertiesTest() throws Exception {
- // Retrieve all properties
- Map<String, IProperty> props = submodel.getProperties();
-
- // Check if number of properties is as expected
- assertEquals(1, props.size());
-
- // Check the value of the property
- IProperty prop = props.get(PROP);
- assertEquals(100, prop.get());
- }
-
- /**
- * Tests if a SubModel's operations can be used correctly
- *
- * @throws Exception
- */
- @Test
- public void operationsTest() throws Exception {
- // Retrieve all operations
- Map<String, IOperation> ops = submodel.getOperations();
-
- // Check if number of operations is as expected
- assertEquals(1, ops.size());
-
- // Check the operation itself
- IOperation op = ops.get(OP);
- assertEquals(5, op.invoke(2, 3));
- }
-
- @Test
- public void saveAndLoadPropertyTest() throws Exception {
-
- // Get sample DataElements and save them into SubModel
- Map<String, IProperty> testData = getTestDataProperty();
- for(ISubmodelElement element: testData.values()) {
- submodel.addSubModelElement(element);
- }
-
- // Load it
- Map<String, IProperty> map = submodel.getProperties();
-
- // Check if it loaded correctly
- checkProperties(map);
- }
-
- @Test
- public void saveAndLoadOperationTest() throws Exception {
- // Get sample Operations and save them into SubModel
- Map<String, IOperation> testOperations = getTestOperations();
- for(ISubmodelElement element: testOperations.values()) {
- submodel.addSubModelElement(element);
- }
-
- // Load it
- Map<String, IOperation> map = submodel.getOperations();
-
- // Check if it loaded correctly
- checkOperations(map);
- }
-
-
- @Test
- public void saveAndLoadSubmodelElementTest() throws Exception {
-
- // Get sample DataElements and save them into SubModel
- Map<String, IProperty> testDataElements = getTestDataProperty();
- for(ISubmodelElement element: testDataElements.values()) {
- submodel.addSubModelElement(element);
- }
-
- // Get sample Operations and save them into SubModel
- Map<String, IOperation> testOperations = getTestOperations();
- for(ISubmodelElement element: testOperations.values()) {
- submodel.addSubModelElement(element);
- }
-
- // Get sample SubmodelElements and save them into SubModel
- Map<String, ISubmodelElement> testSMElements = getTestSubmodelElements();
- for(ISubmodelElement element: testSMElements.values()) {
- submodel.addSubModelElement(element);
- }
-
- // Load it
- Map<String, ISubmodelElement> map = submodel.getSubmodelElements();
-
- // Check if it loaded correctly
- // Including DataElements and Operations as they are also SubmodelElements
- checkProperties(map);
- checkOperations(map);
- checkSubmodelElements(map);
- }
-
- /**
- * Tests if the semantic Id can be retrieved correctly
- */
- @Test
- public void semanticIdRetrievalTest() {
- IReference ref = submodel.getSemanticId();
- assertEquals(testSemanticIdRef, ref);
- }
-
- /**
- * Tests if the adding a submodel element is correctly done
- * Also checks the addition of parent reference to the submodel
- */
- @Test
- public void addSubModelElementTest() {
- Property property = new Property("testProperty");
- property.setIdShort("testIdShort");
- submodel.addSubModelElement(property);
-
- // creates an expected reference for assertion
- Reference expected = new Reference(new Key(KeyElements.SUBMODELELEMENT, true, "", IdentifierType.IRDI));
- assertEquals(expected, property.getParent());
- }
-
- /**
- * Generates test IDataElements
- */
- private Map<String, IProperty> getTestDataProperty() {
- Map<String, IProperty> ret = new HashMap<>();
-
- Property property = new Property();
- property.setIdShort(PROPERTY_ID);
- property.set("test2");
-
- ret.put(property.getIdShort(), property);
- return ret;
- }
-
- /**
- * Generates test IOperations
- */
- private Map<String, IOperation> getTestOperations() {
- Map<String, IOperation> ret = new HashMap<>();
-
- Operation operation = new Operation();
- operation.setIdShort(OPERATION_ID);
- ret.put(operation.getIdShort(), operation);
-
- return ret;
- }
-
- /**
- * Generates test ISubmodelElements
- */
- private Map<String, ISubmodelElement> getTestSubmodelElements() {
- Map<String, ISubmodelElement> ret = new HashMap<>();
-
- SubmodelElementCollection smECollection = new SubmodelElementCollection();
- smECollection.setIdShort(SUBMODEL_ELEM_COLLECTION_ID);
-
- // Create a Blob to use as Value for smECollection
- Blob blob = new Blob();
- blob.setIdShort(BLOB_ID);
-
- List<ISubmodelElement> values = new ArrayList<>();
- values.add(blob);
-
- smECollection.setValue(values);
- ret.put(smECollection.getIdShort(), smECollection);
-
- RelationshipElement relElement = new RelationshipElement();
- relElement.setIdShort(RELATIONSHIP_ELEM_ID);
- ret.put(relElement.getIdShort(), relElement);
-
- return ret;
- }
-
-
- /**
- * Checks if the given Map contains all expected IDataElements
- */
- private void checkProperties(Map<String, ? extends ISubmodelElement> actual) throws Exception {
- assertNotNull(actual);
-
- Map<String, IProperty> expected = getTestDataProperty();
-
- IProperty expectedProperty = expected.get(PROPERTY_ID);
- IProperty acutalProperty = (IProperty) actual.get(PROPERTY_ID);
- assertNotNull(acutalProperty);
- assertEquals(expectedProperty.get(), acutalProperty.get());
- }
-
- /**
- * Checks if the given Map contains all expected IOperations
- */
- private void checkOperations(Map<String, ? extends ISubmodelElement> actual) throws Exception {
- assertNotNull(actual);
-
- Map<String, IOperation> expected = getTestOperations();
-
- IOperation expectedOperation = expected.get(OPERATION_ID);
- IOperation actualOperation = (IOperation) actual.get(OPERATION_ID);
-
- assertNotNull(actualOperation);
- assertEquals(expectedOperation.getIdShort(), actualOperation.getIdShort());
- }
-
- /**
- * Checks if the given Map contains all expected ISubmodelElements
- */
- private void checkSubmodelElements(Map<String, ISubmodelElement> actual) throws Exception {
- assertNotNull(actual);
-
- Map<String, ISubmodelElement> expected = getTestSubmodelElements();
-
- ISubmodelElementCollection expectedCollection =
- (ISubmodelElementCollection) expected.get(SUBMODEL_ELEM_COLLECTION_ID);
- ISubmodelElementCollection actualCollection =
- (ISubmodelElementCollection) actual.get(SUBMODEL_ELEM_COLLECTION_ID);
-
- assertNotNull(actualCollection);
-
- Collection<ISubmodelElement> elements = actualCollection.getValue();
-
- // Check for correct Type
- for (ISubmodelElement iSubmodelElement: elements) {
- assertTrue(iSubmodelElement instanceof IBlob);
- }
-
- assertEquals(expectedCollection.getValue().size(), elements.size());
-
- IRelationshipElement expectedRelElem = (IRelationshipElement) expected.get(RELATIONSHIP_ELEM_ID);
- IRelationshipElement actualRelElem = (IRelationshipElement) actual.get(RELATIONSHIP_ELEM_ID);
-
- assertNotNull(actualRelElem);
- assertEquals(expectedRelElem.getIdShort(), actualRelElem.getIdShort());
- }
-
-}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedSubmodel.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedSubmodel.java
new file mode 100644
index 0000000..0c56bc7
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedSubmodel.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected;
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Function;
+
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
+import org.eclipse.basyx.submodel.metamodel.connected.ConnectedSubmodel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
+import org.eclipse.basyx.testsuite.regression.submodel.metamodel.TestSubmodelSuite;
+import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
+import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
+import org.eclipse.basyx.vab.support.TypeDestroyer;
+import org.eclipse.basyx.vab.support.TypeDestroyingProvider;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests if a ConnectSubmodel can be created and used correctly
+ *
+ * @author schnicke
+ *
+ */
+public class TestConnectedSubmodel extends TestSubmodelSuite {
+
+ // String constants used in this test case
+ private final static String OP = "add";
+
+ private final String OPERATION_ID = "operation_id";
+
+ ConnectedSubmodel submodel;
+
+ @Before
+ public void build() {
+
+ Submodel reference = getReferenceSubmodel();
+ // Create an operation
+ Operation op = new Operation((Function<Object[], Object> & Serializable) obj -> {
+ return (int) obj[0] + (int) obj[1];
+ });
+ Property aProp = new Property("a", 1);
+ aProp.setModelingKind(ModelingKind.TEMPLATE);
+ Property bProp = new Property("b", 2);
+ bProp.setModelingKind(ModelingKind.TEMPLATE);
+ Property rProp = new Property("r", 3);
+ rProp.setModelingKind(ModelingKind.TEMPLATE);
+ OperationVariable a = new OperationVariable(aProp);
+ OperationVariable b = new OperationVariable(bProp);
+ OperationVariable r = new OperationVariable(rProp);
+ op.setInputVariables(Arrays.asList(a, b));
+ op.setOutputVariables(Collections.singletonList(r));
+ op.setIdShort(OP);
+ reference.addSubmodelElement(op);
+
+ SubmodelProvider provider = new SubmodelProvider(new TypeDestroyingProvider(new VABLambdaProvider(reference)));
+
+ // Create the ConnectedSubmodel based on the manager
+ submodel = new ConnectedSubmodel(new VABConnectionManagerStub(provider).connectToVABElement(""));
+ }
+
+ /**
+ * Tests if a Submodel's operations can be used correctly
+ *
+ * @throws Exception
+ */
+ @Test
+ public void operationsTest() throws Exception {
+ // Retrieve all operations
+ Map<String, IOperation> ops = submodel.getOperations();
+
+ // Check if number of operations is as expected
+ assertEquals(1, ops.size());
+
+ // Check the operation itself
+ IOperation op = ops.get(OP);
+ assertEquals(5, op.invoke(2, 3));
+ }
+
+ @Test
+ public void saveAndLoadOperationTest() throws Exception {
+ // Get sample Operations and save them into Submodel
+ Map<String, IOperation> testOperations = getTestOperations();
+ for (ISubmodelElement element : testOperations.values()) {
+ submodel.addSubmodelElement(element);
+ }
+
+ // Load it
+ Map<String, IOperation> map = submodel.getOperations();
+
+ // Check if it loaded correctly
+ checkOperations(map);
+ }
+
+ @Test
+ public void testGetLocalCopy() {
+ Submodel reference = getReferenceSubmodel();
+ SubmodelProvider provider = new SubmodelProvider(new TypeDestroyingProvider(new VABLambdaProvider(reference)));
+
+ // Create the ConnectedSubmodel based on the manager
+ ConnectedSubmodel cSM = new ConnectedSubmodel(new VABConnectionManagerStub(provider).connectToVABElement(""));
+
+ Object expected = TypeDestroyer.destroyType(reference);
+ Object actual = cSM.getLocalCopy();
+ assertEquals(expected, actual);
+ }
+
+ /**
+ * Generates test IOperations
+ */
+ private Map<String, IOperation> getTestOperations() {
+ Map<String, IOperation> ret = new HashMap<>();
+
+ Operation operation = new Operation();
+ operation.setIdShort(OPERATION_ID);
+ ret.put(operation.getIdShort(), operation);
+
+ return ret;
+ }
+
+ /**
+ * Checks if the given Map contains all expected IOperations
+ */
+ private void checkOperations(Map<String, ? extends ISubmodelElement> actual) throws Exception {
+ assertNotNull(actual);
+
+ Map<String, IOperation> expected = getTestOperations();
+
+ IOperation expectedOperation = expected.get(OPERATION_ID);
+ IOperation actualOperation = (IOperation) actual.get(OPERATION_ID);
+
+ assertNotNull(actualOperation);
+ assertEquals(expectedOperation.getIdShort(), actualOperation.getIdShort());
+ }
+
+ @Override
+ protected ConnectedSubmodel getSubmodel() {
+ return submodel;
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedSubmodelElementCollection.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedSubmodelElementCollection.java
index 62f15ad..9dfc2d6 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedSubmodelElementCollection.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedSubmodelElementCollection.java
@@ -1,18 +1,36 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected;
import static org.junit.Assert.assertEquals;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
import java.util.Map;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.ConnectedSubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementCollectionProvider;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
import org.eclipse.basyx.vab.support.TypeDestroyer;
import org.junit.Before;
@@ -29,7 +47,7 @@
private static final String PROP = "prop";
private static final String OPERATION = "sum";
- ISubmodelElementCollection prop;
+ ConnectedSubmodelElementCollection prop;
@Before
public void build() {
@@ -41,21 +59,36 @@
Operation operation = new Operation(arr -> {
return (int) arr[0] + (int) arr[1];
});
+ Property aProp = new Property("a", 1);
+ aProp.setModelingKind(ModelingKind.TEMPLATE);
+ Property bProp = new Property("b", 2);
+ bProp.setModelingKind(ModelingKind.TEMPLATE);
+ Property rProp = new Property("r", 3);
+ rProp.setModelingKind(ModelingKind.TEMPLATE);
+ OperationVariable a = new OperationVariable(aProp);
+ OperationVariable b = new OperationVariable(bProp);
+ OperationVariable r = new OperationVariable(rProp);
+ operation.setInputVariables(Arrays.asList(a, b));
+ operation.setOutputVariables(Collections.singletonList(r));
operation.setIdShort(OPERATION);
// Create ComplexDataProperty containing the created operation and property
- SubmodelElementCollection complex = new SubmodelElementCollection();
- complex.addElement(propertyMeta);
- complex.addElement(operation);
+ SubmodelElementCollection complex = new SubmodelElementCollection("SubmodelCollectionId");
+ complex.addSubmodelElement(propertyMeta);
+ complex.addSubmodelElement(operation);
+ complex.setIdShort("CollectionId");
- Map<String, Object> destroyType = TypeDestroyer.destroyType(complex);
+ Submodel sm = new Submodel("submodelId", new ModelUrn("testUrn"));
+ sm.addSubmodelElement(complex);
+
+ Map<String, Object> destroyType = TypeDestroyer.destroyType(sm);
// Create a dummy connection manager containing the created ContainerProperty map
// The model is wrapped in the corresponding ModelProvider that implements the API access
VABConnectionManagerStub manager = new VABConnectionManagerStub(
- new SubmodelElementCollectionProvider(new VABLambdaProvider(destroyType)));
+ new SubmodelProvider(new VABLambdaProvider(destroyType)));
// Retrieve the ConnectedContainerProperty
- prop = new ConnectedSubmodelElementCollection(manager.connectToVABElement(""));
+ prop = new ConnectedSubmodelElementCollection(manager.connectToVABElement("").getDeepProxy("/submodel/submodelElements/" + complex.getIdShort()));
}
/**
@@ -75,7 +108,7 @@
IProperty prop = props.get(PROP);
// Check contained values
- assertEquals(4, prop.get());
+ assertEquals(4, prop.getValue());
}
/**
@@ -95,4 +128,43 @@
// Check operation invocation
assertEquals(5, sum.invoke(2, 3));
}
+
+ @Test
+ public void testSetValue() {
+ Property property = new Property("testProperty");
+ property.setIdShort(PROP);
+
+
+ Collection<ISubmodelElement> newValue = new ArrayList<>();
+ newValue.add(property);
+
+ prop.setValue(newValue);
+
+ Map<String, ISubmodelElement> value = prop.getSubmodelElements();
+ IProperty property2 = (IProperty) value.get(PROP);
+
+ assertEquals("testProperty", property2.getValue());
+ }
+
+ @Test
+ public void testGetSubmodelElement() {
+ ISubmodelElement element = prop.getSubmodelElement(PROP);
+ assertEquals(PROP, element.getIdShort());
+ }
+
+ @Test(expected = ResourceNotFoundException.class)
+ public void testDeleteSubmodelElement() {
+ prop.deleteSubmodelElement(PROP);
+ prop.getSubmodelElement(PROP);
+ }
+
+ @Test
+ public void testAddSubmodelElement() {
+ String newId = "abc";
+ Property newProp = new Property(6);
+ newProp.setIdShort(newId);
+ prop.addSubmodelElement(newProp);
+ ISubmodelElement element = prop.getSubmodelElement(newId);
+ assertEquals(newId, element.getIdShort());
+ }
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/TestConnectedSubmodelElementFactory.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/TestConnectedSubmodelElementFactory.java
index 9bb6631..0cdb7b9 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/TestConnectedSubmodelElementFactory.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/TestConnectedSubmodelElementFactory.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement;
import static org.junit.Assert.assertEquals;
@@ -20,19 +29,19 @@
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.event.ConnectedBasicEvent;
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.operation.ConnectedOperation;
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.relationship.ConnectedRelationshipElement;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Blob;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Range;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.ReferenceElement;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.Range;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.event.BasicEvent;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElement;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
import org.eclipse.basyx.vab.support.TypeDestroyingProvider;
@@ -76,11 +85,9 @@
Map<String, Object> values = new HashMap<>();
- values.put(SubmodelElementProvider.PROPERTIES, dataElements);
- values.put(SubmodelElementProvider.OPERATIONS, operations);
- values.put(SubModel.SUBMODELELEMENT, submodelElements);
+ values.put(Submodel.SUBMODELELEMENT, submodelElements);
- proxy = new VABElementProxy("", new SubModelProvider(new TypeDestroyingProvider(new VABLambdaProvider(values))));
+ proxy = new VABElementProxy("", new SubmodelProvider(new TypeDestroyingProvider(new VABLambdaProvider(values))));
}
/**
@@ -161,7 +168,7 @@
public void testGetProperties() {
Map<String, IProperty> properties =
ConnectedSubmodelElementFactory.getProperties(
- proxy, SubmodelElementProvider.PROPERTIES, SubmodelElementProvider.PROPERTIES);
+ proxy, MultiSubmodelElementProvider.ELEMENTS, MultiSubmodelElementProvider.ELEMENTS);
assertEquals(1, properties.size());
assertTrue(properties.get(PROPERTY_ID) instanceof ConnectedProperty);
@@ -174,7 +181,7 @@
public void testGetOperations() {
Map<String, IOperation> operations =
ConnectedSubmodelElementFactory.getOperations(
- proxy, SubmodelElementProvider.OPERATIONS, SubmodelElementProvider.OPERATIONS);
+ proxy, MultiSubmodelElementProvider.ELEMENTS, MultiSubmodelElementProvider.ELEMENTS);
assertEquals(1, operations.size());
assertTrue(operations.get(OPERATION_ID) instanceof ConnectedOperation);
@@ -187,7 +194,7 @@
public void testGetSubmodelElements() {
Map<String, ISubmodelElement> submodelElements =
ConnectedSubmodelElementFactory.getConnectedSubmodelElements(
- proxy, SubModel.SUBMODELELEMENT, SubModel.SUBMODELELEMENT);
+ proxy, Submodel.SUBMODELELEMENT, Submodel.SUBMODELELEMENT);
assertEquals(10, submodelElements.size());
assertTrue(submodelElements.get(PROPERTY_ID) instanceof ConnectedProperty);
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedBlob.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedBlob.java
index e6866ba..425f108 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedBlob.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedBlob.java
@@ -1,14 +1,23 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.dataelement;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import java.util.Arrays;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedBlob;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Blob;
-import org.eclipse.basyx.submodel.restapi.PropertyProvider;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
import org.eclipse.basyx.vab.support.TypeDestroyingProvider;
@@ -22,18 +31,19 @@
*
*/
public class TestConnectedBlob {
+ public final String BLOB_CONTENT = "BLOB_VALUE";
- ConnectedBlob connectedBlob;
- Blob blob;
+ protected ConnectedBlob connectedBlob;
+ protected Blob blob;
@Before
public void build() {
- blob = new Blob();
- blob.setValue("BLOB_VALUE".getBytes());
- blob.setMimeType("mimeType");
+ blob = new Blob("testIdShort", "mimeType");
+ byte[] value = BLOB_CONTENT.getBytes(StandardCharsets.UTF_8);
+ blob.setByteArrayValue(value);
VABConnectionManagerStub manager = new VABConnectionManagerStub(
- new PropertyProvider(new TypeDestroyingProvider(new VABLambdaProvider(blob))));
+ new SubmodelElementProvider(new TypeDestroyingProvider(new VABLambdaProvider(blob))));
connectedBlob = new ConnectedBlob(manager.connectToVABElement(""));
}
@@ -43,8 +53,19 @@
*/
@Test
public void testGetValue() {
- assertTrue(Arrays.equals(blob.getValue(), connectedBlob.getValue()));
- assertArrayEquals(blob.getValue(), connectedBlob.getValue());
+ assertEquals(blob.getValue(), connectedBlob.getValue());
+ byte[] byteArray = BLOB_CONTENT.getBytes(StandardCharsets.UTF_8);
+ assertEquals(Base64.getEncoder().encodeToString(byteArray), blob.getValue());
+
+ }
+
+ /**
+ * Tests if getByteArrayValue() returns the correct value
+ */
+ @Test
+ public void testGetByteArrayValue() {
+ assertArrayEquals(blob.getByteArrayValue(), connectedBlob.getByteArrayValue());
+ assertArrayEquals(BLOB_CONTENT.getBytes(StandardCharsets.UTF_8), connectedBlob.getByteArrayValue());
}
/**
@@ -55,4 +76,43 @@
assertEquals(blob.getMimeType(), connectedBlob.getMimeType());
}
+ /**
+ * Tests if getUTF8String() returns the correct value
+ */
+ @Test
+ public void testGetUTF8() {
+ assertEquals(BLOB_CONTENT, connectedBlob.getUTF8String());
+ }
+
+ /**
+ * Tests if SetUTF8 sets the correct value
+ */
+ @Test
+ public void testSetUTF8() {
+ connectedBlob.setUTF8String("NEW");
+ assertEquals("NEW", connectedBlob.getUTF8String());
+ assertArrayEquals("NEW".getBytes(StandardCharsets.UTF_8), connectedBlob.getByteArrayValue());
+ }
+
+ /**
+ * Tests if SetByteArrayValue sets the correct value
+ */
+ @Test
+ public void testSetByteArray() {
+ byte[] newArrayValue = "NEW".getBytes(StandardCharsets.UTF_8);
+ connectedBlob.setByteArrayValue(newArrayValue);
+ assertEquals("NEW", connectedBlob.getUTF8String());
+ assertArrayEquals("NEW".getBytes(StandardCharsets.UTF_8), connectedBlob.getByteArrayValue());
+ }
+
+ /**
+ * Tests if setValue sets the correct value
+ */
+ @Test
+ public void testSetValue() {
+ byte[] newArrayValue = "NEW".getBytes(StandardCharsets.UTF_8);
+ String newStringValue = Base64.getEncoder().encodeToString(newArrayValue);
+ connectedBlob.setValue(newStringValue);
+ assertEquals("NEW", connectedBlob.getUTF8String());
+ }
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedFile.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedFile.java
index a4e7e25..da0a241 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedFile.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedFile.java
@@ -1,10 +1,19 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.dataelement;
import static org.junit.Assert.assertEquals;
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedFile;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
-import org.eclipse.basyx.submodel.restapi.PropertyProvider;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
import org.eclipse.basyx.vab.support.TypeDestroyingProvider;
@@ -25,11 +34,12 @@
@Before
public void build() {
file = new File();
+ file.setIdShort("testIdShort");
file.setValue("FILE_VALUE");
file.setMimeType("mimeType");
VABConnectionManagerStub manager = new VABConnectionManagerStub(
- new PropertyProvider(new TypeDestroyingProvider(new VABLambdaProvider(file))));
+ new SubmodelElementProvider(new TypeDestroyingProvider(new VABLambdaProvider(file))));
connectedFile = new ConnectedFile(manager.connectToVABElement(""));
}
@@ -50,4 +60,12 @@
assertEquals(file.getMimeType(), connectedFile.getMimeType());
}
+ @Test
+ public void testSetValue() {
+ String value = connectedFile.getValue();
+ value += "TEST";
+ connectedFile.setValue(value);
+ assertEquals(value, connectedFile.getValue());
+ }
+
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedMultiLanguageProperty.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedMultiLanguageProperty.java
index 5b53146..8e45751 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedMultiLanguageProperty.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedMultiLanguageProperty.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.dataelement;
import static org.junit.Assert.assertEquals;
@@ -9,7 +18,7 @@
import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
-import org.eclipse.basyx.submodel.restapi.PropertyProvider;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
import org.eclipse.basyx.vab.support.TypeDestroyingProvider;
@@ -36,7 +45,7 @@
MLP = new MultiLanguageProperty(ref, langStrings);
VABConnectionManagerStub manager = new VABConnectionManagerStub(
- new PropertyProvider(new TypeDestroyingProvider(new VABLambdaProvider(MLP))));
+ new SubmodelElementProvider(new TypeDestroyingProvider(new VABLambdaProvider(MLP))));
// Retrieve the ConnectedContainerProperty
connectedMLP = new ConnectedMultiLanguageProperty(manager.connectToVABElement(""));
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedRange.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedRange.java
index e83a023..db88e50 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedRange.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedRange.java
@@ -1,10 +1,21 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.dataelement;
import static org.junit.Assert.assertEquals;
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedRange;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Range;
-import org.eclipse.basyx.submodel.restapi.PropertyProvider;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.Range;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.RangeValue;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
import org.eclipse.basyx.vab.support.TypeDestroyingProvider;
@@ -24,10 +35,10 @@
@Before
public void build() {
- range = new Range("valueType", new Integer(1), new Integer(10));
-
+ range = new Range(ValueType.Integer, new Integer(1), new Integer(10));
+ range.setIdShort("testIdShort");
VABConnectionManagerStub manager = new VABConnectionManagerStub(
- new PropertyProvider(new TypeDestroyingProvider(new VABLambdaProvider(range))));
+ new SubmodelElementProvider(new TypeDestroyingProvider(new VABLambdaProvider(range))));
connectedRange = new ConnectedRange(manager.connectToVABElement(""));
}
@@ -55,4 +66,28 @@
public void testGetMax() {
assertEquals(range.getMax(), connectedRange.getMax());
}
+
+ /**
+ * Tests if getValue() returns the correct value
+ */
+ @Test
+ public void testGetValue() {
+ RangeValue rv = connectedRange.getValue();
+ assertEquals(range.getMin(), rv.getMin());
+ assertEquals(range.getMax(), rv.getMax());
+ }
+
+ /**
+ * Tests if setValue() sets the correct value.
+ */
+ @Test
+ public void testSetValue() {
+ RangeValue value = new RangeValue(2, 8);
+
+ connectedRange.setValue(value);
+
+ assertEquals(2, connectedRange.getMin());
+ assertEquals(8, connectedRange.getMax());
+ assertEquals(range.getValueType(), connectedRange.getValueType());
+ }
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedReferenceElement.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedReferenceElement.java
index 562d7d8..049abc0 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedReferenceElement.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedReferenceElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.dataelement;
import static org.junit.Assert.assertEquals;
@@ -8,7 +17,7 @@
import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.ReferenceElement;
-import org.eclipse.basyx.submodel.restapi.PropertyProvider;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
import org.eclipse.basyx.vab.support.TypeDestroyingProvider;
@@ -34,7 +43,7 @@
refElem = new ReferenceElement(ref);
VABConnectionManagerStub manager = new VABConnectionManagerStub(
- new PropertyProvider(new TypeDestroyingProvider(new VABLambdaProvider(refElem))));
+ new SubmodelElementProvider(new TypeDestroyingProvider(new VABLambdaProvider(refElem))));
connectedRefElem = new ConnectedReferenceElement(manager.connectToVABElement(""));
}
@@ -46,4 +55,4 @@
public void testGetValue() {
assertEquals(refElem.getValue(), connectedRefElem.getValue());
}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/event/TestConnectedBasicEvent.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/event/TestConnectedBasicEvent.java
index 58f8f91..ad870f5 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/event/TestConnectedBasicEvent.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/event/TestConnectedBasicEvent.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.event;
import static org.junit.Assert.assertEquals;
@@ -8,7 +17,7 @@
import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.event.BasicEvent;
-import org.eclipse.basyx.submodel.restapi.PropertyProvider;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
import org.eclipse.basyx.vab.support.TypeDestroyingProvider;
@@ -34,7 +43,7 @@
event = new BasicEvent(ref);
VABConnectionManagerStub manager = new VABConnectionManagerStub(
- new PropertyProvider(new TypeDestroyingProvider(new VABLambdaProvider(event))));
+ new SubmodelElementProvider(new TypeDestroyingProvider(new VABLambdaProvider(event))));
connectedEvent = new ConnectedBasicEvent(manager.connectToVABElement(""));
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/operation/TestConnectedOperation.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/operation/TestConnectedOperation.java
index ecd5f16..3674dcd 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/operation/TestConnectedOperation.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/operation/TestConnectedOperation.java
@@ -1,26 +1,25 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.operation;
-import static org.junit.Assert.assertEquals;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
import java.util.Map;
-import java.util.function.Function;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.operation.ConnectedOperation;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDef;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationHelper;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
import org.eclipse.basyx.submodel.restapi.OperationProvider;
+import org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.operation.TestOperationSuite;
import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
import org.eclipse.basyx.vab.manager.VABConnectionManager;
import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
import org.eclipse.basyx.vab.support.TypeDestroyer;
-import org.junit.Before;
-import org.junit.Test;
/**
* Tests if a ConnectedOperation can be created and used correctly
@@ -29,42 +28,16 @@
* @author schnicke
*
*/
-public class TestConnectedOperation {
+public class TestConnectedOperation extends TestOperationSuite {
- IOperation operation;
-
- @Before
- public void build() {
- // Create the operation map using the MetaModelElementFactory
- Operation op = new Operation((Function<Object[], Object>) obj -> {
- return (int) obj[0] + (int) obj[1];
- });
-
- List<OperationVariable> in = new ArrayList<>();
-
- in.add(new OperationVariable(OperationHelper.createPropertyTemplate(PropertyValueTypeDef.Integer)));
- in.add(new OperationVariable(OperationHelper.createPropertyTemplate(PropertyValueTypeDef.Integer)));
-
- op.setInputVariables(in);
-
- op.setOutputVariables(Collections.singletonList(new OperationVariable(OperationHelper.createPropertyTemplate(PropertyValueTypeDef.Integer))));
-
- Map<String, Object> destroyType = TypeDestroyer.destroyType(op);
+ @Override
+ protected IOperation prepareOperation(Operation operation) {
+ Map<String, Object> destroyType = TypeDestroyer.destroyType(operation);
// Create a dummy connection manager containing the created Operation map
VABConnectionManager manager = new VABConnectionManagerStub(
new OperationProvider(new VABMapProvider(destroyType)));
// Create the ConnectedOperation based on the manager stub
- operation = new ConnectedOperation(manager.connectToVABElement(""));
- }
-
- /**
- * Tests if a operation invocation is handled correctly
- *
- * @throws Exception
- */
- @Test
- public void invokeTest() throws Exception {
- assertEquals(4, operation.invoke(2, 2));
+ return new ConnectedOperation(manager.connectToVABElement(""));
}
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/relationship/TestConnectedAnnotatedRelationshipElement.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/relationship/TestConnectedAnnotatedRelationshipElement.java
new file mode 100644
index 0000000..a101f93
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/relationship/TestConnectedAnnotatedRelationshipElement.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.relationship;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IDataElement;
+import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.relationship.ConnectedAnnotatedRelationshipElement;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.AnnotatedRelationshipElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.AnnotatedRelationshipElementValue;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
+import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
+import org.eclipse.basyx.vab.support.TypeDestroyingProvider;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests if a ConnectedAnnotatedRelationshipElement can be created and used correctly
+ *
+ * @author conradi
+ *
+ */
+public class TestConnectedAnnotatedRelationshipElement {
+
+ ConnectedAnnotatedRelationshipElement connectedElement;
+ AnnotatedRelationshipElement element;
+
+ @Before
+ public void build() {
+ Reference ref1 = new Reference(new Key(KeyElements.BLOB, true, "1", IdentifierType.CUSTOM));
+ Reference ref2 = new Reference(new Key(KeyElements.FILE, false, "2", IdentifierType.IRDI));
+
+ Property property = new Property("PropertyId", 10);
+ List<IDataElement> annotations = new ArrayList<>();
+ annotations.add(property);
+
+ element = new AnnotatedRelationshipElement("testId", ref1, ref2);
+ element.setAnnotation(annotations);
+
+ VABConnectionManagerStub manager = new VABConnectionManagerStub(
+ new SubmodelElementProvider(new TypeDestroyingProvider(new VABLambdaProvider(element))));
+
+ connectedElement = new ConnectedAnnotatedRelationshipElement(manager.connectToVABElement(""));
+ }
+
+ /**
+ * Tests if getValue() returns the correct value
+ */
+ @Test
+ public void testGetValue() {
+ AnnotatedRelationshipElementValue value = connectedElement.getValue();
+ assertEquals(element.getFirst(), value.getFirst());
+ assertEquals(element.getSecond(), value.getSecond());
+ assertEquals(element.getValue().getAnnotations().size(), value.getAnnotations().size());
+ }
+
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/relationship/TestConnectedRelationshipElement.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/relationship/TestConnectedRelationshipElement.java
index 95dd6a3..49308e7 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/relationship/TestConnectedRelationshipElement.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/relationship/TestConnectedRelationshipElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.relationship;
import static org.junit.Assert.assertEquals;
@@ -8,7 +17,8 @@
import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElement;
-import org.eclipse.basyx.submodel.restapi.PropertyProvider;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElementValue;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
import org.eclipse.basyx.vab.support.TypeDestroyingProvider;
@@ -32,28 +42,23 @@
Reference ref1 = new Reference(new Key(KeyElements.BLOB, true, "1", IdentifierType.CUSTOM));
Reference ref2 = new Reference(new Key(KeyElements.FILE, false, "2", IdentifierType.IRDI));
- relElem = new RelationshipElement(ref1, ref2);
+ relElem = new RelationshipElement("testId", ref1, ref2);
VABConnectionManagerStub manager = new VABConnectionManagerStub(
- new PropertyProvider(new TypeDestroyingProvider(new VABLambdaProvider(relElem))));
+ new SubmodelElementProvider(new TypeDestroyingProvider(new VABLambdaProvider(relElem))));
connectedRelElem = new ConnectedRelationshipElement(manager.connectToVABElement(""));
}
/**
- * Tests if getFirst() returns the correct value
+ * Tests if getValue() returns the correct value
*/
@Test
- public void testGetFirst() {
- assertEquals(relElem.getFirst(), connectedRelElem.getFirst());
+ public void testGetValue() {
+ RelationshipElementValue value = connectedRelElem.getValue();
+ assertEquals(relElem.getFirst(), value.getFirst());
+ assertEquals(relElem.getSecond(), value.getSecond());
}
- /**
- * Tests if getSecond() returns the correct value
- */
- @Test
- public void testGetSecond() {
- assertEquals(relElem.getSecond(), connectedRelElem.getSecond());
- }
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/facade/TestSubmodelElementMapCollectionConverter.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/facade/TestSubmodelElementMapCollectionConverter.java
new file mode 100644
index 0000000..ddc55c9
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/facade/TestSubmodelElementMapCollectionConverter.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.metamodel.facade;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.vab.support.TypeDestroyer;
+import org.junit.Test;
+
+/**
+ * Tests for SubmodelElementMapCollectionConverter
+ *
+ * @author conradi
+ *
+ */
+public class TestSubmodelElementMapCollectionConverter {
+
+ private static final String ID_SHORT = "testElement";
+
+
+ @Test
+ public void testMapToSM() {
+ Submodel sm = getSM();
+
+ // Replace the smElement Map with a Collection
+ sm.put(Submodel.SUBMODELELEMENT, sm.getSubmodelElements().values());
+
+ // Make a Map from the SM, as if it was transferred over the VAB
+ Map<String, Object> map = TypeDestroyer.destroyType(sm);
+
+
+ sm = SubmodelElementMapCollectionConverter.mapToSM(map);
+
+ assertTrue(sm.get(Submodel.SUBMODELELEMENT) instanceof Map<?, ?>);
+
+ assertNotNull(sm.getSubmodelElements().get(ID_SHORT));
+ assertTrue(sm.getSubmodelElements().get(ID_SHORT) instanceof Property);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testSMToMap() {
+ Submodel sm = getSM();
+
+ Map<String, Object> map = SubmodelElementMapCollectionConverter.smToMap(sm);
+
+ assertTrue(map.get(Submodel.SUBMODELELEMENT) instanceof Collection<?>);
+ assertEquals(1, ((Collection<ISubmodelElement>) map.get(Submodel.SUBMODELELEMENT)).size());
+ }
+
+
+ private Submodel getSM() {
+ Submodel sm = new Submodel("submodelIdShort", new ModelUrn("submodelUrn"));
+ Property property = new Property(ID_SHORT, ValueType.String);
+
+ sm.addSubmodelElement(property);
+ return sm;
+ }
+
+
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/TestSubmodel.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/TestSubmodel.java
index e287d2f..4b6ae58 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/TestSubmodel.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/TestSubmodel.java
@@ -1,72 +1,64 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashMap;
import java.util.Map;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
-import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.haskind.HasKind;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Formula;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifiable;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.testsuite.regression.submodel.metamodel.TestSubmodelSuite;
+import org.junit.Before;
import org.junit.Test;
/**
- * Ensures correct behavior of {@link SubModel}
+ * Ensures correct behavior of {@link Submodel}
*
* @author haque
*
*/
-public class TestSubmodel {
-
+public class TestSubmodel extends TestSubmodelSuite {
+
+ ISubmodel submodel;
+
+ @Before
+ public void build() {
+ submodel = getReferenceSubmodel();
+ }
+
@Test
- public void testAddSubmodelElement() {
- String submodelId = "submodelID";
- String identifierId = "testId";
- String propId = "propertyID";
-
- HasSemantics semantics = new HasSemantics(new Reference(new Key(KeyElements.ASSET, true, "testValue", IdentifierType.IRDI)));
- Identifiable identifiable = new Identifiable("1", "5", submodelId, "testCategory", new LangStrings("DE", "test"), IdentifierType.IRDI, identifierId);
- Qualifiable qualifiable = new Qualifiable(new Formula(Collections.singleton(new Reference(new Key(KeyElements.BLOB, true, "TestValue", IdentifierType.IRI)))));
- HasDataSpecification specification = new HasDataSpecification(new ArrayList<>(), Collections.singleton(new Reference(new Key(KeyElements.BLOB, true, "testRef", IdentifierType.IRI))));
- HasKind hasKind = new HasKind(ModelingKind.INSTANCE);
-
- // Create a submodel
- SubModel subModel = new SubModel(semantics, identifiable, qualifiable, specification, hasKind);
-
- //Create a submodel element and set an id to it
- Property property = new Property("testValue");
- property.setIdShort(propId);
-
- // Add the element to the submodel
- subModel.addSubModelElement(property);
-
- // Create expected map of added submodel element for assertion
- Map<String, ISubmodelElement> submodelElemMap = new HashMap<String, ISubmodelElement>();
- submodelElemMap.put(propId, property);
- assertEquals(submodelElemMap, subModel.getSubmodelElements());
+ public void testParentAddSubmodelElement() {
+ Property prop = new Property("propIdShort", ValueType.String);
+ IIdentifier identifier = new ModelUrn("testId");
+ Submodel submodel = new Submodel("smIdShort", identifier);
+ submodel.addSubmodelElement(prop);
// Create expected parent of the element for assertion
- Reference expectedParent = new Reference(new Key(KeyElements.SUBMODEL, true, identifierId, IdentifierType.IRDI));
- assertEquals(expectedParent, property.getParent());
+ Reference expectedParent = new Reference(new Key(KeyElements.SUBMODEL, true, identifier.getId(), identifier.getIdType()));
+ assertEquals(expectedParent, prop.getParent());
}
/**
- * Tests if a SubModel containing a list for SUBMODELELEMENT is correctly
+ * Tests if a Submodel containing a list for SUBMODELELEMENT is correctly
* handled by the facading submodel. This is necessary because the submodel
* serialization does specify SUBMODELELEMENT as list
*/
@@ -79,12 +71,18 @@
expected.setIdShort(propId);
// Create test submodel and force key SUBMODELELEMENT to contain a list
- SubModel sm = new SubModel();
- sm.put(SubModel.SUBMODELELEMENT, Collections.singleton(expected));
+ String id = "testIdShort";
+ Submodel sm = new Submodel(id, new Identifier(IdentifierType.IRDI, id));
+ sm.put(Submodel.SUBMODELELEMENT, Collections.singleton(expected));
// Check if the facade converts the SUBMODELELEMENT value correctly
- SubModel facade = SubModel.createAsFacade(sm);
- assertTrue(facade.get(SubModel.SUBMODELELEMENT) instanceof Map<?, ?>);
+ Submodel facade = Submodel.createAsFacade(sm);
+ assertTrue(facade.get(Submodel.SUBMODELELEMENT) instanceof Map<?, ?>);
assertEquals(expected, facade.getSubmodelElements().get(propId));
}
+
+ @Override
+ protected ISubmodel getSubmodel() {
+ return submodel;
+ }
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestDataSpecificationIEC61360.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestDataSpecificationIEC61360.java
index 196a755..b001dc4 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestDataSpecificationIEC61360.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestDataSpecificationIEC61360.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.dataspecification;
import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestEmbeddedDataSpecification.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestEmbeddedDataSpecification.java
index 9cac7a6..24bdb99 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestEmbeddedDataSpecification.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestEmbeddedDataSpecification.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.dataspecification;
import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestValueReferencePair.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestValueReferencePair.java
index 9267004..b0e84f1 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestValueReferencePair.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestValueReferencePair.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.dataspecification;
import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/identifier/TestIdentifier.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/identifier/TestIdentifier.java
index c7c8584..c1e1165 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/identifier/TestIdentifier.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/identifier/TestIdentifier.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.identifier;
import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/modeltype/TestModelType.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/modeltype/TestModelType.java
index b927f1c..71c22a9 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/modeltype/TestModelType.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/modeltype/TestModelType.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.modeltype;
import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/parts/TestConceptDescription.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/parts/TestConceptDescription.java
index 6eee6dc..1592000 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/parts/TestConceptDescription.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/parts/TestConceptDescription.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.parts;
import static org.junit.Assert.assertEquals;
@@ -40,7 +49,7 @@
@Before
public void buildConceptDescription() {
- description = new ConceptDescription();
+ description = new ConceptDescription("testConceptDescriptionID", new Identifier(IdentifierType.IRDI, "testId"));
}
@Test
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestAdministrativeInformation.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestAdministrativeInformation.java
index e7a21ba..64315ed 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestAdministrativeInformation.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestAdministrativeInformation.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier;
import static org.junit.Assert.assertEquals;
@@ -56,16 +65,34 @@
}
@Test
- public void testSetVersion() {
+ public void testSetVersionInformation() {
String newVersionString = "2.0";
- information.setVersion(newVersionString);
+ String newRevisionString = "2.0.1";
+ information.setVersionInformation(newVersionString, newRevisionString);
assertEquals(newVersionString, information.getVersion());
+ assertEquals(newRevisionString, information.getRevision());
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testSetVersionInformationExceptionEmptyString() {
+ String newVersionString = "";
+ String newRevisionString = "2.0.1";
+ information.setVersionInformation(newVersionString, newRevisionString);
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testSetVersionInformationExceptionNullString() {
+ String newVersionString = null;
+ String newRevisionString = "2.0.1";
+ information.setVersionInformation(newVersionString, newRevisionString);
}
@Test
- public void testSetRevision() {
- String newRevisionString = "2.0.1";
- information.setRevision(newRevisionString);
+ public void testSetVersionInformationNoRevision() {
+ String newVersionString = "";
+ String newRevisionString = "";
+ information.setVersionInformation(newVersionString, newRevisionString);
+ assertEquals(newVersionString, information.getVersion());
assertEquals(newRevisionString, information.getRevision());
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestHasDataSpecification.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestHasDataSpecification.java
index 0ed4b74..6c4128c 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestHasDataSpecification.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestHasDataSpecification.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier;
import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestHasSemantics.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestHasSemantics.java
index 01d8861..2d753ff 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestHasSemantics.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestHasSemantics.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier;
import static org.junit.Assert.assertEquals;
@@ -45,7 +54,7 @@
KeyElements keyElements = KeyElements.BLOB;
boolean isLocal = true;
Reference reference = new Reference(identifier, keyElements, isLocal);
- semantics.setSemanticID(reference);
+ semantics.setSemanticId(reference);
assertEquals(reference, semantics.getSemanticId());
}
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestIdentifiable.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestIdentifiable.java
index 34f842e..3206a38 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestIdentifiable.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestIdentifiable.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier;
import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestLangString.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestLangString.java
index 5fef18d..d5d36b6 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestLangString.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestLangString.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier;
import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestLangStrings.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestLangStrings.java
index 5f02fb9..5a6fd7e 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestLangStrings.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestLangStrings.java
@@ -1,6 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Collection;
@@ -75,4 +86,18 @@
assertEquals(languageSet, langStrings.getLanguages());
}
+ @Test
+ public void testIsLangStrings() {
+ LangStrings langStrings = new LangStrings(LANGUAGE1, TEXT1);
+
+ assertTrue(LangStrings.isLangStrings(langStrings));
+
+ LangString langString = new LangString(LANGUAGE1, TEXT1);
+ langString.put("language", null);
+
+ langStrings.add(langString);
+
+ assertFalse(LangStrings.isLangStrings(langStrings));
+ }
+
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestReferable.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestReferable.java
index efa1b8a..d16211c 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestReferable.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestReferable.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier;
import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/haskind/TestHasKind.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/haskind/TestHasKind.java
index 711b21f..f2f79b2 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/haskind/TestHasKind.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/haskind/TestHasKind.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier.haskind;
import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestFormula.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestFormula.java
index 016cc51..e2bd682 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestFormula.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestFormula.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier.qualifiable;
import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestQualifiable.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestQualifiable.java
index 38da65f..0ad6c11 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestQualifiable.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestQualifiable.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier.qualifiable;
import static org.junit.Assert.assertEquals;
@@ -29,7 +38,7 @@
@Test
public void testConstructor1() {
Qualifiable qualifiable = new Qualifiable(FORMULA1);
- assertEquals(Collections.singleton(FORMULA1), qualifiable.getQualifier());
+ assertEquals(Collections.singleton(FORMULA1), qualifiable.getQualifiers());
}
@Test
@@ -39,14 +48,14 @@
constraints.add(FORMULA2);
Qualifiable qualifiable = new Qualifiable(constraints);
- assertEquals(constraints, qualifiable.getQualifier());
+ assertEquals(constraints, qualifiable.getQualifiers());
}
@Test
public void testSetQualifier() {
Qualifiable qualifiable = new Qualifiable(FORMULA1);
- qualifiable.setQualifier(Collections.singleton(FORMULA2));
- assertEquals(Collections.singleton(FORMULA2), qualifiable.getQualifier());
+ qualifiable.setQualifiers(Collections.singleton(FORMULA2));
+ assertEquals(Collections.singleton(FORMULA2), qualifiable.getQualifiers());
}
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestQualifier.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestQualifier.java
index 7f62e34..3b9cbad 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestQualifier.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestQualifier.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier.qualifiable;
import static org.junit.Assert.assertEquals;
@@ -7,6 +16,8 @@
import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifier;
import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueTypeHelper;
import org.junit.Before;
import org.junit.Test;
@@ -22,7 +33,7 @@
private static final boolean IS_LOCAL = false;
private static final String VALUE = "testValue";
private static final String TYPE = "testType";
- private static final String VALUE_TYPE = "testValueType";
+ private static final String VALUE_TYPE = "anyType";
private static final IdentifierType ID_TYPE = IdentifierType.CUSTOM;
private static final Identifier IDENTIFIER = new Identifier(ID_TYPE, VALUE);
private static final Reference VALUE_ID = new Reference(IDENTIFIER, KEY_ELEMENTS, IS_LOCAL);
@@ -38,7 +49,7 @@
public void testConstructor() {
assertEquals(TYPE, qualifier.getType());
assertEquals(VALUE, qualifier.getValue());
- assertEquals(VALUE_TYPE, qualifier.getValueType());
+ assertEquals(ValueTypeHelper.fromName(VALUE_TYPE), qualifier.getValueType());
assertEquals(VALUE_ID, qualifier.getValueId());
}
@@ -65,15 +76,23 @@
@Test
public void testSetValueType() {
- String newValueTypeString = "newValueType";
+ ValueType newValueTypeString = ValueType.AnyType;
qualifier.setValueType(newValueTypeString);
assertEquals(newValueTypeString, qualifier.getValueType());
}
+ // Tests if the valueType is correctly converted to a string
+ @Test
+ public void testSetValueCorrectValueType() {
+ Qualifier emptyQualifier = new Qualifier();
+ emptyQualifier.setValue("Test");
+ assertEquals(ValueType.String.toString(), emptyQualifier.get(Qualifier.VALUETYPE));
+ }
+
@Test
public void testSetSemanticID() {
Reference reference = new Reference(new Identifier(IdentifierType.IRI, "newId"), KeyElements.BLOB, true);
- qualifier.setSemanticID(reference);
+ qualifier.setSemanticId(reference);
assertEquals(reference, qualifier.getSemanticId());
}
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/reference/TestKey.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/reference/TestKey.java
index 7039b7c..a274010 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/reference/TestKey.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/reference/TestKey.java
@@ -1,6 +1,16 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.reference;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -83,4 +93,13 @@
key.setIdType(type);
assertEquals(type, key.getIdType());
}
+
+ @Test
+ public void testIsKey() {
+ assertTrue(Key.isKey(key));
+
+ key.put(Key.IDTYPE, "nonsense");
+
+ assertFalse(Key.isKey(key));
+ }
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/reference/TestReference.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/reference/TestReference.java
index 4ec0377..4f37231 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/reference/TestReference.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/reference/TestReference.java
@@ -1,6 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.reference;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Collection;
@@ -77,4 +88,16 @@
reference.setKeys(keysList);
assertEquals(keysList, reference.getKeys());
}
+
+ @Test
+ public void testIsReference() {
+ Identifiable identifiable = new Identifiable("2.0", "5", "testIDShort", "testCategory", new LangStrings("Eng", "test"), IdentifierType.IRI, "newId");
+ Reference reference = new Reference(identifiable, KEY_ELEMENTS, IS_LOCAL);
+
+ assertTrue(Reference.isReference(reference));
+
+ reference.put(Reference.KEY, "nonsense");
+
+ assertFalse(Reference.isReference(reference));
+ }
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelElement.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelElement.java
new file mode 100644
index 0000000..0898ed9
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelElement.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IEmbeddedDataSpecification;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.map.dataspecification.EmbeddedDataSpecification;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Formula;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests constructor and getter of {@link SubmodelElement} for their
+ * correctness
+ *
+ * @author haque
+ *
+ */
+public class TestSubmodelElement {
+ private static final Reference REFERENCE = new Reference(new Identifier(IdentifierType.CUSTOM, "testValue"), KeyElements.ACCESSPERMISSIONRULE, false);
+ private static final Formula FORMULA = new Formula(Collections.singleton(new Reference(new Key(KeyElements.BLOB, true, "TestValue", IdentifierType.IRI))));
+
+ private SubmodelElement submodelElement;
+
+ @Before
+ public void buidSubmodelElement() {
+ submodelElement = new Property("testIdShort", "testId");
+ }
+
+ @Test
+ public void testSetDataSpecificationReferences() {
+ Collection<IReference> refs = Collections.singleton(REFERENCE);
+ submodelElement.setDataSpecificationReferences(refs);
+ assertEquals(refs, submodelElement.getDataSpecificationReferences());
+ }
+
+ @Test
+ public void testSetEmbeddedDataSpecifications() {
+ EmbeddedDataSpecification embeddedDataSpecification = new EmbeddedDataSpecification();
+ Collection<IEmbeddedDataSpecification> specifications = Collections.singleton(embeddedDataSpecification);
+ submodelElement.setEmbeddedDataSpecifications(specifications);
+ assertEquals(specifications, submodelElement.getEmbeddedDataSpecifications());
+ }
+
+ @Test
+ public void testSetIdShort() {
+ String newIdString = "newId";
+ submodelElement.setIdShort(newIdString);
+ assertEquals(newIdString, submodelElement.getIdShort());
+ }
+
+ @Test
+ public void testSetCategory() {
+ String newCategoryString = "newCategory";
+ submodelElement.setCategory(newCategoryString);
+ assertEquals(newCategoryString, submodelElement.getCategory());
+ }
+
+ @Test
+ public void testSetDescription() {
+ LangStrings newDescriptionString = new LangStrings("DE", "newTest");
+ submodelElement.setDescription(newDescriptionString);
+ assertEquals(newDescriptionString, submodelElement.getDescription());
+ }
+
+ @Test
+ public void testSetParent() {
+ submodelElement.setParent(REFERENCE);
+ assertEquals(REFERENCE, submodelElement.getParent());
+ }
+
+ @Test
+ public void testSetQualifier() {
+ submodelElement.setQualifiers(Collections.singleton(FORMULA));
+ assertEquals(Collections.singleton(FORMULA), submodelElement.getQualifiers());
+ }
+
+ @Test
+ public void testSetSemanticID() {
+ submodelElement.setSemanticId(REFERENCE);
+ assertEquals(REFERENCE, submodelElement.getSemanticId());
+ }
+
+ @Test
+ public void testSetModelingKind() {
+ ModelingKind newModelingKind = ModelingKind.TEMPLATE;
+ submodelElement.setModelingKind(newModelingKind);
+ assertEquals(newModelingKind, submodelElement.getModelingKind());
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelElementCollection.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelElementCollection.java
index 6d24f0d..2721243 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelElementCollection.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelElementCollection.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement;
import static org.junit.Assert.assertEquals;
@@ -11,6 +20,7 @@
import java.util.Map;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
@@ -28,6 +38,7 @@
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
import org.junit.Before;
import org.junit.Test;
@@ -54,9 +65,10 @@
elements1.add(getOperation());
elements2 = new ArrayList<ISubmodelElement>();
- elements2.add(new Property("testId1"));
- elements2.add(new Property("testId2"));
+ elements2.add(new Property("idShort1", "testId1"));
+ elements2.add(new Property("idShort2","testId2"));
elementCollection = new SubmodelElementCollection(elements2, false, false);
+ elementCollection.setIdShort("testCollectionId");
}
@Test
@@ -64,15 +76,20 @@
SubmodelElementCollection elementCollection = new SubmodelElementCollection(elements1, true, true);
assertTrue(elementCollection.isAllowDuplicates());
assertTrue(elementCollection.isOrdered());
- assertEquals(elements1, elementCollection.getValue());
+
+ ISubmodelElement checkOperation = elementCollection.getSubmodelElements().get(OPERATION_ID);
+ assertEquals(OPERATION_ID, checkOperation.getIdShort());
}
@Test
public void testAddValue() {
- ISubmodelElement element = new Property("testIdNew");
- elementCollection.addElement(element);
+ Property element = new Property("testProperty");
+ element.setIdShort("propId");
+ elementCollection.addSubmodelElement(element);
elements2.add(element);
- assertEquals(elements2, elementCollection.getValue());
+
+ ISubmodelElement checkProperty = elementCollection.getSubmodelElements().get("propId");
+ assertEquals(element.getIdShort(), checkProperty.getIdShort());
}
@Test
@@ -85,9 +102,13 @@
@Test
public void testSetValue() {
Collection<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
- elements.add(new Property("testId1"));
+ Property element = new Property("testProperty");
+ element.setIdShort("propId");
+ elements.add(element);
elementCollection.setValue(elements);
- assertEquals(elements, elementCollection.getValue());
+
+ ISubmodelElement checkProperty = elementCollection.getSubmodelElements().get("propId");
+ assertEquals(element.getIdShort(), checkProperty.getIdShort());
}
@Test
@@ -134,19 +155,47 @@
}
@Test
- public void testAddSubModelElement() {
+ public void testAddSubmodelElement() {
SubmodelElementCollection collection = new SubmodelElementCollection(elements1, false, false);
+ String smCollIdShort = "coll1";
+ collection.setIdShort(smCollIdShort);
Property property = new Property("testValue");
String newIdShort = "newIdShort";
property.put(Referable.IDSHORT, newIdShort);
- collection.addElement(property);
- assertEquals(new Reference(new Key(KeyElements.SUBMODELELEMENTCOLLECTION, true, "", KeyType.IDSHORT)), property.getParent());
+ collection.addSubmodelElement(property);
+ assertEquals(new Reference(new Key(KeyElements.SUBMODELELEMENTCOLLECTION, true, smCollIdShort, KeyType.IDSHORT)), property.getParent());
Map<String, ISubmodelElement> submodelElements = new HashMap<String, ISubmodelElement>();
submodelElements.put(PROPERTY_ID, getProperty());
submodelElements.put(OPERATION_ID, getOperation());
submodelElements.put(newIdShort, property);
assertEquals(submodelElements, collection.getSubmodelElements());
}
+
+ @Test
+ public void testGetSubmodelElement() {
+ SubmodelElementCollection collection = new SubmodelElementCollection(elements1, false, false);
+ ISubmodelElement retrievedElement = collection.getSubmodelElement(PROPERTY_ID);
+ assertEquals(getProperty(), retrievedElement);
+ }
+
+ @Test(expected = ResourceNotFoundException.class)
+ public void testGetSubmodelElementNotExist() {
+ SubmodelElementCollection collection = new SubmodelElementCollection(elements1, false, false);
+ collection.getSubmodelElement("Id_Which_Does_Not_Exist");
+ }
+
+ @Test(expected = ResourceNotFoundException.class)
+ public void testDeleteSubmodelElement() {
+ SubmodelElementCollection collection = new SubmodelElementCollection(elements1, false, false);
+ collection.deleteSubmodelElement(PROPERTY_ID);
+ collection.getSubmodelElement(PROPERTY_ID);
+ }
+
+ @Test(expected = ResourceNotFoundException.class)
+ public void testDeleteSubmodelElementNotExist() {
+ SubmodelElementCollection collection = new SubmodelElementCollection(elements1, false, false);
+ collection.deleteSubmodelElement("Id_Which_Does_Not_Exist");
+ }
/**
* Get a dummy property
@@ -168,8 +217,10 @@
* @return operation
*/
private Operation getOperation() {
+ Property property = new Property("testOpVariableId");
+ property.setModelingKind(ModelingKind.TEMPLATE);
List<OperationVariable> variable = Collections
- .singletonList(new OperationVariable(new Property("testOpVariableId")));
+ .singletonList(new OperationVariable(property));
Operation operation = new Operation(variable, variable, variable, null);
operation.put(Referable.IDSHORT, OPERATION_ID);
return operation;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelmodelElement.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelmodelElement.java
deleted file mode 100644
index 226081f..0000000
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelmodelElement.java
+++ /dev/null
@@ -1,103 +0,0 @@
-package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Collection;
-import java.util.Collections;
-
-import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IEmbeddedDataSpecification;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
-import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
-import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
-import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
-import org.eclipse.basyx.submodel.metamodel.map.dataspecification.EmbeddedDataSpecification;
-import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Formula;
-import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
-import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Tests constructor and getter of {@link SubmodelElement} for their
- * correctness
- *
- * @author haque
- *
- */
-public class TestSubmodelmodelElement {
- private static final Reference REFERENCE = new Reference(new Identifier(IdentifierType.CUSTOM, "testValue"), KeyElements.ACCESSPERMISSIONRULE, false);
- private static final Formula FORMULA = new Formula(Collections.singleton(new Reference(new Key(KeyElements.BLOB, true, "TestValue", IdentifierType.IRI))));
-
- private SubmodelElement submodelElement;
-
- @Before
- public void buidSubmodelElement() {
- Property property = new Property("testId");
- submodelElement = SubmodelElement.createAsFacade(property);
- }
-
- @Test
- public void testSetDataSpecificationReferences() {
- Collection<IReference> refs = Collections.singleton(REFERENCE);
- submodelElement.setDataSpecificationReferences(refs);
- assertEquals(refs, submodelElement.getDataSpecificationReferences());
- }
-
- @Test
- public void testSetEmbeddedDataSpecifications() {
- EmbeddedDataSpecification embeddedDataSpecification = new EmbeddedDataSpecification();
- Collection<IEmbeddedDataSpecification> specifications = Collections.singleton(embeddedDataSpecification);
- submodelElement.setEmbeddedDataSpecifications(specifications);
- assertEquals(specifications, submodelElement.getEmbeddedDataSpecifications());
- }
-
- @Test
- public void testSetIdShort() {
- String newIdString = "newId";
- submodelElement.setIdShort(newIdString);
- assertEquals(newIdString, submodelElement.getIdShort());
- }
-
- @Test
- public void testSetCategory() {
- String newCategoryString = "newCategory";
- submodelElement.setCategory(newCategoryString);
- assertEquals(newCategoryString, submodelElement.getCategory());
- }
-
- @Test
- public void testSetDescription() {
- LangStrings newDescriptionString = new LangStrings("DE", "newTest");
- submodelElement.setDescription(newDescriptionString);
- assertEquals(newDescriptionString, submodelElement.getDescription());
- }
-
- @Test
- public void testSetParent() {
- submodelElement.setParent(REFERENCE);
- assertEquals(REFERENCE, submodelElement.getParent());
- }
-
- @Test
- public void testSetQualifier() {
- submodelElement.setQualifier(Collections.singleton(FORMULA));
- assertEquals(Collections.singleton(FORMULA), submodelElement.getQualifier());
- }
-
- @Test
- public void testSetSemanticID() {
- submodelElement.setSemanticID(REFERENCE);
- assertEquals(REFERENCE, submodelElement.getSemanticId());
- }
-
- @Test
- public void testSetModelingKind() {
- ModelingKind newModelingKind = ModelingKind.TEMPLATE;
- submodelElement.setModelingKind(newModelingKind);
- assertEquals(newModelingKind, submodelElement.getModelingKind());
- }
-}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestBlob.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestBlob.java
new file mode 100644
index 0000000..953d649
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestBlob.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.dataelement;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Blob;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests if a Blob stores its data correctly
+ *
+ * @author espen
+ *
+ */
+public class TestBlob {
+ public final String BLOB_CONTENT = "BLOB_VALUE";
+
+ protected Blob blob;
+ protected String testString = "NEW!";
+ protected byte[] testBytes = testString.getBytes(StandardCharsets.UTF_8);
+ protected String testBase64 = Base64.getEncoder().encodeToString(testBytes);
+
+ @Before
+ public void build() {
+ blob = new Blob("testIdShort", "mimeType");
+ }
+
+ /**
+ * Tests if getMimeType() returns the correct value
+ */
+ @Test
+ public void testGetMimeType() {
+ assertEquals("mimeType", blob.getMimeType());
+ }
+
+ /**
+ * Tests if getValue() returns the correct value if it hasn't been set before
+ */
+ @Test
+ public void testGetEmptyValue() {
+ assertNull(blob.getValue());
+ }
+
+ /**
+ * Tests if setValue sets the correct values
+ */
+ @Test
+ public void testSetValue() {
+ blob.setValue(testBase64);
+ assertEquals(testString, blob.getUTF8String());
+ assertArrayEquals(testBytes, blob.getByteArrayValue());
+ assertEquals(testBase64, blob.getValue());
+ }
+
+ /**
+ * Tests if setUTF8 sets the correct value
+ */
+ @Test
+ public void testSetUTF8() {
+ blob.setUTF8String(testString);
+ assertEquals(testString, blob.getUTF8String());
+ assertArrayEquals(testBytes, blob.getByteArrayValue());
+ assertEquals(testBase64, blob.getValue());
+ }
+
+ /**
+ * Tests if SetByteArrayValue() sets the correct value
+ */
+ @Test
+ public void testSetByteArray() {
+ blob.setByteArrayValue(testBytes);
+ assertEquals(testString, blob.getUTF8String());
+ assertArrayEquals(testBytes, blob.getByteArrayValue());
+ assertEquals(testBase64, blob.getValue());
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestFile.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestFile.java
index b599c26..f5da076 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestFile.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestFile.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.dataelement;
import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestReferenceElement.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestReferenceElement.java
index 734685a..c5336c5 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestReferenceElement.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestReferenceElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.dataelement;
import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/property/TestProperty.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/property/TestProperty.java
index 565aaaa..97e3270 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/property/TestProperty.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/property/TestProperty.java
@@ -1,14 +1,29 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.dataelement.property;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
+import java.math.BigInteger;
+import java.time.Duration;
+import java.time.LocalDate;
+import java.time.Month;
+import java.time.Period;
import java.util.Collections;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
import org.eclipse.basyx.submodel.metamodel.map.parts.ConceptDescription;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
@@ -17,10 +32,11 @@
import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDef;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
import org.junit.Before;
import org.junit.Test;
+
/**
* Tests constructor, getter and setter of {@link Property} for their
* correctness
@@ -30,7 +46,7 @@
*/
public class TestProperty {
private static final String VALUE = "testValue";
- private static final String STRING_TYPE = "string";
+ private static final ValueType STRING_TYPE = ValueType.String;
private Property property;
@Before
@@ -39,59 +55,69 @@
}
@Test
- public void testConstructor1() {
- assertEquals(VALUE, property.get());
+ public void testConstructor1(){
+ assertEquals(VALUE, property.getValue());
assertNull(property.getValueId());
assertEquals(STRING_TYPE, property.getValueType());
}
@Test
- public void testConstructor2() {
+ public void testConstructor2(){
Referable referable = new Referable("testIdShort", "testCategory", new LangStrings("DE", "test"));
Reference semanticId = new Reference(new Key(KeyElements.ASSET, true, "testValue", IdentifierType.IRI));
Qualifiable qualifiable = new Qualifiable(new Formula(Collections.singleton(new Reference(new Key(KeyElements.BLOB, true, "TestValue", IdentifierType.IRI)))));
Property property = new Property(VALUE, referable, semanticId, qualifiable);
- assertEquals(VALUE, property.get());
+ assertEquals(VALUE, property.getValue());
assertNull(property.getValueId());
assertEquals(STRING_TYPE, property.getValueType());
}
@Test
public void testSetValueType() {
- property.setValueType(PropertyValueTypeDef.String);
+ property.setValueType(ValueType.String);
assertEquals(STRING_TYPE, property.getValueType());
}
@Test
- public void testGetNonMapValueType() {
- property.put(Property.VALUETYPE, "string");
- assertEquals("string", property.getValueType());
- }
-
- @Test
- public void testGetNotExistingValueType() {
- // I would vote for fail fast - directly when setting the value
- property.put(Property.VALUETYPE, "IDoNotExistInPropertyValueTypeDef");
- try {
- property.getValueType();
- fail("Expecting exception when providing invalid type");
- } catch (RuntimeException e) {
- }
- }
-
- @Test
- public void testSet() {
+ public void testSet(){
+ Property booleanProp = new Property();
Boolean isSomething = true;
- property.set(isSomething);
- assertEquals(isSomething, property.get());
- assertEquals("boolean", property.getValueType());
+ booleanProp.setValue(isSomething);
+ assertEquals(isSomething, booleanProp.getValue());
+ assertEquals(ValueType.Boolean, booleanProp.getValueType());
+
+ Byte byteNumber = new Byte("2");
+ Property byteProp = new Property();
+ byteProp.setValue(byteNumber);
+ assertEquals(byteNumber, byteProp.getValue());
+ assertEquals(ValueType.Int8, byteProp.getValueType());
+
+ Duration duration = Duration.ofSeconds(10);
+ Property durationProp = new Property();
+ durationProp.setValue(duration);
+ assertEquals(duration, durationProp.getValue());
+ assertEquals(ValueType.Duration, durationProp.getValueType());
+
+ Property periodProp = new Property();
+ LocalDate today = LocalDate.now();
+ LocalDate birthday = LocalDate.of(1960, Month.JANUARY, 1);
+ Period p = Period.between(birthday, today);
+ periodProp.setValue(p);
+ assertEquals(p, periodProp.getValue());
+ assertEquals(ValueType.YearMonthDuration, periodProp.getValueType());
+
+ Property bigNumberProp = new Property();
+ BigInteger bignumber = new BigInteger("9223372036854775817");
+ bigNumberProp.setValue(bignumber);
+ assertEquals(bignumber, bigNumberProp.getValue());
+ assertEquals(ValueType.PositiveInteger, bigNumberProp.getValueType());
}
@Test
- public void testSetCustom() {
- property.set(null, PropertyValueTypeDef.String);
- assertEquals(null, property.get());
- assertEquals(PropertyValueTypeDef.String.getStandardizedLiteral(), property.getValueType());
+ public void testSetCustom(){
+ property.set(null, ValueType.String);
+ assertEquals(null, property.getValue());
+ assertEquals(ValueType.String, property.getValueType());
}
@Test
@@ -104,9 +130,32 @@
@Test
public void testAddConceptDescription() {
- ConceptDescription description = new ConceptDescription();
+ String id = "idShort";
+ ConceptDescription description = new ConceptDescription(id, new Identifier(IdentifierType.IRDI, id));
Property property = new Property(VALUE);
property.addConceptDescription(description);
assertEquals(new Reference(description, KeyElements.CONCEPTDESCRIPTION, true), property.getSemanticId());
- }
+ }
+
+ @Test
+ public void testInitializeWithNullValue() {
+ try {
+ // Should not work as valueType is a mandatory attribute
+ new Property("id", null);
+ fail();
+ } catch (RuntimeException e) {
+ }
+
+ try {
+ // Should not work as valueType can not be set with null as value
+ Property prop = new Property();
+ prop.setValue(null);
+ fail();
+ } catch (RuntimeException e) {
+ }
+
+ Property prop = new Property("id", "value");
+ // This should work as the valueType is already set
+ prop.setValue(null);
+ }
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/range/TestRange.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/range/TestRange.java
new file mode 100644
index 0000000..d2a6c86
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/range/TestRange.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.dataelement.range;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.Range;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.RangeValue;
+import org.junit.Before;
+import org.junit.Test;
+
+
+/**
+ * Test for Range
+ *
+ * @author conradi
+ *
+ */
+public class TestRange {
+
+ private static final int MIN = 0;
+ private static final int MAX = 10;
+ private Range range;
+
+ @Before
+ public void buildRange() {
+ range = new Range(ValueType.Integer, MIN, MAX);
+ }
+
+ @Test
+ public void testGetValue() {
+ assertEquals(MIN, range.getMin());
+ assertEquals(MAX, range.getMax());
+
+ RangeValue value = range.getValue();
+ assertEquals(MIN, value.getMin());
+ assertEquals(MAX, value.getMax());
+ }
+
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/AsyncOperationHelper.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/AsyncOperationHelper.java
new file mode 100644
index 0000000..284e0cf
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/AsyncOperationHelper.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.operation;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.function.Function;
+
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
+
+/**
+ * Helperclass for testing async invocations of Operations
+ *
+ * @author conradi
+ *
+ */
+public class AsyncOperationHelper {
+
+ public static final String ASYNC_OP_ID = "asyncOperation";
+ public static Collection<OperationVariable> IN;
+ protected static Collection<OperationVariable> OUT;
+ public static final String ASYNC_EXCEPTION_OP_ID = "asyncExceptionOperation";
+
+ private Object waitObject = new Object();
+ private boolean shouldWait = true;
+
+ public AsyncOperationHelper() {
+ IN = new ArrayList<OperationVariable>();
+ OUT = new ArrayList<OperationVariable>();
+ Property asyncIn1 = new Property("asyncIn1", "");
+ asyncIn1.setModelingKind(ModelingKind.TEMPLATE);
+ Property asyncIn2 = new Property("asyncIn2", "");
+ asyncIn2.setModelingKind(ModelingKind.TEMPLATE);
+ IN.add(new OperationVariable(asyncIn1));
+ IN.add(new OperationVariable(asyncIn2));
+ Property asyncOut = new Property("asyncOut", "");
+ asyncOut.setModelingKind(ModelingKind.TEMPLATE);
+ OUT.add(new OperationVariable(asyncOut));
+ }
+
+ private final Function<Object[], Object> ASYNC_FUNC = (Function<Object[], Object>) v -> {
+ int result = (int)v[0] + (int)v[1];
+ synchronized (waitObject) {
+ while (shouldWait) {
+ try {
+ waitObject.wait();
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+ return result;
+ };
+
+ private final Function<Object[], Object> ASYNC_EXCEPTION_FUNC = (Function<Object[], Object>) v -> {
+ NullPointerException ex = new NullPointerException();
+ synchronized (waitObject) {
+ while (shouldWait) {
+ try {
+ waitObject.wait();
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+ throw ex;
+ };
+
+ public Operation getAsyncOperation() {
+ shouldWait = true;
+ Operation op = new Operation(ASYNC_FUNC);
+ op.setIdShort(ASYNC_OP_ID);
+ op.setInputVariables(IN);
+ op.setOutputVariables(OUT);
+ return op;
+ }
+
+ public Operation getAsyncExceptionOperation() {
+ shouldWait = true;
+ Operation op = new Operation(ASYNC_EXCEPTION_FUNC);
+ op.setIdShort(ASYNC_EXCEPTION_OP_ID);
+ return op;
+ }
+
+ public void releaseWaitingOperation() {
+ shouldWait = false;
+ synchronized (waitObject) {
+ waitObject.notifyAll();
+ }
+
+ // Give the Operation a bit of time to finish
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ }
+ }
+
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperation.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperation.java
index f546717..de18ee7 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperation.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperation.java
@@ -1,6 +1,16 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.operation;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
import java.util.ArrayList;
import java.util.Collection;
@@ -10,108 +20,74 @@
import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
-import org.junit.Before;
import org.junit.Test;
/**
* Tests constructor, getter and setter of {@link Operation} for their
* correctness
*
- * @author haque
+ * @author haque, conradi
*
*/
-public class TestOperation {
- private static final Collection<OperationVariable> IN = Collections.singletonList(new OperationVariable(new Property("inValue")));
- private static final Collection<OperationVariable> OUT = Collections.singletonList(new OperationVariable(new Property("outValue")));
- private static final Collection<OperationVariable> INOUT = Collections.singletonList(new OperationVariable(new Property("inOutValue")));
- private static final Function<Object[], Object> FUNC = (Function<Object[], Object>) v -> {
- return (int)v[0] + (int)v[1];
- };
+public class TestOperation extends TestOperationSuite {
- private Operation operation;
+ private static final String KEY_VALUE = "testKeyValue";
- @Before
- public void buildOperation() {
- operation = new Operation(FUNC);
+ @Override
+ protected IOperation prepareOperation(Operation operation) {
+ return operation;
}
@Test
- public void testConstructor1() throws Exception {
- operation = new Operation(IN, OUT, INOUT, FUNC);
- testInputVariables();
- testOutputVariables();
- testInOutputVariables();
- testInvokable();
- }
-
- @Test
- public void testConstructor2() throws Exception {
- assertEquals(new ArrayList<OperationVariable>(), operation.getInputVariables());
- assertEquals(new ArrayList<OperationVariable>(), operation.getOutputVariables());
- assertEquals(new ArrayList<OperationVariable>(), operation.getInOutputVariables());
- testInvokable();
- }
-
- @Test
public void testOptionalElements() throws Exception {
operation = new Operation(null, null, null, FUNC);
assertEquals(0, operation.getInputVariables().size());
assertEquals(0, operation.getOutputVariables().size());
assertEquals(0, operation.getInOutputVariables().size());
- }
-
- @Test
- public void testSetInputVariables() {
- operation.setInputVariables(IN);
- testInputVariables();
- }
-
- @Test
- public void testSetOutputVariables() {
- operation.setOutputVariables(OUT);
- testOutputVariables();
- }
-
- @Test
- public void testSetInOutputVariables() {
- operation.setInOutputVariables(INOUT);
- testInOutputVariables();
}
@Test
public void testSetInvocable() throws Exception {
+ Operation operation = new Operation(IN, OUT, INOUT, FUNC);
+ assertEquals(5, operation.invoke(3, 2));
+
Function<Object[], Object> newFunction = (Function<Object[], Object>) v -> {
return (int)v[0] - (int)v[1];
};
- operation.setInvocable(newFunction);
+ operation.setInvokable(newFunction);
+
assertEquals(1, operation.invoke(3,2));
}
-
+
+ @Override
+ @Test
+ public void testInvokeWithSubmodelElements() {
+ Property param1 = new Property("testIn1", 1);
+ Property param2 = new Property("testIn2", 1);
+ try {
+ operation.invoke(param1, param2);
+ // Only unwrapped invokation is supported for local operations
+ fail();
+ } catch (UnsupportedOperationException e) {
+ }
+ }
+
@Test
public void testSetDataSpecificationReferences() {
- Collection<IReference> references = Collections.singleton(new Reference(new Key(KeyElements.ASSET, true, "testValue", IdentifierType.IRI)));
+ Operation operation = new Operation(IN, OUT, INOUT, FUNC);
+ Collection<IReference> references = Collections.singleton(new Reference(new Key(KeyElements.ASSET, true, KEY_VALUE, IdentifierType.IRI)));
operation.setDataSpecificationReferences(references);
- assertEquals(references, operation.getDataSpecificationReferences());
- }
-
- private void testInvokable() throws Exception {
- assertEquals(5, operation.invoke(2,3));
- }
-
- private void testInputVariables() {
- assertEquals(IN, operation.getInputVariables());
- }
-
- private void testOutputVariables() {
- assertEquals(OUT, operation.getOutputVariables());
- }
-
- private void testInOutputVariables() {
- assertEquals(INOUT, operation.getInOutputVariables());
+
+ Collection<IReference> newReferences = operation.getDataSpecificationReferences();
+ assertEquals(1, newReferences.size());
+
+ IReference newReference = new ArrayList<>(newReferences).get(0);
+
+ assertEquals(KEY_VALUE, newReference.getKeys().get(0).getValue());
}
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationSuite.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationSuite.java
new file mode 100644
index 0000000..6eeb59d
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationSuite.java
@@ -0,0 +1,237 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.operation;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.function.Function;
+
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IAsyncInvocation;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperationVariable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationExecutionErrorException;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationExecutionTimeoutException;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
+import org.eclipse.basyx.vab.exception.provider.WrongNumberOfParametersException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests for IOperation
+ *
+ * @author conradi
+ *
+ */
+public abstract class TestOperationSuite {
+
+ protected static final String IN_VALUE = "inValue";
+ protected static final String OUT_VALUE = "outValue";
+ protected static final String INOUT_VALUE = "inOutValue";
+ protected static Collection<OperationVariable> IN;
+ protected static Collection<OperationVariable> OUT;
+ protected static Collection<OperationVariable> INOUT;
+
+ protected static final Function<Object[], Object> FUNC = (Function<Object[], Object>) v -> {
+ return (int)v[0] + (int)v[1];
+ };
+
+ protected static final Function<Object[], Object> EXCEPTION_FUNC = (Function<Object[], Object>) v -> {
+ throw new NullPointerException();
+ };
+
+ protected IOperation operation;
+ protected IOperation operationException;
+
+ /**
+ * Converts an Operation into the IOperation to be tested
+ */
+ protected abstract IOperation prepareOperation(Operation operation);
+
+ @Before
+ public void setup() {
+ IN = new ArrayList<OperationVariable>();
+ OUT = new ArrayList<OperationVariable>();
+ INOUT = new ArrayList<OperationVariable>();
+ Property inProp1 = new Property("testIn1", IN_VALUE);
+ inProp1.setModelingKind(ModelingKind.TEMPLATE);
+ Property inProp2 = new Property("testIn2", IN_VALUE);
+ inProp2.setModelingKind(ModelingKind.TEMPLATE);
+ Property outProp = new Property("testId2", OUT_VALUE);
+ outProp.setModelingKind(ModelingKind.TEMPLATE);
+ Property inOutProp = new Property("testId3", INOUT_VALUE);
+ inOutProp.setModelingKind(ModelingKind.TEMPLATE);
+ IN.add(new OperationVariable(inProp1));
+ IN.add(new OperationVariable(inProp2));
+ OUT.add(new OperationVariable(outProp));
+ INOUT.add(new OperationVariable(inOutProp));
+
+ Operation op1 = new Operation(IN, OUT, INOUT, FUNC);
+ op1.setIdShort("op1");
+ operation = prepareOperation(op1);
+
+ Operation op2 = new Operation(IN, OUT, INOUT, EXCEPTION_FUNC);
+ op2.setIdShort("op2");
+ operationException = prepareOperation(op2);
+ }
+
+ @Test
+ public void testInvoke() throws Exception {
+ assertEquals(5, operation.invoke(2, 3));
+ }
+
+ @Test
+ public void testInvokeException() throws Exception {
+ try {
+ // Ensure the operation is invoked directly
+ operationException.invoke(1, 2);
+ fail();
+ } catch (Exception e) {
+ // Exceptions from ConnectedOperation are wrapped in ProviderException
+ assertTrue(e instanceof NullPointerException
+ || e.getCause() instanceof NullPointerException);
+ }
+ }
+
+ @Test
+ public void testInvokeWithSubmodelElements() {
+ Property param1 = new Property("testIn1", 2);
+ param1.setModelingKind(ModelingKind.TEMPLATE);
+ Property param2 = new Property("testIn2", 4);
+ param2.setModelingKind(ModelingKind.TEMPLATE);
+ SubmodelElement[] result = operation.invoke(param1, param2);
+ assertEquals(1, result.length);
+ assertEquals(6, result[0].getValue());
+ }
+
+ @Test
+ public void testInvokeParametersException() throws Exception {
+ try {
+ operation.invoke(1);
+ fail();
+ } catch (Exception e) {
+ // Exceptions from ConnectedOperation are wrapped in ProviderException
+ assertTrue(e instanceof WrongNumberOfParametersException
+ || e.getCause() instanceof WrongNumberOfParametersException);
+ }
+ }
+
+ @Test
+ public void testInvokeAsync() throws Exception {
+ AsyncOperationHelper helper = new AsyncOperationHelper();
+ IOperation operation = prepareOperation(helper.getAsyncOperation());
+
+ IAsyncInvocation invocation = operation.invokeAsync(3, 2);
+
+ assertFalse(invocation.isFinished());
+
+ helper.releaseWaitingOperation();
+
+ assertTrue(invocation.isFinished());
+ assertEquals(5, invocation.getResult());
+ }
+
+ @Test
+ public void testInvokeMultipleAsync() throws Exception {
+ AsyncOperationHelper helper = new AsyncOperationHelper();
+ IOperation operation = prepareOperation(helper.getAsyncOperation());
+
+ IAsyncInvocation invocation1 = operation.invokeAsync(1, 2);
+ IAsyncInvocation invocation2 = operation.invokeAsync(6, 2);
+
+ assertFalse(invocation1.isFinished());
+ assertFalse(invocation2.isFinished());
+
+ helper.releaseWaitingOperation();
+
+ assertTrue(invocation1.isFinished());
+ assertTrue(invocation2.isFinished());
+ assertEquals(3, invocation1.getResult());
+ assertEquals(8, invocation2.getResult());
+ }
+
+ @Test
+ public void testInvokeAsyncTimeout() throws Exception {
+ AsyncOperationHelper helper = new AsyncOperationHelper();
+ IOperation operation = prepareOperation(helper.getAsyncOperation());
+
+ // timeout of 1ms
+ IAsyncInvocation invocation = operation.invokeAsyncWithTimeout(1, 3, 2);
+
+ // Should be more than enough to trigger the timeout exception
+ Thread.sleep(100);
+ helper.releaseWaitingOperation();
+
+ assertTrue(invocation.isFinished());
+ try {
+ invocation.getResult();
+ fail();
+ } catch (OperationExecutionTimeoutException e) {
+ }
+ }
+
+ @Test
+ public void testInvokeExceptionAsync() throws Exception {
+ AsyncOperationHelper helper = new AsyncOperationHelper();
+ IOperation operationException = prepareOperation(helper.getAsyncExceptionOperation());
+ IAsyncInvocation invocation = operationException.invokeAsync();
+ assertFalse(invocation.isFinished());
+
+ helper.releaseWaitingOperation();
+
+ try {
+ invocation.getResult();
+ fail();
+ } catch (OperationExecutionErrorException e) {
+ }
+
+ }
+
+ @Test
+ public void testInputVariables() {
+ Collection<IOperationVariable> inputVariables = operation.getInputVariables();
+ assertEquals(2, inputVariables.size());
+ Object value = getValueFromOpVariable(inputVariables);
+ assertEquals(IN_VALUE, value);
+ }
+
+ @Test
+ public void testOutputVariables() {
+ Collection<IOperationVariable> outputVariables = operation.getOutputVariables();
+ assertEquals(1, outputVariables.size());
+ Object value = getValueFromOpVariable(outputVariables);
+ assertEquals(OUT_VALUE, value);
+ }
+
+ @Test
+ public void testInOutputVariables() {
+ Collection<IOperationVariable> inoutVariables = operation.getInOutputVariables();
+ assertEquals(1, inoutVariables.size());
+ Object value = getValueFromOpVariable(inoutVariables);
+ assertEquals(INOUT_VALUE, value);
+ }
+
+ /**
+ * Gets the Value from the OperationVariable in a collection
+ */
+ private Object getValueFromOpVariable(Collection<IOperationVariable> vars) {
+ IOperationVariable var = new ArrayList<>(vars).get(0);
+ return var.getValue().getValue();
+ }
+
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationVariable.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationVariable.java
index 88b13d7..60f9ed7 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationVariable.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationVariable.java
@@ -1,8 +1,19 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.operation;
import static org.junit.Assert.assertEquals;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
import org.junit.Before;
import org.junit.Test;
@@ -15,11 +26,12 @@
*
*/
public class TestOperationVariable {
- private static final Property PROPERTY = new Property("testOpVariable");
+ private static final Property PROPERTY = new Property("testIdShort", "testOpVariable");
private OperationVariable operationVariable;
@Before
public void buildOperationVariable() {
+ PROPERTY.setModelingKind(ModelingKind.TEMPLATE);
operationVariable = new OperationVariable(PROPERTY);
}
@@ -30,8 +42,18 @@
@Test
public void testSetValue() {
- Property property = new Property("testNewProperty");
+ Property property = new Property("testIdShort", ValueType.String);
+ property.setModelingKind(ModelingKind.TEMPLATE);
operationVariable.setValue(property);
assertEquals(property, operationVariable.getValue());
}
+
+ @Test
+ // TODO: Change with 1.0 Release when ModelingKind.Template is obligatory for OperationVariables
+ public void testSetValueChangedModelingKind() {
+ Property property = new Property("testIdShort", ValueType.String);
+ property.setModelingKind(ModelingKind.INSTANCE);
+ operationVariable.setValue(property);
+ assertEquals(ModelingKind.TEMPLATE, operationVariable.getValue().getModelingKind());
+ }
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/relationship/TestAnnotatedRelationshipElement.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/relationship/TestAnnotatedRelationshipElement.java
new file mode 100644
index 0000000..79bf0a2
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/relationship/TestAnnotatedRelationshipElement.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.relationship;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IDataElement;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.AnnotatedRelationshipElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElementValue;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests constructor, getter and setter of {@link AnnotatedRelationshipElement} for correctness
+ *
+ * @author conradi
+ *
+ */
+public class TestAnnotatedRelationshipElement {
+ private static final Reference FIRST = new Reference(new Key(KeyElements.ASSET, true, "firstValue", IdentifierType.IRI));
+ private static final Reference SECOND = new Reference(new Identifier(IdentifierType.CUSTOM, "secondId"), KeyElements.BLOB, false);
+
+ private AnnotatedRelationshipElement element;
+
+ @Before
+ public void buildElement() {
+ element = new AnnotatedRelationshipElement("testId", FIRST, SECOND);
+ Property property = new Property("PropertyId", 10);
+ List<IDataElement> annotations = new ArrayList<>();
+ annotations.add(property);
+ element.setAnnotation(annotations);
+ }
+
+ @Test
+ public void testConstructor() {
+ assertEquals(FIRST, element.getFirst());
+ assertEquals(SECOND, element.getSecond());
+ }
+
+ @Test
+ public void testSetFirst() {
+ Reference newFirst = new Reference(new Key(KeyElements.CAPABILITY, false, "newFirst", IdentifierType.IRI));
+ element.setFirst(newFirst);
+ assertEquals(newFirst, element.getFirst());
+ }
+
+ @Test
+ public void testSetSecond() {
+ Reference newSecond = new Reference(new Key(KeyElements.CAPABILITY, false, "newFirst", IdentifierType.IRI));
+ element.setSecond(newSecond);
+ assertEquals(newSecond, element.getSecond());
+ }
+
+ @Test
+ public void testGetValue() {
+ RelationshipElementValue value = element.getValue();
+ assertEquals(FIRST.getKeys().get(0).getValue(), value.getFirst().getKeys().get(0).getValue());
+ assertEquals(SECOND.getKeys().get(0).getValue(), value.getSecond().getKeys().get(0).getValue());
+ }
+
+ @Test
+ public void testGetAnnotations() {
+ Collection<IDataElement> annotations = element.getValue().getAnnotations();
+ assertEquals(1, annotations.size());
+
+ // Check the element
+ for (IDataElement element: annotations) {
+ assertEquals("PropertyId", element.getIdShort());
+ }
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/relationship/TestRelationshipElement.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/relationship/TestRelationshipElement.java
index 0e63510..30cbcdf 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/relationship/TestRelationshipElement.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/relationship/TestRelationshipElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.relationship;
import static org.junit.Assert.assertEquals;
@@ -8,6 +17,7 @@
import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElementValue;
import org.junit.Before;
import org.junit.Test;
@@ -47,6 +57,13 @@
Reference newSecond = new Reference(new Key(KeyElements.CAPABILITY, false, "newFirst", IdentifierType.IRI));
relationshipElement.setSecond(newSecond);
assertEquals(newSecond, relationshipElement.getSecond());
- }
+ }
+
+ @Test
+ public void testGetValue() {
+ RelationshipElementValue value = relationshipElement.getValue();
+ assertEquals(FIRST.getKeys().get(0).getValue(), value.getFirst().getKeys().get(0).getValue());
+ assertEquals(SECOND.getKeys().get(0).getValue(), value.getSecond().getKeys().get(0).getValue());
+ }
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/support/TestAASLambdaPropertyHelper.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/support/TestAASLambdaPropertyHelper.java
index ca8b1af..3f02b71 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/support/TestAASLambdaPropertyHelper.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/support/TestAASLambdaPropertyHelper.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.support;
import static org.junit.Assert.assertEquals;
@@ -5,8 +14,8 @@
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedProperty;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.AASLambdaPropertyHelper;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDef;
-import org.eclipse.basyx.submodel.restapi.PropertyProvider;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
import org.junit.Test;
@@ -31,21 +40,21 @@
});
// Wrap in provider
- PropertyProvider provider = new PropertyProvider(new VABLambdaProvider(temperature));
+ SubmodelElementProvider provider = new SubmodelElementProvider(new VABLambdaProvider(temperature));
ConnectedProperty connectedProperty = new ConnectedProperty(new VABElementProxy("", provider));
// Check correct property type
- String expectedType = PropertyValueTypeDef.Double.toString();
+ ValueType expectedType = ValueType.Double;
assertEquals(expectedType, connectedProperty.getValueType());
// Check value is correctly retrievable by property
testValue = 10;
- assertEquals(testValue, connectedProperty.get());
+ assertEquals(testValue, connectedProperty.getValue());
// Check value is correctly written by property
double expectedValue = 2.1;
- connectedProperty.set(expectedValue);
- assertEquals(expectedValue, connectedProperty.get());
+ connectedProperty.setValue(expectedValue);
+ assertEquals(expectedValue, connectedProperty.getValue());
assertEquals(expectedValue, testValue, 0);
}
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SimpleAASSubmodel.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SimpleAASSubmodel.java
index 672668d..9257cef 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SimpleAASSubmodel.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SimpleAASSubmodel.java
@@ -1,11 +1,26 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.submodel.restapi;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.function.Function;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
import org.eclipse.basyx.vab.exception.provider.ProviderException;
/**
@@ -15,7 +30,11 @@
* @author kuhn
*
*/
-public class SimpleAASSubmodel extends SubModel {
+public class SimpleAASSubmodel extends Submodel {
+
+ public static final String INTPROPIDSHORT = "integerProperty";
+ public static final String OPERATIONSIMPLEIDSHORT = "simple";
+
public SimpleAASSubmodel() {
this("SimpleAASSubmodel");
}
@@ -27,31 +46,41 @@
// Create sub model
setIdShort(idShort);
+ setIdentification(new ModelUrn("simpleAASSubmodelUrn"));
Property intProp = new Property(123);
- intProp.setIdShort("integerProperty");
- addSubModelElement(intProp);
+ intProp.setIdShort(INTPROPIDSHORT);
+ addSubmodelElement(intProp);
Property stringProp = new Property("Test");
stringProp.setIdShort("stringProperty");
- addSubModelElement(stringProp);
+ addSubmodelElement(stringProp);
- Property nullProp = new Property(null);
- nullProp.setIdShort("nullProperty");
- addSubModelElement(nullProp);
+ Property nullProp = new Property("nullProperty", ValueType.String);
+ nullProp.setValue(null);
+ addSubmodelElement(nullProp);
// Create example operations
Operation complex = new Operation((Function<Object[], Object>) v -> {
return (int) v[0] - (int) v[1];
});
+ Property inProp1 = new Property("complexIn1", 0);
+ inProp1.setModelingKind(ModelingKind.TEMPLATE);
+ Property inProp2 = new Property("complexIn2", 0);
+ inProp2.setModelingKind(ModelingKind.TEMPLATE);
+ Property outProp = new Property("complexOut", 0);
+ outProp.setModelingKind(ModelingKind.TEMPLATE);
+ complex.setInputVariables(Arrays.asList(new OperationVariable(inProp1),
+ new OperationVariable(inProp2)));
+ complex.setOutputVariables(Collections.singleton(new OperationVariable(outProp)));
complex.setIdShort("complex");
- addSubModelElement(complex);
+ addSubmodelElement(complex);
Operation simple = new Operation((Function<Object[], Object>) v -> {
return true;
});
- simple.setIdShort("simple");
- addSubModelElement(simple);
+ simple.setIdShort(OPERATIONSIMPLEIDSHORT);
+ addSubmodelElement(simple);
// Create example operations
// - Contained operation that throws native JAVA exception
@@ -59,22 +88,28 @@
throw new NullPointerException();
});
exception1.setIdShort("exception1");
- addSubModelElement(exception1);
+ addSubmodelElement(exception1);
// - Contained operation that throws VAB exception
Operation exception2 = new Operation((Function<Object[], Object>) elId -> {
throw new ProviderException("Exception description");
});
exception2.setIdShort("exception2");
- addSubModelElement(exception2);
+ addSubmodelElement(exception2);
+ Operation opInCollection = new Operation((Function<Object[], Object>) v -> {
+ return 123;
+ });
+ opInCollection.setIdShort("operationId");
+
SubmodelElementCollection containerProp = new SubmodelElementCollection();
containerProp.setIdShort("container");
- containerProp.addElement(intProp);
+ containerProp.addSubmodelElement(intProp);
+ containerProp.addSubmodelElement(opInCollection);
SubmodelElementCollection containerPropRoot = new SubmodelElementCollection();
containerPropRoot.setIdShort("containerRoot");
- containerPropRoot.addElement(containerProp);
- addSubModelElement(containerPropRoot);
+ containerPropRoot.addSubmodelElement(containerProp);
+ addSubmodelElement(containerPropRoot);
}
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SubModelProviderTest.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SubModelProviderTest.java
deleted file mode 100644
index 3a6a7c4..0000000
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SubModelProviderTest.java
+++ /dev/null
@@ -1,254 +0,0 @@
-package org.eclipse.basyx.testsuite.regression.submodel.restapi;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDefHelper;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.testsuite.regression.vab.protocol.http.TestsuiteDirectory;
-import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-import org.eclipse.basyx.vab.protocol.api.ConnectorProvider;
-import org.junit.Test;
-
-public class SubModelProviderTest {
- private VABConnectionManager connManager;
- private static final String submodelAddr = "urn:fhg:es.iese:aas:1:1:submodel";
-
- protected VABConnectionManager getConnectionManager() {
- if (connManager == null) {
- connManager = new VABConnectionManager(new TestsuiteDirectory(), new ConnectorProvider() {
- @Override
- protected IModelProvider createProvider(String addr) {
- // Simple submodel for testing specific mappings for submodels
- return new SubModelProvider(new SimpleAASSubmodel("mySubmodelId"));
- }
- });
- }
- return connManager;
- }
-
- /**
- * Tests accessing different paths that should be supported
- * @throws Exception
- */
- @Test
- public void testPathsRaw() throws Exception {
- SubModelProvider provider = new SubModelProvider(new SimpleAASSubmodel("mySubmodelId"));
- provider.getModelPropertyValue("/submodel");
- provider.getModelPropertyValue("/submodel/");
-
- try {
- provider.getModelPropertyValue("invalid");
- fail();
- } catch (Exception e) {
-
- }
- }
-
- /**
- * Test creating single property
- */
- @SuppressWarnings("unchecked")
- @Test
- public void testCreateProperty() {
- VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
-
- // Create element
- Property prop = new Property(500);
- prop.setIdShort("newProperty");
- submodelElement.createValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "", prop);
-
- // Read back value
- Map<String, Object> result = (Map<String, Object>) submodelElement
- .getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/newProperty/value");
- assertEquals(500, result.get(Property.VALUE));
- }
-
- /**
- * Test reading single property
- */
- @SuppressWarnings("unchecked")
- @Test
- public void testReadProperty() {
- VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
-
- // Read list of properties
- Object result = submodelElement.getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "");
- Collection<Map<String, Object>> propertySet = (Collection<Map<String, Object>>) result;
- Map<String, Object> property = propertySet.stream().filter(elem -> elem.get(Identifiable.IDSHORT).equals("integerProperty")).findFirst().get();
- assertEquals(123, property.get(Property.VALUE));
-
- // Read whole property
- result = submodelElement.getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty");
- property = (Map<String, Object>) result;
- assertEquals(123, property.get(Property.VALUE));
-
- // Read idShort
- result = submodelElement.getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/stringProperty");
- property = (Map<String, Object>) result;
- assertEquals("stringProperty", property.get(Identifiable.IDSHORT));
-
- // Read single value
- Map<String, Object> resMap = (Map<String, Object>) submodelElement
- .getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/stringProperty/value");
- assertEquals("Test", resMap.get(Property.VALUE));
-
- // Read null value
- resMap = (Map<String, Object>) submodelElement
- .getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/nullProperty/value");
- assertEquals(null, resMap.get(Property.VALUE));
-
- // Read container property
- Collection<Object> resSet = (Collection<Object>) submodelElement
- .getModelPropertyValue("/submodel/submodelElements/containerRoot/value");
- assertEquals(1, resSet.size());
- resSet.forEach(x -> assertEquals("container", ((Map<String, Object>) x).get(Referable.IDSHORT)));
-
- // Read nested property
- String pathToNestedContainer = "/submodel/submodelElements/containerRoot/container";
- String pathToNestedProperty = pathToNestedContainer + "/integerProperty/";
- result = submodelElement.getModelPropertyValue(pathToNestedProperty);
- property = (Map<String, Object>) result;
- assertEquals(123, property.get(Property.VALUE));
- }
-
- /**
- * Test updating single property
- */
- @SuppressWarnings("unchecked")
- @Test
- public void testUpdateProperty() {
- VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
-
- // Wrap object before updating element
- Map<String, Object> updatedElement = new HashMap<>();
- updatedElement.put(Property.VALUE, 3);
- updatedElement.put("valueType", PropertyValueTypeDefHelper.getTypeWrapperFromObject(3));
-
- // Update element
- submodelElement.setModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty/value", updatedElement);
-
- // Check result
- Map<String, Object> result = (Map<String, Object>) submodelElement
- .getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty");
- assertEquals(3, result.get(Property.VALUE));
- }
-
- /**
- * Test reading all properties of the submodel
- */
- @SuppressWarnings("unchecked")
- @Test
- public void testReadProperties() {
- VABElementProxy submodel = getConnectionManager().connectToVABElement(submodelAddr);
- Collection<Map<String, Object>> set = (Collection<Map<String, Object>>) submodel.getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES);
- // Should be two properties, one collection and four operations
- assertEquals(3, set.size());
- }
-
- /**
- * Test reading all operations of the submodel
- */
- @SuppressWarnings("unchecked")
- @Test
- public void testReadOperations() {
- VABElementProxy submodel = getConnectionManager().connectToVABElement(submodelAddr);
- Collection<Map<String, Object>> set = (Collection<Map<String, Object>>) submodel.getModelPropertyValue("/submodel/operations");
- assertEquals(4, set.size());
- }
-
- /**
- * Test reading a single operation
- */
- @SuppressWarnings("unchecked")
- @Test
- public void testReadSingleOperation() {
- VABElementProxy submodel = getConnectionManager().connectToVABElement(submodelAddr);
- Map<String, Object> operation = (Map<String, Object>) submodel.getModelPropertyValue("/submodel/operations/simple");
- assertEquals("simple", operation.get(Identifiable.IDSHORT));
- }
-
- /**
- * Test reading all submodel elements of the submodel
- */
- @SuppressWarnings("unchecked")
- @Test
- public void testReadSubModelElements() {
- VABElementProxy submodel = getConnectionManager().connectToVABElement(submodelAddr);
- Collection<Map<String, Object>> set = (Collection<Map<String, Object>>) submodel
- .getModelPropertyValue("/submodel/submodelElements");
- assertEquals(8, set.size());
- }
-
- /**
- * Test deleting a single property
- */
- @Test
- public void testDeleteProperty() {
- VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
-
- // Delete property
- submodelElement.deleteValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty");
-
- // Test, if it has been deleted
- try {
- submodelElement.getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty");
- fail();
- } catch (ResourceNotFoundException e) {}
- }
-
- /**
- * Test deleting a single operation
- */
- @Test
- public void testDeleteOperation() {
- VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
-
- // Delete operation
- submodelElement.deleteValue("/submodel/operations/simple");
-
- // Test, if it has been deleted
- try {
- submodelElement.getModelPropertyValue("/submodel/operations/simple");
- fail();
- } catch (ResourceNotFoundException e) {}
- }
-
- /**
- * Test invoking an operation
- */
- @Test
- public void testInvokeOperation() {
- VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
-
- // Wrap parameters before invoking add-operation
- Map<String, Object> param1 = new HashMap<>();
- param1.put("idShort", "SecondNumber");
- param1.put(Property.VALUE, 5);
- param1.put("valueType", PropertyValueTypeDefHelper.getTypeWrapperFromObject(5));
- Map<String, Object> param2 = new HashMap<>();
- param2.put("idShort", "FirstNumber");
- param2.put(Property.VALUE, 2);
- param2.put("valueType", PropertyValueTypeDefHelper.getTypeWrapperFromObject(2));
-
- // Invoke operation with wrapped parameters and check result
- Object result = submodelElement.invokeOperation("/submodel/operations/complex", param1, param2);
- assertEquals(3, result);
-
- // Invoke operation on parent element
- result = submodelElement.invokeOperation("/submodel/operations/simple");
- assertTrue((boolean) result);
- }
-}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SubmodelProviderTest.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SubmodelProviderTest.java
new file mode 100644
index 0000000..02406d0
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SubmodelProviderTest.java
@@ -0,0 +1,571 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.restapi;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueTypeHelper;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
+import org.eclipse.basyx.submodel.restapi.OperationProvider;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
+import org.eclipse.basyx.submodel.restapi.operation.CallbackResponse;
+import org.eclipse.basyx.submodel.restapi.operation.ExecutionState;
+import org.eclipse.basyx.submodel.restapi.operation.InvocationResponse;
+import org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.operation.AsyncOperationHelper;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.TestsuiteDirectory;
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.protocol.api.ConnectorFactory;
+import org.junit.Test;
+
+public class SubmodelProviderTest {
+ private VABConnectionManager connManager;
+ protected static final String submodelAddr = "urn:fhg:es.iese:aas:1:1:submodel";
+
+ protected VABConnectionManager getConnectionManager() {
+ if (connManager == null) {
+ connManager = new VABConnectionManager(new TestsuiteDirectory(), new ConnectorFactory() {
+ @Override
+ protected IModelProvider createProvider(String addr) {
+ // Simple submodel for testing specific mappings for submodels
+ return new SubmodelProvider(new SimpleAASSubmodel("mySubmodelId"));
+ }
+ });
+ }
+ return connManager;
+ }
+
+ /**
+ * Tests accessing different paths that should be supported
+ * @throws Exception
+ */
+ @Test
+ public void testPathsRaw() throws Exception {
+ SubmodelProvider provider = new SubmodelProvider(new SimpleAASSubmodel("mySubmodelId"));
+ provider.getValue("/submodel");
+ provider.getValue("/submodel/");
+
+ try {
+ provider.getValue("invalid");
+ fail();
+ } catch (Exception e) {
+
+ }
+ }
+
+ /**
+ * Test creating single property
+ */
+ @Test
+ public void testCreateProperty() {
+ VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+
+ // Create element
+ Property prop = new Property(500);
+ prop.setIdShort("newProperty");
+ submodelElement.setValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/newProperty", prop);
+
+ // Read back value
+ Integer result = (Integer) submodelElement
+ .getValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/newProperty/value");
+ assertEquals(500, result.intValue());
+ }
+
+ /**
+ * Test updating a full property
+ */
+ @Test
+ public void testUpdateFullProperty() {
+ VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+
+ // Create element
+ Property prop = new Property("newProperty", 500);
+ submodelElement.setValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/newProperty", prop);
+
+ // Update element
+ Property updatedProp = new Property("newProperty", 400);
+ submodelElement.setValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/newProperty", updatedProp);
+
+ // Read back value
+ Integer result = (Integer) submodelElement
+ .getValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/newProperty/value");
+ assertEquals(400, result.intValue());
+ }
+
+ /**
+ * Test creating single property
+ */
+ @Test
+ public void testCreatePropertyInCollection() {
+ VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+
+ // Create element
+ Property prop = new Property(500);
+ prop.setIdShort("newProperty");
+ submodelElement.setValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/newProperty", prop);
+
+ // Read back value
+ Integer result = (Integer) submodelElement
+ .getValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/newProperty/value");
+ assertEquals(500, result.intValue());
+
+
+ submodelElement.setValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/container/newProperty", prop);
+
+ // Read back value
+ result = (Integer) submodelElement
+ .getValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/container/newProperty/value");
+ assertEquals(500, result.intValue());
+ }
+
+ @Test
+ public void testUpdatePropertyInCollection() {
+ VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+
+ // Create element
+ Property prop = new Property("newProperty", 500);
+ submodelElement.setValue(
+ "/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/container/newProperty", prop);
+
+ // Update element
+ Property prop2 = new Property("newProperty", 400);
+ submodelElement.setValue(
+ "/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/container/newProperty", prop2);
+
+ // Read back value
+ Integer result = (Integer) submodelElement.getValue(
+ "/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/container/newProperty/value");
+ assertEquals(400, result.intValue());
+ }
+
+ /**
+ * Test reading single property
+ */
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testReadProperty() {
+ VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+
+ // Read list of properties
+ Object result = submodelElement.getValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "");
+ Collection<Map<String, Object>> propertySet = (Collection<Map<String, Object>>) result;
+ Map<String, Object> property = propertySet.stream().filter(elem -> elem.get(Identifiable.IDSHORT).equals("integerProperty")).findFirst().get();
+ assertEquals(123, property.get(Property.VALUE));
+
+ // Read whole property
+ result = submodelElement.getValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty");
+ property = (Map<String, Object>) result;
+ assertEquals(123, property.get(Property.VALUE));
+
+ // Read idShort
+ result = submodelElement.getValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/stringProperty");
+ property = (Map<String, Object>) result;
+ assertEquals("stringProperty", property.get(Identifiable.IDSHORT));
+
+ // Read single value
+ String resString = (String) submodelElement
+ .getValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/stringProperty/value");
+ assertEquals("Test", resString);
+
+ // Read null value
+ Object resObject = submodelElement
+ .getValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/nullProperty/value");
+ assertEquals(null, resObject);
+
+ // Read container property
+ Collection<Object> resSet = (Collection<Object>) submodelElement
+ .getValue("/submodel/submodelElements/containerRoot/value");
+ assertEquals(1, resSet.size());
+
+ // Get Collection from root-Collection
+ Map<String, Object> container = (Map<String, Object>) resSet.iterator().next();
+
+ assertEquals("container", container.get(Referable.IDSHORT));
+ assertTrue(container.get(Property.VALUE) instanceof Collection<?>);
+
+ // Get Value of nested Collection
+ Map<String, Object> containerValue = SubmodelElementMapCollectionConverter.convertCollectionToIDMap(container.get(Property.VALUE));
+
+ // Check content of nested Collection
+ assertTrue(containerValue.containsKey("operationId"));
+ assertTrue(containerValue.containsKey("integerProperty"));
+ assertEquals(123, ((Property) containerValue.get("integerProperty")).getValue());
+
+ // Read nested property
+ String pathToNestedContainer = "/submodel/submodelElements/containerRoot/container";
+ String pathToNestedProperty = pathToNestedContainer + "/integerProperty/";
+ result = submodelElement.getValue(pathToNestedProperty);
+ property = (Map<String, Object>) result;
+ assertEquals(123, property.get(Property.VALUE));
+ }
+
+ /**
+ * Test updating single property
+ */
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testUpdateProperty() {
+ VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+
+ // Update element
+ submodelElement.setValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty/value", 3);
+
+ // Check result
+ Map<String, Object> result = (Map<String, Object>) submodelElement
+ .getValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty");
+ assertEquals(3, result.get(Property.VALUE));
+ }
+
+ /**
+ * Test updating a SubmodelElementCollection
+ */
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testUpdateSmElementCollection() {
+ VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+
+ Collection<ISubmodelElement> smElements = new ArrayList<>();
+ Property newProperty = new Property("propValue");
+ newProperty.setIdShort("propIdShort");
+ smElements.add(newProperty);
+
+ // update value of smElemCollection
+ String path = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS, "containerRoot");
+ submodelElement.setValue(path + "/value", smElements);
+
+ // read back the collection
+ Map<String, Object> map = (Map<String, Object>) submodelElement
+ .getValue(path);
+
+ assertTrue(map.get(Property.VALUE) instanceof Collection<?>);
+
+ Collection<Map<String, Object>> elements = (Collection<Map<String, Object>>) map.get(Property.VALUE);
+ assertEquals(1, elements.size());
+
+ Iterator<Map<String, Object>> i = elements.iterator();
+
+ assertEquals("propIdShort", i.next().get(Referable.IDSHORT));
+ }
+
+ /**
+ * Test updating a Property inside a SubmodelElementCollection
+ */
+ @Test
+ public void testUpdateElementInSmElementCollection() {
+ VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+
+ String path = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS,
+ "containerRoot", "container", "integerProperty", "value");
+
+ Integer value = (Integer) submodelElement.getValue(path);
+ assertEquals(123, value.intValue());
+
+ submodelElement.setValue(path, 321);
+
+ value = (Integer) submodelElement.getValue(path);
+ assertEquals(321, value.intValue());
+ }
+
+ /**
+ * Test reading a single operation
+ */
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testReadSingleOperation() {
+ VABElementProxy submodel = getConnectionManager().connectToVABElement(submodelAddr);
+ Map<String, Object> operation = (Map<String, Object>) submodel.getValue("/submodel/submodelElements/simple");
+ assertEquals("simple", operation.get(Identifiable.IDSHORT));
+
+ try {
+ submodel.getValue("/submodel/submodelElements/simple/value");
+ fail();
+ } catch (MalformedRequestException e) {
+ // An Operation has no value
+ }
+ }
+
+ /**
+ * Checks if the submodel elements in a read submodel are within a collection
+ */
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testReadSubmodelCheckElementsInCollection() {
+ VABElementProxy submodel = getConnectionManager().connectToVABElement(submodelAddr);
+ Map<String, Object> smMap = (Map<String, Object>) submodel.getValue("/submodel");
+ Object o = smMap.get(Submodel.SUBMODELELEMENT);
+ assertTrue(o instanceof Collection<?>);
+ }
+
+ /**
+ * Test reading all submodel elements of the submodel
+ */
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testReadSubmodelElements() {
+ VABElementProxy submodel = getConnectionManager().connectToVABElement(submodelAddr);
+ Collection<Map<String, Object>> set = (Collection<Map<String, Object>>) submodel
+ .getValue("/submodel/submodelElements");
+ assertEquals(8, set.size());
+ }
+
+ /**
+ * Test deleting a single property
+ */
+ @Test
+ public void testDeleteProperty() {
+ VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+
+ // Delete property
+ submodelElement.deleteValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty");
+
+ // Test, if it has been deleted
+ try {
+ submodelElement.getValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty");
+ fail();
+ } catch (ResourceNotFoundException e) {}
+ }
+
+ /**
+ * Test deleting a single operation
+ */
+ @Test
+ public void testDeleteOperation() {
+ VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+
+ // Delete operation
+ submodelElement.deleteValue("/submodel/submodelElements/simple");
+
+ // Test, if it has been deleted
+ try {
+ submodelElement.getValue("/submodel/submodelElements/simple");
+ fail();
+ } catch (ResourceNotFoundException e) {}
+ }
+
+ /**
+ * Test deleting a single property from a SubmodelElementCollection
+ */
+ @Test
+ public void testDeletePropertyFromCollection() {
+ VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+
+ String path = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS,
+ "containerRoot", "container", "integerProperty");
+
+ assertNotNull(submodelElement.getValue(path));
+
+ // Delete property
+ submodelElement.deleteValue(path);
+
+ // Test if parent Collection is still there
+ assertNotNull(submodelElement.getValue(VABPathTools.getParentPath(path)));
+
+ // Test, if it has been deleted
+ try {
+ submodelElement.getValue(path);
+ fail();
+ } catch (ResourceNotFoundException e) {}
+
+ // Test delete the Collection "container"
+ path = VABPathTools.getParentPath(path);
+
+ // Delete property
+ submodelElement.deleteValue(path);
+
+ // Test if parent Collection is still there
+ assertNotNull(submodelElement.getValue(VABPathTools.getParentPath(path)));
+
+ // Test, if it has been deleted
+ try {
+ submodelElement.getValue(path);
+ fail();
+ } catch (ResourceNotFoundException e) {}
+ }
+
+ /**
+ * Test invoking an operation
+ */
+ @Test
+ public void testInvokeOperation() {
+ VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+
+ // Wrap parameters before invoking add-operation
+ Map<String, Object> param1 = wrapParameter("FirstNumber", 5);
+ Map<String, Object> param2 = wrapParameter("SecondNumber", 2);
+
+ // Invoke operation with wrapped parameters and check result
+ Object result = submodelElement.invokeOperation("/submodel/submodelElements/complex/invoke", param1, param2);
+ assertEquals(3, result);
+
+ // Invoke operation on parent element
+ result = submodelElement.invokeOperation("/submodel/submodelElements/simple/invoke");
+ assertTrue((boolean) result);
+ }
+
+ /**
+ * Test invoking an operation from within a SubmodelElementCollection
+ */
+ @Test
+ public void testInvokeOperationInCollection() {
+ VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+
+ String path = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS,
+ "containerRoot", "container", "operationId", "invoke");
+
+ Object result = submodelElement.invokeOperation(path);
+ assertEquals(123, result);
+ }
+
+ /**
+ * Test getting /values of the Submodel
+ */
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testGetValues() {
+ VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+ Map<String, Object> values = (Map<String, Object>) submodelElement.getValue("submodel/" + SubmodelProvider.VALUES);
+
+ assertEquals(4, values.size());
+
+ // Check if all expected Values are present
+ assertTrue(values.containsKey("containerRoot"));
+ Map<String, Object> collection1 = (Map<String, Object>) values.get("containerRoot");
+
+ assertTrue(collection1.containsKey("container"));
+ Map<String, Object> collection2 = (Map<String, Object>) collection1.get("container");
+
+ // Check the Value in /containerRoot/container/integerProperty
+ assertEquals(123, collection2.get("integerProperty"));
+
+ assertEquals("Test", values.get("stringProperty"));
+ assertEquals(123, values.get("integerProperty"));
+ assertEquals(null, values.get("nullProperty"));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testInvokeAsync() throws Exception {
+ VABElementProxy elementProxy = getConnectionManager().connectToVABElement(submodelAddr);
+ AsyncOperationHelper helper = new AsyncOperationHelper();
+
+ String path = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS, AsyncOperationHelper.ASYNC_OP_ID);
+ elementProxy.setValue(path, helper.getAsyncOperation());
+
+ // Wrap parameters before invoking add-operation
+ Map<String, Object> param1 = wrapParameter("FirstNumber", 5);
+ Map<String, Object> param2 = wrapParameter("SecondNumber", 2);
+
+ path = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS, AsyncOperationHelper.ASYNC_OP_ID, "invoke?async=true");
+
+ CallbackResponse response = CallbackResponse.createAsFacade((Map<String, Object>) elementProxy.invokeOperation(path, param1, param2));
+ String requestId = response.getRequestId();
+
+ String listPath = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS, AsyncOperationHelper.ASYNC_OP_ID, OperationProvider.INVOCATION_LIST);
+
+ // Try correct operationId, wrong requestId
+ try {
+ elementProxy.getValue(VABPathTools.append(listPath, "nonexistent"));
+ fail();
+ } catch (ResourceNotFoundException e) {
+ }
+
+ // Try wrong operationId, correct requestId
+ try {
+ elementProxy.getValue("/submodel/submodelElements/simple/invocationList/" + requestId);
+ fail();
+ } catch (ResourceNotFoundException e) {
+ }
+
+ String requestPath = VABPathTools.append(listPath, requestId);
+
+ // Check that it has not finished yet
+ InvocationResponse result = (InvocationResponse) elementProxy.getValue(requestPath);
+ assertEquals(ExecutionState.INITIATED, result.getExecutionState());
+
+ helper.releaseWaitingOperation();
+
+ result = (InvocationResponse) elementProxy.getValue(requestPath);
+ assertEquals(7, result.getFirstOutput());
+
+ // Check if the async-invocation is deleted after retrieving its result
+ try {
+ elementProxy.getValue(requestPath);
+ fail();
+ } catch (ResourceNotFoundException e) {
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testInvokeAsyncException() throws Exception {
+ VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+ AsyncOperationHelper helper = new AsyncOperationHelper();
+
+ String path = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS, AsyncOperationHelper.ASYNC_EXCEPTION_OP_ID);
+ submodelElement.setValue(path, helper.getAsyncExceptionOperation());
+
+ path = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS,
+ AsyncOperationHelper.ASYNC_EXCEPTION_OP_ID, "invoke?async=true");
+
+ CallbackResponse response = (CallbackResponse) submodelElement.invokeOperation(path);
+ String requestId = response.getRequestId();
+
+ String requestPath = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS,
+ AsyncOperationHelper.ASYNC_EXCEPTION_OP_ID, OperationProvider.INVOCATION_LIST, requestId);
+
+ // Check that it has not finished yet
+ InvocationResponse invResp = InvocationResponse
+ .createAsFacade((Map<String, Object>) submodelElement.getValue(requestPath));
+ assertNotEquals(ExecutionState.COMPLETED, invResp.getExecutionState());
+ assertNotEquals(ExecutionState.FAILED, invResp.getExecutionState());
+
+ helper.releaseWaitingOperation();
+
+
+ invResp = InvocationResponse
+ .createAsFacade((Map<String, Object>) submodelElement.getValue(requestPath));
+ assertEquals(ExecutionState.FAILED, invResp.getExecutionState());
+
+ // Check if the async-invocation is deleted after retrieving its result
+ try {
+ submodelElement.getValue(requestPath);
+ fail();
+ } catch (ResourceNotFoundException e) {
+ }
+ }
+
+ private Map<String, Object> wrapParameter(String name, Object value) {
+ Map<String, Object> param = new HashMap<>();
+ param.put(Identifiable.IDSHORT, name);
+ param.put(Property.VALUE, value);
+ param.put(Property.VALUETYPE, ValueTypeHelper.getType(value).toString());
+ return param;
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/TestDigitalNameplateSubmodel.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/TestDigitalNameplateSubmodel.java
new file mode 100644
index 0000000..7045229
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/TestDigitalNameplateSubmodel.java
@@ -0,0 +1,171 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address.Address;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.assetspecificproperties.AssetSpecificProperties;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.markings.Marking;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.markings.Markings;
+import org.eclipse.basyx.submodel.types.digitalnameplate.DigitalNameplateSubmodel;
+import org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.address.TestAddress;
+import org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.assetspecificproperties.TestAssetSpecificProperties;
+import org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.markings.TestMarking;
+import org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.markings.TestMarkings;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests createAsFacade and isValid of {@link DigitalNameplateSubmodel} for their
+ * correctness
+ *
+ * @author haque
+ *
+ */
+public class TestDigitalNameplateSubmodel {
+ public static MultiLanguageProperty manufacturerName = new MultiLanguageProperty(DigitalNameplateSubmodel.MANUFACTURERNAMEID);
+ public static MultiLanguageProperty designation = new MultiLanguageProperty(DigitalNameplateSubmodel.MANUFACTURERPRODUCTDESIGNATIONID);
+ public static Address address = new Address(TestAddress.street, TestAddress.zipCode, TestAddress.cityTown, TestAddress.nationalCode);
+ public static MultiLanguageProperty productFamily = new MultiLanguageProperty(DigitalNameplateSubmodel.MANUFACTURERPRODUCTFAMILYID);
+ public static Property serialNumber = new Property(DigitalNameplateSubmodel.SERIALNUMBERID, ValueType.String);
+ public static Property yearsOfConstruction = new Property(DigitalNameplateSubmodel.YEARSOFCONSTRUCTIONID, ValueType.String);
+ public static Markings markings;
+ public static AssetSpecificProperties assetSpecificProperties = new AssetSpecificProperties(Collections.singletonList(TestAssetSpecificProperties.guidelineSpecificProperties));
+ public static Identifier identifier = new Identifier(IdentifierType.IRI, "https://admin-shell.io/zvei/nameplate/1/0/Nameplate");
+ private Map<String, Object> submodelMap = new HashMap<String, Object>();
+
+ @Before
+ public void buildFax() {
+ manufacturerName.setValue(new LangStrings(new LangString("DE", "Test Manufacturer")));
+ designation.setValue(new LangStrings(new LangString("DE", "Test Designation")));
+ productFamily.setValue(new LangStrings(new LangString("DE", "Test Product Family")));
+ serialNumber.setValue("123456");
+ yearsOfConstruction.setValue("2020");
+
+ TestMarking.markingFile.setIdShort(Marking.MARKINGFILEID);
+ TestMarking.markingName.setValue("0173-1#07-DAA603#004");
+ TestMarkings.marking = new Marking(TestMarking.IDSHORT, TestMarking.markingName, TestMarking.markingFile);
+ TestMarkings.marking.setParent(new Reference(new Key(KeyElements.SUBMODELELEMENTCOLLECTION, true, Markings.IDSHORT, IdentifierType.IRDI)));
+ TestMarkings.markings = new ArrayList<Marking>();
+ TestMarkings.markings.add(TestMarkings.marking);
+ markings = new Markings(TestMarkings.markings);
+
+ TestAddress.street.setValue(new LangStrings(new LangString("DE", "musterstraße 1")));
+ TestAddress.zipCode.setValue(new LangStrings(new LangString("DE", "12345")));
+ TestAddress.cityTown.setValue(new LangStrings(new LangString("DE", "MusterStadt")));
+ TestAddress.nationalCode.setValue(new LangStrings(new LangString("DE", "DE")));
+
+ List<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
+ elements.add(manufacturerName);
+ elements.add(designation);
+ elements.add(productFamily);
+ elements.add(serialNumber);
+ elements.add(yearsOfConstruction);
+ elements.add(markings);
+ elements.add(address);
+ elements.add(assetSpecificProperties);
+ submodelMap.put(Referable.IDSHORT, DigitalNameplateSubmodel.SUBMODELID);
+ submodelMap.put(HasSemantics.SEMANTICID, DigitalNameplateSubmodel.SEMANTICID);
+ submodelMap.put(Submodel.SUBMODELELEMENT, elements);
+ submodelMap.put(Identifiable.IDENTIFICATION, identifier);
+ }
+
+ @Test
+ public void testCreateAsFacade() {
+ DigitalNameplateSubmodel submodelFromMap = DigitalNameplateSubmodel.createAsFacade(submodelMap);
+ assertEquals(DigitalNameplateSubmodel.SEMANTICID, submodelFromMap.getSemanticId());
+ assertEquals(manufacturerName, submodelFromMap.getManufacturerName());
+ assertEquals(designation, submodelFromMap.getManufacturerProductDesignation());
+ assertEquals(address, submodelFromMap.getAddress());
+ assertEquals(productFamily, submodelFromMap.getManufacturerProductFamily());
+ assertEquals(serialNumber, submodelFromMap.getSerialNumber());
+ assertEquals(yearsOfConstruction, submodelFromMap.getYearOfConstruction());
+ assertEquals(markings, submodelFromMap.getMarkings());
+ assertEquals(assetSpecificProperties, submodelFromMap.getAssetSpecificProperties());
+ assertEquals(DigitalNameplateSubmodel.SUBMODELID, submodelFromMap.getIdShort());
+ assertEquals(identifier, submodelFromMap.getIdentification());
+ }
+
+ @Test (expected = MetamodelConstructionException.class)
+ public void testCreateAsFacadeExceptionIdShort() {
+ submodelMap.remove(Referable.IDSHORT);
+ DigitalNameplateSubmodel.createAsFacade(submodelMap);
+ }
+
+ @Test (expected = MetamodelConstructionException.class)
+ public void testCreateAsFacadeExceptionIdentifier() {
+ submodelMap.remove(Identifiable.IDENTIFICATION);
+ DigitalNameplateSubmodel.createAsFacade(submodelMap);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test (expected = ResourceNotFoundException.class)
+ public void testCreateAsFacadeExceptionManufacturerName() {
+ List<ISubmodelElement> elements = (List<ISubmodelElement>)submodelMap.get(Submodel.SUBMODELELEMENT);
+ elements.remove(manufacturerName);
+ DigitalNameplateSubmodel.createAsFacade(submodelMap);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test (expected = ResourceNotFoundException.class)
+ public void testCreateAsFacadeExceptionZearsOfConstruction() {
+ List<ISubmodelElement> elements = (List<ISubmodelElement>)submodelMap.get(Submodel.SUBMODELELEMENT);
+ elements.remove(yearsOfConstruction);
+ DigitalNameplateSubmodel.createAsFacade(submodelMap);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test (expected = ResourceNotFoundException.class)
+ public void testCreateAsFacadeExceptionManufacturerProductDesignation() {
+ List<ISubmodelElement> elements = (List<ISubmodelElement>)submodelMap.get(Submodel.SUBMODELELEMENT);
+ elements.remove(designation);
+ DigitalNameplateSubmodel.createAsFacade(submodelMap);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test (expected = ResourceNotFoundException.class)
+ public void testCreateAsFacadeExceptionAddress() {
+ List<ISubmodelElement> elements = (List<ISubmodelElement>)submodelMap.get(Submodel.SUBMODELELEMENT);
+ elements.remove(address);
+ DigitalNameplateSubmodel.createAsFacade(submodelMap);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test (expected = ResourceNotFoundException.class)
+ public void testCreateAsFacadeExceptionManufacturerProductFamily() {
+ List<ISubmodelElement> elements = (List<ISubmodelElement>)submodelMap.get(Submodel.SUBMODELELEMENT);
+ elements.remove(productFamily);
+ DigitalNameplateSubmodel.createAsFacade(submodelMap);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestAddress.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestAddress.java
new file mode 100644
index 0000000..9da5fca
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestAddress.java
@@ -0,0 +1,171 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.address;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address.Address;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address.Email;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address.Fax;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address.Phone;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests createAsFacade and isValid of {@link Address} for their
+ * correctness
+ *
+ * @author haque
+ *
+ */
+public class TestAddress {
+ public static final String IDSHORT = "testAddressId";
+ public static MultiLanguageProperty department = new MultiLanguageProperty(Address.DEPARTMENTID);
+ public static MultiLanguageProperty street = new MultiLanguageProperty(Address.STREETID);
+ public static MultiLanguageProperty zipCode = new MultiLanguageProperty(Address.ZIPCODEID);
+ public static MultiLanguageProperty poBox = new MultiLanguageProperty(Address.POBOXID);
+ public static MultiLanguageProperty zipPoBox = new MultiLanguageProperty(Address.ZIPCODEOFPOBOXID);
+ public static MultiLanguageProperty cityTown = new MultiLanguageProperty(Address.CITYTOWNID);
+ public static MultiLanguageProperty stateCounty = new MultiLanguageProperty(Address.STATECOUNTYID);
+ public static MultiLanguageProperty nationalCode = new MultiLanguageProperty(Address.NATIONALCODEID);
+ public static MultiLanguageProperty vatNumber = new MultiLanguageProperty(Address.VATNUMBERID);
+ public static MultiLanguageProperty addressRemarks = new MultiLanguageProperty(Address.ADDRESSREMARKSID);
+ public static Property additLink = new Property(Address.ADDRESSOFADDITIONALLINKID, ValueType.String);
+ public static Phone phone1 = new Phone("Phone01", new LangString("DE", "123456789"));
+ public static Phone phone2 = new Phone("Phone02", new LangString("US", "123456711"));
+ public static Fax fax1 = new Fax("Fax01", new LangString("DE", "123456789"));
+ public static Fax fax2 = new Fax("Fax02", new LangString("DE", "123456711"));
+ public static Email email1 = new Email("Email01", new Property(Email.EMAILADDRESSID, "abc@test.com"));
+ public static Email email2 = new Email("Email02", new Property(Email.EMAILADDRESSID, "abcd@test.com"));
+
+
+ private Map<String, Object> addressMap = new HashMap<String, Object>();
+
+ @Before
+ public void buildFax() {
+ department.setValue(new LangStrings(new LangString("DE", "Dept Test")));
+ street.setValue(new LangStrings(new LangString("DE", "musterstraße 1")));
+ zipCode.setValue(new LangStrings(new LangString("DE", "12345")));
+ poBox.setValue(new LangStrings(new LangString("DE", "PE 1234")));
+ zipPoBox.setValue(new LangStrings(new LangString("DE", "12345")));
+ cityTown.setValue(new LangStrings(new LangString("DE", "MusterStadt")));
+ stateCounty.setValue(new LangStrings(new LangString("DE", "RLP")));
+ nationalCode.setValue(new LangStrings(new LangString("DE", "DE")));
+ vatNumber.setValue(new LangStrings(new LangString("DE", "123456")));
+ addressRemarks.setValue(new LangStrings(new LangString("DE", "test remarks")));
+ additLink.setValue("test.com");
+
+ List<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
+ elements.add(department);
+ elements.add(street);
+ elements.add(zipCode);
+ elements.add(poBox);
+ elements.add(zipPoBox);
+ elements.add(cityTown);
+ elements.add(stateCounty);
+ elements.add(nationalCode);
+ elements.add(vatNumber);
+ elements.add(addressRemarks);
+ elements.add(additLink);
+ elements.add(phone1);
+ elements.add(phone2);
+ elements.add(fax1);
+ elements.add(fax2);
+ elements.add(email1);
+ elements.add(email2);
+
+ addressMap.put(Referable.IDSHORT, IDSHORT);
+ addressMap.put(HasSemantics.SEMANTICID, Address.SEMANTICID);
+ addressMap.put(Property.VALUE, elements);
+ }
+
+ @Test
+ public void testCreateAsFacade() {
+ Address addressFromMap = Address.createAsFacade(addressMap);
+ assertEquals(Address.SEMANTICID, addressFromMap.getSemanticId());
+ assertEquals(IDSHORT, addressFromMap.getIdShort());
+ assertEquals(department, addressFromMap.getDepartment());
+ assertEquals(street, addressFromMap.getStreet());
+ assertEquals(poBox, addressFromMap.getPOBox());
+ assertEquals(zipPoBox, addressFromMap.getZipCodeOfPOBox());
+ assertEquals(cityTown, addressFromMap.getCityTown());
+ assertEquals(stateCounty, addressFromMap.getStateCounty());
+ assertEquals(nationalCode, addressFromMap.getNationalCode());
+ assertEquals(zipCode, addressFromMap.getZipCode());
+ assertEquals(vatNumber, addressFromMap.getVatNumber());
+ assertEquals(addressRemarks, addressFromMap.getAddressRemarks());
+ assertEquals(additLink, addressFromMap.getAddressOfAdditionalLink());
+ List<Phone> phones = new ArrayList<Phone>();
+ phones.add(phone2);
+ phones.add(phone1);
+ List<Fax> faxes = new ArrayList<Fax>();
+ faxes.add(fax1);
+ faxes.add(fax2);
+ List<Email> emails = new ArrayList<Email>();
+ emails.add(email2);
+ emails.add(email1);
+ assertEquals(phones, addressFromMap.getPhone());
+ assertEquals(faxes, addressFromMap.getFax());
+ assertEquals(emails, addressFromMap.getEmail());
+ }
+
+ @Test (expected = MetamodelConstructionException.class)
+ public void testCreateAsFacadeExceptionIdShort() {
+ addressMap.remove(Referable.IDSHORT);
+ Address.createAsFacade(addressMap);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test (expected = ResourceNotFoundException.class)
+ public void testCreateAsFacadeExceptionStreet() {
+ List<ISubmodelElement> elements = (List<ISubmodelElement>)addressMap.get(Property.VALUE);
+ elements.remove(street);
+ Address.createAsFacade(addressMap);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test (expected = ResourceNotFoundException.class)
+ public void testCreateAsFacadeExceptionZipCode() {
+ List<ISubmodelElement> elements = (List<ISubmodelElement>)addressMap.get(Property.VALUE);
+ elements.remove(zipCode);
+ Address.createAsFacade(addressMap);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test (expected = ResourceNotFoundException.class)
+ public void testCreateAsFacadeExceptionCityTown() {
+ List<ISubmodelElement> elements = (List<ISubmodelElement>)addressMap.get(Property.VALUE);
+ elements.remove(cityTown);
+ Address.createAsFacade(addressMap);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test (expected = ResourceNotFoundException.class)
+ public void testCreateAsFacadeExceptionNationalCode() {
+ List<ISubmodelElement> elements = (List<ISubmodelElement>)addressMap.get(Property.VALUE);
+ elements.remove(nationalCode);
+ Address.createAsFacade(addressMap);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestEmail.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestEmail.java
new file mode 100644
index 0000000..7397b47
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestEmail.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.address;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.digitalnameplate.enums.MailType;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address.Email;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests createAsFacade and isValid of {@link Email} for their
+ * correctness
+ *
+ * @author haque
+ *
+ */
+public class TestEmail {
+ public static final String IDSHORT = "testEmailId";
+ public static Property emailAddress = new Property(Email.EMAILADDRESSID, ValueType.String);
+ public static MultiLanguageProperty publicKey = new MultiLanguageProperty(Email.PUBLICKEYID);
+ public static Property typeOfEmailAddress = new Property(Email.TYPEOFEMAILADDRESSID, ValueType.String);
+ public static MultiLanguageProperty typeOfPublicKey = new MultiLanguageProperty(Email.TYPEOFPUBLICKEYID);
+
+ private Map<String, Object> emailMap = new HashMap<String, Object>();
+
+ @Before
+ public void buildFax() {
+ emailAddress.setValue("test@muster-ag.de");
+ publicKey.setValue(new LangStrings(new LangString("DE", "123456")));
+ typeOfEmailAddress.setValue(MailType.SECRETARY);
+ typeOfPublicKey.setValue(new LangStrings(new LangString("DE", "1234")));
+ List<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
+ elements.add(emailAddress);
+ elements.add(publicKey);
+ elements.add(typeOfEmailAddress);
+ elements.add(typeOfPublicKey);
+ emailMap.put(Referable.IDSHORT, IDSHORT);
+ emailMap.put(HasSemantics.SEMANTICID, Email.SEMANTICID);
+ emailMap.put(Property.VALUE, elements);
+ }
+
+ @Test
+ public void testCreateAsFacade() {
+ Email emailFromMap = Email.createAsFacade(emailMap);
+ assertEquals(Email.SEMANTICID, emailFromMap.getSemanticId());
+ assertEquals(emailAddress, emailFromMap.getEmailAddress());
+ assertEquals(publicKey, emailFromMap.getPublicKey());
+ assertEquals(typeOfEmailAddress, emailFromMap.getTypeOfEmailAddress());
+ assertEquals(typeOfPublicKey, emailFromMap.getTypeOfPublicKey());
+ assertEquals(IDSHORT, emailFromMap.getIdShort());
+ }
+
+ @Test (expected = MetamodelConstructionException.class)
+ public void testCreateAsFacadeExceptionIdShort() {
+ emailMap.remove(Referable.IDSHORT);
+ Email.createAsFacade(emailMap);
+ }
+
+ @Test (expected = ResourceNotFoundException.class)
+ public void testCreateAsFacadeExceptionEmailAddress() {
+ List<ISubmodelElement> newElements = new ArrayList<ISubmodelElement>();
+ newElements.add(typeOfEmailAddress);
+ emailMap.put(Property.VALUE, newElements);
+ Email.createAsFacade(emailMap);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestFax.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestFax.java
new file mode 100644
index 0000000..40f7069
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestFax.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.address;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.digitalnameplate.enums.FaxType;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address.Fax;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests createAsFacade and isValid of {@link Fax} for their
+ * correctness
+ *
+ * @author haque
+ *
+ */
+public class TestFax {
+ public static final String IDSHORT = "testFaxId";
+ public static MultiLanguageProperty faxNumber = new MultiLanguageProperty(Fax.FAXNUMBERID);
+ public static Property typeOfFax = new Property(Fax.TYPEOFFAXID, ValueType.String);
+
+ private Map<String, Object> faxMap = new HashMap<String, Object>();
+
+ @Before
+ public void buildFax() {
+ faxNumber.setValue(new LangStrings(new LangString("DE", "0631123456")));
+ typeOfFax.setValue(FaxType.HOME);
+ List<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
+ elements.add(faxNumber);
+ elements.add(typeOfFax);
+ faxMap.put(Referable.IDSHORT, IDSHORT);
+ faxMap.put(HasSemantics.SEMANTICID, Fax.SEMANTICID);
+ faxMap.put(Property.VALUE, elements);
+ }
+
+ @Test
+ public void testCreateAsFacade() {
+ Fax faxFromMap = Fax.createAsFacade(faxMap);
+ assertEquals(Fax.SEMANTICID, faxFromMap.getSemanticId());
+ assertEquals(faxNumber, faxFromMap.getFaxNumber());
+ assertEquals(typeOfFax, faxFromMap.getTypeOfFaxNumber());
+ assertEquals(IDSHORT, faxFromMap.getIdShort());
+ }
+
+ @Test (expected = MetamodelConstructionException.class)
+ public void testCreateAsFacadeExceptionIdShort() {
+ faxMap.remove(Referable.IDSHORT);
+ Fax.createAsFacade(faxMap);
+ }
+
+ @Test (expected = ResourceNotFoundException.class)
+ public void testCreateAsFacadeExceptionFaxNumber() {
+ List<ISubmodelElement> newElements = new ArrayList<ISubmodelElement>();
+ newElements.add(typeOfFax);
+ faxMap.put(Property.VALUE, newElements);
+ Fax.createAsFacade(faxMap);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestPhone.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestPhone.java
new file mode 100644
index 0000000..575daa4
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestPhone.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.address;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.digitalnameplate.enums.PhoneType;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address.Phone;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests createAsFacade and isValid of {@link Phone} for their
+ * correctness
+ *
+ * @author haque
+ *
+ */
+public class TestPhone {
+ public static final String IDSHORT = "testPhoneId";
+ public static MultiLanguageProperty telephone = new MultiLanguageProperty(Phone.TELEPHONENUMBERID);
+ public static Property typeOfTelephone = new Property(Phone.TYPEOFTELEPHONEID, ValueType.String);
+ private Map<String, Object> phoneMap = new HashMap<String, Object>();
+
+ @Before
+ public void buildPhone() {
+ telephone.setValue(new LangStrings(new LangString("DE", "0631123456")));
+ typeOfTelephone.setValue(PhoneType.HOME);
+ List<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
+ elements.add(telephone);
+ elements.add(typeOfTelephone);
+ phoneMap.put(Referable.IDSHORT, IDSHORT);
+ phoneMap.put(HasSemantics.SEMANTICID, Phone.SEMANTICID);
+ phoneMap.put(Property.VALUE, elements);
+ }
+
+ @Test
+ public void testCreateAsFacade() {
+ Phone phoneFromMap = Phone.createAsFacade(phoneMap);
+ assertEquals(Phone.SEMANTICID, phoneFromMap.getSemanticId());
+ assertEquals(telephone, phoneFromMap.getTelephoneNumber());
+ assertEquals(typeOfTelephone, phoneFromMap.getTypeOfTelephone());
+ assertEquals(IDSHORT, phoneFromMap.getIdShort());
+ }
+
+ @Test (expected = MetamodelConstructionException.class)
+ public void testCreateAsFacadeExceptionIdShort() {
+ phoneMap.remove(Referable.IDSHORT);
+ Phone.createAsFacade(phoneMap);
+ }
+
+ @Test (expected = ResourceNotFoundException.class)
+ public void testCreateAsFacadeExceptionTelephoneNumber() {
+ List<ISubmodelElement> newElements = new ArrayList<ISubmodelElement>();
+ newElements.add(typeOfTelephone);
+ phoneMap.put(Property.VALUE, newElements);
+ Phone.createAsFacade(phoneMap);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/TestAssetSpecificProperties.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/TestAssetSpecificProperties.java
new file mode 100644
index 0000000..eba7643
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/TestAssetSpecificProperties.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.assetspecificproperties;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.assetspecificproperties.AssetSpecificProperties;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.assetspecificproperties.GuidelineSpecificProperties;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests createAsFacade and isValid of {@link AssetSpecificProperties} for their
+ * correctness
+ *
+ * @author haque
+ *
+ */
+public class TestAssetSpecificProperties {
+ public static final String IDSHORT = "AssetSpecificProperties";
+ public static GuidelineSpecificProperties guidelineSpecificProperties = new GuidelineSpecificProperties(TestGuidelineSpecificProperties.IDSHORT, TestGuidelineSpecificProperties.conformityDeclaration, Collections.singletonList(TestGuidelineSpecificProperties.arbitrary));
+
+ private Map<String, Object> assetMap = new HashMap<String, Object>();
+
+ @Before
+ public void buildAssetSpecificProperties() {
+
+ List<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
+ elements.add(guidelineSpecificProperties);
+
+ assetMap.put(Referable.IDSHORT, IDSHORT);
+ assetMap.put(HasSemantics.SEMANTICID, AssetSpecificProperties.SEMANTICID);
+ assetMap.put(Property.VALUE, elements);
+ }
+
+ @Test
+ public void testCreateAsFacade() {
+ AssetSpecificProperties assetFromMap = AssetSpecificProperties.createAsFacade(assetMap);
+ assertEquals(AssetSpecificProperties.SEMANTICID, assetFromMap.getSemanticId());
+ assertEquals(Collections.singletonList(guidelineSpecificProperties), assetFromMap.getGuidelineSpecificProperties());
+ assertEquals(IDSHORT, assetFromMap.getIdShort());
+ }
+
+ @Test (expected = MetamodelConstructionException.class)
+ public void testCreateAsFacadeExceptionIdShort() {
+ assetMap.remove(Referable.IDSHORT);
+ AssetSpecificProperties.createAsFacade(assetMap);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test (expected = MetamodelConstructionException.class)
+ public void testCreateAsFacadeExceptionGuideline() {
+ List<ISubmodelElement> elements = (List<ISubmodelElement>)assetMap.get(Property.VALUE);
+ elements.remove(guidelineSpecificProperties);
+ AssetSpecificProperties.createAsFacade(assetMap);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/TestGuidelineSpecificProperties.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/TestGuidelineSpecificProperties.java
new file mode 100644
index 0000000..c23dfa0
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/TestGuidelineSpecificProperties.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.assetspecificproperties;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.assetspecificproperties.GuidelineSpecificProperties;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests createAsFacade and isValid of {@link GuidelineSpecificProperties} for their
+ * correctness
+ *
+ * @author haque
+ *
+ */
+public class TestGuidelineSpecificProperties {
+ public static final String IDSHORT = "GuidelineSpecificProperties01";
+ public static Property conformityDeclaration = new Property(GuidelineSpecificProperties.GUIDELINEFORCONFORMITYDECLARATIONID, ValueType.String);
+ public static Property arbitrary = new Property("arbitraryId", ValueType.String);
+
+ private Map<String, Object> guidelineMap = new HashMap<String, Object>();
+
+ @Before
+ public void buildGuidelineSpecificProperties() {
+ conformityDeclaration.setValue("test Declaration");
+ arbitrary.setValue("0173-1#07-DAA603#004");
+
+ List<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
+ elements.add(conformityDeclaration);
+ elements.add(arbitrary);
+
+ guidelineMap.put(Referable.IDSHORT, IDSHORT);
+ guidelineMap.put(HasSemantics.SEMANTICID, GuidelineSpecificProperties.SEMANTICID);
+ guidelineMap.put(Property.VALUE, elements);
+ }
+
+ @Test
+ public void testCreateAsFacade() {
+ GuidelineSpecificProperties guidelineFromMap = GuidelineSpecificProperties.createAsFacade(guidelineMap);
+ assertEquals(GuidelineSpecificProperties.SEMANTICID, guidelineFromMap.getSemanticId());
+ assertEquals(conformityDeclaration, guidelineFromMap.getGuidelineForConformityDeclaration());
+ assertEquals(Collections.singletonList(arbitrary), guidelineFromMap.getArbitrary());
+ assertEquals(IDSHORT, guidelineFromMap.getIdShort());
+ }
+
+ @Test (expected = MetamodelConstructionException.class)
+ public void testCreateAsFacadeExceptionIdShort() {
+ guidelineMap.remove(Referable.IDSHORT);
+ GuidelineSpecificProperties.createAsFacade(guidelineMap);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test (expected = MetamodelConstructionException.class)
+ public void testCreateAsFacadeExceptionArbitrary() {
+ List<ISubmodelElement> elements = (List<ISubmodelElement>)guidelineMap.get(Property.VALUE);
+ elements.remove(arbitrary);
+ GuidelineSpecificProperties.createAsFacade(guidelineMap);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test (expected = ResourceNotFoundException.class)
+ public void testCreateAsFacadeExceptionDeclaration() {
+ List<ISubmodelElement> elements = (List<ISubmodelElement>)guidelineMap.get(Property.VALUE);
+ elements.remove(conformityDeclaration);
+ GuidelineSpecificProperties.createAsFacade(guidelineMap);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/markings/TestMarking.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/markings/TestMarking.java
new file mode 100644
index 0000000..c3939be
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/markings/TestMarking.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.markings;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.markings.Marking;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests createAsFacade and isValid of {@link Marking} for their
+ * correctness
+ *
+ * @author haque
+ *
+ */
+public class TestMarking {
+ public static final String IDSHORT = "Marking01";
+ public static Property markingName = new Property(Marking.MARKINGNAMEID, ValueType.String);
+ public static File markingFile = new File("/to/the/image.jpg", "image/jpg");
+ public static Property additText = new Property(Marking.MARKINGADDITIONALTEXTPREFIX + "01", ValueType.String);
+
+ private Map<String, Object> markingMap = new HashMap<String, Object>();
+
+ @Before
+ public void buildFax() {
+ markingFile.setIdShort(Marking.MARKINGFILEID);
+ markingName.setValue("0173-1#07-DAA603#004");
+ additText.setValue("text additional");
+
+ List<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
+ elements.add(markingFile);
+ elements.add(markingName);
+ elements.add(additText);
+
+ markingMap.put(Referable.IDSHORT, IDSHORT);
+ markingMap.put(HasSemantics.SEMANTICID, Marking.SEMANTICID);
+ markingMap.put(Property.VALUE, elements);
+ }
+
+ @Test
+ public void testCreateAsFacade() {
+ Marking markingFromMap = Marking.createAsFacade(markingMap);
+ assertEquals(Marking.SEMANTICID, markingFromMap.getSemanticId());
+ assertEquals(markingFile, markingFromMap.getMarkingFile());
+ assertEquals(markingName, markingFromMap.getMarkingName());
+ assertEquals(Collections.singletonList(additText), markingFromMap.getMarkingAdditionalText());
+ assertEquals(IDSHORT, markingFromMap.getIdShort());
+ }
+
+ @Test (expected = MetamodelConstructionException.class)
+ public void testCreateAsFacadeExceptionIdShort() {
+ markingMap.remove(Referable.IDSHORT);
+ Marking.createAsFacade(markingMap);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test (expected = ResourceNotFoundException.class)
+ public void testCreateAsFacadeExceptionMarkingName() {
+ List<ISubmodelElement> elements = (List<ISubmodelElement>)markingMap.get(Property.VALUE);
+ elements.remove(markingName);
+ Marking.createAsFacade(markingMap);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test (expected = ResourceNotFoundException.class)
+ public void testCreateAsFacadeExceptionMarkingFile() {
+ List<ISubmodelElement> elements = (List<ISubmodelElement>)markingMap.get(Property.VALUE);
+ elements.remove(markingFile);
+ Marking.createAsFacade(markingMap);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/markings/TestMarkings.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/markings/TestMarkings.java
new file mode 100644
index 0000000..fc2a613
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/markings/TestMarkings.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.markings;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.markings.Marking;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.markings.Markings;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+
+/**
+ * Tests createAsFacade and isValid of {@link Markings} for their
+ * correctness
+ *
+ * @author haque
+ *
+ */
+public class TestMarkings {
+ public static final String IDSHORT = "Markings";
+ public static List<Marking> markings;
+ public static Marking marking;
+
+ private Map<String, Object> markingsMap = new HashMap<String, Object>();
+
+ @Before
+ public void initMarkings() {
+ TestMarking.markingFile.setIdShort(Marking.MARKINGFILEID);
+ TestMarking.markingName.setValue("0173-1#07-DAA603#004");
+ marking = new Marking(TestMarking.IDSHORT, TestMarking.markingName, TestMarking.markingFile);
+ marking.setParent(new Reference(new Key(KeyElements.SUBMODELELEMENTCOLLECTION, true, IDSHORT, IdentifierType.IRDI)));
+ markings = new ArrayList<Marking>();
+ markings.add(marking);
+
+ markingsMap.put(Referable.IDSHORT, IDSHORT);
+ markingsMap.put(Property.VALUE, markings);
+ markingsMap.put(HasSemantics.SEMANTICID, Markings.SEMANTICID);
+ }
+
+ @Test
+ public void testCreateAsFacade() {
+ Markings markingsFromMap = Markings.createAsFacade(markingsMap);
+ assertEquals(Markings.SEMANTICID, markingsFromMap.getSemanticId());
+ assertEquals(markings, markingsFromMap.getMarking());
+ assertEquals(IDSHORT, markingsFromMap.getIdShort());
+ }
+
+ @Test (expected = MetamodelConstructionException.class)
+ public void testCreateAsFacadeExceptionIdShort() {
+ markingsMap.remove(Referable.IDSHORT);
+ Markings.createAsFacade(markingsMap);
+ }
+
+ @Test (expected = MetamodelConstructionException.class)
+ public void testCreateAsFacadeExceptionNullMarkings() {
+ markingsMap.remove(Property.VALUE);
+ Markings.createAsFacade(markingsMap);
+ }
+
+ @Test (expected = MetamodelConstructionException.class)
+ public void testCreateAsFacadeExceptionEmptyMarkings() {
+ markingsMap.put(Property.VALUE, new ArrayList<Marking>());
+ Markings.createAsFacade(markingsMap);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/TestTechnicalDataSubmodel.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/TestTechnicalDataSubmodel.java
new file mode 100644
index 0000000..c8e70ce
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/TestTechnicalDataSubmodel.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+* Copyright (C) 2021 the Eclipse BaSyx Authors
+*
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+
+*
+* SPDX-License-Identifier: EPL-2.0
+******************************************************************************/
+
+package org.eclipse.basyx.testsuite.regression.submodel.types.technicaldata;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.technicaldata.TechnicalDataSubmodel;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.furtherinformation.FurtherInformation;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.generalinformation.GeneralInformation;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.productclassifications.ProductClassifications;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.technicalproperties.TechnicalProperties;
+import org.eclipse.basyx.testsuite.regression.submodel.types.technicaldata.generalinformation.TestGeneralInformation;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests createAsFacade and isValid of {@link TechnicalDataSubmodel} for their
+ * correctness
+ *
+ * @author haque
+ *
+ */
+public class TestTechnicalDataSubmodel {
+ public static GeneralInformation generalInformation = new GeneralInformation(TestGeneralInformation.manufacturerName, TestGeneralInformation.designation, TestGeneralInformation.partNumber, TestGeneralInformation.orderCode);
+ public static ProductClassifications productClassifications = new ProductClassifications(TechnicalDataSubmodel.PRODUCTCLASSIFICATIONSID);
+ public static TechnicalProperties technicalProperties = new TechnicalProperties(TechnicalDataSubmodel.TECHNICALPROPERTIESID);
+ public static FurtherInformation furtherInformation = new FurtherInformation(new Property(FurtherInformation.VALIDDATEID, ValueType.DateTime));
+
+ public static Identifier identifier = new Identifier(IdentifierType.IRI, "http://admin-shell.io/ZVEI/TechnicalData/Submodel/1/1");
+ private Map<String, Object> submodelMap = new HashMap<String, Object>();
+
+ @Before
+ public void buildFax() {
+ TestGeneralInformation.manufacturerName.setValue("Example Company");
+ TestGeneralInformation.designation.setValue(new LangStrings(new LangString("de", "Elektrischer Energie Beschleuniger")));
+ TestGeneralInformation.partNumber.setValue("A123-456");
+ TestGeneralInformation.orderCode.setValue("EEA-EX-200-S/47-Q3");
+
+ List<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
+ elements.add(generalInformation);
+ elements.add(furtherInformation);
+ elements.add(productClassifications);
+ elements.add(technicalProperties);
+
+ submodelMap.put(Referable.IDSHORT, TechnicalDataSubmodel.SUBMODELID);
+ submodelMap.put(HasSemantics.SEMANTICID, TechnicalDataSubmodel.SEMANTICID);
+ submodelMap.put(Submodel.SUBMODELELEMENT, elements);
+ submodelMap.put(Identifiable.IDENTIFICATION, identifier);
+ }
+
+ @Test
+ public void testCreateAsFacade() {
+ TechnicalDataSubmodel submodelFromMap = TechnicalDataSubmodel.createAsFacade(submodelMap);
+ assertEquals(TechnicalDataSubmodel.SEMANTICID, submodelFromMap.getSemanticId());
+ assertEquals(generalInformation, submodelFromMap.getGeneralInformation());
+ assertEquals(furtherInformation, submodelFromMap.getFurtherInformation());
+ assertEquals(technicalProperties, submodelFromMap.getTechnicalProperties());
+ assertEquals(productClassifications, submodelFromMap.getProductClassifications());
+ assertEquals(TechnicalDataSubmodel.SUBMODELID, submodelFromMap.getIdShort());
+ assertEquals(identifier, submodelFromMap.getIdentification());
+ }
+
+ @Test (expected = MetamodelConstructionException.class)
+ public void testCreateAsFacadeExceptionIdShort() {
+ submodelMap.remove(Referable.IDSHORT);
+ TechnicalDataSubmodel.createAsFacade(submodelMap);
+ }
+
+ @Test (expected = MetamodelConstructionException.class)
+ public void testCreateAsFacadeExceptionIdentifier() {
+ submodelMap.remove(Identifiable.IDENTIFICATION);
+ TechnicalDataSubmodel.createAsFacade(submodelMap);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test (expected = ResourceNotFoundException.class)
+ public void testCreateAsFacadeExceptionGeneralInfo() {
+ List<ISubmodelElement> elements = (List<ISubmodelElement>)submodelMap.get(Submodel.SUBMODELELEMENT);
+ elements.remove(generalInformation);
+ TechnicalDataSubmodel.createAsFacade(submodelMap);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test (expected = ResourceNotFoundException.class)
+ public void testCreateAsFacadeExceptionTechnicalProp() {
+ List<ISubmodelElement> elements = (List<ISubmodelElement>)submodelMap.get(Submodel.SUBMODELELEMENT);
+ elements.remove(technicalProperties);
+ TechnicalDataSubmodel.createAsFacade(submodelMap);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/furtherinformation/TestFurtherInformation.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/furtherinformation/TestFurtherInformation.java
new file mode 100644
index 0000000..b82ed47
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/furtherinformation/TestFurtherInformation.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+* Copyright (C) 2021 the Eclipse BaSyx Authors
+*
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+
+*
+* SPDX-License-Identifier: EPL-2.0
+******************************************************************************/
+
+package org.eclipse.basyx.testsuite.regression.submodel.types.technicaldata.furtherinformation;
+
+import static org.junit.Assert.assertEquals;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.furtherinformation.FurtherInformation;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests createAsFacade and isValid of {@link FurtherInformation} for their
+ * correctness
+ *
+ * @author haque
+ *
+ */
+public class TestFurtherInformation {
+ public static MultiLanguageProperty statement = new MultiLanguageProperty(FurtherInformation.TEXTSTATEMENTPREFIX + "01");
+ public static Property validDate = new Property(FurtherInformation.VALIDDATEID, ValueType.DateTime);
+ private Map<String, Object> furtherInfoMap = new HashMap<String, Object>();
+
+ @Before
+ public void init() {
+ statement.setValue(new LangStrings(new LangString("DE", "test statement")));
+ validDate.setValue("01-01-2021");
+ List<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
+ elements.add(statement);
+ elements.add(validDate);
+ furtherInfoMap.put(Referable.IDSHORT, FurtherInformation.IDSHORT);
+ furtherInfoMap.put(HasSemantics.SEMANTICID, FurtherInformation.SEMANTICID);
+ furtherInfoMap.put(Property.VALUE, elements);
+ }
+
+ @Test
+ public void testCreateAsFacade() {
+ FurtherInformation infoFromMap = FurtherInformation.createAsFacade(furtherInfoMap);
+ assertEquals(FurtherInformation.SEMANTICID, infoFromMap.getSemanticId());
+ assertEquals(Collections.singletonList(statement), infoFromMap.getStatements());
+ assertEquals(validDate, infoFromMap.getValidDate());
+ assertEquals(FurtherInformation.IDSHORT, infoFromMap.getIdShort());
+ }
+
+ @Test (expected = MetamodelConstructionException.class)
+ public void testCreateAsFacadeExceptionIdShort() {
+ furtherInfoMap.remove(Referable.IDSHORT);
+ FurtherInformation.createAsFacade(furtherInfoMap);
+ }
+
+ @Test (expected = ResourceNotFoundException.class)
+ public void testCreateAsFacadeExceptionValidDate() {
+ List<ISubmodelElement> newElements = new ArrayList<ISubmodelElement>();
+ newElements.add(statement);
+ furtherInfoMap.put(Property.VALUE, newElements);
+ FurtherInformation.createAsFacade(furtherInfoMap);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/generalinformation/TestGeneralInformation.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/generalinformation/TestGeneralInformation.java
new file mode 100644
index 0000000..a54c763
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/generalinformation/TestGeneralInformation.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+* Copyright (C) 2021 the Eclipse BaSyx Authors
+*
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+
+*
+* SPDX-License-Identifier: EPL-2.0
+******************************************************************************/
+
+package org.eclipse.basyx.testsuite.regression.submodel.types.technicaldata.generalinformation;
+
+import static org.junit.Assert.assertEquals;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.generalinformation.GeneralInformation;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests createAsFacade and isValid of {@link GeneralInformation} for their
+ * correctness
+ *
+ * @author haque
+ *
+ */
+public class TestGeneralInformation {
+ public static Property manufacturerName = new Property(GeneralInformation.MANUFACTURERNAMEID, ValueType.String);
+ public static File manufacturerLogo = new File("image/png");
+ public static MultiLanguageProperty designation = new MultiLanguageProperty(GeneralInformation.MANUFACTURERPRODUCTDESIGNATIONID);
+ public static Property partNumber = new Property(GeneralInformation.MANUFACTURERPARTNUMBERID, ValueType.String);
+ public static Property orderCode = new Property(GeneralInformation.MANUFACTURERORDERCODEID, ValueType.String);
+ public static File image = new File("image/jpg");
+
+ private Map<String, Object> InfoMap = new HashMap<String, Object>();
+
+ @Before
+ public void init() {
+ manufacturerName.setValue("Example Company");
+ manufacturerLogo.setIdShort(GeneralInformation.MANUFACTURERLOGOID);
+ manufacturerLogo.setValue("/aasx/TechnicalData/logo.png");
+ designation.setValue(new LangStrings(new LangString("de", "Elektrischer Energie Beschleuniger")));
+ partNumber.setValue("A123-456");
+ orderCode.setValue("EEA-EX-200-S/47-Q3");
+ image.setIdShort(GeneralInformation.PRODUCTIMAGEPREFIX + "01");
+ image.setValue("/aasx/TechnicalData/ ProdFromTop.jpg");
+
+ List<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
+ elements.add(manufacturerName);
+ elements.add(manufacturerLogo);
+ elements.add(designation);
+ elements.add(partNumber);
+ elements.add(orderCode);
+ elements.add(image);
+
+ InfoMap.put(Referable.IDSHORT, GeneralInformation.IDSHORT);
+ InfoMap.put(HasSemantics.SEMANTICID, GeneralInformation.SEMANTICID);
+ InfoMap.put(Property.VALUE, elements);
+ }
+
+ @Test
+ public void testCreateAsFacade() {
+ GeneralInformation infoFromMap = GeneralInformation.createAsFacade(InfoMap);
+ assertEquals(GeneralInformation.SEMANTICID, infoFromMap.getSemanticId());
+ assertEquals(Collections.singletonList(image), infoFromMap.getProductImages());
+ assertEquals(manufacturerName, infoFromMap.getManufacturerName());
+ assertEquals(manufacturerLogo, infoFromMap.getManufacturerLogo());
+ assertEquals(designation, infoFromMap.getManufacturerProductDesignation());
+ assertEquals(partNumber, infoFromMap.getManufacturerPartNumber());
+ assertEquals(orderCode, infoFromMap.getManufacturerOrderCode());
+ assertEquals(GeneralInformation.IDSHORT, infoFromMap.getIdShort());
+ }
+
+ @Test (expected = MetamodelConstructionException.class)
+ public void testCreateAsFacadeExceptionIdShort() {
+ InfoMap.remove(Referable.IDSHORT);
+ GeneralInformation.createAsFacade(InfoMap);
+ }
+
+ @Test (expected = ResourceNotFoundException.class)
+ @SuppressWarnings("unchecked")
+ public void testCreateAsFacadeExceptionName() {
+ List<ISubmodelElement> elements = (List<ISubmodelElement>)InfoMap.get(Property.VALUE);
+ elements.remove(manufacturerName);
+ GeneralInformation.createAsFacade(InfoMap);
+ }
+
+ @Test (expected = ResourceNotFoundException.class)
+ @SuppressWarnings("unchecked")
+ public void testCreateAsFacadeExceptionDesignation() {
+ List<ISubmodelElement> elements = (List<ISubmodelElement>)InfoMap.get(Property.VALUE);
+ elements.remove(designation);
+ GeneralInformation.createAsFacade(InfoMap);
+ }
+
+ @Test (expected = ResourceNotFoundException.class)
+ @SuppressWarnings("unchecked")
+ public void testCreateAsFacadeExceptionPartNumber() {
+ List<ISubmodelElement> elements = (List<ISubmodelElement>)InfoMap.get(Property.VALUE);
+ elements.remove(partNumber);
+ GeneralInformation.createAsFacade(InfoMap);
+ }
+
+ @Test (expected = ResourceNotFoundException.class)
+ @SuppressWarnings("unchecked")
+ public void testCreateAsFacadeExceptionOrderCode() {
+ List<ISubmodelElement> elements = (List<ISubmodelElement>)InfoMap.get(Property.VALUE);
+ elements.remove(orderCode);
+ GeneralInformation.createAsFacade(InfoMap);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/productclassifications/TestProductClassificationItem.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/productclassifications/TestProductClassificationItem.java
new file mode 100644
index 0000000..8175a46
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/productclassifications/TestProductClassificationItem.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+* Copyright (C) 2021 the Eclipse BaSyx Authors
+*
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+
+*
+* SPDX-License-Identifier: EPL-2.0
+******************************************************************************/
+
+package org.eclipse.basyx.testsuite.regression.submodel.types.technicaldata.productclassifications;
+
+import static org.junit.Assert.assertEquals;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.productclassifications.ProductClassificationItem;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.productclassifications.ProductClassifications;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests createAsFacade and isValid of {@link ProductClassificationItem} for their
+ * correctness
+ *
+ * @author haque
+ *
+ */
+public class TestProductClassificationItem {
+ public static Property classificationSystem = new Property(ProductClassificationItem.PRODUCTCLASSIFICATIONSYSTEMID, ValueType.String);
+ public static Property version = new Property(ProductClassificationItem.CLASSIFICATIONSYSTEMVERSIONID, ValueType.String);
+ public static Property productClass = new Property(ProductClassificationItem.PRODUCTCLASSID, ValueType.String);
+
+ private Map<String, Object> classificationMap = new HashMap<String, Object>();
+
+ @Before
+ public void init() {
+ classificationSystem.setValue("ECLASS");
+ version.setValue("9.0 (BASIC)");
+ productClass.setValue("27-01-88-77");
+
+ List<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
+ elements.add(classificationSystem);
+ elements.add(version);
+ elements.add(productClass);
+
+ classificationMap.put(Referable.IDSHORT, ProductClassifications.PRODUCTCLASSIFICATIONITEMPREFIX + "01");
+ classificationMap.put(HasSemantics.SEMANTICID, ProductClassificationItem.SEMANTICID);
+ classificationMap.put(Property.VALUE, elements);
+ }
+
+ @Test
+ public void testCreateAsFacade() {
+ ProductClassificationItem classificationFromMap = ProductClassificationItem.createAsFacade(classificationMap);
+ assertEquals(ProductClassificationItem.SEMANTICID, classificationFromMap.getSemanticId());
+ assertEquals(classificationSystem, classificationFromMap.getProductClassificationSystem());
+ assertEquals(version, classificationFromMap.getClassificationSystemVersion());
+ assertEquals(productClass, classificationFromMap.getProductClassId());
+ assertEquals(ProductClassifications.PRODUCTCLASSIFICATIONITEMPREFIX + "01", classificationFromMap.getIdShort());
+ }
+
+ @Test (expected = MetamodelConstructionException.class)
+ public void testCreateAsFacadeExceptionIdShort() {
+ classificationMap.remove(Referable.IDSHORT);
+ ProductClassificationItem.createAsFacade(classificationMap);
+ }
+
+ @Test (expected = ResourceNotFoundException.class)
+ @SuppressWarnings("unchecked")
+ public void testCreateAsFacadeExceptionProductClassificationSystem() {
+ List<ISubmodelElement> elements = (List<ISubmodelElement>)classificationMap.get(Property.VALUE);
+ elements.remove(classificationSystem);
+ ProductClassificationItem.createAsFacade(classificationMap);
+ }
+
+ @Test (expected = ResourceNotFoundException.class)
+ @SuppressWarnings("unchecked")
+ public void testCreateAsFacadeExceptionProductClassId() {
+ List<ISubmodelElement> elements = (List<ISubmodelElement>)classificationMap.get(Property.VALUE);
+ elements.remove(productClass);
+ ProductClassificationItem.createAsFacade(classificationMap);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/productclassifications/TestProductClassifications.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/productclassifications/TestProductClassifications.java
new file mode 100644
index 0000000..1069b98
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/productclassifications/TestProductClassifications.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+* Copyright (C) 2021 the Eclipse BaSyx Authors
+*
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+
+*
+* SPDX-License-Identifier: EPL-2.0
+******************************************************************************/
+
+package org.eclipse.basyx.testsuite.regression.submodel.types.technicaldata.productclassifications;
+
+import static org.junit.Assert.assertEquals;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.productclassifications.ProductClassificationItem;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.productclassifications.ProductClassifications;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests createAsFacade and isValid of {@link ProductClassifications} for their
+ * correctness
+ *
+ * @author haque
+ *
+ */
+public class TestProductClassifications {
+ public static ProductClassificationItem productClassificationItem = new ProductClassificationItem(ProductClassifications.PRODUCTCLASSIFICATIONITEMPREFIX + "01", TestProductClassificationItem.classificationSystem, TestProductClassificationItem.productClass);
+
+ private Map<String, Object> classificationMap = new HashMap<String, Object>();
+
+ @Before
+ public void init() {
+ List<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
+ elements.add(productClassificationItem);
+
+ classificationMap.put(Referable.IDSHORT, ProductClassifications.IDSHORT);
+ classificationMap.put(HasSemantics.SEMANTICID, ProductClassifications.SEMANTICID);
+ classificationMap.put(Property.VALUE, elements);
+ }
+
+ @Test
+ public void testCreateAsFacade() {
+ ProductClassifications classificationFromMap = ProductClassifications.createAsFacade(classificationMap);
+ assertEquals(ProductClassifications.SEMANTICID, classificationFromMap.getSemanticId());
+ assertEquals(ProductClassifications.IDSHORT, classificationFromMap.getIdShort());
+ assertEquals(Collections.singletonList(productClassificationItem), classificationFromMap.getProductClassificationItems());
+ }
+
+ @Test (expected = MetamodelConstructionException.class)
+ public void testCreateAsFacadeExceptionIdShort() {
+ classificationMap.remove(Referable.IDSHORT);
+ ProductClassifications.createAsFacade(classificationMap);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/technicalproperties/TestTechnicalProperties.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/technicalproperties/TestTechnicalProperties.java
new file mode 100644
index 0000000..7dd6666
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/technicalproperties/TestTechnicalProperties.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+* Copyright (C) 2021 the Eclipse BaSyx Authors
+*
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+
+*
+* SPDX-License-Identifier: EPL-2.0
+******************************************************************************/
+
+package org.eclipse.basyx.testsuite.regression.submodel.types.technicaldata.technicalproperties;
+
+import static org.junit.Assert.assertEquals;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.technicalproperties.TechnicalProperties;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests createAsFacade and isValid of {@link TestTechnicalProperties} for their
+ * correctness
+ *
+ * @author haque
+ *
+ */
+public class TestTechnicalProperties {
+ public static SubmodelElementCollection mainSection = new SubmodelElementCollection(TechnicalProperties.MAINSECTIONPREFIX + "01");
+ public static SubmodelElementCollection subSection = new SubmodelElementCollection(TechnicalProperties.SUBSECTIONPREFIX + "01");
+ public static SubmodelElement arbitrary1 = new Property("arbitraryId1", ValueType.String);
+ public static SubmodelElement arbitrary2 = new Property("arbitraryId2", ValueType.String);
+
+ private Map<String, Object> technicalMap = new HashMap<String, Object>();
+
+ @Before
+ public void init() {
+ mainSection.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, TechnicalProperties.MAINSECTIONID, IdentifierType.IRDI)));
+ subSection.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, TechnicalProperties.SUBSECTIONID, IdentifierType.IRDI)));
+ arbitrary1.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "anyid", IdentifierType.IRDI)));
+ arbitrary2.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, TechnicalProperties.SMENOTDESCRIBEDID, IdentifierType.IRDI)));
+
+ List<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
+ elements.add(mainSection);
+ elements.add(subSection);
+ elements.add(arbitrary1);
+ elements.add(arbitrary2);
+
+ technicalMap.put(Referable.IDSHORT, TechnicalProperties.IDSHORT);
+ technicalMap.put(HasSemantics.SEMANTICID, TechnicalProperties.SEMANTICID);
+ technicalMap.put(Property.VALUE, elements);
+ }
+
+ @Test
+ public void testCreateAsFacade() {
+ TechnicalProperties propFromMap = TechnicalProperties.createAsFacade(technicalMap);
+ assertEquals(TechnicalProperties.SEMANTICID, propFromMap.getSemanticId());
+ assertEquals(TechnicalProperties.IDSHORT, propFromMap.getIdShort());
+ assertEquals(Collections.singletonList(mainSection), propFromMap.getMainSections());
+ assertEquals(Collections.singletonList(subSection), propFromMap.getSubSections());
+ assertEquals(Collections.singletonList(arbitrary1), propFromMap.getArbitrary());
+ assertEquals(Collections.singletonList(arbitrary2), propFromMap.getSMENotDescribedBySemanticId());
+ }
+
+ @Test (expected = MetamodelConstructionException.class)
+ public void testCreateAsFacadeExceptionIdShort() {
+ technicalMap.remove(Referable.IDSHORT);
+ TechnicalProperties.createAsFacade(technicalMap);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/IBasyxConnectorFacade.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/IBasyxConnectorFacade.java
index 9ac52a9..e065250 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/IBasyxConnectorFacade.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/IBasyxConnectorFacade.java
@@ -1,13 +1,22 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.coder.json;
-import java.io.FileNotFoundException;
+import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
import org.eclipse.basyx.vab.coder.json.provider.JSONProvider;
import org.eclipse.basyx.vab.exception.provider.ProviderException;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
import org.eclipse.basyx.vab.protocol.api.IBaSyxConnector;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* This class is required for Meta-protocol integration testing. It makes
@@ -20,8 +29,6 @@
*/
public class IBasyxConnectorFacade<T extends IModelProvider> implements IBaSyxConnector {
- private static Logger logger = LoggerFactory.getLogger(IBasyxConnectorFacade.class);
-
JSONProvider<T> provider;
public IBasyxConnectorFacade(JSONProvider<T> p) {
@@ -33,19 +40,15 @@
* message
*/
@Override
- public String getModelPropertyValue(String path) {
- try {
- PrintWriterStub outputstream = new PrintWriterStub("test.txt", "ignore");
+ public String getValue(String path) {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ provider.processBaSysGet(path, outputStream);
- provider.processBaSysGet(path, outputstream);
-
- return outputstream.getResult();
- } catch (FileNotFoundException e) {
- logger.error("[TEST] Exception in getModelPropertyValue", e);
+ try {
+ return outputStream.toString(StandardCharsets.UTF_8.displayName());
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("Should not happen...");
}
-
- // This should never happen
- return null;
}
/**
@@ -53,17 +56,15 @@
* message
*/
@Override
- public String setModelPropertyValue(String path, String newValue) throws ProviderException {
- try {
- PrintWriterStub outputstream = new PrintWriterStub("test.txt", "ignore");
+ public String setValue(String path, String newValue) throws ProviderException {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ provider.processBaSysSet(path, newValue, outputStream);
- provider.processBaSysSet(path, newValue, outputstream);
-
- return outputstream.getResult();
- } catch (FileNotFoundException e) {
- logger.error("[TEST] Exception in setModelPropertyValue", e);
+ try {
+ return outputStream.toString(StandardCharsets.UTF_8.displayName());
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("Should not happen...");
}
- return null;
}
/**
@@ -72,16 +73,14 @@
*/
@Override
public String createValue(String path, String newEntity) throws ProviderException {
- try {
- PrintWriterStub outputstream = new PrintWriterStub("test.txt", "ignore");
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ provider.processBaSysCreate(path, newEntity, outputStream);
- provider.processBaSysCreate(path, newEntity, outputstream);
-
- return outputstream.getResult();
- } catch (FileNotFoundException e) {
- logger.error("[TEST] Exception in createValue", e);
- }
- return null;
+ try {
+ return outputStream.toString(StandardCharsets.UTF_8.displayName());
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("Should not happen...");
+ }
}
/**
@@ -90,17 +89,15 @@
*/
@Override
public String deleteValue(String path) throws ProviderException {
- try {
- PrintWriterStub outputstream = new PrintWriterStub("test.txt", "ignore");
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ String nullParam = "null";
+ provider.processBaSysDelete(path, nullParam, outputStream);
- String nullParam = "null";
- provider.processBaSysDelete(path, nullParam, outputstream);
-
- return outputstream.getResult();
- } catch (FileNotFoundException e) {
- logger.error("[TEST] Exception in deleteValue", e);
+ try {
+ return outputStream.toString(StandardCharsets.UTF_8.displayName());
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("Should not happen...");
}
- return null;
}
/**
@@ -109,16 +106,14 @@
*/
@Override
public String deleteValue(String path, String obj) throws ProviderException {
- try {
- PrintWriterStub outputstream = new PrintWriterStub("test.txt", "ignore");
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ provider.processBaSysDelete(path, obj, outputStream);
- provider.processBaSysDelete(path, obj, outputstream);
-
- return outputstream.getResult();
- } catch (FileNotFoundException e) {
- logger.error("[TEST] Exception in deleteValue", e);
+ try {
+ return outputStream.toString(StandardCharsets.UTF_8.displayName());
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("Should not happen...");
}
- return null;
}
/**
@@ -127,17 +122,18 @@
*/
@Override
public String invokeOperation(String path, String jsonObject) throws ProviderException {
- try {
- PrintWriterStub outputstream = new PrintWriterStub("test.txt", "ignore");
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ provider.processBaSysInvoke(path, jsonObject, outputStream);
- provider.processBaSysInvoke(path, jsonObject, outputstream);
-
- return outputstream.getResult();
- } catch (FileNotFoundException e) {
- logger.error("[TEST] Exception in invokeOperation", e);
+ try {
+ return outputStream.toString(StandardCharsets.UTF_8.displayName());
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("Should not happen...");
}
- return null;
}
-
+ @Override
+ public String getEndpointRepresentation(String path) {
+ return "test://" + path;
+ }
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/PrintWriterStub.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/PrintWriterStub.java
index e5d0c12..392ba46 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/PrintWriterStub.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/PrintWriterStub.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.coder.json;
import static org.junit.Assert.assertTrue;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/TestJSONConnectorProviderIntegration.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/TestJSONConnectorProviderIntegration.java
index b263fa2..f6ed4f9 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/TestJSONConnectorProviderIntegration.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/TestJSONConnectorProviderIntegration.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.coder.json;
import org.eclipse.basyx.testsuite.regression.vab.modelprovider.SimpleVABElement;
@@ -8,7 +17,7 @@
import org.eclipse.basyx.vab.manager.VABConnectionManager;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
-import org.eclipse.basyx.vab.protocol.api.ConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.ConnectorFactory;
/**
* Test JSONConnector against JSONProvider
@@ -19,7 +28,7 @@
public class TestJSONConnectorProviderIntegration extends TestProvider {
protected VABConnectionManager connManager = new VABConnectionManager(new TestsuiteDirectory(),
- new ConnectorProvider() {
+ new ConnectorFactory() {
@Override
protected IModelProvider createProvider(String addr) {
@@ -46,4 +55,4 @@
protected VABConnectionManager getConnectionManager() {
return connManager;
}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/TestJson.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/TestJson.java
index f42432d..d1d4735 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/TestJson.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/TestJson.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.coder.json;
import static org.junit.Assert.assertEquals;
@@ -7,6 +16,7 @@
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
+import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
@@ -37,7 +47,7 @@
*/
public class TestJson {
- GSONTools tools = new GSONTools(new DefaultTypeFactory());
+ GSONTools tools = new GSONTools(new DefaultTypeFactory(), false, false);
/**
* Tests if a double is correctly (de-)serialized
@@ -61,6 +71,13 @@
assertEquals(primitive.toString(), tools.serialize(12));
}
+ @Test
+ public void testBigInteger() {
+ BigInteger dec = new BigInteger("10000000000000000000000000000000000000");
+ BigInteger deserialized = (BigInteger) tools.deserialize(tools.serialize(dec));
+ assertEquals(dec, deserialized);
+ }
+
/**
* Tests if a boolean is correctly (de-)serialized
*/
@@ -301,6 +318,32 @@
assertEquals(testFunction.apply(5), deserialized.apply(5));
}
+
+ /**
+ * Tests if null values and empty arrays are getting removed successfully
+ * with remove flag on
+ *
+ */
+ @Test
+ public void testSerializeWithRemoveFlagsOn() throws IOException {
+ GSONTools toolWithRemoveFlagOn = new GSONTools(new DefaultTypeFactory(), true, true);
+ Map<String, Object> expected = new HashMap<>();
+ Map<String, Object> a = new HashMap<>();
+ a.put("x", 123);
+ expected.put("a", a);
+ expected.put("b", "123");
+ expected.put("c", null);
+ expected.put("d", new ArrayList<String>());
+
+ JsonObject aObj = new JsonObject();
+ aObj.add("x", new JsonPrimitive(123));
+
+ JsonObject expectedObj = new JsonObject();
+ expectedObj.add("a", aObj);
+ expectedObj.add("b", new JsonPrimitive("123"));
+
+ assertEquals(expectedObj.toString(), toolWithRemoveFlagOn.serialize(expected));
+ }
/**
* Tests for an arbitrary primitive object if it is deserialized correctly
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/memory/TestInMemoryDirectory.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/memory/TestInMemoryDirectory.java
index d918554..9bc9f8d 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/memory/TestInMemoryDirectory.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/memory/TestInMemoryDirectory.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.directory.memory;
import static org.junit.Assert.assertEquals;
@@ -6,8 +15,8 @@
import java.util.Map;
import org.eclipse.basyx.testsuite.regression.vab.directory.proxy.TestDirectory;
-import org.eclipse.basyx.vab.directory.api.IVABDirectoryService;
-import org.eclipse.basyx.vab.directory.memory.InMemoryDirectory;
+import org.eclipse.basyx.vab.registry.api.IVABRegistryService;
+import org.eclipse.basyx.vab.registry.memory.VABInMemoryRegistry;
import org.junit.Test;
/**
@@ -19,19 +28,19 @@
public class TestInMemoryDirectory extends TestDirectory {
@Override
- protected IVABDirectoryService getRegistry() {
- return new InMemoryDirectory();
+ protected IVABRegistryService getRegistry() {
+ return new VABInMemoryRegistry();
}
@Test
public void testConstructor() {
- IVABDirectoryService registry = new InMemoryDirectory(getAddedValues());
+ IVABRegistryService registry = new VABInMemoryRegistry(getAddedValues());
testElementsInMap(registry, getAddedValues());
}
@Test
public void testAddMappingMultipleKey() {
- InMemoryDirectory registry = new InMemoryDirectory();
+ VABInMemoryRegistry registry = new VABInMemoryRegistry();
String key3 = "key3";
String value3 = "value3";
String key4 = "key4";
@@ -43,7 +52,7 @@
testElementsInMap(registry, map);
}
- private void testElementsInMap(IVABDirectoryService registry, Map<String, String> map) {
+ private void testElementsInMap(IVABRegistryService registry, Map<String, String> map) {
for (Map.Entry<String, String> entry : map.entrySet()) {
assertEquals(entry.getValue(), registry.lookup(entry.getKey()));
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/proxy/TestDirectory.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/proxy/TestDirectory.java
index 5f4fabd..4589c53 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/proxy/TestDirectory.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/proxy/TestDirectory.java
@@ -1,11 +1,20 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.directory.proxy;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
-import org.eclipse.basyx.vab.directory.api.IVABDirectoryService;
import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.registry.api.IVABRegistryService;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -19,7 +28,7 @@
*/
public abstract class TestDirectory {
// The registry proxy that is used to access the backend
- protected final IVABDirectoryService registry = getRegistry();
+ protected final IVABRegistryService registry = getRegistry();
// Ids and endpoints for registered elements
protected String elem1 = "elem1";
@@ -33,7 +42,7 @@
* Getter for the tested registry provider. Tests for actual registry provider
* have to realize this method.
*/
- protected abstract IVABDirectoryService getRegistry();
+ protected abstract IVABRegistryService getRegistry();
/**
* During setup of the tests, new entries are created in the registry using a
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/restapi/TestDirectoryProvider.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/restapi/TestDirectoryProvider.java
index caaf81a..5a26165 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/restapi/TestDirectoryProvider.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/restapi/TestDirectoryProvider.java
@@ -1,9 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.directory.restapi;
import org.eclipse.basyx.testsuite.regression.vab.directory.proxy.TestDirectory;
-import org.eclipse.basyx.vab.directory.api.IVABDirectoryService;
-import org.eclipse.basyx.vab.directory.proxy.VABDirectoryProxy;
-import org.eclipse.basyx.vab.directory.restapi.DirectoryModelProvider;
+import org.eclipse.basyx.vab.registry.api.IVABRegistryService;
+import org.eclipse.basyx.vab.registry.proxy.VABRegistryProxy;
+import org.eclipse.basyx.vab.registry.restapi.VABRegistryModelProvider;
/**
* Tests the directory provider using the TestDirectory Suite
@@ -14,9 +23,9 @@
public class TestDirectoryProvider extends TestDirectory {
@Override
- protected IVABDirectoryService getRegistry() {
- DirectoryModelProvider provider = new DirectoryModelProvider();
- return new VABDirectoryProxy(provider);
+ protected IVABRegistryService getRegistry() {
+ VABRegistryModelProvider provider = new VABRegistryModelProvider();
+ return new VABRegistryProxy(provider);
}
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/factory/xml/TestVABXmlProviderFactory.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/factory/xml/TestVABXmlProviderFactory.java
index 118616d..6249fa6 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/factory/xml/TestVABXmlProviderFactory.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/factory/xml/TestVABXmlProviderFactory.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.factory.xml;
import static org.junit.Assert.assertEquals;
@@ -21,17 +30,17 @@
Map<String, String> map;
- assertEquals(provider.getModelPropertyValue("tags/name/"), TestXmlParser.SOME_NAME);
- assertEquals(provider.getModelPropertyValue("tags/value/"), TestXmlParser.VALUEV);
- assertEquals(provider.getModelPropertyValue("tags/nestedTags/attrnt"), TestXmlParser.ATTRNT_1_VAL);
- Iterator<Object> iterator = ((Collection) provider.getModelPropertyValue("tags/nestedTags/nestedTag/"))
+ assertEquals(provider.getValue("tags/name/"), TestXmlParser.SOME_NAME);
+ assertEquals(provider.getValue("tags/value/"), TestXmlParser.VALUEV);
+ assertEquals(provider.getValue("tags/nestedTags/attrnt"), TestXmlParser.ATTRNT_1_VAL);
+ Iterator<Object> iterator = ((Collection) provider.getValue("tags/nestedTags/nestedTag/"))
.iterator();
assertEquals(TestXmlParser.NESTED_TAG_1, iterator.next());
assertEquals(TestXmlParser.NESTED_TAG_2, iterator.next());
assertEquals(TestXmlParser.NESTED_TAG_3, iterator.next());
iterator = ((Collection) provider
- .getModelPropertyValue("tags/deeplyNestedTagParent/deeplyNestedTagsChild/deeplyNestedTagsLeaf/"))
+ .getValue("tags/deeplyNestedTagParent/deeplyNestedTagsChild/deeplyNestedTagsLeaf/"))
.iterator();
map = (Map<String, String>) (iterator.next());
assertEquals(map.get(TestXmlParser.TEXT), TestXmlParser.DN_TEXT_1);
@@ -41,7 +50,7 @@
assertEquals(map.get(TestXmlParser.TEXT), TestXmlParser.DN_TEXT_2);
assertEquals(map.get(TestXmlParser.ATTRDN), TestXmlParser.ATTR_2_VAL);
- iterator = ((Collection) provider.getModelPropertyValue("tags/someTag/")).iterator();
+ iterator = ((Collection) provider.getValue("tags/someTag/")).iterator();
assertEquals(TestXmlParser.SOME_TEXT_1, iterator.next());
assertEquals(TestXmlParser.SOME_TEXT_2, iterator.next());
assertEquals(TestXmlParser.SOME_TEXT_3, iterator.next());
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/factory/xml/TestXmlParser.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/factory/xml/TestXmlParser.java
index a50439e..5b59aac 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/factory/xml/TestXmlParser.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/factory/xml/TestXmlParser.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.factory.xml;
import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/ConnectorProviderStub.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/ConnectorProviderStub.java
index 6b9bcb3..1e48f77 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/ConnectorProviderStub.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/ConnectorProviderStub.java
@@ -1,10 +1,19 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.gateway;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-import org.eclipse.basyx.vab.protocol.api.IConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
/**
* A simple ConnectorProvider stub returning connectors based on a String
@@ -13,7 +22,7 @@
* @author schnicke
*
*/
-public class ConnectorProviderStub implements IConnectorProvider {
+public class ConnectorProviderStub implements IConnectorFactory {
private Map<String, IModelProvider> providerMap = new HashMap<>();
public void addMapping(String addr, IModelProvider provider) {
@@ -22,6 +31,9 @@
@Override
public IModelProvider getConnector(String addr) {
+ if (!providerMap.containsKey(addr)) {
+ throw new RuntimeException("Unknown addr " + addr);
+ }
return providerMap.get(addr);
}
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestConnectorProviderMapper.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestConnectorProviderMapper.java
index 885704a..7dac3df 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestConnectorProviderMapper.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestConnectorProviderMapper.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.gateway;
import static org.junit.Assert.assertEquals;
@@ -5,7 +14,7 @@
import org.eclipse.basyx.vab.gateway.ConnectorProviderMapper;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-import org.eclipse.basyx.vab.protocol.api.IConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
import org.junit.Test;
/**
@@ -28,7 +37,7 @@
ConnectorProviderMapper provider = new ConnectorProviderMapper();
// Add basyx IConnectorProvider stub
- provider.addConnectorProvider("basyx", new IConnectorProvider() {
+ provider.addConnectorProvider("basyx", new IConnectorFactory() {
@Override
public IModelProvider getConnector(String addr) {
@@ -38,7 +47,7 @@
});
// Add http IConnectorProvider stub
- provider.addConnectorProvider("http", new IConnectorProvider() {
+ provider.addConnectorProvider("http", new IConnectorFactory() {
@Override
public IModelProvider getConnector(String addr) {
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestDelegatingModelProvider.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestDelegatingModelProvider.java
index 1662f9a..b7ca4f6 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestDelegatingModelProvider.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestDelegatingModelProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.gateway;
import static org.junit.Assert.assertEquals;
@@ -5,7 +14,7 @@
import org.eclipse.basyx.testsuite.regression.vab.modelprovider.IModelProviderStub;
import org.eclipse.basyx.vab.gateway.DelegatingModelProvider;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-import org.eclipse.basyx.vab.protocol.api.IConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
import org.junit.Test;
/**
@@ -31,7 +40,7 @@
// Create DelegatingModelProvider with a stub writing the address and returning
// the IModelProviderStub
- DelegatingModelProvider provider = new DelegatingModelProvider(new IConnectorProvider() {
+ DelegatingModelProvider provider = new DelegatingModelProvider(new IConnectorFactory() {
@Override
public IModelProvider getConnector(String addr) {
@@ -41,7 +50,7 @@
});
// Get a value based on path
- provider.getModelPropertyValue(basyx + "//" + rest);
+ provider.getValue(basyx + "//" + rest);
// Assert that correct address was given to IConnectorProvider
assertEquals(address, basyx);
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestGateway.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestGateway.java
index bb1d52b..4b70f98 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestGateway.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestGateway.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.gateway;
import static org.junit.Assert.assertEquals;
@@ -7,18 +16,18 @@
import java.util.HashMap;
import java.util.Map;
-import org.eclipse.basyx.vab.directory.memory.InMemoryDirectory;
import org.eclipse.basyx.vab.gateway.ConnectorProviderMapper;
import org.eclipse.basyx.vab.gateway.DelegatingModelProvider;
import org.eclipse.basyx.vab.manager.VABConnectionManager;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
-import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnectorProvider;
+import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnectorFactory;
import org.eclipse.basyx.vab.protocol.basyx.server.BaSyxTCPServer;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.eclipse.basyx.vab.protocol.http.server.AASHTTPServer;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxHTTPServer;
import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
+import org.eclipse.basyx.vab.registry.memory.VABInMemoryRegistry;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -33,7 +42,7 @@
public class TestGateway {
private BaSyxTCPServer<VABMapProvider> server;
private BaSyxTCPServer<DelegatingModelProvider> basyxGateway;
- private AASHTTPServer httpGateway;
+ private BaSyxHTTPServer httpGateway;
@Before
public void build() { // Create VAB element
@@ -46,8 +55,8 @@
// Create ConnectorProviderMapper and add mapping from "basyx" to
// BaSyxConnectorProvider for gateway
ConnectorProviderMapper gatewayMapper = new ConnectorProviderMapper();
- gatewayMapper.addConnectorProvider("basyx", new BaSyxConnectorProvider());
- gatewayMapper.addConnectorProvider("http", new HTTPConnectorProvider());
+ gatewayMapper.addConnectorProvider("basyx", new BaSyxConnectorFactory());
+ gatewayMapper.addConnectorProvider("http", new HTTPConnectorFactory());
// Create tcp gateway using DelegatingModelProvider
basyxGateway = new BaSyxTCPServer<>(new DelegatingModelProvider(gatewayMapper), 6999);
@@ -56,7 +65,7 @@
DelegatingModelProvider httpGWProvider = new DelegatingModelProvider(gatewayMapper);
BaSyxContext context = new BaSyxContext("", "", "localhost", 5123);
context.addServletMapping("/path/to/gateway/*", new VABHTTPInterface<DelegatingModelProvider>(httpGWProvider));
- httpGateway = new AASHTTPServer(context);
+ httpGateway = new BaSyxHTTPServer(context);
// Start element provider and gateway
server.start();
@@ -89,12 +98,12 @@
public void test() throws UnknownHostException, IOException {
// Create Directory, here it is configured statically, of course a dynamic
// request to e.g. a servlet is also possible
- InMemoryDirectory directory = new InMemoryDirectory();
+ VABInMemoryRegistry directory = new VABInMemoryRegistry();
directory.addMapping("Elem", "http://localhost:5123/path/to/gateway//basyx://127.0.0.1:6999//basyx://127.0.0.1:6998");
// Create ConnectionProviderMapper for client
ConnectorProviderMapper clientMapper = new ConnectorProviderMapper();
- clientMapper.addConnectorProvider("http", new HTTPConnectorProvider());
+ clientMapper.addConnectorProvider("http", new HTTPConnectorFactory());
// Create VABConnectionManager
VABConnectionManager manager = new VABConnectionManager(directory, clientMapper);
@@ -103,7 +112,7 @@
VABElementProxy proxy = manager.connectToVABElement("Elem");
// Test if the value is retrieved correctly
- assertEquals(10, proxy.getModelPropertyValue("propertyA"));
+ assertEquals(10, proxy.getValue("propertyA"));
}
@After
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/manager/VABConnectionManagerStub.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/manager/VABConnectionManagerStub.java
index 662dbf7..3af0ac5 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/manager/VABConnectionManagerStub.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/manager/VABConnectionManagerStub.java
@@ -1,9 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.manager;
import org.eclipse.basyx.testsuite.regression.vab.gateway.ConnectorProviderStub;
-import org.eclipse.basyx.vab.directory.memory.InMemoryDirectory;
import org.eclipse.basyx.vab.manager.VABConnectionManager;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.registry.memory.VABInMemoryRegistry;
/**
* A VABConnectionManager stub which automatically creates the directory entries
@@ -16,7 +25,7 @@
public VABConnectionManagerStub() {
// Create Stub with default DirectoryStub/ConnectorProviderStub
- super(new InMemoryDirectory(), new ConnectorProviderStub());
+ super(new VABInMemoryRegistry(), new ConnectorProviderStub());
}
/**
@@ -31,12 +40,12 @@
getDirectoryService().addMapping("", "");
}
- private InMemoryDirectory getDirectoryService() {
- return (InMemoryDirectory) directoryService;
+ private VABInMemoryRegistry getDirectoryService() {
+ return (VABInMemoryRegistry) directoryService;
}
private ConnectorProviderStub getConnectorProvider() {
- return (ConnectorProviderStub) connectorProvider;
+ return (ConnectorProviderStub) connectorFactory;
}
/**
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/model/VABModelMapTest.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/model/VABModelMapTest.java
index 7361dd6..9a3dc55 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/model/VABModelMapTest.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/model/VABModelMapTest.java
@@ -1,6 +1,16 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.model;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
import java.util.HashMap;
import java.util.Map;
@@ -47,11 +57,61 @@
public void testEquals() {
VABModelMap<Object> expected = new VABModelMap<>();
expected.put("a", "b");
+ expected.put("x", "y");
Map<String, Object> map = new HashMap<>();
map.put("a", "b");
+ map.put("x", "y");
assertEquals(expected, map);
+
+ map.put("a", "c");
+ assertNotEquals(expected, map);
+
+ map.remove("a");
+ assertNotEquals(expected, map);
+ }
+
+ @Test
+ public void testEqualsFirstEntryNull() {
+ VABModelMap<Object> expected = new VABModelMap<>();
+ expected.put("a", null);
+ expected.put("x", "b");
+
+ VABModelMap<Object> map = new VABModelMap<>();
+ map.put("a", null);
+ map.put("x", "c");
+
+ assertNotEquals(map, expected);
+ }
+
+ @Test
+ public void testEqualsFirstEntrySame() {
+ VABModelMap<Object> expected = new VABModelMap<>();
+ expected.put("a", "1");
+ expected.put("x", "b");
+
+ VABModelMap<Object> map = new VABModelMap<>();
+ map.put("a", "1");
+ map.put("x", "c");
+
+ assertNotEquals(map, expected);
+ }
+
+ @Test
+ public void testEqualsMapEntrySame() {
+ VABModelMap<Object> contained = new VABModelMap<>();
+ contained.put("hello", "world");
+
+ VABModelMap<Object> expected = new VABModelMap<>();
+ expected.put("a", contained);
+ expected.put("x", "b");
+
+ VABModelMap<Object> map = new VABModelMap<>();
+ map.put("a", contained);
+ map.put("x", "c");
+
+ assertNotEquals(map, expected);
}
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/Exceptions.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/Exceptions.java
index de5e108..dba4bf8 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/Exceptions.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/Exceptions.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.modelprovider;
import static org.junit.Assert.assertEquals;
@@ -37,7 +46,7 @@
// Non-existing parent element
try {
- connVABElement.getModelPropertyValue("unknown/x");
+ connVABElement.getValue("unknown/x");
fail();
} catch (ResourceNotFoundException e) {
Result result = new Result(e);
@@ -58,7 +67,7 @@
// Invoke unsupported functional interface
try {
- connVABElement.invokeOperation("operations/supplier");
+ connVABElement.invokeOperation("operations/supplier/invoke");
fail();
} catch (MalformedRequestException e) {
// this is for FileSystemProvider that does not support invoke
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/IModelProviderStub.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/IModelProviderStub.java
index 4de662d..7abe93a 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/IModelProviderStub.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/IModelProviderStub.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.modelprovider;
import org.eclipse.basyx.vab.exception.provider.ProviderException;
@@ -9,14 +18,14 @@
private Object value;
@Override
- public Object getModelPropertyValue(String path) {
+ public Object getValue(String path) {
value = null;
this.path = path;
return null;
}
@Override
- public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
+ public void setValue(String path, Object newValue) throws ProviderException {
value = newValue;
this.path = path;
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapCreateDelete.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapCreateDelete.java
index ac3f71c..ee88b4d 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapCreateDelete.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapCreateDelete.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.modelprovider;
import static org.junit.Assert.assertEquals;
@@ -33,12 +42,12 @@
private static void testCreateElements(VABElementProxy connVABElement) {
// Create property directly in root element
connVABElement.createValue("inRoot", 1.2);
- Object toTest = connVABElement.getModelPropertyValue("inRoot");
+ Object toTest = connVABElement.getValue("inRoot");
assertEquals(1.2, toTest);
// Create element in Map (with new key contained in the path)
connVABElement.createValue("/structure/map/inMap", "34");
- toTest = connVABElement.getModelPropertyValue("/structure/map/inMap");
+ toTest = connVABElement.getValue("/structure/map/inMap");
assertEquals("34", toTest);
// Create map element
@@ -46,7 +55,7 @@
newMap.put("entryA", 3);
newMap.put("entryB", 4);
connVABElement.createValue("mapInRoot", newMap);
- toTest = connVABElement.getModelPropertyValue("mapInRoot");
+ toTest = connVABElement.getValue("mapInRoot");
assertTrue(toTest instanceof Map<?, ?>);
assertEquals(2, ((Map<String, Object>) toTest).size());
assertEquals(3, ((Map<String, Object>) toTest).get("entryA"));
@@ -59,14 +68,14 @@
// If inRoot would have been a list 0 could be added here
// => 1.2 has an "invalid" type for creating values in it
}
- toTest = connVABElement.getModelPropertyValue("inRoot");
+ toTest = connVABElement.getValue("inRoot");
assertEquals(1.2, toTest);
// Check case-sensitivity
connVABElement.createValue("inroot", 78);
- toTest = connVABElement.getModelPropertyValue("inRoot");
+ toTest = connVABElement.getValue("inRoot");
assertEquals(1.2, toTest);
- toTest = connVABElement.getModelPropertyValue("inroot");
+ toTest = connVABElement.getValue("inroot");
assertEquals(78, toTest);
// Non-existing parent element
@@ -75,7 +84,7 @@
fail();
} catch (ResourceNotFoundException e) {}
try {
- connVABElement.getModelPropertyValue("unknown/x");
+ connVABElement.getValue("unknown/x");
fail();
} catch (ResourceNotFoundException e) {}
@@ -100,24 +109,24 @@
fail();
} catch (MalformedRequestException e) {
}
- Object toTest = connVABElement.getModelPropertyValue("inRoot");
+ Object toTest = connVABElement.getValue("inRoot");
assertEquals(1.2, toTest);
// - by index
connVABElement.deleteValue("inRoot");
try {
// "inRoot" should not exist anymore
- connVABElement.getModelPropertyValue("inRoot");
+ connVABElement.getValue("inRoot");
fail();
} catch (ResourceNotFoundException e) {}
// Check case-sensitivity
- toTest = connVABElement.getModelPropertyValue("inroot");
+ toTest = connVABElement.getValue("inroot");
assertEquals(78, toTest);
connVABElement.deleteValue("inroot");
try {
// "inroot" should not exist anymore
- connVABElement.getModelPropertyValue("inroot");
+ connVABElement.getValue("inroot");
fail();
} catch (ResourceNotFoundException e) {}
@@ -129,18 +138,18 @@
} catch (MalformedRequestException e) {
}
- toTest = connVABElement.getModelPropertyValue("/structure/map/inMap");
+ toTest = connVABElement.getValue("/structure/map/inMap");
assertEquals("34", toTest);
// - by index
connVABElement.deleteValue("/structure/map/inMap");
- toTest = connVABElement.getModelPropertyValue("/structure/map");
+ toTest = connVABElement.getValue("/structure/map");
assertEquals(0, ((Map<?, ?>) toTest).size());
// Delete remaining complete Map
connVABElement.deleteValue("mapInRoot");
try {
// "mapInRoot" should not exist anymore
- connVABElement.getModelPropertyValue("mapInRoot");
+ connVABElement.getValue("mapInRoot");
fail();
} catch (ResourceNotFoundException e) {}
@@ -153,7 +162,7 @@
// It would be possible to delete "" from a "root list"
// => invalid type
}
- toTest = connVABElement.getModelPropertyValue("/primitives/integer");
+ toTest = connVABElement.getValue("/primitives/integer");
assertEquals(123, toTest);
// Null path - should throw exception
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapInvoke.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapInvoke.java
index df62326..a84f32f 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapInvoke.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapInvoke.java
@@ -1,8 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.modelprovider;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
import org.eclipse.basyx.vab.exception.provider.ProviderException;
import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
@@ -22,30 +32,30 @@
VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement");
// Invoke complex function
- Object complex = connVABElement.invokeOperation("operations/complex", 12, 34);
+ Object complex = connVABElement.invokeOperation("operations/complex/", 12, 34);
assertEquals(46, complex);
// Invoke unsupported functional interface
try {
- connVABElement.invokeOperation("operations/supplier");
+ connVABElement.invokeOperation("operations/supplier/" + Operation.INVOKE);
fail();
} catch (ProviderException e) {}
// Invoke non-existing operation
try {
- connVABElement.invokeOperation("operations/unknown");
+ connVABElement.invokeOperation("operations/unknown/" + Operation.INVOKE);
fail();
} catch (ResourceNotFoundException e) {}
// Invoke invalid operation -> not a function, but a primitive data type
try {
- connVABElement.invokeOperation("operations/invalid");
+ connVABElement.invokeOperation("operations/invalid/" + Operation.INVOKE);
fail();
} catch (ProviderException e) {}
// Invoke operations that throw Exceptions
try {
- connVABElement.invokeOperation("operations/providerException");
+ connVABElement.invokeOperation("operations/providerException/" + Operation.INVOKE);
fail();
} catch (ProviderException e) {
// exception type not implemented, yet
@@ -53,7 +63,7 @@
}
try {
- connVABElement.invokeOperation("operations/nullException");
+ connVABElement.invokeOperation("operations/nullException/" + Operation.INVOKE);
fail();
} catch (ProviderException e) {
// exception type not implemented, yet
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapRead.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapRead.java
index 21eaa61..7523372 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapRead.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapRead.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.modelprovider;
import static org.junit.Assert.assertEquals;
@@ -26,66 +35,66 @@
VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement");
// Test path access
- Object slashA = connVABElement.getModelPropertyValue("/primitives/integer");
- Object slashB = connVABElement.getModelPropertyValue("primitives/integer/");
- Object slashC = connVABElement.getModelPropertyValue("/primitives/integer/");
- Object slashD = connVABElement.getModelPropertyValue("/primitives/integer/");
+ Object slashA = connVABElement.getValue("/primitives/integer");
+ Object slashB = connVABElement.getValue("primitives/integer/");
+ Object slashC = connVABElement.getValue("/primitives/integer/");
+ Object slashD = connVABElement.getValue("/primitives/integer/");
assertEquals(slashA, 123);
assertEquals(slashB, 123);
assertEquals(slashC, 123);
assertEquals(slashD, 123);
// Test reading different data types
- Object map = connVABElement.getModelPropertyValue("primitives");
- Object doubleValue = connVABElement.getModelPropertyValue("primitives/double");
- Object string = connVABElement.getModelPropertyValue("primitives/string");
+ Object map = connVABElement.getValue("primitives");
+ Object doubleValue = connVABElement.getValue("primitives/double");
+ Object string = connVABElement.getValue("primitives/string");
assertEquals(3, ((Map<?, ?>) map).size());
assertEquals(3.14d, doubleValue);
assertEquals("TestValue", string);
// Test case sensitivity
- Object caseSensitiveA = connVABElement.getModelPropertyValue("special/casesensitivity");
- Object caseSensitiveB = connVABElement.getModelPropertyValue("special/caseSensitivity");
+ Object caseSensitiveA = connVABElement.getValue("special/casesensitivity");
+ Object caseSensitiveB = connVABElement.getValue("special/caseSensitivity");
assertEquals(true, caseSensitiveA);
assertEquals(false, caseSensitiveB);
// Test reading null value
- Object nullValue = connVABElement.getModelPropertyValue("special/null");
+ Object nullValue = connVABElement.getValue("special/null");
assertNull(nullValue);
// Test reading serializable functions
- Object serializableFunction = connVABElement.getModelPropertyValue("operations/serializable");
+ Object serializableFunction = connVABElement.getValue("operations/serializable");
Function<Object[], Object> testFunction = (Function<Object[], Object>) serializableFunction;
assertEquals(3, testFunction.apply(new Object[] { 1, 2 }));
// Non-existing parent element
try {
- connVABElement.getModelPropertyValue("unknown/x");
+ connVABElement.getValue("unknown/x");
fail();
} catch (ResourceNotFoundException e) {}
// Non-existing target element
try {
- connVABElement.getModelPropertyValue("primitives/unkown");
+ connVABElement.getValue("primitives/unkown");
fail();
} catch (ResourceNotFoundException e) {}
try {
- connVABElement.getModelPropertyValue("unkown");
+ connVABElement.getValue("unkown");
fail();
} catch (ResourceNotFoundException e) {}
// Nested access
- assertEquals(100, connVABElement.getModelPropertyValue("special/nested/nested/value"));
+ assertEquals(100, connVABElement.getValue("special/nested/nested/value"));
// Empty path
- Object rootValueA = connVABElement.getModelPropertyValue("");
- Object rootValueB = connVABElement.getModelPropertyValue("/");
+ Object rootValueA = connVABElement.getValue("");
+ Object rootValueB = connVABElement.getValue("/");
assertEquals(4, ((Map<?, ?>) rootValueA).size());
assertEquals(4, ((Map<?, ?>) rootValueB).size());
// Null path - should throw exception
try {
- connVABElement.getModelPropertyValue(null);
+ connVABElement.getValue(null);
fail();
} catch (MalformedRequestException e) {}
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapUpdate.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapUpdate.java
index 8a8631e..b3b36df 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapUpdate.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapUpdate.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.modelprovider;
import static org.junit.Assert.assertEquals;
@@ -27,13 +36,13 @@
VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement");
// Set primitives
- connVABElement.setModelPropertyValue("primitives/integer", 12);
- connVABElement.setModelPropertyValue("primitives/double", 1.2d);
- connVABElement.setModelPropertyValue("primitives/string", "updated");
+ connVABElement.setValue("primitives/integer", 12);
+ connVABElement.setValue("primitives/double", 1.2d);
+ connVABElement.setValue("primitives/string", "updated");
// Read back
- Object integer = connVABElement.getModelPropertyValue("primitives/integer");
- Object doubleValue = connVABElement.getModelPropertyValue("primitives/double");
- Object string = connVABElement.getModelPropertyValue("primitives/string");
+ Object integer = connVABElement.getValue("primitives/integer");
+ Object doubleValue = connVABElement.getValue("primitives/double");
+ Object string = connVABElement.getValue("primitives/string");
// Test
assertTrue(integer instanceof Integer);
assertEquals(12, integer);
@@ -42,22 +51,22 @@
assertTrue(string instanceof String);
assertEquals("updated", string);
// Revert
- connVABElement.setModelPropertyValue("primitives/integer", 123);
- connVABElement.setModelPropertyValue("primitives/double", 3.14d);
- connVABElement.setModelPropertyValue("primitives/string", "TestValue");
+ connVABElement.setValue("primitives/integer", 123);
+ connVABElement.setValue("primitives/double", 3.14d);
+ connVABElement.setValue("primitives/string", "TestValue");
// Update serializable function
- connVABElement.setModelPropertyValue("operations/serializable",
+ connVABElement.setValue("operations/serializable",
(Function<Object[], Object> & Serializable) (param) -> {
return (int) param[0] - (int) param[1];
});
// Read back
- Object serializableFunction = connVABElement.getModelPropertyValue("operations/serializable");
+ Object serializableFunction = connVABElement.getValue("operations/serializable");
// Test
Function<Object[], Object> testFunction = (Function<Object[], Object>) serializableFunction;
assertEquals(-1, testFunction.apply(new Object[] { 2, 3 }));
// Revert
- connVABElement.setModelPropertyValue("operations/serializable",
+ connVABElement.setValue("operations/serializable",
(Function<Object[], Object> & Serializable) (param) -> {
return (int) param[0] + (int) param[1];
});
@@ -68,28 +77,28 @@
fail();
} catch (ResourceNotFoundException e) {}
try {
- connVABElement.getModelPropertyValue("unknown/newElement");
+ connVABElement.getValue("unknown/newElement");
fail();
} catch (ResourceNotFoundException e) {}
// Test updating a non-existing element
try {
- connVABElement.setModelPropertyValue("newElement", 10);
+ connVABElement.setValue("newElement", 10);
fail();
} catch (ResourceNotFoundException e) {}
try {
- connVABElement.getModelPropertyValue("newElement");
+ connVABElement.getValue("newElement");
fail();
} catch (ResourceNotFoundException e) {}
// Test updating an existing null-element
- connVABElement.setModelPropertyValue("special/null", true);
- Object bool = connVABElement.getModelPropertyValue("special/null");
+ connVABElement.setValue("special/null", true);
+ Object bool = connVABElement.getValue("special/null");
assertTrue((boolean) bool);
// Null path - should throw exception
try {
- connVABElement.setModelPropertyValue(null, "");
+ connVABElement.setValue(null, "");
fail();
} catch (MalformedRequestException e) {}
}
@@ -104,7 +113,7 @@
newMap.put("testKey", "testValue");
// - push
try {
- connVABElement.setModelPropertyValue(null, newMap);
+ connVABElement.setValue(null, newMap);
fail();
} catch (MalformedRequestException e) {}
@@ -113,15 +122,15 @@
HashMap<String, Object> newMap2 = new HashMap<>();
newMap2.put("testKey2", "testValue2");
// - push
- connVABElement.setModelPropertyValue("", newMap2);
+ connVABElement.setValue("", newMap2);
// - test
- assertEquals("testValue2", connVABElement.getModelPropertyValue("testKey2"));
+ assertEquals("testValue2", connVABElement.getValue("testKey2"));
try {
- connVABElement.getModelPropertyValue("testKey");
+ connVABElement.getValue("testKey");
fail();
} catch (ResourceNotFoundException e) {}
try {
- connVABElement.getModelPropertyValue("primitives/integer");
+ connVABElement.getValue("primitives/integer");
fail();
} catch (ResourceNotFoundException e) {}
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/SimpleVABElement.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/SimpleVABElement.java
index 98a5299..8087a69 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/SimpleVABElement.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/SimpleVABElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.modelprovider;
import java.io.Serializable;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/TestCollectionProperty.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/TestCollectionProperty.java
index 7d304db..eb44011 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/TestCollectionProperty.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/TestCollectionProperty.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.modelprovider;
import static org.junit.Assert.assertEquals;
@@ -31,7 +40,7 @@
connVABElement.createValue("/structure/list/", 12);
// Test reading whole lists
- Collection<Object> collection = (Collection<Object>) connVABElement.getModelPropertyValue("/structure/list/");
+ Collection<Object> collection = (Collection<Object>) connVABElement.getValue("/structure/list/");
Iterator<Object> iterator = collection.iterator();
assertEquals(5, iterator.next());
assertEquals(12, iterator.next());
@@ -39,7 +48,7 @@
// Test invalid list access - single list elements cannot be accessed directly
try {
- connVABElement.getModelPropertyValue("/structure/list/0");
+ connVABElement.getValue("/structure/list/0");
fail();
} catch (ResourceNotFoundException e) {}
@@ -54,17 +63,17 @@
VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement");
// Read original collection
- Collection<Object> original = (Collection<Object>) connVABElement.getModelPropertyValue("/structure/list/");
+ Collection<Object> original = (Collection<Object>) connVABElement.getValue("/structure/list/");
// Replace complete value of the collection property
Collection<Object> replacement = new ArrayList<>();
replacement.add(100);
replacement.add(200);
replacement.add(300);
- connVABElement.setModelPropertyValue("/structure/list/", replacement);
+ connVABElement.setValue("/structure/list/", replacement);
// Read values back
- Collection<Object> collection = (Collection<Object>) connVABElement.getModelPropertyValue("/structure/list/");
+ Collection<Object> collection = (Collection<Object>) connVABElement.getValue("/structure/list/");
// Check test case results
assertEquals(3, collection.size());
@@ -72,13 +81,13 @@
// Test invalid list access - single list elements cannot be accessed directly
try {
- connVABElement.setModelPropertyValue("/structure/list/0", 3);
+ connVABElement.setValue("/structure/list/0", 3);
fail();
} catch (ResourceNotFoundException e) {
}
// Write original back
- connVABElement.setModelPropertyValue("/structure/list/", original);
+ connVABElement.setValue("/structure/list/", original);
}
public static void testCreateDelete(VABConnectionManager connManager) {
@@ -87,7 +96,7 @@
// Create element in Set (no key provided)
connVABElement.createValue("/structure/set/", true);
- Object toTest = connVABElement.getModelPropertyValue("/structure/set/");
+ Object toTest = connVABElement.getValue("/structure/set/");
assertTrue(((Collection<?>) toTest).contains(true));
// Delete at Set
@@ -96,28 +105,28 @@
connVABElement.deleteValue("/structure/set/0/");
fail();
} catch (ResourceNotFoundException e) {}
- toTest = connVABElement.getModelPropertyValue("/structure/set/");
+ toTest = connVABElement.getValue("/structure/set/");
assertEquals(1, ((Collection<?>) toTest).size());
// - by object
connVABElement.deleteValue("/structure/set/", true);
- toTest = connVABElement.getModelPropertyValue("/structure/set/");
+ toTest = connVABElement.getValue("/structure/set/");
assertEquals(0, ((Collection<?>) toTest).size());
// Create elements in List (no key provided)
connVABElement.createValue("/structure/list/", 56);
- toTest = connVABElement.getModelPropertyValue("/structure/list/");
+ toTest = connVABElement.getValue("/structure/list/");
assertTrue(((List<?>) toTest).contains(56));
// Delete at List
// by object
connVABElement.deleteValue("/structure/list/", 56);
- toTest = connVABElement.getModelPropertyValue("/structure/list/");
+ toTest = connVABElement.getValue("/structure/list/");
assertEquals(0, ((List<?>) toTest).size());
// Create a list element
connVABElement.createValue("listInRoot", Arrays.asList(1, 1, 2, 3, 5));
// Test whole list
- toTest = connVABElement.getModelPropertyValue("listInRoot");
+ toTest = connVABElement.getValue("listInRoot");
assertTrue(toTest instanceof List);
assertEquals(5, ((List<?>) toTest).size());
assertEquals(2, ((List<?>) toTest).get(2));
@@ -125,7 +134,7 @@
// Delete whole list
connVABElement.deleteValue("listInRoot");
try {
- connVABElement.getModelPropertyValue("listInRoot");
+ connVABElement.getValue("listInRoot");
fail();
} catch (ResourceNotFoundException e) {}
@@ -142,19 +151,19 @@
fail();
} catch (ResourceNotFoundException e) {}
- toTest = connVABElement.getModelPropertyValue("/structure/list/");
+ toTest = connVABElement.getValue("/structure/list/");
assertEquals(4, ((List<?>) toTest).size());
// Delete half of the elements
connVABElement.deleteValue("/structure/list/", 10);
connVABElement.deleteValue("/structure/list/", 40);
- toTest = connVABElement.getModelPropertyValue("/structure/list/");
+ toTest = connVABElement.getValue("/structure/list/");
assertEquals(2, ((List<?>) toTest).size());
// Delete remaining elements
connVABElement.deleteValue("/structure/list/", 20);
connVABElement.deleteValue("/structure/list/", 80);
- toTest = connVABElement.getModelPropertyValue("/structure/list/");
+ toTest = connVABElement.getValue("/structure/list/");
assertEquals(0, ((List<?>) toTest).size());
}
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/TestProvider.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/TestProvider.java
index dc916cd..071ee1f 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/TestProvider.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/TestProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.modelprovider;
import org.eclipse.basyx.vab.manager.VABConnectionManager;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABElementProxyTest.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABElementProxyTest.java
index c1eeee9..4c4dd26 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABElementProxyTest.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABElementProxyTest.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.modelprovider;
import static org.junit.Assert.assertEquals;
@@ -36,6 +45,6 @@
// Connect to element <i>a/b</i>
VABElementProxy bProxy = proxy.getDeepProxy("a/b");
- assertEquals(0, bProxy.getModelPropertyValue("c"));
+ assertEquals(0, bProxy.getValue("c"));
}
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABPathToolsTest.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABPathToolsTest.java
index 79efe0d..33d2842 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABPathToolsTest.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABPathToolsTest.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.modelprovider;
import static org.junit.Assert.assertArrayEquals;
@@ -169,15 +178,63 @@
@Test
public void testIsOperationPath() {
- String[] positive = { "operations", "operations/", "/operations", "operations/", "operations/test/",
- "operations/test", "/operations/test", "operations/test/" };
- String[] negative = { "", "/operationX/", "/myOperation/", "/operationsFake/", "/operationsFake/operationX/" };
+ String[] positive = { "submodelElements/id/invoke", "submodelElements/id/invoke/",
+ "operations/id/invoke", "operations/id/invoke/", "operations/test", "elem/operations/id" };
+ String[] negative = { "", "/submodelElementsX/", "/myoperations/", "/submodelElementsFake/",
+ "/submodelElementsFake/operationX/", "submodelElements/id/" };
for (String test : positive) {
- assertTrue(test, VABPathTools.isOperationPath(test));
+ assertTrue(test, VABPathTools.isOperationInvokationPath(test));
}
for (String test : negative) {
- assertFalse(test, VABPathTools.isOperationPath(test));
+ assertFalse(test, VABPathTools.isOperationInvokationPath(test));
}
- assertFalse(VABPathTools.isOperationPath(null));
+ assertFalse(VABPathTools.isOperationInvokationPath(null));
}
-}
\ No newline at end of file
+
+ @Test
+ public void testStripInvokeFromPath() {
+ assertEquals("id", VABPathTools.stripInvokeFromPath("id/invoke"));
+ assertEquals("", VABPathTools.stripInvokeFromPath("invoke"));
+ assertEquals("", VABPathTools.stripInvokeFromPath("/invoke"));
+ assertEquals("id/value", VABPathTools.stripInvokeFromPath("id/value"));
+ assertEquals("", VABPathTools.stripInvokeFromPath(""));
+ }
+
+ @Test
+ public void testGetPathFromURL() {
+
+ String[] urls = {"http://localhost:8080/test/elem.aasx", "http://localhost/test/elem.aasx",
+ "basyx://127.0.0.1:4000//http://localhost:8080/test/elem.aasx", "/test/elem.aasx", "test/elem.aasx"};
+
+ for(String url: urls) {
+ assertEquals("/test/elem.aasx", VABPathTools.getPathFromURL(url));
+ }
+ }
+
+ @Test
+ public void testHarmonizePathWithSuffix() {
+ String expected = "http://localhost:8080/server/subserver/suffix";
+ String[] toTest = { expected,
+ "http://localhost:8080/server/subserver/suffix/",
+ "http://localhost:8080/server/subserver/",
+ "http://localhost:8080/server/subserver", };
+
+ for (String t : toTest) {
+ String harmonized = VABPathTools.harmonizePathWithSuffix(t, "suffix");
+ assertEquals(expected, harmonized);
+
+ // Check also for suffixes with a leading slash
+ String harmonizedLeadingSlash = VABPathTools.harmonizePathWithSuffix(t, "/suffix");
+ assertEquals(expected, harmonizedLeadingSlash);
+
+ // Check also for suffixes with a ending slash
+ String harmonizedEndingSlash = VABPathTools.harmonizePathWithSuffix(t, "suffix/");
+ assertEquals(expected, harmonizedEndingSlash);
+ }
+
+ // Check for edge case where a path is ending with the suffix, but not on its
+ // own
+ String edgeCaseExpected = "http://localhost:8080/server/subserversuffix/suffix";
+ assertEquals(edgeCaseExpected, VABPathTools.harmonizePathWithSuffix("http://localhost:8080/server/subserversuffix/", "suffix"));
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/filesystem/TestFileSystemProvider.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/filesystem/TestFileSystemProvider.java
index 8ada71c..bf72095 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/filesystem/TestFileSystemProvider.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/filesystem/TestFileSystemProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.modelprovider.filesystem;
import org.eclipse.basyx.testsuite.regression.vab.modelprovider.SimpleVABElement;
@@ -8,7 +17,7 @@
import org.eclipse.basyx.vab.modelprovider.filesystem.FileSystemProvider;
import org.eclipse.basyx.vab.modelprovider.filesystem.filesystem.FileSystem;
import org.eclipse.basyx.vab.modelprovider.filesystem.filesystem.GenericFileSystem;
-import org.eclipse.basyx.vab.protocol.api.ConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.ConnectorFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -28,7 +37,7 @@
@Override
protected VABConnectionManager getConnectionManager() {
if (connManager == null) {
- connManager = new VABConnectionManager(new TestsuiteDirectory(), new ConnectorProvider() {
+ connManager = new VABConnectionManager(new TestsuiteDirectory(), new ConnectorFactory() {
@Override
protected IModelProvider createProvider(String addr) {
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/lambda/TestLambdaProvider.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/lambda/TestLambdaProvider.java
index 207fb81..846b0c6 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/lambda/TestLambdaProvider.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/lambda/TestLambdaProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.modelprovider.lambda;
import java.util.ArrayList;
@@ -15,7 +24,7 @@
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProviderHelper;
-import org.eclipse.basyx.vab.protocol.api.ConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.ConnectorFactory;
/**
* Tests the functionality of the VABLambdaProvider according to the test cases
@@ -36,7 +45,7 @@
private static HashMap<String, Object> mapElement = (HashMap<String, Object>) structureElement.get("map");
protected VABConnectionManager connManager = new VABConnectionManager(new TestsuiteDirectory(),
- new ConnectorProvider() {
+ new ConnectorFactory() {
@Override
protected IModelProvider createProvider(String addr) {
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/map/TestMapProvider.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/map/TestMapProvider.java
index 624a0ea..65210f6 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/map/TestMapProvider.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/map/TestMapProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.modelprovider.map;
import org.eclipse.basyx.testsuite.regression.vab.modelprovider.SimpleVABElement;
@@ -6,7 +15,7 @@
import org.eclipse.basyx.vab.manager.VABConnectionManager;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
-import org.eclipse.basyx.vab.protocol.api.ConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.ConnectorFactory;
/**
* Tests the functionality of the VABMapProvider according to the test cases in
@@ -21,7 +30,7 @@
@Override
protected VABConnectionManager getConnectionManager() {
if (connManager == null) {
- connManager = new VABConnectionManager(new TestsuiteDirectory(), new ConnectorProvider() {
+ connManager = new VABConnectionManager(new TestsuiteDirectory(), new ConnectorFactory() {
@Override
protected IModelProvider createProvider(String addr) {
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/TestVABBaSyxTCP.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/TestVABBaSyxTCP.java
index fdfbd4a..1cac05a 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/TestVABBaSyxTCP.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/TestVABBaSyxTCP.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.protocol.basyx;
import static org.junit.Assert.assertFalse;
@@ -9,7 +18,7 @@
import org.eclipse.basyx.vab.manager.VABConnectionManager;
import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnector;
-import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnectorProvider;
+import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnectorFactory;
import org.eclipse.basyx.vab.protocol.basyx.server.VABBaSyxTCPInterface;
import org.junit.Rule;
import org.junit.Test;
@@ -22,7 +31,7 @@
*/
public class TestVABBaSyxTCP extends TestProvider {
protected VABConnectionManager connManager = new VABConnectionManager(new TestsuiteDirectory_BaSyxNative(),
- new BaSyxConnectorProvider());
+ new BaSyxConnectorFactory());
@Rule
public VABTCPServerResource res = new VABTCPServerResource(new VABMapProvider(new SimpleVABElement()));
@@ -42,7 +51,7 @@
public void testSuccessfulShutdown() throws InterruptedException {
BaSyxConnector connector = new BaSyxConnector("localhost", 6998);
- connector.getModelPropertyValue("integer");
+ connector.getValue("integer");
// Wait until thread is closed on server
Thread.sleep(100);
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/TestsuiteDirectory_BaSyxNative.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/TestsuiteDirectory_BaSyxNative.java
index 2eb8d50..61776a2 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/TestsuiteDirectory_BaSyxNative.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/TestsuiteDirectory_BaSyxNative.java
@@ -1,6 +1,15 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.protocol.basyx;
-import org.eclipse.basyx.vab.directory.memory.InMemoryDirectory;
+import org.eclipse.basyx.vab.registry.memory.VABInMemoryRegistry;
@@ -11,7 +20,7 @@
* @author kuhn
*
*/
-public class TestsuiteDirectory_BaSyxNative extends InMemoryDirectory {
+public class TestsuiteDirectory_BaSyxNative extends VABInMemoryRegistry {
/**
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/VABTCPServerResource.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/VABTCPServerResource.java
index 8743bf6..1d04e72 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/VABTCPServerResource.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/VABTCPServerResource.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.protocol.basyx;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
@@ -32,4 +41,4 @@
protected void after() {
server.stop();
}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/AASHTTPServerResource.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/AASHTTPServerResource.java
index f8c451e..9f68f61 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/AASHTTPServerResource.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/AASHTTPServerResource.java
@@ -1,6 +1,15 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.protocol.http;
-import org.eclipse.basyx.vab.protocol.http.server.AASHTTPServer;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxHTTPServer;
import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
import org.junit.rules.ExternalResource;
@@ -11,7 +20,7 @@
*
*/
public class AASHTTPServerResource extends ExternalResource {
- private AASHTTPServer server;
+ private BaSyxHTTPServer server;
private BaSyxContext context;
/**
@@ -26,7 +35,7 @@
*/
@Override
protected void before() {
- server = new AASHTTPServer(context);
+ server = new BaSyxHTTPServer(context);
server.start();
}
@@ -37,4 +46,4 @@
protected void after() {
server.shutdown();
}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/SimpleVABElementServlet.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/SimpleVABElementServlet.java
index ff97a3d..4cda615 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/SimpleVABElementServlet.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/SimpleVABElementServlet.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.protocol.http;
import org.eclipse.basyx.testsuite.regression.vab.modelprovider.SimpleVABElement;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/TestVABHTTP.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/TestVABHTTP.java
index 78772e2..37658c5 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/TestVABHTTP.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/TestVABHTTP.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.protocol.http;
import static org.junit.Assert.assertEquals;
@@ -16,7 +25,7 @@
import org.eclipse.basyx.vab.manager.VABConnectionManager;
import org.eclipse.basyx.vab.modelprovider.VABPathTools;
import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
import org.junit.Rule;
@@ -30,7 +39,7 @@
*/
public class TestVABHTTP extends TestProvider {
protected VABConnectionManager connManager = new VABConnectionManager(new TestsuiteDirectory(),
- new HTTPConnectorProvider());
+ new HTTPConnectorFactory());
private RecordingProvider recorder = new RecordingProvider(new VABMapProvider(new HashMap<>()));
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/TestsuiteDirectory.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/TestsuiteDirectory.java
index 4177a48..4ebc0d7 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/TestsuiteDirectory.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/TestsuiteDirectory.java
@@ -1,6 +1,15 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.protocol.http;
-import org.eclipse.basyx.vab.directory.memory.InMemoryDirectory;
+import org.eclipse.basyx.vab.registry.memory.VABInMemoryRegistry;
@@ -11,16 +20,29 @@
* @author kuhn
*
*/
-public class TestsuiteDirectory extends InMemoryDirectory {
-
+public class TestsuiteDirectory extends VABInMemoryRegistry {
/**
* Constructor - load all directory entries
*/
public TestsuiteDirectory() {
- // Define mappings
- // - Asset administration shells
- addMapping("urn:fhg:es.iese:vab:1:1:simplevabelement", "http://localhost:8080/basys.sdk/Testsuite/SimpleVAB/");
- addMapping("urn:fhg:es.iese:aas:1:1:submodel", "http://localhost:8080/basys.sdk/Testsuite/SimpleAASSubmodel/");
+ this("http");
+ }
+
+ /**
+ * Constructor - load all directory entries with link
+ * protocol defined in the parameter
+ * @param protocol
+ */
+ public TestsuiteDirectory(String protocol) {
+ defineMapping(protocol);
+ }
+
+ /**
+ * Define mapping of submodel and vab element
+ */
+ private void defineMapping(String protocol) {
+ addMapping("urn:fhg:es.iese:vab:1:1:simplevabelement", protocol + "://localhost:8080/basys.sdk/Testsuite/SimpleVAB/");
+ addMapping("urn:fhg:es.iese:aas:1:1:submodel", protocol + "://localhost:8080/basys.sdk/Testsuite/SimpleAASSubmodel/");
}
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/DefaultHostNameVerifier.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/DefaultHostNameVerifier.java
new file mode 100644
index 0000000..7e0f876
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/DefaultHostNameVerifier.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.vab.protocol.https;
+
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLSession;
+
+/**
+ * A default host name verifier which verifies every host name
+ * Used for testing with self signed certificate
+ * @author haque
+ *
+ */
+public class DefaultHostNameVerifier implements HostnameVerifier {
+ @Override
+ public boolean verify(String s, SSLSession sslSession) {
+ return true;
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/DefaultTrustManager.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/DefaultTrustManager.java
new file mode 100644
index 0000000..0cee46b
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/DefaultTrustManager.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.vab.protocol.https;
+
+import javax.net.ssl.X509TrustManager;
+import java.security.cert.X509Certificate;
+
+/**
+ * A Default Trust manager class which trusts everything
+ * Used for testing with self signed certificate
+ * @author haque
+ *
+ */
+public class DefaultTrustManager implements X509TrustManager {
+ @Override
+ public void checkClientTrusted(X509Certificate[] x509Certificates, String s) {
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] x509Certificates, String s) {
+ }
+
+ @Override
+ public X509Certificate[] getAcceptedIssuers() {
+ return new X509Certificate[0];
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/HTTPSConnector.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/HTTPSConnector.java
new file mode 100644
index 0000000..0d6bd32
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/HTTPSConnector.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.vab.protocol.https;
+
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnector;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * An HTTPS Connector class which can be used
+ * for creating an HTTPS Client with self signed SSL certificate
+ * and communicating in REST
+ *
+ * @author haque
+ *
+ */
+public class HTTPSConnector extends HTTPConnector {
+ private static Logger logger = LoggerFactory.getLogger(HTTPSConnector.class);
+
+ /**
+ * Initiates an HTTPSConnector with given address
+ * @param address
+ */
+ public HTTPSConnector(String address) {
+ super(address);
+ setHttpsClient();
+ }
+
+ /**
+ * Initiates an HTTPSConnector with given address and media type
+ * @param address
+ * @param mediaType
+ */
+ public HTTPSConnector(String address, String mediaType) {
+ super(address, mediaType);
+ setHttpsClient();
+ }
+
+ /**
+ * Configures the client so that it can run with HTTPS protocol
+ */
+ private void setHttpsClient() {
+ try {
+ this.client = JerseyHttpsClientFactory.getJerseyHTTPSClient();
+ } catch (KeyManagementException | NoSuchAlgorithmException e) {
+ logger.error("Cannot create a https client");
+ }
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/HTTPSConnectorProvider.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/HTTPSConnectorProvider.java
new file mode 100644
index 0000000..3d63679
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/HTTPSConnectorProvider.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.vab.protocol.https;
+
+import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.protocol.api.ConnectorFactory;
+
+/**
+ * An HTTPS Connector provider class
+ * which uses a HTTPSConnector in domain having self signed certificate
+ * @author haque
+ *
+ */
+public class HTTPSConnectorProvider extends ConnectorFactory {
+
+ /**
+ * returns HTTPSConnetor wrapped with ConnectedHashmapProvider that handles
+ * message header information
+ */
+ @Override
+ protected IModelProvider createProvider(String addr) {
+ return new JSONConnector(new HTTPSConnector(addr));
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/JerseyHttpsClientFactory.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/JerseyHttpsClientFactory.java
new file mode 100644
index 0000000..6d68d2c
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/JerseyHttpsClientFactory.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.vab.protocol.https;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+
+/**
+ * A Factory class containing methods creating an HTTPS client
+ * with no verification and validation for self signed SSL
+ * and other helper methods
+ *
+ * @author haque
+ *
+ */
+public class JerseyHttpsClientFactory {
+
+ /**
+ * Returns an HTTPS client
+ * @return
+ * @throws KeyManagementException
+ * @throws NoSuchAlgorithmException
+ */
+ public static Client getJerseyHTTPSClient() throws KeyManagementException, NoSuchAlgorithmException {
+ SSLContext sslContext = getSslContext();
+ HostnameVerifier allHostsValid = new DefaultHostNameVerifier();
+
+ return ClientBuilder.newBuilder()
+ .sslContext(sslContext)
+ .hostnameVerifier(allHostsValid)
+ .build();
+ }
+
+ /**
+ * Retrieves an SSL Context
+ * with TLSv1 protocol
+ * @return
+ * @throws NoSuchAlgorithmException
+ * @throws KeyManagementException
+ */
+ private static SSLContext getSslContext() throws NoSuchAlgorithmException,
+ KeyManagementException {
+ SSLContext sslContext = SSLContext.getInstance("TLSv1");
+
+ KeyManager[] keyManagers = null;
+ TrustManager[] trustManager = {new DefaultTrustManager()};
+ SecureRandom secureRandom = new SecureRandom();
+
+ sslContext.init(keyManagers, trustManager, secureRandom);
+
+ return sslContext;
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/TestVABHTTPS.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/TestVABHTTPS.java
new file mode 100644
index 0000000..a467dd4
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/TestVABHTTPS.java
@@ -0,0 +1,146 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.vab.protocol.https;
+
+import static org.junit.Assert.assertEquals;
+
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.client.Invocation.Builder;
+import javax.ws.rs.core.MediaType;
+
+import org.eclipse.basyx.testsuite.regression.vab.modelprovider.TestProvider;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.SimpleVABElementServlet;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.TestVABHTTP;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.TestsuiteDirectory;
+import org.eclipse.basyx.testsuite.regression.vab.support.RecordingProvider;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
+import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Test VAB using HTTPS protocol. This is an integration test
+ *
+ * @author haque
+ *
+ */
+public class TestVABHTTPS extends TestProvider {
+ protected VABConnectionManager connManager = new VABConnectionManager(new TestsuiteDirectory("https"),
+ new HTTPSConnectorProvider());
+
+ private RecordingProvider recorder = new RecordingProvider(new VABMapProvider(new HashMap<>()));
+
+ /**
+ * Makes sure Tomcat Server is started after before each test case
+ */
+ @Rule
+ public AASHTTPServerResource res = new AASHTTPServerResource(
+ new BaSyxContext("/basys.sdk",
+ System.getProperty("java.io.tmpdir"), "localhost", 8080, true, "resources/ssl.cert", "pass123")
+ .addServletMapping("/Testsuite/SimpleVAB/*", new SimpleVABElementServlet())
+ .addServletMapping("/Testsuite/Recorder/*", new VABHTTPInterface<RecordingProvider>(recorder)));
+
+ @Override
+ protected VABConnectionManager getConnectionManager() {
+ return connManager;
+ }
+
+ /**
+ * Tests for URL with no ending slash when accessing the root element, e.g.
+ * http://localhost:8080/basys.sdk/Testsuite/SimpleVAB <br />
+ * The SDK ensures that each access ends with a <i>/</i>. However, browser
+ * requests do not necessarily conform to this
+ * @throws NoSuchAlgorithmException
+ * @throws KeyManagementException
+ */
+ @Test
+ public void testRootURL() throws KeyManagementException, NoSuchAlgorithmException {
+ performRequest("https://localhost:8080/basys.sdk/Testsuite/SimpleVAB");
+ }
+
+ /**
+ * Tests if multiple parameters are correctly accepted and passed to the
+ * provider
+ */
+ @Test
+ public void testParameters() {
+ recorder.reset();
+
+ String parameterRequest = "test?a=1,2&b=3,4";
+
+ performRequestNoException("https://localhost:8080/basys.sdk/Testsuite/Recorder/" + parameterRequest);
+
+ List<String> paths = recorder.getPaths();
+
+ assertEquals(1, paths.size());
+ assertEquals(parameterRequest, paths.get(0));
+ }
+
+ /**
+ * Tests if having no parameter has no influence on the path
+ */
+ @Test
+ public void testNoParameters() {
+ recorder.reset();
+
+ String parameterRequest = "test";
+
+ performRequestNoException("https://localhost:8080/basys.sdk/Testsuite/Recorder/" + parameterRequest);
+
+ List<String> paths = recorder.getPaths();
+
+ assertEquals(1, paths.size());
+ assertEquals(parameterRequest, VABPathTools.stripSlashes(paths.get(0)));
+ }
+
+ /**
+ * Performs an HTTP request on an URL
+ *
+ * @param URL
+ * @throws NoSuchAlgorithmException
+ * @throws KeyManagementException
+ */
+ private void performRequest(String URL) throws KeyManagementException, NoSuchAlgorithmException {
+ Client client = JerseyHttpsClientFactory.getJerseyHTTPSClient();
+
+ // Called URL
+ WebTarget resource = client.target(URL);
+
+ // Build request, set JSON encoding
+ Builder request = resource.request();
+ request.accept(MediaType.APPLICATION_JSON);
+
+ // Perform request
+ request.get(String.class);
+ }
+
+ /**
+ * Same as {@link TestVABHTTP#performRequest} but ignores exceptions
+ *
+ * @param URL
+ */
+ private void performRequestNoException(String URL) {
+ try {
+ performRequest(URL);
+ } catch (Exception e) {
+ // Does not matter
+ }
+ }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/opcua/TestVABOpcUa.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/opcua/TestVABOpcUa.java
index f324bbe..fa50ad4 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/opcua/TestVABOpcUa.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/opcua/TestVABOpcUa.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.protocol.opcua;
import org.eclipse.basyx.vab.gateway.ConnectorProviderMapper;
@@ -45,10 +54,10 @@
clientMapper.addConnectorProvider("opc.tcp", new OpcUaConnectorProvider());
try {
clientMapper.getConnector("opc.tcp://opcua.demo-this.com:51210/UA/SampleServer")
- .setModelPropertyValue("0:Objects/2:Data/2:Static/2:AnalogScalar/2:Int32Value", 42);
+ .setValue("0:Objects/2:Data/2:Static/2:AnalogScalar/2:Int32Value", 42);
Object ret = clientMapper.getConnector("opc.tcp://opcua.demo-this.com:51210/UA/SampleServer")
- .getModelPropertyValue("0:Objects/2:Data/2:Static/2:AnalogScalar/2:Int32Value");
+ .getValue("0:Objects/2:Data/2:Static/2:AnalogScalar/2:Int32Value");
Assert.assertEquals("42", ret);
} catch (Exception e) {
// TODO Auto-generated catch block
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/support/RecordingProvider.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/support/RecordingProvider.java
index 8b318e6..c59d731 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/support/RecordingProvider.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/support/RecordingProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.support;
import java.util.ArrayList;
@@ -36,15 +45,15 @@
@Override
- public Object getModelPropertyValue(String path) throws ProviderException {
+ public Object getValue(String path) throws ProviderException {
paths.add(path);
- return wrapped.getModelPropertyValue(path);
+ return wrapped.getValue(path);
}
@Override
- public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
+ public void setValue(String path, Object newValue) throws ProviderException {
paths.add(path);
- wrapped.setModelPropertyValue(path, newValue);
+ wrapped.setValue(path, newValue);
}
@Override
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/support/TestTypeDestroyer.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/support/TestTypeDestroyer.java
index e6c40b9..617fc77 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/support/TestTypeDestroyer.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/support/TestTypeDestroyer.java
@@ -1,9 +1,19 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
package org.eclipse.basyx.testsuite.regression.vab.support;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import java.util.ArrayList;
import java.util.Map;
import org.eclipse.basyx.testsuite.regression.vab.modelprovider.SimpleVABElement;
@@ -17,12 +27,16 @@
*/
public class TestTypeDestroyer {
+ @SuppressWarnings("unchecked")
@Test
public void testTypeDestroyer() {
SimpleVABElement sm = new SimpleVABElement();
Map<String, Object> generic = TypeDestroyer.destroyType(sm);
assertTrue(sm instanceof SimpleVABElement);
assertFalse(generic instanceof SimpleVABElement);
+
+ // Replace set with list as transmission over VAB would do
+ ((Map<String, Object>) sm.get("structure")).put("set", new ArrayList<>());
assertEquals(generic, sm);
}
}
diff --git a/sdks/java/basys.sdk/src/test/resources/aas/factory/json/aasJsonSchemaV2.0.1_Example.json b/sdks/java/basys.sdk/src/test/resources/aas/factory/json/aasJsonSchemaV2.0.1_Example.json
new file mode 100644
index 0000000..afa70e0
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/resources/aas/factory/json/aasJsonSchemaV2.0.1_Example.json
@@ -0,0 +1,570 @@
+{
+ "assetAdministrationShells": [
+ {
+ "asset": {
+ "keys": [
+ {
+ "type": "Asset",
+ "local": true,
+ "value": "http://customer.com/assets/KHBVZJSQKIY",
+ "idType": "IRI"
+ }
+ ],
+ "kind": "Type",
+ "idShort": "assetId1",
+ "identification": {
+ "idType": "IRI",
+ "id": "assetId1"
+ }
+ },
+ "submodels": [
+ {
+ "keys": [
+ {
+ "type": "Submodel",
+ "local": true,
+ "value": "http.//i40.customer.com/type/1/1/7A7104BDAB57E184",
+ "idType": "IRI"
+ }
+ ],
+ "idShort": "submodelId1",
+ "identification": {
+ "idType": "IRI",
+ "id": "submodelId1"
+ }
+ },
+ {
+ "keys": [
+ {
+ "type": "Submodel",
+ "local": true,
+ "value": "http://i40.customer.com/instance/1/1/AC69B1CB44F07935",
+ "idType": "IRI"
+ }
+ ],
+ "idShort": "submodelId2",
+ "identification": {
+ "idType": "IRI",
+ "id": "submodelId2"
+ }
+ },
+ {
+ "keys": [
+ {
+ "type": "Submodel",
+ "local": true,
+ "value": "http://i40.customer.com/type/1/1/1A7B62B529F19152",
+ "idType": "IRI"
+ }
+ ],
+ "idShort": "submodelId3",
+ "identification": {
+ "idType": "IRI",
+ "id": "submodelId3"
+ }
+ }
+ ],
+ "conceptDictionaries": [],
+ "identification": {
+ "idType": "IRI",
+ "id": "http://customer.com/aas/9175_7013_7091_9168"
+ },
+ "idShort": "ExampleMotor",
+ "category": "CONSTANT",
+ "modelType": {
+ "name": "AssetAdministrationShell"
+ }
+ }
+ ],
+ "assets": [
+ {
+ "assetIdentificationModelRef": {
+ "keys": [
+ {
+ "type": "Submodel",
+ "local": true,
+ "value": "i40.customer.com/type/1/1/F13E8576F6488342",
+ "idType": "IRI"
+ }
+ ]
+ },
+ "identification": {
+ "idType": "IRI",
+ "id": "http://customer.com/assets/KHBVZJSQKIY"
+ },
+ "idShort": "ServoDCMotor",
+ "category": "",
+ "modelType": {
+ "name": "Asset"
+ },
+ "kind": "Instance"
+ }
+ ],
+ "submodels": [
+ {
+ "semanticId": {
+ "keys": [
+ {
+ "type": "GlobalReference",
+ "local": false,
+ "value": "0173-1#01-AFZ615#016",
+ "idType": "IRDI"
+ }
+ ]
+ },
+ "identification": {
+ "idType": "IRI",
+ "id": "http.//i40.customer.com/type/1/1/7A7104BDAB57E184"
+ },
+ "idShort": "TechnicalData",
+ "category": "CONSTANT",
+ "modelType": {
+ "name": "Submodel"
+ },
+ "kind": "Instance",
+ "submodelElements": [
+ {
+ "value": "5000",
+ "semanticId": {
+ "keys": [
+ {
+ "type": "ConceptDescription",
+ "local": true,
+ "value": "0173-1#02-BAA120#008",
+ "idType": "IRDI"
+ }
+ ]
+ },
+ "constraints": [],
+ "idShort": "MaxRotationSpeed",
+ "category": "PARAMETER",
+ "modelType": {
+ "name": "Property"
+ },
+ "valueType": "integer",
+ "kind": "Instance"
+ }
+ ]
+ },
+ {
+ "semanticId": {
+ "keys": []
+ },
+ "identification": {
+ "idType": "IRI",
+ "id": "http://i40.customer.com/type/1/1/1A7B62B529F19152"
+ },
+ "idShort": "Documentation",
+ "category": "CONSTANT",
+ "modelType": {
+ "name": "Submodel"
+ },
+ "kind": "Instance",
+ "submodelElements": [
+ {
+ "ordered": false,
+ "allowDuplicates": false,
+ "semanticId": {
+ "keys": [
+ {
+ "type": "ConceptDescription",
+ "local": true,
+ "value": "www.vdi2770.com/blatt1/Entwurf/Okt18/cd/Document",
+ "idType": "IRI"
+ }
+ ]
+ },
+ "constraints": [],
+ "idShort": "OperatingManual",
+ "category": "",
+ "modelType": {
+ "name": "SubmodelElementCollection"
+ },
+ "value": [
+ {
+ "value": "Operating Manual",
+ "semanticId": {
+ "keys": [
+ {
+ "type": "ConceptDescription",
+ "local": true,
+ "value": "www.vdi2770.com/blatt1/Entwurf/Okt18/cd/Description/Title",
+ "idType": "IRI"
+ }
+ ]
+ },
+ "constraints": [],
+ "idShort": "Title",
+ "modelType": {
+ "name": "Property"
+ },
+ "valueType": "langString",
+ "kind": "Instance"
+ },
+ {
+ "mimeType": "application/pdf",
+ "value": "/aasx/OperatingManual.pdf",
+ "semanticId": {
+ "keys": [
+ {
+ "type": "ConceptDescription",
+ "local": true,
+ "value": "www.vdi2770.com/blatt1/Entwurf/Okt18/cd/StoredDocumentRepresentation/DigitalFile",
+ "idType": "IRI"
+ }
+ ]
+ },
+ "constraints": [],
+ "idShort": "DigitalFile_PDF",
+ "category": "PARAMETER",
+ "modelType": {
+ "name": "File"
+ },
+ "kind": "Instance"
+ }
+ ],
+ "kind": "Instance"
+ }
+ ]
+ },
+ {
+ "semanticId": {
+ "keys": []
+ },
+ "qualifiers": [],
+ "identification": {
+ "idType": "IRI",
+ "id": "http://i40.customer.com/instance/1/1/AC69B1CB44F07935"
+ },
+ "idShort": "OperationalData",
+ "category": "VARIABLE",
+ "modelType": {
+ "name": "Submodel"
+ },
+ "kind": "Instance",
+ "submodelElements": [
+ {
+ "value": "4370",
+ "hasDataSpecification": {
+ "reference": []
+ },
+ "semanticId": {
+ "keys": [
+ {
+ "type": "ConceptDescription",
+ "local": true,
+ "value": "http://customer.com/cd/1/1/18EBD56F6B43D895",
+ "idType": "IRI"
+ }
+ ]
+ },
+ "constraints": [],
+ "idShort": "RotationSpeed",
+ "category": "VARIABLE",
+ "modelType": {
+ "name": "Property"
+ },
+ "valueType": "integer",
+ "kind": "Instance"
+ }
+ ]
+ }
+ ],
+ "conceptDescriptions": [
+ {
+ "identification": {
+ "idType": "IRI",
+ "id": "www.vdi2770.com/blatt1/Entwurf/Okt18/cd/Description/Title"
+ },
+ "idShort": "Title",
+ "category": "CONSTANT",
+ "modelType": {
+ "name": "ConceptDescription"
+ },
+ "embeddedDataSpecifications": [
+ {
+ "dataSpecification": {
+ "keys": [
+ {
+ "type": "GlobalReference",
+ "local": false,
+ "value": "http://admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360",
+ "idType": "IRI"
+ }
+ ]
+ },
+ "dataSpecificationContent": {
+ "preferredName": [
+ {
+ "language": "EN",
+ "text": "Title"
+ },
+ {
+ "language": "DE",
+ "text": "Titel"
+ }
+ ],
+ "shortName": [
+ {
+ "language": "EN",
+ "text": "Title"
+ },
+ {
+ "language": "DE",
+ "text": "Titel"
+ }
+ ],
+ "unit": "",
+ "sourceOfDefinition": "",
+ "dataType": "STRING_TRANSLATABLE",
+ "definition": [
+ {
+ "language": "DE",
+ "text": "Sprachabhängiger Titel des Dokuments."
+ }
+ ]
+ }
+ }
+ ],
+ "isCaseOf": []
+ },
+ {
+ "identification": {
+ "idType": "IRI",
+ "id": "www.vdi2770.com/blatt1/Entwurf/Okt18/cd/StoredDocumentRepresentation/DigitalFile"
+ },
+ "idShort": "DigitalFile",
+ "modelType": {
+ "name": "ConceptDescription"
+ },
+ "embeddedDataSpecifications": [
+ {
+ "dataSpecification": {
+ "keys": [
+ {
+ "type": "GlobalReference",
+ "local": false,
+ "value": "http://admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360",
+ "idType": "IRI"
+ }
+ ]
+ },
+ "dataSpecificationContent": {
+ "preferredName": [
+ {
+ "language": "EN",
+ "text": "Digital File"
+ },
+ {
+ "language": "DE",
+ "text": "Digitale Datei"
+ }
+ ],
+ "shortName": [
+ {
+ "language": "EN",
+ "text": "DigitalFile"
+ },
+ {
+ "language": "DE",
+ "text": "DigitaleDatei"
+ }
+ ],
+ "unit": "",
+ "sourceOfDefinition": "",
+ "dataType": "STRING",
+ "definition": [
+ {
+ "language": "DE",
+ "text": "Eine Datei, die die DocumentVersion repräsentiert. Neben der obligatorischen PDF/A Datei können weitere Dateien angegeben werden."
+ }
+ ]
+ }
+ }
+ ],
+ "isCaseOf": []
+ },
+ {
+ "identification": {
+ "idType": "IRDI",
+ "id": "0173-1#02-BAA120#008"
+ },
+ "administration": {
+ "version": "",
+ "revision": "2"
+ },
+ "idShort": "MaxRotationSpeed",
+ "category": "PROPERTY",
+ "modelType": {
+ "name": "ConceptDescription"
+ },
+ "embeddedDataSpecifications": [
+ {
+ "dataSpecification": {
+ "keys": []
+ },
+ "dataSpecificationContent": {
+ "preferredName": [
+ {
+ "language": "de",
+ "text": "max. Drehzahl"
+ },
+ {
+ "language": "en",
+ "text": "Max. rotation speed"
+ }
+ ],
+ "shortName": [],
+ "unit": "1/min",
+ "unitId": {
+ "keys": [
+ {
+ "type": "GlobalReference",
+ "local": false,
+ "value": "0173-1#05-AAA650#002",
+ "idType": "IRDI"
+ }
+ ]
+ },
+ "sourceOfDefinition": "",
+ "dataType": "REAL_MEASURE",
+ "definition": [
+ {
+ "language": "de",
+ "text": "Höchste zulässige Drehzahl, mit welcher der Motor oder die Speiseinheit betrieben werden darf"
+ },
+ {
+ "language": "en",
+ "text": "Greatest permissible rotation speed with which the motor or feeding unit may be operated"
+ }
+ ]
+ }
+ }
+ ],
+ "isCaseOf": [
+ {
+ "keys": []
+ }
+ ]
+ },
+ {
+ "identification": {
+ "idType": "IRI",
+ "id": "http://customer.com/cd/1/1/18EBD56F6B43D895"
+ },
+ "idShort": "RotationSpeed",
+ "category": "PROPERTY",
+ "modelType": {
+ "name": "ConceptDescription"
+ },
+ "embeddedDataSpecifications": [
+ {
+ "dataSpecification": {
+ "keys": [
+ {
+ "type": "GlobalReference",
+ "local": false,
+ "value": "http://admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360",
+ "idType": "IRI"
+ }
+ ]
+ },
+ "dataSpecificationContent": {
+ "preferredName": [
+ {
+ "language": "DE",
+ "text": "Aktuelle Drehzahl"
+ },
+ {
+ "language": "EN",
+ "text": "Actual rotation speed"
+ }
+ ],
+ "shortName": [
+ {
+ "language": "DE",
+ "text": "AktuelleDrehzahl"
+ },
+ {
+ "language": "EN",
+ "text": "ActualRotationSpeed"
+ }
+ ],
+ "unit": "1/min",
+ "unitId": {
+ "keys": [
+ {
+ "type": "GlobalReference",
+ "local": false,
+ "value": "0173-1#05-AAA650#002",
+ "idType": "IRDI"
+ }
+ ]
+ },
+ "sourceOfDefinition": "",
+ "dataType": "REAL_MEASURE",
+ "definition": [
+ {
+ "language": "DE",
+ "text": "Aktuelle Drehzahl, mit welcher der Motor oder die Speiseinheit betrieben wird"
+ },
+ {
+ "language": "EN",
+ "text": "Actual rotation speed with which the motor or feeding unit is operated"
+ }
+ ]
+ }
+ }
+ ],
+ "isCaseOf": []
+ },
+ {
+ "identification": {
+ "idType": "IRI",
+ "id": "www.vdi2770.com/blatt1/Entwurf/Okt18/cd/Document"
+ },
+ "idShort": "Document",
+ "modelType": {
+ "name": "ConceptDescription"
+ },
+ "embeddedDataSpecifications": [
+ {
+ "dataSpecification": {
+ "keys": [
+ {
+ "type": "GlobalReference",
+ "local": false,
+ "value": "http://admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360",
+ "idType": "IRI"
+ }
+ ]
+ },
+ "dataSpecificationContent": {
+ "preferredName": [],
+ "shortName": [
+ {
+ "language": "EN",
+ "text": "Document"
+ },
+ {
+ "language": "DE",
+ "text": "Dokument"
+ }
+ ],
+ "unit": "",
+ "sourceOfDefinition": "[ISO 15519-1:2010]",
+ "dataType": "STRING",
+ "definition": [
+ {
+ "language": "DE",
+ "text": "Feste und geordnete Menge von für die Verwendung durch Personen bestimmte Informationen, die verwaltet und als Einheit zwischen Benutzern und System ausgetauscht werden kann."
+ }
+ ]
+ }
+ }
+ ],
+ "isCaseOf": [],
+ "descriptions": []
+ }
+ ]
+}
\ No newline at end of file
diff --git a/sdks/java/basys.sdk/src/test/resources/aas/factory/xml/in.xml b/sdks/java/basys.sdk/src/test/resources/aas/factory/xml/in.xml
index a36ecd4..31a966a 100644
--- a/sdks/java/basys.sdk/src/test/resources/aas/factory/xml/in.xml
+++ b/sdks/java/basys.sdk/src/test/resources/aas/factory/xml/in.xml
@@ -201,11 +201,12 @@
<aas:key type="ConceptDescription" local="true" idType="IRI">www.festo.com/dic/08111234</aas:key>
</aas:keys>
</aas:assetIdentificationModelRef>
- <aas:kind>Instance</aas:kind>
+ <aas:kind>Type</aas:kind>
</aas:asset>
<aas:asset>
<aas:idShort>emptyAsset</aas:idShort>
<aas:identification idType="IRI">http://pk.festo.com/q30j38dlajx</aas:identification>
+ <aas:kind>Instance</aas:kind>
</aas:asset>
</aas:assets>
<aas:submodels>
@@ -233,34 +234,54 @@
</aas:keys>
</aas:semanticId>
<aas:qualifier>
- <aas:qualifiers>
- <aas:formula>
- <aas:dependsOnRefs>
- <aas:reference>
- <aas:keys>
- <aas:key local="false" type="GlobalReference" idType="IRDI">qualifier_reference</aas:key>
- </aas:keys>
- </aas:reference>
- </aas:dependsOnRefs>
- </aas:formula>
- </aas:qualifiers>
- <aas:qualifiers>
- <aas:qualifier>
- <aas:valueId>
+ <aas:formula>
+ <aas:dependsOnRefs>
+ <aas:reference>
<aas:keys>
- <aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+ <aas:key local="false" type="GlobalReference" idType="IRDI">qualifier_reference</aas:key>
</aas:keys>
- </aas:valueId>
- <aas:value>qualifierValue</aas:value>
- <aas:type>qualifierType</aas:type>
- <aas:valueType>valueType</aas:valueType>
- <aas:semanticId>
+ </aas:reference>
+ </aas:dependsOnRefs>
+ </aas:formula>
+ <aas:formula>
+ <aas:dependsOnRefs>
+ <aas:reference>
<aas:keys>
- <aas:key idType="IRI" local="false" type="GlobalReference">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+ <aas:key local="false" type="GlobalReference" idType="IRDI">qualifier_reference2</aas:key>
</aas:keys>
- </aas:semanticId>
- </aas:qualifier>
- </aas:qualifiers>
+ </aas:reference>
+ </aas:dependsOnRefs>
+ </aas:formula>
+ <aas:qualifier>
+ <aas:valueId>
+ <aas:keys>
+ <aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+ </aas:keys>
+ </aas:valueId>
+ <aas:value>qualifierValue</aas:value>
+ <aas:type>qualifierType</aas:type>
+ <aas:valueType>anyType</aas:valueType>
+ <aas:semanticId>
+ <aas:keys>
+ <aas:key idType="IRI" local="false" type="GlobalReference">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+ </aas:keys>
+ </aas:semanticId>
+ </aas:qualifier>
+ <aas:qualifier>
+ <aas:valueId>
+ <aas:keys>
+ <aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+ </aas:keys>
+ </aas:valueId>
+ <aas:value>qualifierValue2</aas:value>
+ <aas:type>qualifierType</aas:type>
+ <aas:valueType>anyType</aas:valueType>
+ <aas:semanticId>
+ <aas:keys>
+ <aas:key idType="IRI" local="false" type="GlobalReference">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+ </aas:keys>
+ </aas:semanticId>
+ </aas:qualifier>
</aas:qualifier>
<aas:embeddedDataSpecification>
<aas:dataSpecificationContent>
@@ -298,23 +319,21 @@
</aas:keys>
</aas:semanticId>
<aas:qualifier>
- <aas:qualifiers>
- <aas:qualifier>
- <aas:valueId>
- <aas:keys>
- <aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
- </aas:keys>
- </aas:valueId>
- <aas:value>qualifierValue</aas:value>
- <aas:type>qualifierType</aas:type>
- <aas:valueType>valueType</aas:valueType>
- <aas:semanticId>
- <aas:keys>
- <aas:key idType="IRI" local="false" type="GlobalReference">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
- </aas:keys>
- </aas:semanticId>
- </aas:qualifier>
- </aas:qualifiers>
+ <aas:qualifier>
+ <aas:valueId>
+ <aas:keys>
+ <aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+ </aas:keys>
+ </aas:valueId>
+ <aas:value>qualifierValue</aas:value>
+ <aas:type>qualifierType</aas:type>
+ <aas:valueType>anyType</aas:valueType>
+ <aas:semanticId>
+ <aas:keys>
+ <aas:key idType="IRI" local="false" type="GlobalReference">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+ </aas:keys>
+ </aas:semanticId>
+ </aas:qualifier>
</aas:qualifier>
<aas:embeddedDataSpecification>
<aas:dataSpecificationContent>
@@ -341,6 +360,11 @@
</aas:keys>
</aas:dataSpecification>
</aas:embeddedDataSpecification>
+ <aas:valueId>
+ <aas:keys>
+ <aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</aas:key>
+ </aas:keys>
+ </aas:valueId>
<aas:value>2000</aas:value>
<aas:valueType>double</aas:valueType>
</aas:property>
@@ -383,7 +407,7 @@
<aas:range>
<aas:idShort>range_id</aas:idShort>
<aas:min>10</aas:min>
- <aas:valueType>int</aas:valueType>
+ <aas:valueType>integer</aas:valueType>
</aas:range>
</aas:submodelElement>
</aas:statements>
@@ -408,7 +432,7 @@
<aas:idShort>range_id</aas:idShort>
<aas:max>10</aas:max>
<aas:min>1</aas:min>
- <aas:valueType>int</aas:valueType>
+ <aas:valueType>integer</aas:valueType>
</aas:range>
</aas:submodelElement>
<aas:submodelElement>
@@ -474,6 +498,39 @@
</aas:relationshipElement>
</aas:submodelElement>
<aas:submodelElement>
+ <aas:annotatedRelationshipElement>
+ <aas:idShort>annotatedRelationshipElement_ID</aas:idShort>
+ <aas:first>
+ <aas:keys>
+ <aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#003</aas:key>
+ </aas:keys>
+ </aas:first>
+ <aas:second>
+ <aas:keys>
+ <aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#004</aas:key>
+ </aas:keys>
+ </aas:second>
+ <aas:annotations>
+ <aas:dataElement>
+ <aas:property>
+ <aas:idShort>prop1</aas:idShort>
+ <aas:kind>Instance</aas:kind>
+ <aas:value>1</aas:value>
+ <aas:valueType>integer</aas:valueType>
+ </aas:property>
+ </aas:dataElement>
+ <aas:dataElement>
+ <aas:property>
+ <aas:idShort>prop2</aas:idShort>
+ <aas:kind>Instance</aas:kind>
+ <aas:value>2</aas:value>
+ <aas:valueType>integer</aas:valueType>
+ </aas:property>
+ </aas:dataElement>
+ </aas:annotations>
+ </aas:annotatedRelationshipElement>
+ </aas:submodelElement>
+ <aas:submodelElement>
<aas:operation>
<aas:idShort>operation_ID</aas:idShort>
<aas:inoutputVariable>
@@ -486,6 +543,7 @@
<aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#003</aas:key>
</aas:keys>
</aas:value>
+ <aas:kind>Template</aas:kind>
</aas:referenceElement>
</aas:value>
</aas:operationVariable>
@@ -497,6 +555,7 @@
<aas:idShort>file_ID</aas:idShort>
<aas:mimeType>file_mimetype</aas:mimeType>
<aas:value>file_value</aas:value>
+ <aas:kind>Template</aas:kind>
</aas:file>
</aas:value>
</aas:operationVariable>
@@ -506,6 +565,7 @@
<aas:idShort>blob_ID</aas:idShort>
<aas:value>YmxvYit2YWx1ZQ==</aas:value>
<aas:mimeType>blob_mimetype</aas:mimeType>
+ <aas:kind>Template</aas:kind>
</aas:blob>
</aas:value>
</aas:operationVariable>
@@ -520,6 +580,7 @@
<aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</aas:key>
</aas:keys>
</aas:value>
+ <aas:kind>Template</aas:kind>
</aas:referenceElement>
</aas:value>
</aas:operationVariable>
@@ -530,9 +591,8 @@
</aas:submodel>
<!-- This is a Submodel with only the minimal required information in it. To test for Nullpointers and such. -->
<aas:submodel>
- <aas:idShort></aas:idShort>
- <aas:identification>
- </aas:identification>
+ <aas:idShort>testSubmodelIdShort2</aas:idShort>
+ <aas:identification idType="IRI">http://www.zvei.de/demo/submodel/12345679</aas:identification>
<aas:submodelElements></aas:submodelElements>
</aas:submodel>
</aas:submodels>
diff --git a/sdks/java/basys.sdk/src/test/resources/config/moquette.conf b/sdks/java/basys.sdk/src/test/resources/config/moquette.conf
new file mode 100644
index 0000000..8511afc
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/resources/config/moquette.conf
@@ -0,0 +1,6 @@
+# Moquette Java Broker configuration file for testing
+
+# Do not use the default 1883 port
+port 1884
+host 0.0.0.0
+allow_anonymous true
\ No newline at end of file
diff --git a/sdks/java/basys.sdk/tomcat.8080/resources/ssl.cert b/sdks/java/basys.sdk/tomcat.8080/resources/ssl.cert
new file mode 100644
index 0000000..d29113a
--- /dev/null
+++ b/sdks/java/basys.sdk/tomcat.8080/resources/ssl.cert
Binary files differ
diff --git a/sdks/java/basys.vabClient/.gitignore b/sdks/java/basys.vabClient/.gitignore
new file mode 100644
index 0000000..e0e5af1
--- /dev/null
+++ b/sdks/java/basys.vabClient/.gitignore
@@ -0,0 +1,72 @@
+regressiontest/
+
+.classpath
+.project
+
+test.txt
+
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+.mvn/wrapper/maven-wrapper.jar
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.settings/
+.loadpath
+.recommenders
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# PyDev specific (Python IDE for Eclipse)
+*.pydevproject
+
+# CDT-specific (C/C++ Development Tooling)
+.cproject
+
+# CDT- autotools
+.autotools
+
+# Java annotation processor (APT)
+.factorypath
+
+# PDT-specific (PHP Development Tools)
+.buildpath
+
+# sbteclipse plugin
+.target
+
+# Tern plugin
+.tern-project
+
+# TeXlipse plugin
+.texlipse
+
+# STS (Spring Tool Suite)
+.springBeans
+
+# Code Recommenders
+.recommenders/
+
+# Annotation Processing
+.apt_generated/
+
+# Scala IDE specific (Scala & Java development for Eclipse)
+.cache-main
+.scala_dependencies
+.worksheet
\ No newline at end of file
diff --git a/sdks/java/basys.vabClient/.project b/sdks/java/basys.vabClient/.project
new file mode 100644
index 0000000..bc25cf5
--- /dev/null
+++ b/sdks/java/basys.vabClient/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>basyx.vabClient</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.m2e.core.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.m2e.core.maven2Nature</nature>
+ </natures>
+</projectDescription>
diff --git a/sdks/java/basys.vabClient/pom.xml b/sdks/java/basys.vabClient/pom.xml
new file mode 100644
index 0000000..13c4acf
--- /dev/null
+++ b/sdks/java/basys.vabClient/pom.xml
@@ -0,0 +1,56 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.eclipse.basyx</groupId>
+ <artifactId>basyx.vabClient</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ <name>BaSyx VAB Client</name>
+
+ <packaging>jar</packaging>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+ </properties>
+
+ <build>
+ <plugins>
+ <!-- Compile Sources using Java 8 -->
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.8.1</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <!-- JUnit 4 for running JUnit tests -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.12</version>
+ <scope>test</scope>
+ </dependency>
+
+ <!-- Add BaSys SDK from local repository -->
+ <dependency>
+ <groupId>org.eclipse.basyx</groupId>
+ <artifactId>basyx.sdk</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </dependency>
+
+ <!-- Add test classes in BaSys SDK from local repository -->
+ <dependency>
+ <groupId>org.eclipse.basyx</groupId>
+ <artifactId>basyx.sdk</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ <classifier>tests</classifier>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
diff --git a/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppExceptions.java b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppExceptions.java
new file mode 100644
index 0000000..2873dbb
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppExceptions.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.eclipse.basyx.vab.coder.json.metaprotocol.Message;
+import org.eclipse.basyx.vab.coder.json.metaprotocol.Result;
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.eclipse.basyx.vab.exception.provider.ResourceAlreadyExistsException;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+
+/**
+ * Snippet to test the exception handling of an IModelProvider
+ * Based on the VAB Exceptions tests within the SDK, but removes
+ * Java-specific local tests.
+ *
+ * @author espen
+ *
+ */
+public class CppExceptions {
+ /**
+ * Tests for handling an exception and its code
+ */
+ public static void testHandlingException(VABConnectionManager connManager) {
+ VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement");
+
+ // Empty paths - at "" is a Map. Therefore create should throw an Exception
+ try {
+ connVABElement.createValue("", "");
+ fail();
+ } catch (ResourceAlreadyExistsException e) {
+ Result result = new Result(e);
+ Message msg = result.getMessages().get(0);
+ assertEquals("422", msg.getCode());
+ }
+
+ // Non-existing parent element
+ try {
+ connVABElement.getModelPropertyValue("unknown/x");
+ fail();
+ } catch (ResourceNotFoundException e) {
+ Result result = new Result(e);
+ Message msg = result.getMessages().get(0);
+ assertEquals("404", msg.getCode());
+
+ }
+
+ // Null path - should throw exception
+ try {
+ connVABElement.createValue(null, "");
+ fail();
+ } catch (MalformedRequestException e) {
+ Result result = new Result(e);
+ Message msg = result.getMessages().get(0);
+ assertEquals("400", msg.getCode());
+ }
+
+ }
+}
diff --git a/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppMapInvoke.java b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppMapInvoke.java
new file mode 100644
index 0000000..4658e48
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppMapInvoke.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+
+/**
+ * Snippet to test invoke functionality of a IModelProvider.
+ * Based on the MapInvoke tests within the SDK, but removes
+ * Java-specific local tests.
+ *
+ * @author espen
+ *
+ */
+public class CppMapInvoke {
+
+ public static void test(VABConnectionManager connManager) {
+ // Connect to VAB element with ID "urn:fhg:es.iese:vab:1:1:simplevabelement"
+ VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement");
+
+ // Invoke complex function
+ Object complex = connVABElement.invokeOperation("operations/complex", 12, 34);
+ assertEquals(46, complex);
+
+ // Invoke non-existing operation
+ try {
+ connVABElement.invokeOperation("operations/unknown");
+ fail();
+ } catch (ResourceNotFoundException e) {}
+
+ // Invoke invalid operation -> not a function, but a primitive data type
+ try {
+ connVABElement.invokeOperation("operations/invalid");
+ fail();
+ } catch (ProviderException e) {}
+
+ // Invoke operations that throw Exceptions
+ try {
+ connVABElement.invokeOperation("operations/providerException");
+ fail();
+ } catch (ProviderException e) {
+ // exception type not implemented, yet
+ // assertEquals(e.getType(), "testExceptionType");
+ }
+
+ try {
+ connVABElement.invokeOperation("operations/nullException");
+ fail();
+ } catch (ProviderException e) {
+ // exception type not implemented, yet
+ // assertEquals(e.getType(), "java.lang.NullPointerException");
+ }
+
+ // Empty paths - should execute, but has no effect
+ try {
+ connVABElement.invokeOperation("", "");
+ fail();
+ } catch (ProviderException e) {}
+
+
+ // Null path - should throw exception
+ try {
+ connVABElement.invokeOperation(null, "");
+ fail();
+ } catch (MalformedRequestException e) {}
+ }
+}
diff --git a/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppMapRead.java b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppMapRead.java
new file mode 100644
index 0000000..b3da381
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppMapRead.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import java.util.Map;
+
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+
+/**
+ * Snippet to test get functionality of a IModelProvider.
+ * Based on the MapRead tests within the SDK, but removes
+ * Java-specific local tests.
+ *
+ * @author espen
+ *
+ */
+public class CppMapRead {
+ public static void test(VABConnectionManager connManager) {
+ // Connect to VAB element with ID "urn:fhg:es.iese:vab:1:1:simplevabelement"
+ VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement");
+
+ // Test path access
+ Object slashA = connVABElement.getModelPropertyValue("/primitives/integer");
+ Object slashB = connVABElement.getModelPropertyValue("primitives/integer/");
+ Object slashC = connVABElement.getModelPropertyValue("/primitives/integer/");
+ Object slashD = connVABElement.getModelPropertyValue("/primitives/integer/");
+ assertEquals(slashA, 123);
+ assertEquals(slashB, 123);
+ assertEquals(slashC, 123);
+ assertEquals(slashD, 123);
+
+ // Test reading different data types
+ Object map = connVABElement.getModelPropertyValue("primitives");
+ Object doubleValue = connVABElement.getModelPropertyValue("primitives/double");
+ Object string = connVABElement.getModelPropertyValue("primitives/string");
+ assertEquals(3, ((Map<?, ?>) map).size());
+ assertEquals(3.14d, doubleValue);
+ assertEquals("TestValue", string);
+
+ // Test case sensitivity
+ Object caseSensitiveA = connVABElement.getModelPropertyValue("special/casesensitivity");
+ Object caseSensitiveB = connVABElement.getModelPropertyValue("special/caseSensitivity");
+ assertEquals(true, caseSensitiveA);
+ assertEquals(false, caseSensitiveB);
+
+ // Test reading null value
+ Object nullValue = connVABElement.getModelPropertyValue("special/null");
+ assertNull(nullValue);
+
+ // Non-existing parent element
+ try {
+ connVABElement.getModelPropertyValue("unknown/x");
+ fail();
+ } catch (ResourceNotFoundException e) {}
+
+ // Non-existing target element
+ try {
+ connVABElement.getModelPropertyValue("primitives/unkown");
+ fail();
+ } catch (ResourceNotFoundException e) {}
+ try {
+ connVABElement.getModelPropertyValue("unkown");
+ fail();
+ } catch (ResourceNotFoundException e) {}
+
+ // Nested access
+ assertEquals(100, connVABElement.getModelPropertyValue("special/nested/nested/value"));
+
+ // Empty path
+ Object rootValueA = connVABElement.getModelPropertyValue("");
+ Object rootValueB = connVABElement.getModelPropertyValue("/");
+ assertEquals(4, ((Map<?, ?>) rootValueA).size());
+ assertEquals(4, ((Map<?, ?>) rootValueB).size());
+
+ // Null path - should throw exception
+ try {
+ connVABElement.getModelPropertyValue(null);
+ fail();
+ } catch (MalformedRequestException e) {}
+ }
+}
diff --git a/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppMapUpdate.java b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppMapUpdate.java
new file mode 100644
index 0000000..c1f1f71
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppMapUpdate.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+
+/**
+ * Snippet to test set functionality of a IModelProvider.
+ * Based on the MapUpdate tests within the SDK, but removes
+ * Java-specific local tests.
+ *
+ * @author espen
+ *
+ */
+public class CppMapUpdate {
+ public static void test(VABConnectionManager connManager) {
+ // Connect to VAB element with ID "urn:fhg:es.iese:vab:1:1:simplevabelement"
+ VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement");
+
+ // Set primitives
+ connVABElement.setModelPropertyValue("primitives/integer", 12);
+ connVABElement.setModelPropertyValue("primitives/double", 1.2d);
+ connVABElement.setModelPropertyValue("primitives/string", "updated");
+ // Read back
+ Object integer = connVABElement.getModelPropertyValue("primitives/integer");
+ Object doubleValue = connVABElement.getModelPropertyValue("primitives/double");
+ Object string = connVABElement.getModelPropertyValue("primitives/string");
+ // Test
+ assertTrue(integer instanceof Integer);
+ assertEquals(12, integer);
+ assertTrue(doubleValue instanceof Double);
+ assertEquals(1.2d, doubleValue);
+ assertTrue(string instanceof String);
+ assertEquals("updated", string);
+ // Revert
+ connVABElement.setModelPropertyValue("primitives/integer", 123);
+ connVABElement.setModelPropertyValue("primitives/double", 3.14d);
+ connVABElement.setModelPropertyValue("primitives/string", "TestValue");
+
+ // Test non-existing parent element
+ try {
+ connVABElement.createValue("unkown/newElement", 5);
+ fail();
+ } catch (ResourceNotFoundException e) {}
+ try {
+ connVABElement.getModelPropertyValue("unknown/newElement");
+ fail();
+ } catch (ResourceNotFoundException e) {}
+
+ // Test updating a non-existing element
+ try {
+ connVABElement.setModelPropertyValue("newElement", 10);
+ fail();
+ } catch (ResourceNotFoundException e) {
+ }
+ try {
+ connVABElement.getModelPropertyValue("newElement");
+ fail();
+ } catch (ResourceNotFoundException e) {}
+
+ // Test updating an existing null-element
+ connVABElement.setModelPropertyValue("special/null", true);
+ Object bool = connVABElement.getModelPropertyValue("special/null");
+ assertTrue((boolean) bool);
+
+ // Null path - should throw exception
+ try {
+ connVABElement.setModelPropertyValue(null, "");
+ fail();
+ } catch (MalformedRequestException e) {}
+ }
+}
diff --git a/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppTestCollectionProperty.java b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppTestCollectionProperty.java
new file mode 100644
index 0000000..1e56efd
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppTestCollectionProperty.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+
+/**
+ * Tests a IModelProvider's capability to handle collections.
+ * Based on the TestCollectionProperty tests within the SDK, but removes
+ * Java-specific local tests.
+ *
+ * @author espen
+ */
+public class CppTestCollectionProperty {
+ @SuppressWarnings("unchecked")
+ public static void testUpdate(VABConnectionManager connManager) {
+ // Connect to VAB element with ID "urn:fhg:es.iese:vab:1:1:simplevabelement"
+ VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement");
+
+ // Read original collection
+ Collection<Object> original = (Collection<Object>) connVABElement.getModelPropertyValue("/structure/list/");
+
+ // Replace complete value of the collection property
+ Collection<Object> replacement = new ArrayList<>();
+ replacement.add(100);
+ replacement.add(200);
+ replacement.add(300);
+ connVABElement.setModelPropertyValue("/structure/list/", replacement);
+
+ // Read values back
+ Collection<Object> collection = (Collection<Object>) connVABElement.getModelPropertyValue("/structure/list/");
+
+ // Check test case results
+ assertEquals(3, collection.size());
+ assertEquals(replacement, collection);
+
+ // Test invalid list access - single list elements cannot be accessed directly
+ try {
+ connVABElement.setModelPropertyValue("/structure/list/0", 3);
+ fail();
+ } catch (ResourceNotFoundException e) {
+ }
+
+ // Write original back
+ connVABElement.setModelPropertyValue("/structure/list/", original);
+ }
+
+ public static void testCreateDelete(VABConnectionManager connManager) {
+ // Connect to VAB element with ID "urn:fhg:es.iese:vab:1:1:simplevabelement"
+ VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement");
+
+ // Create elements in List (no key provided)
+ connVABElement.createValue("/structure/list/", 56);
+ Object toTest = connVABElement.getModelPropertyValue("/structure/list/");
+ assertTrue(((List<?>) toTest).contains(56));
+
+ // Delete at List
+ // by object
+ connVABElement.deleteValue("/structure/list/", 56);
+ toTest = connVABElement.getModelPropertyValue("/structure/list/");
+ assertEquals(0, ((List<?>) toTest).size());
+
+ // Create a list element
+ connVABElement.createValue("listInRoot", Arrays.asList(1, 1, 2, 3, 5));
+ // Test whole list
+ toTest = connVABElement.getModelPropertyValue("listInRoot");
+ assertTrue(toTest instanceof List);
+ assertEquals(5, ((List<?>) toTest).size());
+ assertEquals(2, ((List<?>) toTest).get(2));
+
+ // Delete whole list
+ connVABElement.deleteValue("listInRoot");
+ try {
+ connVABElement.getModelPropertyValue("listInRoot");
+ fail();
+ } catch (ResourceNotFoundException e) {}
+
+ // Delete at List
+ // - referring to new list: [10, 20, 40, 80]
+ connVABElement.createValue("/structure/list/", 10);
+ connVABElement.createValue("/structure/list/", 20);
+ connVABElement.createValue("/structure/list/", 40);
+ connVABElement.createValue("/structure/list/", 80);
+ // - by index - is not possible, as list access is only allowed using references
+ // - in contrast to indices, references always point to the same object in the list
+ try {
+ connVABElement.deleteValue("/structure/list/3");
+ fail();
+ } catch (ResourceNotFoundException e) {}
+
+ toTest = connVABElement.getModelPropertyValue("/structure/list/");
+ assertEquals(4, ((List<?>) toTest).size());
+
+ // Delete half of the elements
+ connVABElement.deleteValue("/structure/list/", 10);
+ connVABElement.deleteValue("/structure/list/", 40);
+ toTest = connVABElement.getModelPropertyValue("/structure/list/");
+ assertEquals(2, ((List<?>) toTest).size());
+
+ // Delete remaining elements
+ connVABElement.deleteValue("/structure/list/", 20);
+ connVABElement.deleteValue("/structure/list/", 80);
+ toTest = connVABElement.getModelPropertyValue("/structure/list/");
+ assertEquals(0, ((List<?>) toTest).size());
+ }
+}
diff --git a/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppTestProvider.java b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppTestProvider.java
new file mode 100644
index 0000000..b9854db
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppTestProvider.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab;
+
+import org.eclipse.basyx.testsuite.regression.vab.modelprovider.TestProvider;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Abstract test suite for testing CRUD-operations for different types of model providers.
+ * The concrete test cases implement concrete VABConnectionManagers that are tested
+ * This extension supports resetting a remote VAB test server before each test.
+ *
+ * @author espen
+ *
+ */
+public abstract class CppTestProvider extends TestProvider {
+ @Before
+ public void before() {
+ VABElementProxy connVABElement = getConnectionManager()
+ .connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement");
+ connVABElement.invokeOperation("/reset", 1);
+ }
+
+ @Test
+ public void testMapRead() {
+ CppMapRead.test(getConnectionManager());
+ }
+
+ @Test
+ public void testMapUpdate() {
+ CppMapUpdate.test(getConnectionManager());
+ }
+
+ @Test
+ public void testCollectionCreateDelete() throws Exception {
+ CppTestCollectionProperty.testCreateDelete(getConnectionManager());
+ }
+
+ @Test
+ public void testCollectionUpdate() {
+ CppTestCollectionProperty.testUpdate(getConnectionManager());
+ }
+
+ @Test
+ public void testMapInvoke() {
+ CppMapInvoke.test(getConnectionManager());
+ }
+
+ @Test
+ public void testHandlingException() {
+ CppExceptions.testHandlingException(getConnectionManager());
+ }
+}
diff --git a/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppVABTestApplication.java b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppVABTestApplication.java
new file mode 100644
index 0000000..9c76317
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppVABTestApplication.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab;
+
+import org.eclipse.basyx.testsuite.regression.aas.aggregator.AASAggregatorSuite;
+import org.junit.internal.TextListener;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+
+/**
+ * The main class that executes the test provider.
+ * Structure is based on the TCK
+ *
+ * @author espen
+ *
+ */
+public class CppVABTestApplication {
+
+ public static void main(String[] args) {
+ // First argument is the inserted url
+ String url = args[0];
+ // Run junit test in a java application
+ JUnitCore junit = new JUnitCore();
+ junit.addListener(new TextListener(System.out));
+
+ VABClientTest.url = url;
+ Result result = junit.run(AASAggregatorSuite.class);
+
+ System.out.println("Finished. Result: Failures: " +
+ result.getFailureCount() + ". Ignored: " +
+ result.getIgnoreCount() + ". Tests run: " +
+ result.getRunCount() + ". Time: " +
+ result.getRunTime() + "ms.");
+ }
+
+}
diff --git a/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/VABClientTest.java b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/VABClientTest.java
new file mode 100644
index 0000000..d8e47d7
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/VABClientTest.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab;
+
+import org.eclipse.basyx.vab.directory.api.IVABDirectoryService;
+import org.eclipse.basyx.vab.directory.memory.InMemoryDirectory;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnectorProvider;
+
+/**
+ * The client side for a Java-Cpp integration test
+ *
+ * @author espen
+ *
+ */
+public class VABClientTest extends CppTestProvider {
+ public static String url = "basyx://localhost:8384/";
+
+ protected VABConnectionManager connManager;
+
+ public VABClientTest() {
+ // Setup the directory based on the SDK-VAB tests
+ IVABDirectoryService directory = new InMemoryDirectory();
+ String simpleVABID = "urn:fhg:es.iese:vab:1:1:simplevabelement";
+ directory.addMapping(simpleVABID, url);
+ connManager = new VABConnectionManager(directory, new BaSyxConnectorProvider());
+ }
+
+ @Override
+ protected VABConnectionManager getConnectionManager() {
+ return connManager;
+ }
+}
diff --git a/sdks/java/basys.vabServer/.gitignore b/sdks/java/basys.vabServer/.gitignore
new file mode 100644
index 0000000..e0e5af1
--- /dev/null
+++ b/sdks/java/basys.vabServer/.gitignore
@@ -0,0 +1,72 @@
+regressiontest/
+
+.classpath
+.project
+
+test.txt
+
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+.mvn/wrapper/maven-wrapper.jar
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.settings/
+.loadpath
+.recommenders
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# PyDev specific (Python IDE for Eclipse)
+*.pydevproject
+
+# CDT-specific (C/C++ Development Tooling)
+.cproject
+
+# CDT- autotools
+.autotools
+
+# Java annotation processor (APT)
+.factorypath
+
+# PDT-specific (PHP Development Tools)
+.buildpath
+
+# sbteclipse plugin
+.target
+
+# Tern plugin
+.tern-project
+
+# TeXlipse plugin
+.texlipse
+
+# STS (Spring Tool Suite)
+.springBeans
+
+# Code Recommenders
+.recommenders/
+
+# Annotation Processing
+.apt_generated/
+
+# Scala IDE specific (Scala & Java development for Eclipse)
+.cache-main
+.scala_dependencies
+.worksheet
\ No newline at end of file
diff --git a/sdks/java/basys.vabServer/pom.xml b/sdks/java/basys.vabServer/pom.xml
new file mode 100644
index 0000000..b4e090b
--- /dev/null
+++ b/sdks/java/basys.vabServer/pom.xml
@@ -0,0 +1,80 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.eclipse.basyx</groupId>
+ <artifactId>basyx.vabServer</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ <name>BaSyx VAB Server</name>
+
+ <packaging>jar</packaging>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+ <exec.mainClass></exec.mainClass>
+ </properties>
+
+ <build>
+ <plugins>
+ <!-- Compile Sources using Java 8 -->
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.8.1</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+
+ <!-- Generate separate jar for tests and exclude logback.xml from generated jars -->
+ <!-- + create the executable jar -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>3.1.1</version>
+ <configuration>
+ <archive>
+ <manifest>
+ <addClasspath>true</addClasspath>
+ <classpathPrefix>lib/</classpathPrefix>
+ <mainClass>ServerApplication</mainClass>
+ </manifest>
+ </archive>
+ <excludes>
+ <exclude>**/logback.xml</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+
+ <!-- Copy the dependencies necessary to run the jar -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copy-dependencies</id>
+ <phase>prepare-package</phase>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ <configuration>
+ <includeScope>compile</includeScope>
+ <outputDirectory>${project.build.directory}/lib/</outputDirectory>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <!-- Add BaSys SDK from local repository. SDK has to be installed previously -->
+ <dependency>
+ <groupId>org.eclipse.basyx</groupId>
+ <artifactId>basyx.sdk</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
diff --git a/sdks/java/basys.vabServer/src/main/java/org/eclipse/basyx/vab/ServerApplication.java b/sdks/java/basys.vabServer/src/main/java/org/eclipse/basyx/vab/ServerApplication.java
new file mode 100644
index 0000000..5d65361
--- /dev/null
+++ b/sdks/java/basys.vabServer/src/main/java/org/eclipse/basyx/vab/ServerApplication.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab;
+
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.protocol.basyx.server.BaSyxTCPServer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A server application that provides a generic VAB-object that can be reset
+ *
+ * @author espen
+ *
+ */
+public class ServerApplication {
+ private static Logger logger = LoggerFactory.getLogger(ServerApplication.class);
+
+ private static BaSyxTCPServer<IModelProvider> server;
+
+ public static void main(String[] args) {
+ int port = 8383;
+ if (args.length > 0) {
+ // First argument is the port
+ port = Integer.parseInt(args[0]);
+ logger.info("Starting server at port " + port);
+ } else {
+ logger.info("Starting server at default port " + port);
+ }
+
+ server = new BaSyxTCPServer<>(new SimpleVABProvider(), port);
+ server.start();
+ }
+}
diff --git a/sdks/java/basys.vabServer/src/main/java/org/eclipse/basyx/vab/SimpleVABElement.java b/sdks/java/basys.vabServer/src/main/java/org/eclipse/basyx/vab/SimpleVABElement.java
new file mode 100644
index 0000000..0df586e
--- /dev/null
+++ b/sdks/java/basys.vabServer/src/main/java/org/eclipse/basyx/vab/SimpleVABElement.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.function.Function;
+
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+
+/**
+ * A simple VAB model that explains the use of the VAB primitives.
+ * Removes local Java-specific properties (e.g. function serialization)
+ *
+ * @author espen
+ *
+ */
+public class SimpleVABElement extends HashMap<String, Object> {
+ private static final long serialVersionUID = 3942399852711325850L;
+
+ /**
+ * Constructor for a simple VAB element that contains all data types
+ */
+ public SimpleVABElement() {
+ // Add primitive types
+ HashMap<String, Object> primitives = new HashMap<>();
+ primitives.put("integer", 123);
+ primitives.put("double", 3.14d);
+ primitives.put("string", "TestValue");
+ put("primitives", primitives);
+
+ // Add function types
+ HashMap<String, Object> functions = new HashMap<>();
+ functions.put("providerException", (Function<Object[], Object>) (param) -> {
+ throw new ProviderException("Exception description");
+ });
+ functions.put("nullException", (Function<Object[], Object>) (param) -> {
+ throw new NullPointerException();
+ });
+ functions.put("complex", (Function<Object[], Object>) (param) -> {
+ return (int) param[0] + (int) param[1];
+ });
+ functions.put("invalid", true);
+ functions.put("invokable", (Function<Object[], Object>) (param) -> {
+ return true;
+ });
+ put("operations", functions);
+
+ // Add structure types
+ HashMap<String, Object> structure = new HashMap<>();
+ structure.put("map", new HashMap<String, Object>());
+ structure.put("list", new ArrayList<Object>());
+ put("structure", structure);
+
+ // Add corner cases
+ HashMap<String, Object> special = new HashMap<>();
+ special.put("casesensitivity", true);
+ special.put("caseSensitivity", false);
+ HashMap<String, Object> nestedA = new HashMap<>();
+ HashMap<String, Object> nestedB = new HashMap<>();
+ nestedA.put("nested", nestedB);
+ nestedB.put("value", 100);
+ special.put("nested", nestedA);
+ special.put("null", null);
+ put("special", special);
+ }
+}
diff --git a/sdks/java/basys.vabServer/src/main/java/org/eclipse/basyx/vab/SimpleVABProvider.java b/sdks/java/basys.vabServer/src/main/java/org/eclipse/basyx/vab/SimpleVABProvider.java
new file mode 100644
index 0000000..0081ad2
--- /dev/null
+++ b/sdks/java/basys.vabServer/src/main/java/org/eclipse/basyx/vab/SimpleVABProvider.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab;
+
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Provider that contains a SimpleVABElement for testing purposes that can be reset.
+ * For this, invoke the provider at path /reset with any parameter.
+ *
+ * @author espen
+ *
+ */
+public class SimpleVABProvider extends VABMapProvider {
+ private static Logger logger = LoggerFactory.getLogger(SimpleVABProvider.class);
+
+ public SimpleVABProvider() {
+ super(new SimpleVABElement());
+ }
+
+ /**
+ * Adds a "reset" operation to reset the SimpleVABElement at /reset
+ */
+ @Override
+ public Object invokeOperation(String path, Object... parameters) {
+ logger.info("Invoke path: " + path);
+ if (path == null) {
+ return super.invokeOperation(path, parameters);
+ }
+ String[] parts = VABPathTools.splitPath(path);
+ String lastElement = VABPathTools.getLastElement(path);
+ if (parts.length == 1 && lastElement.equals("reset")) {
+ super.elements = new SimpleVABElement();
+ logger.info("Reset element");
+ return null;
+ } else {
+ return super.invokeOperation(path, parameters);
+ }
+ }
+}
diff --git a/tools/cpp-enum-generator/enums/KeyElements b/tools/cpp-enum-generator/enums/KeyElements
deleted file mode 100644
index 3c16805..0000000
--- a/tools/cpp-enum-generator/enums/KeyElements
+++ /dev/null
@@ -1,26 +0,0 @@
-GlobalReference
-FragmentReference
-AccessPermissionRule
-AnnotatedRelationshipElement
-BasicEvent
-Blob
-Capability
-ConceptDictionary
-DataElement
-Entity
-Event
-File
-MultiLanguageProperty
-Operation
-Property
-Range
-ReferenceElement
-RelationshipElement
-SubmodelElement
-SubmodelElementCollection
-View
-Unknown
-Asset
-AssetAdministrationShell
-ConceptDescription
-Submodel
diff --git a/tools/cpp-enum-generator/enums_control-components/ExecutionOrder b/tools/cpp-enum-generator/enums_control-components/ExecutionOrder
new file mode 100644
index 0000000..65d9f68
--- /dev/null
+++ b/tools/cpp-enum-generator/enums_control-components/ExecutionOrder
@@ -0,0 +1,10 @@
+start
+complete
+reset
+hold
+unhold
+suspend
+unsuspend
+clear
+stop
+abort
diff --git a/tools/cpp-enum-generator/enums_control-components/ExecutionState b/tools/cpp-enum-generator/enums_control-components/ExecutionState
new file mode 100644
index 0000000..3d8ed05
--- /dev/null
+++ b/tools/cpp-enum-generator/enums_control-components/ExecutionState
@@ -0,0 +1,17 @@
+idle
+starting
+execute
+completing
+complete
+resetting
+holding
+held
+unholding
+suspending
+suspended
+unsuspending
+stopping
+stopped
+aborting
+aborted
+clearing
diff --git a/tools/cpp-enum-generator/enums/AssetKind b/tools/cpp-enum-generator/enums_submodel/AssetKind
similarity index 100%
rename from tools/cpp-enum-generator/enums/AssetKind
rename to tools/cpp-enum-generator/enums_submodel/AssetKind
diff --git a/tools/cpp-enum-generator/enums/DataTypeIEC61360 b/tools/cpp-enum-generator/enums_submodel/DataTypeIEC61360
similarity index 100%
rename from tools/cpp-enum-generator/enums/DataTypeIEC61360
rename to tools/cpp-enum-generator/enums_submodel/DataTypeIEC61360
diff --git a/tools/cpp-enum-generator/enums/EntityType b/tools/cpp-enum-generator/enums_submodel/EntityType
similarity index 100%
rename from tools/cpp-enum-generator/enums/EntityType
rename to tools/cpp-enum-generator/enums_submodel/EntityType
diff --git a/tools/cpp-enum-generator/enums/IdentifiableElements b/tools/cpp-enum-generator/enums_submodel/IdentifiableElements
similarity index 100%
rename from tools/cpp-enum-generator/enums/IdentifiableElements
rename to tools/cpp-enum-generator/enums_submodel/IdentifiableElements
diff --git a/tools/cpp-enum-generator/enums/IdentifierType b/tools/cpp-enum-generator/enums_submodel/IdentifierType
similarity index 100%
rename from tools/cpp-enum-generator/enums/IdentifierType
rename to tools/cpp-enum-generator/enums_submodel/IdentifierType
diff --git a/tools/cpp-enum-generator/enums_submodel/KeyElements b/tools/cpp-enum-generator/enums_submodel/KeyElements
new file mode 100644
index 0000000..c88a558
--- /dev/null
+++ b/tools/cpp-enum-generator/enums_submodel/KeyElements
@@ -0,0 +1,27 @@
+GlobalReference
+FragmentReference
+AccessPermissionRule
+AnnotatedRelationshipElement
+BasicEvent
+Blob
+Capability
+ConceptDictionary
+DataElement
+Entity
+Event
+File
+MultiLanguageProperty
+Operation
+OperationVariable
+Property
+Range
+ReferenceElement
+RelationshipElement
+SubmodelElement
+SubmodelElementCollection
+View
+Unknown
+Asset
+AssetAdministrationShell
+ConceptDescription
+Submodel
diff --git a/tools/cpp-enum-generator/enums/KeyType b/tools/cpp-enum-generator/enums_submodel/KeyType
similarity index 100%
rename from tools/cpp-enum-generator/enums/KeyType
rename to tools/cpp-enum-generator/enums_submodel/KeyType
diff --git a/tools/cpp-enum-generator/enums/LevelType b/tools/cpp-enum-generator/enums_submodel/LevelType
similarity index 100%
rename from tools/cpp-enum-generator/enums/LevelType
rename to tools/cpp-enum-generator/enums_submodel/LevelType
diff --git a/tools/cpp-enum-generator/enums/LocalKeyType b/tools/cpp-enum-generator/enums_submodel/LocalKeyType
similarity index 100%
rename from tools/cpp-enum-generator/enums/LocalKeyType
rename to tools/cpp-enum-generator/enums_submodel/LocalKeyType
diff --git a/tools/cpp-enum-generator/enums/ModelTypes b/tools/cpp-enum-generator/enums_submodel/ModelTypes
similarity index 100%
rename from tools/cpp-enum-generator/enums/ModelTypes
rename to tools/cpp-enum-generator/enums_submodel/ModelTypes
diff --git a/tools/cpp-enum-generator/enums/ModelingKind b/tools/cpp-enum-generator/enums_submodel/ModelingKind
similarity index 100%
rename from tools/cpp-enum-generator/enums/ModelingKind
rename to tools/cpp-enum-generator/enums_submodel/ModelingKind
diff --git a/tools/cpp-enum-generator/enums/ReferableElements b/tools/cpp-enum-generator/enums_submodel/ReferableElements
similarity index 100%
rename from tools/cpp-enum-generator/enums/ReferableElements
rename to tools/cpp-enum-generator/enums_submodel/ReferableElements
diff --git a/tools/cpp-enum-generator/generate_enums.sh b/tools/cpp-enum-generator/generate_enums.sh
old mode 100644
new mode 100755
index 45690b2..f8f76c3
--- a/tools/cpp-enum-generator/generate_enums.sh
+++ b/tools/cpp-enum-generator/generate_enums.sh
@@ -4,7 +4,7 @@
TARGET_SRC_DIR=$CPP_SDK_DIR/src/submodel/submodel/enumerations
TARGET_HEADER_DIR=$CPP_SDK_DIR/include/BaSyx/submodel/enumerations/
-ENUMS_DIR=enums
+ENUMS_DIR=enums_submodel
OUT_DIR=generated
TEMPLATE=template.txt
@@ -20,3 +20,24 @@
mv $OUT_DIR/*.cpp $TARGET_SRC_DIR
mv $OUT_DIR/*.h $TARGET_HEADER_DIR
+
+
+TARGET_SRC_DIR=$CPP_SDK_DIR/src/controlcomponent/enumerations
+TARGET_HEADER_DIR=$CPP_SDK_DIR/include/BaSyx/controlcomponent/enumerations/
+
+ENUMS_DIR=enums_control-components
+OUT_DIR=generated
+
+TEMPLATE=template_control-components.txt
+
+mkdir -p $OUT_DIR
+mkdir -p $TARGET_SRC_DIR
+mkdir -p $TARGET_HEADER_DIR
+
+for f in $ENUMS_DIR/*; do
+ python3 generator.py -t $TEMPLATE -o $OUT_DIR $f
+done
+
+
+mv $OUT_DIR/*.cpp $TARGET_SRC_DIR
+mv $OUT_DIR/*.h $TARGET_HEADER_DIR
diff --git a/tools/cpp-enum-generator/generator.py b/tools/cpp-enum-generator/generator.py
index 88b3ce9..d97d2d8 100755
--- a/tools/cpp-enum-generator/generator.py
+++ b/tools/cpp-enum-generator/generator.py
@@ -54,6 +54,7 @@
for line_template in line_templates:
line = line_template + "\n"
line = line.replace("$ENUM_CLASS$", self.enum_class)
+ line = line.replace("$ENUM_CLASS_CAP$", self.enum_class.upper())
line = line.replace("$SIZE$", str(self.size))
for constant in self.constants.keys():
line = line.replace(constant, self.constants[constant])
diff --git a/tools/cpp-enum-generator/template.txt b/tools/cpp-enum-generator/template.txt
index 016901c..359899b 100644
--- a/tools/cpp-enum-generator/template.txt
+++ b/tools/cpp-enum-generator/template.txt
@@ -3,6 +3,7 @@
; at the end of the file. i.e.: "$FILE_ENDING cpp". If $FILE_ENDING$ is not set, ".hpp" will be used.
; Other tags that can be used are:
; $ENUM_CLASS$ : Class name of enum, obtained from file name
+; $ENUM_CLASS_CAP$ : Class name of enum in uppercase
; $FIRST_ENUM$ : The first enum in the list of enums
; $MIDDLE_ENUM$ : All enums that are in between first and last enum.
; $LAST_ENUM$ : The last enum in the list of enums
@@ -11,8 +12,8 @@
;
;
$CONSTANT$ NAMESPACE submodel
-#ifndef BASYX_SUBMODEL_ENUM_$ENUM_CLASS$_H
-#define BASYX_SUBMODEL_ENUM_$ENUM_CLASS$_H
+#ifndef BASYX_SUBMODEL_ENUMERATIONS_$ENUM_CLASS_CAP$_H
+#define BASYX_SUBMODEL_ENUMERATIONS_$ENUM_CLASS_CAP$_H
#include <string>
@@ -36,7 +37,7 @@
}
}
-#endif
+#endif /* BASYX_SUBMODEL_ENUMERATIONS_$ENUM_CLASS_CAP$_H */
$FILE_ENDING$ h
#include <BaSyx/$NAMESPACE$/enumerations/$ENUM_CLASS$.h>
diff --git a/tools/cpp-enum-generator/template_control-components.txt b/tools/cpp-enum-generator/template_control-components.txt
new file mode 100644
index 0000000..ee054a9
--- /dev/null
+++ b/tools/cpp-enum-generator/template_control-components.txt
@@ -0,0 +1,80 @@
+; Comments must start with ; all other lines will be present in the corresponding file
+; Indicate a source-code file by $FILE_ENDING$-tag and the corresponding file ending
+; at the end of the file. i.e.: "$FILE_ENDING cpp". If $FILE_ENDING$ is not set, ".hpp" will be used.
+; Other tags that can be used are:
+; $ENUM_CLASS$ : Class name of enum, obtained from file name
+; $ENUM_CLASS_CAP$ : Class name of enum in uppercase
+; $FIRST_ENUM$ : The first enum in the list of enums
+; $MIDDLE_ENUM$ : All enums that are in between first and last enum.
+; $LAST_ENUM$ : The last enum in the list of enums
+; $SIZE$ : The number of enums
+; $CONSTANT$ : Define a costant, i.e.: $CONSTSANT$ NAME value, usage in document with $NAME$
+;
+;
+$CONSTANT$ NAMESPACE controlcomponent
+#ifndef BASYX_CONTROLCOMPONENT_ENUM_$ENUM_CLASS_CAP$_H
+#define BASYX_CONTROLCOMPONENT_ENUM_$ENUM_CLASS_CAP$_H
+
+#include <string>
+
+namespace basyx {
+namespace $NAMESPACE$ {
+
+enum class $ENUM_CLASS$ {
+ $FIRST_ENUM$,
+ $MIDDLE_ENUM$,
+ $LAST_ENUM$,
+};
+
+class $ENUM_CLASS$_
+{
+public:
+ static $ENUM_CLASS$ from_string(const std::string & name);
+ static const char * to_string($ENUM_CLASS$ value);
+};
+
+
+}
+}
+
+#endif
+$FILE_ENDING$ h
+#include <BaSyx/$NAMESPACE$/enumerations/$ENUM_CLASS$.h>
+
+#include <array>
+#include <algorithm>
+#include <memory>
+#include <string>
+
+using namespace basyx::controlcomponent;
+
+using enum_pair_t = std::pair<const char*, $ENUM_CLASS$>;
+
+static const std::array<enum_pair_t, $SIZE$> string_to_enum =
+{
+ std::make_pair("$FIRST_ENUM$", $ENUM_CLASS$::$FIRST_ENUM$),
+ std::make_pair("$MIDDLE_ENUM$", $ENUM_CLASS$::$MIDDLE_ENUM$),
+ std::make_pair("$LAST_ENUM$", $ENUM_CLASS$::$LAST_ENUM$),
+};
+
+$ENUM_CLASS$ $ENUM_CLASS$_::from_string(const std::string & name)
+{
+ auto pair = std::find_if(string_to_enum.begin(), string_to_enum.end(),
+ [&name](const enum_pair_t & pair) {
+ return !name.compare(pair.first);
+ });
+
+ return pair->second;
+}
+
+const char * $ENUM_CLASS$_::to_string($ENUM_CLASS$ value)
+{
+ auto pair = std::find_if(string_to_enum.begin(), string_to_enum.end(),
+ [value](const enum_pair_t & pair) {
+ return value == pair.second;
+ });
+
+ return pair->first;
+}
+
+$FILE_ENDING$ cpp