Merging changes from 'master' branch into 'cpp' branch
Change-Id: I5ad63ef3cd9e437afd8036e7f61ffb6c929cc6cb
Signed-off-by: Thomas Psota <thomas.psota@iese.fraunhofer.de>
diff --git a/.gitignore b/.gitignore
index b2e90d3..2124e28 100644
--- a/.gitignore
+++ b/.gitignore
@@ -58,3 +58,4 @@
/.vs
/sdks/dotnet/.vs/BaSyx
launchSettings.json
+.project
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/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.mongodbregistry/docker-compose.yml b/components/basys.components/basyx.components.docker/basyx.components.AASServer/docker-compose.yml
similarity index 97%
rename from components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/docker-compose.yml
rename to components/basys.components/basyx.components.docker/basyx.components.AASServer/docker-compose.yml
index 8daf8d6..b55d107 100644
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/docker-compose.yml
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/docker-compose.yml
@@ -1,6 +1,7 @@
version: '2.1'
services:
- registry:
+
+ aas:
image: ${BASYX_IMAGE_NAME}:${BASYX_IMAGE_TAG}
container_name: ${BASYX_CONTAINER_NAME}
ports:
@@ -14,12 +15,12 @@
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
+ 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..88e4939 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>0.1.0-SNAPSHOT</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,29 @@
</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>
+ </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..68979fa
--- /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,276 @@
+package org.eclipse.basyx.components.aas;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+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.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.IAASRegistryService;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+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.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.xml.XMLAASBundleFactory;
+import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.support.bundle.AASBundle;
+import org.eclipse.basyx.support.bundle.AASBundleDescriptorFactory;
+import org.eclipse.basyx.support.bundle.AASBundleIntegrator;
+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}/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 AASHTTPServer server;
+ private IAASRegistryService registry;
+
+ // Configurations
+ private BaSyxContextConfiguration contextConfig;
+ private BaSyxAASServerConfiguration aasConfig;
+ private BaSyxMongoDBConfiguration mongoDBConfig;
+
+ // 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;
+ }
+
+ public void setRegistry(IAASRegistryService 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
+ 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("/aasx/*", new DefaultServlet());
+
+ // 2. Fix the file paths according to the servlet configuration
+ modifyFilePaths(contextConfig.getHostname(), contextConfig.getPort(), contextConfig.getContextPath());
+
+ // 3. Create registry & register the initial AAS
+ createRegistryFromUrl();
+ registerAAS();
+ }
+
+ logger.info("Start the server");
+ server = new AASHTTPServer(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() {
+ server.shutdown();
+ }
+
+ private void loadBundleFromXML(String xmlPath) throws IOException, ParserConfigurationException, SAXException {
+ logger.info("Loading aas from xml \"" + xmlPath + "\"");
+ String xmlContent = BaSyxConfiguration.getResourceString(xmlPath);
+ this.aasBundles = new XMLAASBundleFactory(xmlContent).create();
+ }
+
+ private void loadBundleFromAASX(String aasxPath)
+ throws IOException, ParserConfigurationException, SAXException, URISyntaxException {
+ 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(aasxPath);
+
+ // 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) {
+ AASBundleIntegrator.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(".xml")) {
+ loadBundleFromXML(aasSource);
+ }
+ } catch (IOException | ParserConfigurationException | SAXException | URISyntaxException e) {
+ logger.error("Could not load initial AAS from source " + aasSource);
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 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) {
+ 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 ) {
+ logger.info("Using InMemory backend");
+ aggregator = new AASAggregator(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.AASX/src/main/java/org/eclipse/basyx/components/aasx/AASXPackageManager.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/aasx/AASXPackageManager.java
similarity index 93%
rename from components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/java/org/eclipse/basyx/components/aasx/AASXPackageManager.java
rename to components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/aasx/AASXPackageManager.java
index 485b391..7cfba6f 100644
--- 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.AASServer/src/main/java/org/eclipse/basyx/components/aas/aasx/AASXPackageManager.java
@@ -1,6 +1,7 @@
-package org.eclipse.basyx.components.aasx;
+package org.eclipse.basyx.components.aas.aasx;
import java.io.File;
+import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -185,13 +186,13 @@
private String getXMLResourceString(String filePath) throws IOException, ParserConfigurationException, SAXException {
String aasXmlPath;
// Create the zip input stream
- try (ZipInputStream stream = new ZipInputStream(BaSyxConfiguration.getResourceStream(filePath))) {
+ try (ZipInputStream stream = getZipInputStream(filePath)) {
// find the path of the aas xml
aasXmlPath = this.findAASXml(stream);
}
- try (ZipInputStream stream = new ZipInputStream(BaSyxConfiguration.getResourceStream(filePath))) {
+ try (ZipInputStream stream = getZipInputStream(filePath)) {
// Find the entry of the aas xml
ZipInputStream streamPointingToEntry = this.returnFileEntryStream(aasXmlPath, stream);
@@ -215,12 +216,12 @@
throws IOException, ParserConfigurationException, SAXException {
String xmlPath;
logger.info("AASX filepath: " + aasxFilePath);
- try (ZipInputStream stream = new ZipInputStream(BaSyxConfiguration.getResourceStream(aasxFilePath))) {
+ try (ZipInputStream stream = getZipInputStream(aasxFilePath)) {
// find the aasx xml file
xmlPath = this.findAASXml(stream);
}
- try (ZipInputStream stream = new ZipInputStream(BaSyxConfiguration.getResourceStream(aasxFilePath))) {
+ try (ZipInputStream stream = getZipInputStream(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";
@@ -291,7 +292,7 @@
byte[] buffer = new byte[1024];
// Find the file with the "filePath"
- try (ZipInputStream stream = new ZipInputStream(BaSyxConfiguration.getResourceStream(aasxPath))) {
+ try (ZipInputStream stream = getZipInputStream(aasxPath)) {
ZipEntry zipEntry = stream.getNextEntry();
while (zipEntry != null) {
if (!zipEntry.isDirectory() && zipEntry.getName().contains(filePath)) {
@@ -373,4 +374,13 @@
}
return files;
}
+
+ private ZipInputStream getZipInputStream(String aasxFilePath) throws IOException {
+ try {
+ return new ZipInputStream(BaSyxConfiguration.getResourceStream(aasxFilePath));
+ } catch (NullPointerException ex) {
+ // Alternativ, if resource has not been found: load from a file
+ return new ZipInputStream(new FileInputStream(aasxFilePath));
+ }
+ }
}
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..df341ca
--- /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,82 @@
+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/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..cfbddbc
--- /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,52 @@
+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..f0a29ca
--- /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,93 @@
+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 {
+ // 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 = "";
+
+ // Configuration keys
+ public static final String REGISTRY = "registry.path";
+ public static final String BACKEND = "aas.backend";
+ public static final String SOURCE = "aas.source";
+
+ // 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);
+ return defaultProps;
+ }
+
+ /**
+ * Empty Constructor - use default values
+ */
+ public BaSyxAASServerConfiguration() {
+ super(getDefaultProperties());
+ }
+
+ /**
+ * Constructor with initial configuration - docBasePath and hostname are default values
+ *
+ * @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 predefined value map
+ */
+ public BaSyxAASServerConfiguration(Map<String, String> values) {
+ super(values);
+ }
+
+ public void loadFromDefaultSource() {
+ loadFileOrDefaultResource(DEFAULT_FILE_KEY, DEFAULT_CONFIG_PATH);
+ }
+
+ public AASServerBackend getAASBackend() {
+ return AASServerBackend.fromString(getProperty(BACKEND));
+ }
+
+ public void setAASBackend(AASServerBackend backend) {
+ setProperty(BACKEND, backend.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..cd3a3e9
--- /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,47 @@
+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.BaSyxAASServerConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+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);
+ 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..99ae7c4
--- /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,155 @@
+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);
+ }
+
+ @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);
+ }
+
+}
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..5c37004
--- /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,240 @@
+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.IAASRegistryService;
+import org.eclipse.basyx.aas.restapi.AASModelProvider;
+import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
+import org.eclipse.basyx.aas.restapi.api.IAASAPI;
+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.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+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, VABMultiSubmodelProvider> aasProviderMap = new HashMap<>();
+ protected BaSyxMongoDBConfiguration config;
+ protected MongoOperations mongoOps;
+ protected String aasCollection;
+ protected String smCollection;
+
+ private IAASRegistryService registry;
+
+ /**
+ * 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(IAASRegistryService 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) {
+ this.config = config;
+ MongoClient client = MongoClients.create(config.getConnectionUrl());
+ this.mongoOps = new MongoTemplate(client, config.getDatabase());
+ this.aasCollection = config.getAASCollection();
+ this.smCollection = config.getSubmodelCollection();
+ }
+
+ /**
+ * 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) {
+ logger.info("Adding AAS from DB: " + aas.getIdentification().getId());
+ VABMultiSubmodelProvider provider = createMultiSubmodelProvider(aas);
+ aasProviderMap.put(aas.getIdentification().getId(), provider);
+ }
+ }
+
+ private VABMultiSubmodelProvider createMultiSubmodelProvider(AssetAdministrationShell aas) {
+ IAASAPI aasApi = new MongoDBAASAPI(config, aas.getIdentification().getId());
+ AASModelProvider aasProvider = new AASModelProvider(aasApi);
+ VABMultiSubmodelProvider provider = new VABMultiSubmodelProvider(aasProvider, registry, new HTTPConnectorProvider());
+
+ // 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);
+ }
+
+ return 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, VABMultiSubmodelProvider 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.getModelPropertyValue("/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.getModelPropertyValue("/aas");
+ return AssetAdministrationShell.createAsFacade(aasMap);
+ }
+
+ @Override
+ public void createAAS(AssetAdministrationShell aas) {
+ MongoDBAASAPI aasApi = new MongoDBAASAPI(config, aas.getIdentification().getId());
+ aasApi.setAAS(aas);
+ AASModelProvider provider = new AASModelProvider(aasApi);
+ aasProviderMap.put(aas.getIdentification().getId(), new VABMultiSubmodelProvider(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 VABMultiSubmodelProvider getProviderForAASId(String aasId) {
+ return aasProviderMap.get(aasId);
+ }
+
+ @Override
+ public IModelProvider getAASProvider(IIdentifier aasId) {
+ VABMultiSubmodelProvider 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..2211d42
--- /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,360 @@
+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.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.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);
+ }
+
+ @Override
+ public ISubmodelElement getSubmodelElement(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.getModelPropertyValue("");
+ return SubmodelElement.createAsFacade((Map<String, Object>) elementVABObj);
+ }
+
+ @Override
+ public void deleteSubmodelElement(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();
+ }
+
+
+ @Override
+ public void addSubmodelElement(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();
+ }
+
+ @Override
+ public void updateSubmodelElement(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).setModelPropertyValue(Property.VALUE, newValue);
+ // Replace db entry
+ Query hasId = query(where(SMIDPATH).is(smId));
+ mongoOps.findAndReplace(hasId, sm, collection);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public 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.setModelPropertyValue(Property.VALUE, newValue);
+
+ // Replace db entry
+ Query hasId = query(where(SMIDPATH).is(smId));
+ mongoOps.findAndReplace(hasId, sm, collection);
+ }
+
+ @Override
+ public Object getSubmodelElementValue(String idShort) {
+ SubModel sm = (SubModel) getSubmodel();
+ return getElementProvider(sm, idShort).getModelPropertyValue("/value");
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Object getNestedSubmodelElementValue(List<String> idShorts) {
+ ISubmodelElement lastElement = getNestedSubmodelElement(idShorts);
+ IModelProvider mapProvider = new VABMapProvider((Map<String, Object>) lastElement);
+ return SubmodelElementProvider.getElementProvider(mapProvider).getModelPropertyValue("/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);
+ }
+
+ @Override
+ public 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));
+ }
+
+ @Override
+ public Object invokeOperation(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");
+ }
+
+ @Override
+ public 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);
+ }
+
+ @Override
+ public 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");
+ }
+
+ @Override
+ public 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(List<String> idShorts, 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");
+ }
+}
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..e5b82cc
--- /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,25 @@
+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..82a0083
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/aas.properties
@@ -0,0 +1,5 @@
+aas.backend=InMemory
+aas.source=
+# Example for loading an .aasx file and registering the AAS:
+#registry.path=http://localhost:4000/registry/
+#aas.source=aasx/01_Festo.aasx
\ 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..bd80d1d 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,3 @@
contextPath=/aasServer
contextHostname=localhost
-contextPort=4000
\ No newline at end of file
+contextPort=4001
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/test/resources/localMongodb.properties b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/mongodb.properties
similarity index 73%
copy from components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/test/resources/localMongodb.properties
copy to components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/mongodb.properties
index e4c65b6..30acebe 100644
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/test/resources/localMongodb.properties
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/mongodb.properties
@@ -9,4 +9,6 @@
dbuser = admin
dbname = admin
dbconnectionstring = mongodb://localhost:27017/
-dbcollection = registry
\ No newline at end of file
+dbcollectionRegistry = registry
+dbcollectionAAS = assetadministrationshells
+dbcollectionSubmodels = submodels
\ 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.AASServer/src/main/resources/xml/aas.xml
similarity index 99%
rename from components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/resources/xml/aas.xml
rename to components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/xml/aas.xml
index 04a32c8..c84ba35 100644
--- 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.AASServer/src/main/resources/xml/aas.xml
@@ -252,7 +252,7 @@
</aas:valueId>
<aas:value>qualifierValue</aas:value>
<aas:type>qualifierType</aas:type>
- <aas:valueType>valueType</aas:valueType>
+ <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>
@@ -306,7 +306,7 @@
</aas:valueId>
<aas:value>qualifierValue</aas:value>
<aas:type>qualifierType</aas:type>
- <aas:valueType>valueType</aas:valueType>
+ <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>
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/AASServerSuite.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/AASServerSuite.java
similarity index 93%
rename from components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/basyx/components/AASServer/AASServerSuite.java
rename to components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/AASServerSuite.java
index 10e3826..cf485e6 100644
--- 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/eclipse/basyx/regression/AASServer/AASServerSuite.java
@@ -1,4 +1,4 @@
-package org.basyx.components.AASServer;
+package org.eclipse.basyx.regression.AASServer;
import static org.junit.Assert.assertEquals;
@@ -18,7 +18,7 @@
* 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
+ * @author espen
*
*/
public abstract class AASServerSuite {
@@ -45,8 +45,7 @@
IIdentifier identifier = new ModelUrn(aasId);
shell.setIdentification(identifier);
shell.setIdShort("aasIdShort");
-
- manager.createAAS(shell, identifier, getURL());
+ 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.AASX/src/test/java/org/eclipse/basyx/regression/aasx/AASXSuite.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/AASXSuite.java
similarity index 81%
rename from components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/java/org/eclipse/basyx/regression/aasx/AASXSuite.java
rename to components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/AASXSuite.java
index bd2c82e..d04a7cc 100644
--- 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.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/AASXSuite.java
@@ -1,6 +1,7 @@
-package org.eclipse.basyx.regression.aasx;
+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;
@@ -10,7 +11,6 @@
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;
@@ -21,7 +21,6 @@
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;
@@ -41,14 +40,14 @@
* @author schnicke, espen
*
*/
-public class AASXSuite {
+public abstract 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 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
@@ -93,13 +92,15 @@
@Test
public void testGetSingleModule() throws Exception {
- checkFile("aasx/Nameplate/marking_rcm.jpg");
+ final String FILE_ENDING = "aasx/Nameplate/marking_rcm.jpg";
+ final String FILE_PATH = rootEndpoint + "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();
+ Collection<ISubmodelElement> values = marking_rcm.getValue().values();
// navigate to the File element
Iterator<ISubmodelElement> iter = values.iterator();
@@ -110,7 +111,7 @@
// get value of the file element
String fileurl = connectedFile.getValue();
- assertEquals("http://localhost:4000/aasx/docs/marking_rcm.jpg", fileurl);
+ assertTrue(fileurl.endsWith(FILE_ENDING));
}
}
}
@@ -124,6 +125,13 @@
Map<String, ISubModel> submodels = aas.getSubModels();
logger.info("# Submodels: " + submodels.size());
for (ISubModel sm : submodels.values()) {
+ // FIXME: In Identification, there's a file referenced that is not contained in aasx folder.
+ // Since the current code only works with files in /aasx folder, this will create an error for now
+ // Remove this after this issue is fixed!
+ if (sm.getIdShort().equals("Identification")) {
+ continue;
+ }
+
logger.info("Checking submodel: " + sm.getIdShort());
checkElementCollectionFiles(sm.getSubmodelElements().values());
}
@@ -137,21 +145,20 @@
checkFile(fileUrl);
} else if (element instanceof ISubmodelElementCollection) {
ISubmodelElementCollection col = (ISubmodelElementCollection) element;
- checkElementCollectionFiles(col.getValue());
+ checkElementCollectionFiles(col.getSubmodelElements().values());
}
}
}
- private void checkFile(String relativePath) {
+ private void checkFile(String absolutePath) {
// 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);
+ WebTarget webTarget = client.target(absolutePath);
+ logger.info("Checking file: " + absolutePath);
+ Invocation.Builder invocationBuilder = webTarget.request();
Response response = invocationBuilder.get();
+
// validate the response
- assertEquals(200, response.getStatus());
+ assertEquals("Path check failed: " + absolutePath, 200, response.getStatus());
}
/**
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..f1ad39f
--- /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,33 @@
+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..c52f530
--- /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,60 @@
+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.AASX/src/test/java/org/eclipse/basyx/regression/aasx/TestAASXPackageManager.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestAASXPackageManager.java
similarity index 93%
rename from components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/java/org/eclipse/basyx/regression/aasx/TestAASXPackageManager.java
rename to components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestAASXPackageManager.java
index 89225de..e96614b 100644
--- 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.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestAASXPackageManager.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.regression.aasx;
+package org.eclipse.basyx.regression.AASServer;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -6,7 +6,6 @@
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;
@@ -15,7 +14,7 @@
import javax.xml.parsers.ParserConfigurationException;
import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
-import org.eclipse.basyx.components.aasx.AASXPackageManager;
+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.reference.IKey;
@@ -23,6 +22,7 @@
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.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDef;
import org.eclipse.basyx.support.bundle.AASBundle;
import org.junit.Before;
import org.junit.Test;
@@ -202,7 +202,7 @@
assertTrue(sele.getModelingKind().name().equalsIgnoreCase("Instance"));
Property prop = (Property) sele;
assertEquals("Festo AG & Co. KG", prop.get());
- assertEquals("string", prop.getValueType());
+ assertEquals(PropertyValueTypeDef.String, prop.getValueType());
// get semantic id
IReference semantic = sele.getSemanticId();
@@ -222,7 +222,7 @@
assertTrue(sele.getModelingKind().name().equalsIgnoreCase("Instance"));
prop = (Property) sele;
assertEquals("OVEL Vacuum generator", prop.get());
- assertEquals("string", prop.getValueType());
+ assertEquals(PropertyValueTypeDef.String, prop.getValueType());
// get semantic id
semantic = sele.getSemanticId();
@@ -251,15 +251,14 @@
// get values
assertTrue(sele.getModelType().equalsIgnoreCase("SubmodelElementCollection"));
SubmodelElementCollection collection = (SubmodelElementCollection) sele;
- Collection<ISubmodelElement> subelements = collection.getValue();
+ Map<String, ISubmodelElement> smElemMap = collection.getSubmodelElements();
- assertEquals(5, subelements.size());
- Iterator<ISubmodelElement> iterator = subelements.iterator();
- Property prop1 = (Property) (iterator.next());
+ assertEquals(5, smElemMap.size());
+ Property prop1 = (Property) smElemMap.get("CountryCode");
assertEquals("CountryCode", prop1.getIdShort());
assertEquals("DE", prop1.get());
- Property prop2 = (Property) (iterator.next());
+ Property prop2 = (Property) smElemMap.get("Street");
assertEquals("Street", prop2.getIdShort());
assertEquals("Ruiter Straße 82", prop2.get());
}
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..1d0f91e
--- /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,86 @@
+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.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.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();
+ submodel.setIdShort("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/basyx/components/AASServer/TestAASServer.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestInMemoryAASServer.java
similarity index 65%
rename from components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/basyx/components/AASServer/TestAASServer.java
rename to components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestInMemoryAASServer.java
index 758237e..4842f86 100644
--- 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/eclipse/basyx/regression/AASServer/TestInMemoryAASServer.java
@@ -1,10 +1,12 @@
-package org.basyx.components.AASServer;
+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;
@@ -14,13 +16,13 @@
* @author schnicke
*
*/
-public class TestAASServer extends AASServerSuite {
+public class TestInMemoryAASServer extends AASServerSuite {
private static AASServerComponent component;
@Override
protected String getURL() {
- return component.getURL();
+ return component.getURL() + "/shells";
}
@BeforeClass
@@ -28,7 +30,12 @@
BaSyxContextConfiguration config = new BaSyxContextConfiguration();
config.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
- component = new AASServerComponent(config.getHostname(), config.getPort(), config.getContextPath(), config.getDocBasePath());
+ 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/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..3350a9d
--- /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,17 @@
+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..f82fcd7
--- /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,52 @@
+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.aas.configuration.AASServerBackend;
+import org.eclipse.basyx.components.aas.configuration.BaSyxAASServerConfiguration;
+import org.eclipse.basyx.components.aas.mongodb.MongoDBAASAggregator;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxMongoDBConfiguration;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.xml.sax.SAXException;
+
+/**
+ * Tests the component using the test suite
+ *
+ * @author espen
+ *
+ */
+public class TestMongoDBServer extends AASServerSuite {
+
+ private static AASServerComponent component;
+
+ @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);
+ BaSyxMongoDBConfiguration mongoDBConfig = new BaSyxMongoDBConfiguration();
+ BaSyxAASServerConfiguration aasConfig = new BaSyxAASServerConfiguration(AASServerBackend.MONGODB, "");
+
+ // Start component
+ component = new AASServerComponent(contextConfig, aasConfig, mongoDBConfig);
+ 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/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..9326fb9
--- /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,114 @@
+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.ConnectorProvider;
+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 ConnectorProvider() {
+ @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
+ .getModelPropertyValue("/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..e6da6c3
--- /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,112 @@
+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.IAASRegistryService;
+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.IConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+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 IAASRegistryService 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
+ IConnectorProvider connectorProvider = new HTTPConnectorProvider();
+ manager = new ConnectedAssetAdministrationShellManager(registry, connectorProvider);
+ }
+
+
+ @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..077762c
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/resources/.env
@@ -0,0 +1,5 @@
+BASYX_HOST_PORT=8082
+BASYX_CONTAINER_PORT=4001
+BASYX_IMAGE_NAME=basys/aas-server
+BASYX_CONTAINER_NAME=aas
+BASYX_IMAGE_TAG=0.1.0-SNAPSHOT
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/resources/dockerMongodb.properties b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/resources/dockerMongodb.properties
similarity index 73%
copy from components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/resources/dockerMongodb.properties
copy to components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/resources/dockerMongodb.properties
index 5fc816a..f91b7d4 100644
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/resources/dockerMongodb.properties
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/resources/dockerMongodb.properties
@@ -9,4 +9,6 @@
dbuser = admin
dbname = admin
dbconnectionstring = mongodb://mongodb:27017/
-dbcollection = registry
\ No newline at end of file
+dbcollectionRegistry = registry
+dbcollectionAAS = assetadministrationshells
+dbcollectionSubmodels = submodels
\ No newline at end of file
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/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/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/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.mongodbregistry/Dockerfile b/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/Dockerfile
deleted file mode 100644
index 3628774..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/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.mongodbregistry/src/main/java/org/eclipse/basyx/components/MongoDBRegistryComponent.java b/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/java/org/eclipse/basyx/components/MongoDBRegistryComponent.java
deleted file mode 100644
index 4b62cf2..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/java/org/eclipse/basyx/components/MongoDBRegistryComponent.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package org.eclipse.basyx.components;
-
-import org.eclipse.basyx.components.mongodbregistry.BaSyxMongoDBConfiguration;
-import org.eclipse.basyx.components.servlet.MongoDBRegistryServlet;
-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 a MongoDB database.
- *
- * @author espen
- */
-public class MongoDBRegistryComponent {
- private static Logger logger = LoggerFactory.getLogger(MongoDBRegistryComponent.class);
-
- // BaSyx context information
- private String hostName;
- private int port;
- private String path;
- private String docBasePath;
- private BaSyxMongoDBConfiguration config;
-
- // The server with the servlet that will be created
- private AASHTTPServer server;
-
- public MongoDBRegistryComponent(String hostName, int port, String path, String docBasePath, String dbPropertyPath) {
- // Load configuration
- this.config = new BaSyxMongoDBConfiguration();
- this.config.loadFromResource(dbPropertyPath);
- // Sets the server context
- this.hostName = hostName;
- this.port = port;
- this.path = path;
- this.docBasePath = docBasePath;
- }
-
- public MongoDBRegistryComponent(String hostName, int port, String path, String docBasePath,
- BaSyxMongoDBConfiguration dbConfig) {
- this.config = dbConfig;
- // 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 MongoDBRegistryServlet(config));
- server = new AASHTTPServer(context);
-
- logger.info("Start the server...");
- server.start();
- }
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/java/org/eclipse/basyx/components/executable/MongoDBRegistryExecutable.java b/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/java/org/eclipse/basyx/components/executable/MongoDBRegistryExecutable.java
deleted file mode 100644
index cbdd94e..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/java/org/eclipse/basyx/components/executable/MongoDBRegistryExecutable.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package org.eclipse.basyx.components.executable;
-
-import org.eclipse.basyx.components.MongoDBRegistryComponent;
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.eclipse.basyx.components.mongodbregistry.BaSyxMongoDBConfiguration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A registry servlet based on a MongoDB database. The servlet therefore provides an implementation
- * for the IAASRegistryService interface with a permanent storage solution. The properties for the
- * MongoDB connection will be read from executables.properties in the resource folder.
- *
- * @author espen
- */
-public class MongoDBRegistryExecutable {
- private static Logger logger = LoggerFactory.getLogger(MongoDBRegistryExecutable.class);
-
- private MongoDBRegistryExecutable() {
- }
-
- 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);
- }
-
- MongoDBRegistryComponent component;
- BaSyxMongoDBConfiguration dbConfig = new BaSyxMongoDBConfiguration();
- if (args.length > 1 && args[1] instanceof String) {
- // file path available? => load mongodb configs from file
- dbConfig.loadFromFile(args[1]);
- component = new MongoDBRegistryComponent(config.getHostname(), config.getPort(), config.getContextPath(),
- config.getDocBasePath(), dbConfig);
- } else {
- component = new MongoDBRegistryComponent(config.getHostname(), config.getPort(), config.getContextPath(),
- config.getDocBasePath(), "dockerMongodb.properties");
- }
-
- component.startComponent();
- }
-}
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/java/org/eclipse/basyx/components/mongodbregistry/BaSyxMongoDBConfiguration.java b/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/java/org/eclipse/basyx/components/mongodbregistry/BaSyxMongoDBConfiguration.java
deleted file mode 100644
index 278ff22..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/java/org/eclipse/basyx/components/mongodbregistry/BaSyxMongoDBConfiguration.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package org.eclipse.basyx.components.mongodbregistry;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.basyx.components.configuration.BaSyxConfiguration;
-
-/**
- * Represents a BaSyx configuration for a MongoDB connection.
- *
- * @author espen
- *
- */
-public class BaSyxMongoDBConfiguration extends BaSyxConfiguration {
- // Default BaSyx SQL configuration
- private static final String DEFAULT_USER = "admin";
- private static final String DEFAULT_CONNECTIONURL = "mongodb://127.0.0.1:27017/";
- private static final String DEFAULT_DATABASE = "admin";
- private static final String DEFAULT_COLLECTION = "basyx";
-
- private static final String USER = "dbuser";
- private static final String DATABASE = "dbname";
- private static final String CONNECTIONURL = "dbconnectionstring";
- private static final String COLLECTION = "dbcollection";
-
- // The default path for the context properties file
- public static final String DEFAULT_CONFIG_PATH = "mongodb.properties";
-
- public static Map<String, String> getDefaultProperties() {
- Map<String, String> defaultProps = new HashMap<>();
- defaultProps.put(USER, DEFAULT_USER);
- defaultProps.put(CONNECTIONURL, DEFAULT_CONNECTIONURL);
- defaultProps.put(DATABASE, DEFAULT_DATABASE);
- defaultProps.put(COLLECTION, DEFAULT_COLLECTION);
-
- return defaultProps;
- }
-
- public BaSyxMongoDBConfiguration(Map<String, String> values) {
- super(values);
- }
-
- public BaSyxMongoDBConfiguration() {
- super(getDefaultProperties());
- }
-
- public String getUser() {
- return getProperty(USER);
- }
-
- public String getDatabase() {
- return getProperty(DATABASE);
- }
-
- public String getConnectionUrl() {
- return getProperty(CONNECTIONURL);
- }
-
- public String getCollection() {
- return getProperty(COLLECTION);
- }
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/resources/logback.xml b/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/resources/logback.xml
deleted file mode 100644
index 86341d6..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/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.mongodbregistry/src/test/resources/.env b/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/test/resources/.env
deleted file mode 100644
index aafb522..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/test/resources/.env
+++ /dev/null
@@ -1,5 +0,0 @@
-BASYX_HOST_PORT=8082
-BASYX_CONTAINER_PORT=4000
-BASYX_IMAGE_NAME=basys/registry-mongodb
-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.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.mongodbregistry/pom.xml b/components/basys.components/basyx.components.docker/basyx.components.registry/pom.xml
similarity index 90%
rename from components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/pom.xml
rename to components/basys.components/basyx.components.docker/basyx.components.registry/pom.xml
index 2f97491..656cc93 100644
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/pom.xml
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/pom.xml
@@ -6,14 +6,14 @@
<parent>
<groupId>org.eclipse.basyx</groupId>
<artifactId>basyx.components.docker</artifactId>
- <version>0.0.1-SNAPSHOT</version>
+ <version>0.1.0-SNAPSHOT</version>
</parent>
- <artifactId>basyx.components.mongodbregistry</artifactId>
- <name>BaSyx MongoDB Registry</name>
+ <artifactId>basyx.components.registry</artifactId>
+ <name>BaSyx Registry</name>
<properties>
- <basyx.components.executable>org.eclipse.basyx.components.executable.MongoDBRegistryExecutable</basyx.components.executable>
+ <basyx.components.executable>org.eclipse.basyx.components.registry.executable.RegistryExecutable</basyx.components.executable>
</properties>
<packaging>jar</packaging>
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..f939dc5
--- /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,181 @@
+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.AASHTTPServer;
+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 AASHTTPServer 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 AASHTTPServer(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..1805538
--- /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,58 @@
+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 {
+ // 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 loadFromDefaultSource() {
+ loadFileOrDefaultResource(DEFAULT_FILE_KEY, DEFAULT_CONFIG_PATH);
+ }
+
+ 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..c0850c0
--- /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,53 @@
+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..0143dda
--- /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,29 @@
+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();
+ }
+}
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/java/org/eclipse/basyx/components/mongodbregistry/MongoDBRegistryHandler.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/mongodb/MongoDBRegistryHandler.java
similarity index 94%
rename from components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/java/org/eclipse/basyx/components/mongodbregistry/MongoDBRegistryHandler.java
rename to components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/mongodb/MongoDBRegistryHandler.java
index 3d1830a..50357db 100644
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/java/org/eclipse/basyx/components/mongodbregistry/MongoDBRegistryHandler.java
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/mongodb/MongoDBRegistryHandler.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.mongodbregistry;
+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;
@@ -7,6 +7,7 @@
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;
@@ -61,7 +62,7 @@
this.config = config;
MongoClient client = MongoClients.create(config.getConnectionUrl());
this.mongoOps = new MongoTemplate(client, config.getDatabase());
- this.collection = config.getCollection();
+ this.collection = config.getRegistryCollection();
}
@Override
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.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/InMemoryRegistryServlet.java
similarity index 93%
rename from components/basys.components/basyx.components.docker/basyx.components.simple/src/main/java/org/eclipse/basyx/components/servlets/InMemoryRegistryServlet.java
rename to components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/InMemoryRegistryServlet.java
index 933577b..493d5c1 100644
--- 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.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/InMemoryRegistryServlet.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.servlets;
+package org.eclipse.basyx.components.registry.servlet;
import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
import org.eclipse.basyx.aas.registration.restapi.DirectoryModelProvider;
diff --git a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/java/org/eclipse/basyx/components/servlet/MongoDBRegistryServlet.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/MongoDBRegistryServlet.java
similarity index 81%
rename from components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/java/org/eclipse/basyx/components/servlet/MongoDBRegistryServlet.java
rename to components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/MongoDBRegistryServlet.java
index 838c533..21d5291 100644
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/java/org/eclipse/basyx/components/servlet/MongoDBRegistryServlet.java
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/MongoDBRegistryServlet.java
@@ -1,9 +1,9 @@
-package org.eclipse.basyx.components.servlet;
+package org.eclipse.basyx.components.registry.servlet;
import org.eclipse.basyx.aas.registration.memory.AASRegistry;
import org.eclipse.basyx.aas.registration.restapi.DirectoryModelProvider;
-import org.eclipse.basyx.components.mongodbregistry.BaSyxMongoDBConfiguration;
-import org.eclipse.basyx.components.mongodbregistry.MongoDBRegistryHandler;
+import org.eclipse.basyx.components.configuration.BaSyxMongoDBConfiguration;
+import org.eclipse.basyx.components.registry.mongodb.MongoDBRegistryHandler;
import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
/**
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.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/SQLRegistryServlet.java
similarity index 69%
rename from components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/servlet/SQLRegistryServlet.java
rename to components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/SQLRegistryServlet.java
index ff69ac7..37e011f 100644
--- 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.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/SQLRegistryServlet.java
@@ -1,7 +1,8 @@
-package org.eclipse.basyx.components.servlet;
+package org.eclipse.basyx.components.registry.servlet;
import org.eclipse.basyx.aas.registration.restapi.DirectoryModelProvider;
-import org.eclipse.basyx.components.sqlregistry.SQLRegistry;
+import org.eclipse.basyx.components.configuration.BaSyxSQLConfiguration;
+import org.eclipse.basyx.components.registry.sql.SQLRegistry;
import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
/**
@@ -21,7 +22,7 @@
super(new DirectoryModelProvider(new SQLRegistry()));
}
- public SQLRegistryServlet(String customConfigFilePath) {
- super(new DirectoryModelProvider(new SQLRegistry(customConfigFilePath)));
+ public SQLRegistryServlet(BaSyxSQLConfiguration sqlConfig) {
+ super(new DirectoryModelProvider(new SQLRegistry(sqlConfig)));
}
}
\ 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.registry/src/main/java/org/eclipse/basyx/components/registry/sql/AASDescriptorMap.java
similarity index 97%
rename from components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/sqlregistry/AASDescriptorMap.java
rename to components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/sql/AASDescriptorMap.java
index d754f4c..5337ec8 100644
--- 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.registry/src/main/java/org/eclipse/basyx/components/registry/sql/AASDescriptorMap.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.sqlregistry;
+package org.eclipse.basyx.components.registry.sql;
import java.util.Collection;
import java.util.Map;
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.registry/src/main/java/org/eclipse/basyx/components/registry/sql/SQLRegistry.java
similarity index 71%
rename from components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/sqlregistry/SQLRegistry.java
rename to components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/sql/SQLRegistry.java
index 7effeeb..cbb16af 100644
--- 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.registry/src/main/java/org/eclipse/basyx/components/registry/sql/SQLRegistry.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.sqlregistry;
+package org.eclipse.basyx.components.registry.sql;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -18,22 +18,11 @@
*
*/
public class SQLRegistry extends AASRegistry {
- 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 MapRegistryHandler(new AASDescriptorMap(createRootMap(configFilePath))));
- }
-
- /**
- * Constructor using default sql connections
+ * Constructor using default sql connection
*/
public SQLRegistry() {
- this(DEFAULT_SQL_CONFIG_PATH);
+ super(new MapRegistryHandler(new AASDescriptorMap(createRootMap(new BaSyxSQLConfiguration()))));
}
/**
@@ -43,12 +32,6 @@
super(new MapRegistryHandler(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();
@@ -71,7 +54,7 @@
String user = config.getUser();
String pass = config.getPass();
String qryPfx = config.getPrefix();
- String qDrvCls = config.getDrv();
+ String qDrvCls = config.getDriver();
// 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.registry/src/main/resources/context.properties
similarity index 100%
rename from components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/resources/context.properties
rename to components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/context.properties
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.mongodbregistry/src/test/resources/localMongodb.properties b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/mongodb.properties
similarity index 90%
rename from components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/test/resources/localMongodb.properties
rename to components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/mongodb.properties
index e4c65b6..279374c 100644
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/test/resources/localMongodb.properties
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/mongodb.properties
@@ -9,4 +9,4 @@
dbuser = admin
dbname = admin
dbconnectionstring = mongodb://localhost:27017/
-dbcollection = registry
\ No newline at end of file
+dbcollectionRegistry = registry
\ 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..f50cc25
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/registry.properties
@@ -0,0 +1 @@
+registry.backend=InMemory
\ No newline at end of file
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..638f973
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/sql.properties
@@ -0,0 +1,9 @@
+# ##############################################################
+# 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.mongodbregistry/src/test/java/org/eclipse/basyx/regression/registry/ITMongoDBRegistry.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/ITRegistry.java
similarity index 87%
rename from components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/test/java/org/eclipse/basyx/regression/registry/ITMongoDBRegistry.java
rename to components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/ITRegistry.java
index 1c1e320..350d4a9 100644
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/test/java/org/eclipse/basyx/regression/registry/ITMongoDBRegistry.java
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/ITRegistry.java
@@ -9,8 +9,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class ITMongoDBRegistry extends TestRegistryProviderSuite {
- private static Logger logger = LoggerFactory.getLogger(ITMongoDBRegistry.class);
+public class ITRegistry extends TestRegistryProviderSuite {
+ private static Logger logger = LoggerFactory.getLogger(ITRegistry.class);
private static String registryUrl;
@@ -34,7 +34,6 @@
@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.registry/src/test/java/org/eclipse/basyx/regression/registry/ITRegistryRaw.java
similarity index 98%
rename from components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/java/org/eclipse/basyx/regression/registry/ITSQLRegistryRaw.java
rename to components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/ITRegistryRaw.java
index 2c5ed04..c06566c 100644
--- 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.registry/src/test/java/org/eclipse/basyx/regression/registry/ITRegistryRaw.java
@@ -32,8 +32,8 @@
* @author espen
*
*/
-public class ITSQLRegistryRaw {
- private static Logger logger = LoggerFactory.getLogger(ITSQLRegistry.class);
+public class ITRegistryRaw {
+ private static Logger logger = LoggerFactory.getLogger(ITRegistryRaw.class);
/**
* Serialization
diff --git a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/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
similarity index 76%
rename from components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/test/java/org/eclipse/basyx/regression/registry/TestMongoDBRegistry.java
rename to components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/TestMongoDBRegistry.java
index d314ada..0ff2b59 100644
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/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
@@ -2,7 +2,7 @@
import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
import org.eclipse.basyx.aas.registration.memory.AASRegistry;
-import org.eclipse.basyx.components.mongodbregistry.MongoDBRegistryHandler;
+import org.eclipse.basyx.components.registry.mongodb.MongoDBRegistryHandler;
import org.eclipse.basyx.testsuite.regression.aas.registration.TestRegistryProviderSuite;
/**
@@ -15,6 +15,6 @@
@Override
protected IAASRegistryService getRegistryService() {
- return new AASRegistry(new MongoDBRegistryHandler("localMongodb.properties"));
+ return new AASRegistry(new MongoDBRegistryHandler("mongodb.properties"));
}
}
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.registry/src/test/java/org/eclipse/basyx/regression/registry/TestSQLRegistryProvider.java
similarity index 61%
rename from components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/java/org/eclipse/basyx/regression/registry/TestSQLRegistryProvider.java
rename to components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/TestSQLRegistryProvider.java
index b1e8613..79fc363 100644
--- 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.registry/src/test/java/org/eclipse/basyx/regression/registry/TestSQLRegistryProvider.java
@@ -1,7 +1,8 @@
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.components.configuration.BaSyxSQLConfiguration;
+import org.eclipse.basyx.components.registry.sql.SQLRegistry;
import org.eclipse.basyx.testsuite.regression.aas.registration.TestRegistryProviderSuite;
/**
@@ -14,6 +15,8 @@
@Override
protected IAASRegistryService getRegistryService() {
- return new SQLRegistry("localRegistry.properties");
+ BaSyxSQLConfiguration sqlConfig = new BaSyxSQLConfiguration();
+ sqlConfig.loadFromResource("sql.properties");
+ return new SQLRegistry(sqlConfig);
}
}
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..11c83fa
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/resources/.env
@@ -0,0 +1,5 @@
+BASYX_HOST_PORT=8082
+BASYX_CONTAINER_PORT=4000
+BASYX_IMAGE_NAME=basyx/registry
+BASYX_CONTAINER_NAME=registry
+BASYX_IMAGE_TAG=0.1.0-SNAPSHOT
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/resources/dockerMongodb.properties b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/resources/dockerMongodb.properties
similarity index 90%
rename from components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/resources/dockerMongodb.properties
rename to components/basys.components/basyx.components.docker/basyx.components.registry/src/test/resources/dockerMongodb.properties
index 5fc816a..3a0b8fe 100644
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/resources/dockerMongodb.properties
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/resources/dockerMongodb.properties
@@ -9,4 +9,4 @@
dbuser = admin
dbname = admin
dbconnectionstring = mongodb://mongodb:27017/
-dbcollection = registry
\ No newline at end of file
+dbcollectionRegistry = registry
\ 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..f96fb32
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/resources/dockerSQL.properties
@@ -0,0 +1,9 @@
+# ##############################################################
+# 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.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/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/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 faf7620..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/java/org/eclipse/basyx/regression/registry/ITSQLRegistry.java
+++ /dev/null
@@ -1,40 +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();
- 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/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/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..f9b0d31 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>0.1.0-SNAPSHOT</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>
diff --git a/components/basys.components/basyx.components.lib/pom.xml b/components/basys.components/basyx.components.lib/pom.xml
index f34dbff..41b0fdd 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>0.1.0-SNAPSHOT</version>
</parent>
<artifactId>basyx.components.lib</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..7f8aacb
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/IComponent.java
@@ -0,0 +1,20 @@
+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/configuration/BaSyxConfiguration.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxConfiguration.java
index 6ad9aba..39b6a8d 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
@@ -53,6 +53,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
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..ca8a966 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
@@ -3,8 +3,7 @@
import java.util.HashMap;
import java.util.Map;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
/**
* Represents a BaSyx http servlet configuration for a BaSyxContext,
@@ -14,58 +13,119 @@
*
*/
public class BaSyxContextConfiguration extends BaSyxConfiguration {
-
- /**
- * Initiates a logger using the current class
- */
- private static final Logger logger = LoggerFactory.getLogger(BaSyxContextConfiguration.class);
-
// Default BaSyx Context configuration
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 loadFromDefaultSource() {
+ loadFileOrDefaultResource(DEFAULT_FILE_KEY, DEFAULT_CONFIG_PATH);
+ }
+
+ 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, 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() {
+ return "http://" + getHostname() + ":" + getPort() + "/" + getContextPath();
+ }
}
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..cd52038 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
@@ -11,19 +11,22 @@
*/
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";
+ 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";
- 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";
+ 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 +37,69 @@
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 loadFromDefaultSource() {
+ loadFileOrDefaultResource(DEFAULT_FILE_KEY, DEFAULT_CONFIG_PATH);
+ }
+
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..5ab9ef5
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxMongoDBConfiguration.java
@@ -0,0 +1,168 @@
+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 {
+ // Default BaSyx SQL configuration
+ public static final String DEFAULT_USER = "admin";
+ 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 USER = "dbuser";
+ 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(USER, DEFAULT_USER);
+ 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 user The username for the mongodb
+ * @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 user, String connectionUrl, String database, String registryCollection,
+ String aasCollection, String submodelCollection) {
+ this();
+ setUser(user);
+ setConnectionUrl(connectionUrl);
+ setDatabase(database);
+ setRegistryCollection(registryCollection);
+ setAASCollection(aasCollection);
+ setSubmodelCollection(submodelCollection);
+ }
+
+ /**
+ * Constructor with initial configuration (without registry collection)
+ *
+ * @param user The username for the mongodb
+ * @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 user, String connectionUrl, String database, String aasCollection,
+ String submodelCollection) {
+ this();
+ setUser(user);
+ setConnectionUrl(connectionUrl);
+ setDatabase(database);
+ setAASCollection(aasCollection);
+ setSubmodelCollection(submodelCollection);
+ }
+
+ /**
+ * Constructor with initial configuration (without aas collection)
+ *
+ * @param user The username for the mongodb
+ * @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 user, String connectionUrl, String database, String registryCollection) {
+ this();
+ setUser(user);
+ setConnectionUrl(connectionUrl);
+ setDatabase(database);
+ setRegistryCollection(registryCollection);
+ }
+
+ public void loadFromDefaultSource() {
+ loadFileOrDefaultResource(DEFAULT_FILE_KEY, DEFAULT_CONFIG_PATH);
+ }
+
+ public String getUser() {
+ return getProperty(USER);
+ }
+
+ public void setUser(String user) {
+ setProperty(USER, user);
+ }
+
+ 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/BaSyxSQLConfiguration.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxSQLConfiguration.java
index 1b31a36..86e1295 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
@@ -11,57 +11,108 @@
*/
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:";
+ 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:";
- 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";
+ 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 loadFromDefaultSource() {
+ loadFileOrDefaultResource(DEFAULT_FILE_KEY, DEFAULT_CONFIG_PATH);
+ }
+
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/devicemanager/DeviceManagerComponent.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/devicemanager/DeviceManagerComponent.java
index 4695058..f707f7b 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,6 @@
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 +78,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");
}
/**
@@ -90,7 +91,7 @@
*/
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/provider/BaseConfiguredProvider.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/provider/BaseConfiguredProvider.java
index ca5da6d..8c0220e 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
@@ -21,7 +21,7 @@
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.MultiSubmodelElementProvider;
import org.eclipse.basyx.submodel.restapi.vab.VABSubmodelAPI;
import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
import org.slf4j.Logger;
@@ -96,7 +96,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));
}
/**
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
index 3d7d21a..08cf893 100644
--- 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
@@ -70,7 +70,7 @@
throw new RuntimeException("Only instances of SubModel are allowed here");
}
- provider.addSubmodel(sm.getIdShort(), new SubModelProvider((SubModel) sm));
+ provider.addSubmodel(new SubModelProvider((SubModel) sm));
}
return provider;
}
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..675742f 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
@@ -4,7 +4,6 @@
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 +18,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 +67,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 +100,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 +124,7 @@
/**
* Operations map
*/
- protected Map<String, Object> operations = new HashMap<String, Object>();
+ protected Map<String, Function<?, ?>> operations = new HashMap<>();
/**
@@ -173,8 +152,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 +159,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 +240,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 +258,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 +272,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 +293,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 +446,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 +485,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 +590,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 +608,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..a4e987c 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
@@ -27,14 +27,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 +56,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/support/bundle/AASBundleDescriptorFactory.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/support/bundle/AASBundleDescriptorFactory.java
index 2291fa4..487ed63 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
@@ -24,7 +24,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/AASBundleIntegrator.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/support/bundle/AASBundleIntegrator.java
new file mode 100644
index 0000000..8507196
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/support/bundle/AASBundleIntegrator.java
@@ -0,0 +1,80 @@
+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.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+
+
+/**
+ * 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 AASBundleIntegrator {
+
+ /**
+ * 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.getModelPropertyValue("/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.setModelPropertyValue("/aas/submodels/" + sm.getIdShort(), sm);
+ objectUploaded = true;
+ } else {
+ throw new RuntimeException("sm Objects in bundles need to be instance of 'SubModel'");
+ }
+ }
+ }
+ }
+ return objectUploaded;
+ }
+
+}
\ No newline at end of file
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/tools/sql/driver/ISQLDriver.java
similarity index 83%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/driver/ISQLDriver.java
rename to components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/driver/ISQLDriver.java
index 37095d0..86514e9 100644
--- 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/tools/sql/driver/ISQLDriver.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.sqlprovider.driver;
+package org.eclipse.basyx.tools.sql.driver;
import java.sql.ResultSet;
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/tools/sql/driver/SQLDriver.java
similarity index 96%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/driver/SQLDriver.java
rename to components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/driver/SQLDriver.java
index 94931ee..0c28589 100644
--- 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/tools/sql/driver/SQLDriver.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.sqlprovider.driver;
+package org.eclipse.basyx.tools.sql.driver;
import java.sql.Connection;
import java.sql.ResultSet;
@@ -90,6 +90,7 @@
/**
* 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
@@ -126,6 +127,7 @@
/**
* Execute a SQL update
*/
+ @Override
public void sqlUpdate(String updateString) {
// Store SQL statement
Statement statement = null;
@@ -159,7 +161,7 @@
// Open connection
if (connect == null) {
openDataSource();
- connect = ds.getConnection();
+ connect = ds.getConnection();
}
} catch (SQLException e) {
logger.error("Failed to open sql driver connection", e);
@@ -208,6 +210,7 @@
ds.setJdbcUrl(queryPrefix+dbPath);
ds.setUsername(userName);
ds.setPassword(password);
+ ds.setMaximumPoolSize(5);
}
}
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/tools/sql/query/DynamicSQLOperation.java
similarity index 95%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLOperation.java
rename to components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLOperation.java
index 9b8449a..af498a0 100644
--- 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/tools/sql/query/DynamicSQLOperation.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.sqlprovider.query;
+package org.eclipse.basyx.tools.sql.query;
import java.lang.reflect.InvocationTargetException;
import java.sql.ResultSet;
@@ -6,10 +6,10 @@
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.eclipse.basyx.tools.sql.driver.ISQLDriver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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/tools/sql/query/DynamicSQLQuery.java
similarity index 96%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLQuery.java
rename to components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLQuery.java
index 6a5befe..a41f060 100644
--- 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/tools/sql/query/DynamicSQLQuery.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.sqlprovider.query;
+package org.eclipse.basyx.tools.sql.query;
import java.lang.reflect.InvocationTargetException;
import java.sql.ResultSet;
@@ -7,10 +7,10 @@
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;
+import org.eclipse.basyx.tools.sql.driver.ISQLDriver;
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/tools/sql/query/DynamicSQLRunner.java
similarity index 87%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLRunner.java
rename to components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLRunner.java
index d3a3a88..fe91225 100644
--- 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/tools/sql/query/DynamicSQLRunner.java
@@ -1,11 +1,12 @@
-package org.eclipse.basyx.components.sqlprovider.query;
+package org.eclipse.basyx.tools.sql.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;
+import org.eclipse.basyx.tools.sql.driver.ISQLDriver;
+import org.eclipse.basyx.tools.sql.driver.SQLDriver;
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/tools/sql/query/DynamicSQLUpdate.java
similarity index 92%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLUpdate.java
rename to components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLUpdate.java
index 773824b..90334f1 100644
--- 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/tools/sql/query/DynamicSQLUpdate.java
@@ -1,10 +1,10 @@
-package org.eclipse.basyx.components.sqlprovider.query;
+package org.eclipse.basyx.tools.sql.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.eclipse.basyx.tools.sql.driver.ISQLDriver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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..7486da0 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
@@ -9,9 +9,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..c869437 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,7 @@
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..307fd78 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
@@ -10,9 +10,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..852026d 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
@@ -7,9 +7,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..31904cf 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
@@ -6,8 +6,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;
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..a6ff7a2 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
@@ -82,7 +82,7 @@
VABMultiSubmodelProvider provider = new VABMultiSubmodelProvider();
// 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));
@@ -96,7 +96,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/sqlprovider/SQLInvocationsTest.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sql/SQLInvocationsTest.java
similarity index 97%
rename from components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlprovider/SQLInvocationsTest.java
rename to components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sql/SQLInvocationsTest.java
index f8beb36..9655073 100644
--- 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/sql/SQLInvocationsTest.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.regression.sqlprovider;
+package org.eclipse.basyx.regression.sql;
import java.util.Collection;
import java.util.LinkedList;
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/sql/SQLQueriesTest.java
similarity index 98%
rename from components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlprovider/SQLQueriesTest.java
rename to components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sql/SQLQueriesTest.java
index a06b966..be4cc10 100644
--- 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/sql/SQLQueriesTest.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.regression.sqlprovider;
+package org.eclipse.basyx.regression.sql;
import java.util.HashMap;
import java.util.Map;
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..e84be6f 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
@@ -8,6 +8,7 @@
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.identifier.Identifier;
import org.eclipse.basyx.support.bundle.AASBundle;
import org.eclipse.basyx.support.bundle.AASBundleDescriptorFactory;
import org.eclipse.basyx.vab.modelprovider.VABPathTools;
@@ -24,7 +25,7 @@
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();
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/bundle/TestAASBundleIntegrator.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/bundle/TestAASBundleIntegrator.java
new file mode 100644
index 0000000..527cced
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/bundle/TestAASBundleIntegrator.java
@@ -0,0 +1,164 @@
+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.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.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.AASBundleIntegrator;
+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 TestAASBundleIntegrator {
+
+ 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(AASBundleIntegrator.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(AASBundleIntegrator.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(AASBundleIntegrator.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() {
+ IAASRegistryService registry = new InMemoryRegistry();
+ provider = new AASAggregatorProvider(new AASAggregator(registry));
+ aggregator = new AASAggregatorProxy(new VABElementProxy("/shells", provider));
+
+ AASBundle bundle = getTestBundle();
+ bundles.add(bundle);
+
+ assertTrue(AASBundleIntegrator.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.getModelPropertyValue("/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.setModelPropertyValue("/" + 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/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..401557f 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,6 +1,8 @@
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;
@@ -13,9 +15,9 @@
IIdentifier id = new Identifier(IdentifierType.CUSTOM, submodelid);
SubModel sm = new SubModel();
sm.setIdentification(id.getIdType(), id.getId());
- AssetAdministrationShell aas = new AssetAdministrationShell();
+ 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);
- aas.put("idshort", aasid);
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..4aff97c 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
@@ -34,7 +34,7 @@
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/submodel/DeviceSubmodelFactory.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/submodel/DeviceSubmodelFactory.java
index 1e1f82d..28a2b53 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
@@ -5,7 +5,9 @@
import java.util.function.Function;
import org.eclipse.basyx.regression.support.processengine.stubs.ICoilcar;
+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;
@@ -45,7 +47,7 @@
propList.add(property3);
// create the sub-model and add the property and operations to the sub-model
SubModel sm = new SubModel(propList, opList);
-
+ sm.setIdentification(new Identifier(IdentifierType.CUSTOM, id + "Custom"));
sm.setIdShort(id);
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..362385c 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,5 @@
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 +29,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/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..bcc33bd 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>0.1.0-SNAPSHOT</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>0.1.0-SNAPSHOT</version>
</dependency>
<!-- BaSyx SDK 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/components/basyx.tck/basyx.tck.AASAggregator/pom.xml b/components/basyx.tck/basyx.tck.AASAggregator/pom.xml
deleted file mode 100644
index 87e9c5c..0000000
--- a/components/basyx.tck/basyx.tck.AASAggregator/pom.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?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>0.0.1-SNAPSHOT</version>
- </parent>
-
- <artifactId>basyx.tck.AASAggregator</artifactId>
- <name>TCK for AASAggregator</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.aggregator.AASAggregatorTestApplication</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.AASAggregator/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorSuiteWithDefinedURL.java b/components/basyx.tck/basyx.tck.AASAggregator/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorSuiteWithDefinedURL.java
deleted file mode 100644
index 2103c20..0000000
--- a/components/basyx.tck/basyx.tck.AASAggregator/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorSuiteWithDefinedURL.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.eclipse.basyx.testsuite.regression.aas.aggregator;
-
-import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
-import org.eclipse.basyx.aas.aggregator.proxy.AASAggregatorProxy;
-
-/**
- * Instantiate a concrete test suite for AASAggregator from the abstract test
- * suite
- *
- * @author zhangzai
- *
- */
-public class AASAggregatorSuiteWithDefinedURL extends AASAggregatorSuite {
-
- public static String url;
-
- @Override
- protected IAASAggregator getAggregator() {
- return new AASAggregatorProxy(url);
- }
-
-}
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..ba6f373
--- /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>0.1.0-SNAPSHOT</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.AASAggregator/src/main/assembly/assembly.xml b/components/basyx.tck/basyx.tck.AASServer/src/main/assembly/assembly.xml
similarity index 100%
rename from components/basyx.tck/basyx.tck.AASAggregator/src/main/assembly/assembly.xml
rename to components/basyx.tck/basyx.tck.AASServer/src/main/assembly/assembly.xml
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..c988c3d
--- /dev/null
+++ b/components/basyx.tck/basyx.tck.AASServer/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/AASAggregatorSuiteWithDefinedURL.java
@@ -0,0 +1,135 @@
+package org.eclipse.basyx.testsuite.regression.aas.metamodel;
+
+import static org.junit.Assert.assertEquals;
+
+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(aasxPath);
+
+ // 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
+ assertEquals(expected, remoteAas.getLocalCopy());
+
+ // 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
+ assertEquals(expectedSm, remote.getLocalCopy());
+ });
+
+
+ // Delete the AAS
+ aasAggregator.deleteAAS(aasIdentifier);
+
+ }
+
+
+}
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..5a3d310
--- /dev/null
+++ b/components/basyx.tck/basyx.tck.AASServer/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/AASServerTestApplication.java
@@ -0,0 +1,42 @@
+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
index 624a4a5..674f83a 100644
--- a/components/basyx.tck/basyx.tck.registry/pom.xml
+++ b/components/basyx.tck/basyx.tck.registry/pom.xml
@@ -6,7 +6,7 @@
<parent>
<groupId>org.eclipse.basyx</groupId>
<artifactId>basyx.tck</artifactId>
- <version>0.0.1-SNAPSHOT</version>
+ <version>0.1.0-SNAPSHOT</version>
</parent>
<artifactId>basyx.tck.registry</artifactId>
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
index 08e05cc..a295ff0 100644
--- 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
@@ -18,4 +18,14 @@
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/pom.xml b/components/basyx.tck/pom.xml
index 28205ad..6a0653d 100644
--- a/components/basyx.tck/pom.xml
+++ b/components/basyx.tck/pom.xml
@@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.eclipse.basyx</groupId>
<artifactId>basyx.tck</artifactId>
- <version>0.0.1-SNAPSHOT</version>
+ <version>0.1.0-SNAPSHOT</version>
<packaging>pom</packaging>
@@ -14,7 +14,7 @@
<!-- Includes all components in this project as separated modules -->
<modules>
- <module>basyx.tck.AASAggregator</module>
+ <module>basyx.tck.AASServer</module>
<module>basyx.tck.registry</module>
</modules>
@@ -111,13 +111,13 @@
<dependency>
<groupId>org.eclipse.basyx</groupId>
<artifactId>basyx.sdk</artifactId>
- <version>0.0.1-SNAPSHOT</version>
+ <version>0.1.0-SNAPSHOT</version>
</dependency>
<!-- BaSyx SDK 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/examples/basys.examples/pom.xml b/examples/basys.examples/pom.xml
index 9091809..26cdb51 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>0.1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>BaSyx Examples</name>
@@ -271,29 +271,28 @@
<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>
+ <artifactId>basyx.components.registry</artifactId>
+ <version>0.1.0-SNAPSHOT</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>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/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..b4b68eb 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,9 +1,18 @@
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.proxy.AASRegistryProxy;
+import org.eclipse.basyx.components.IComponent;
+import org.eclipse.basyx.components.aas.AASServerComponent;
+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;
@@ -20,7 +29,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 +37,8 @@
/**
* The registry used in the manager
*/
- public IAASRegistryService registry;
+ private IAASRegistryService registry;
+ public static String registryPath = "http://localhost:8080/registry";
/**
* AASManager used to handle registration and server communication
@@ -52,6 +62,10 @@
*/
public IIdentifier edgeSmIdentifier = ComponentBuilder.getEdgeSubmodelDescriptor().getIdentifier();
+ // Used for shutting down the scenario
+ private List<IComponent> startedComponents = new ArrayList<>();
+ private AASHTTPServer edgeServer;
+
/**
* Main method to start the scenario
*
@@ -66,20 +80,21 @@
*/
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
@@ -95,6 +110,19 @@
}
/**
+ * 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"
*
@@ -104,8 +132,9 @@
*/
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();
@@ -118,7 +147,7 @@
// Create and start a HTTP server with the context created above
- AASHTTPServer edgeServer = new AASHTTPServer(context);
+ edgeServer = new AASHTTPServer(context);
edgeServer.start();
}
@@ -130,12 +159,22 @@
*
*/
private void startupCloudServer() {
-
- // Create a server at port 8081 with the endpoint "/cloud"
- AASServerComponent cloudServer = new AASServerComponent("localhost", 8081, "/cloud", "/");
+ // Load the AAS context from a .properties file resource
+ BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
+ contextConfig.loadFromResource("CloudEdgeDeploymentScenarioAASContext.properties");
+
+ // Create a server according to this configuration
+ AASServerComponent cloudServer = new AASServerComponent(contextConfig);
+ cloudServer.setRegistry(registry);
// Start the created server
cloudServer.startComponent();
+ startedComponents.add(cloudServer);
+ }
+
+ public void stop() {
+ startedComponents.stream().forEach(IComponent::stopComponent);
+ edgeServer.shutdown();
}
}
\ No newline at end of file
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..2413878 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
@@ -17,15 +17,15 @@
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_ENDPOINT = "http://localhost:8082/oven/current_temp/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 DOCUSM_ENDPOINT = "http://localhost:8081/cloud/shells/aasId/aas/submodels/oven_doc/submodel";
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 AAS_ENDPOINT = "http://localhost:8081/cloud/shells/aasId/aas";
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..5fec083
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/staticdynamic/ExampleDynamicSubmodel.java
@@ -0,0 +1,39 @@
+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.set(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..8bbc6b8
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/staticdynamic/StaticDynamicScenario.java
@@ -0,0 +1,170 @@
+package org.eclipse.basyx.examples.scenarios.staticdynamic;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+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.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.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.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.support.bundle.AASBundle;
+import org.eclipse.basyx.support.bundle.AASBundleIntegrator;
+import org.eclipse.basyx.vab.exception.provider.ResourceAlreadyExistsException;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+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 IOException, ParserConfigurationException, SAXException, URISyntaxException {
+ new StaticDynamicScenario();
+ }
+
+ public StaticDynamicScenario() throws IOException, ParserConfigurationException, SAXException, URISyntaxException {
+
+ // 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
+ AASBundleIntegrator.integrate(new AASAggregatorProxy(SERVER_URL), bundles);
+
+ // Get a RegistryProxy and register all Objects contained in the Bundles
+ AASRegistryProxy proxy = new AASRegistryProxy(REGISTRY_URL);
+ registerBundles(bundles, proxy, 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;
+ }
+
+ /**
+ * Registers all AASs and SMs contained in the given Bundles
+ *
+ * @param bundles the Bundles to be registered
+ * @param registry the registry to be used
+ * @param serverURL the URL of the server, that holds the AASs/SMs
+ */
+ private void registerBundles(Set<AASBundle> bundles, IAASRegistryService registry, String serverURL) {
+ for(AASBundle bundle: bundles) {
+ IAssetAdministrationShell aas = bundle.getAAS();
+ String encodedAASId = VABPathTools.encodePathElement(aas.getIdentification().getId());
+ String aasEndpoint = VABPathTools.concatenatePaths(serverURL, AASAggregatorProvider.PREFIX, encodedAASId, "aas");
+ AASDescriptor aasDescriptor = new AASDescriptor(aas, aasEndpoint);
+ try {
+ registry.register(aasDescriptor);
+ } catch(ResourceAlreadyExistsException e) {
+ // Does not matter; AAS was already registered
+ }
+
+ for(ISubModel sm: bundle.getSubmodels()) {
+ String encodedSMId = VABPathTools.encodePathElement(sm.getIdShort());
+ String smEndpoint = VABPathTools.concatenatePaths(aasEndpoint, "submodels", encodedSMId);
+ SubmodelDescriptor smDescriptor = new SubmodelDescriptor(sm, smEndpoint);
+ try {
+ registry.register(aas.getIdentification(), smDescriptor);
+ } catch(ResourceAlreadyExistsException e) {
+ // Does not matter; SM was already registered
+ }
+ }
+ }
+ }
+
+ /**
+ * 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..62bfe8f
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/AddSubmodelToAAS.java
@@ -0,0 +1,40 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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
+ *
+ * @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/aas/DeleteAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/DeleteAAS.java
new file mode 100644
index 0000000..b79efdf
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/DeleteAAS.java
@@ -0,0 +1,34 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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
+ *
+ * @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/aas/DeleteSubmodelFromAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/DeleteSubmodelFromAAS.java
new file mode 100644
index 0000000..a6e0809
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/DeleteSubmodelFromAAS.java
@@ -0,0 +1,35 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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
+ *
+ * @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);
+ }
+}
\ No newline at end of file
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/LookupAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/LookupAAS.java
new file mode 100644
index 0000000..e7ed77c
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/LookupAAS.java
@@ -0,0 +1,31 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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/aas/PushAASToServer.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/PushAASToServer.java
new file mode 100644
index 0000000..7a78f28
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/PushAASToServer.java
@@ -0,0 +1,37 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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 a AAS to a server
+ *
+ * @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);
+ }
+}
\ No newline at end of file
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/RegisterAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/RegisterAAS.java
new file mode 100644
index 0000000..02e96b3
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/RegisterAAS.java
@@ -0,0 +1,34 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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/aas/RetrieveRemoteAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/RetrieveRemoteAAS.java
new file mode 100644
index 0000000..d50c408
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/RetrieveRemoteAAS.java
@@ -0,0 +1,36 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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
+ *
+ * @author conradi
+ *
+ */
+public class RetrieveRemoteAAS {
+
+ /**
+ * 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/aas/RetrieveSubmodelFromAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/RetrieveSubmodelFromAAS.java
new file mode 100644
index 0000000..1404875
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/RetrieveSubmodelFromAAS.java
@@ -0,0 +1,38 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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 a AAS on a server
+ *
+ * @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/submodel/AddSubmodelElement.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/AddSubmodelElement.java
new file mode 100644
index 0000000..a33e08d
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/AddSubmodelElement.java
@@ -0,0 +1,35 @@
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import org.eclipse.basyx.examples.snippets.aas.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);
+
+ }
+
+}
\ No newline at end of file
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..8e31408
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/DeleteSubmodelElement.java
@@ -0,0 +1,31 @@
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import org.eclipse.basyx.examples.snippets.aas.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..74d5774
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/ExecuteOperation.java
@@ -0,0 +1,45 @@
+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/LookupSubmodel.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/LookupSubmodel.java
new file mode 100644
index 0000000..1b3e4f4
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/LookupSubmodel.java
@@ -0,0 +1,32 @@
+package org.eclipse.basyx.examples.snippets.submodel;
+
+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/submodel/RegisterSubmodel.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/RegisterSubmodel.java
new file mode 100644
index 0000000..6c4a751
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/RegisterSubmodel.java
@@ -0,0 +1,35 @@
+package org.eclipse.basyx.examples.snippets.submodel;
+
+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 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/RetrieveSubmodelElement.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/RetrieveSubmodelElement.java
new file mode 100644
index 0000000..cfce36e
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/RetrieveSubmodelElement.java
@@ -0,0 +1,34 @@
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import org.eclipse.basyx.examples.snippets.aas.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);
+
+ }
+}
\ No newline at end of file
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..4260956
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/ExampleAASComponent.java
@@ -0,0 +1,53 @@
+package org.eclipse.basyx.examples.support;
+
+import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
+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 IAASRegistryService registry;
+
+ // Hold a reference to the server to be able to shut it down
+ private AASServerComponent aasServer = null;
+
+
+ public ExampleAASComponent(int port, IAASRegistryService 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..7db04ec
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/ExampleComponentBuilder.java
@@ -0,0 +1,75 @@
+package org.eclipse.basyx.examples.support;
+
+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.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+
+/**
+ * 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();
+ submodel.setIdShort(idShort);
+ submodel.setIdentification(IdentifierType.CUSTOM, id);
+
+ // Add a Property to the Submodel
+ Property property = new Property();
+ property.setIdShort(PROPERTY_ID);
+ property.setValue(PROPERTY_VALUE);
+ submodel.addSubModelElement(property);
+
+ // Add a SubmodelElementCollection
+ SubmodelElementCollection collection = new SubmodelElementCollection();
+ collection.setIdShort(COLLECTION_ID);
+
+ // Add a Property to the SubmodelElementCollection
+ Property property2 = new Property();
+ property2.setIdShort(COLLECTION_PROPERTY_ID);
+ 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) {
+ AssetAdministrationShell aas = new AssetAdministrationShell();
+ aas.setIdShort(idShort);
+
+ aas.setIdentification(IdentifierType.CUSTOM, id);
+
+ 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..6f6e8a5
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/ExampleRegistryComponent.java
@@ -0,0 +1,53 @@
+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/ExamplesPreconfiguredDirectory.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/directory/ExamplesPreconfiguredDirectory.java
index 3dd8b66..8f18dce 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
@@ -20,6 +20,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..1201930
--- /dev/null
+++ b/examples/basys.examples/src/main/resources/CloudEdgeDeploymentScenarioAASContext.properties
@@ -0,0 +1,3 @@
+contextPath=/cloud
+contextHostname=localhost
+contextPort=8081
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/resources/context.properties b/examples/basys.examples/src/main/resources/RegistryContext.properties
similarity index 100%
rename from components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/resources/context.properties
rename to examples/basys.examples/src/main/resources/RegistryContext.properties
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..cb0bbd5
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/contexts/BaSyxExamplesContext.java
@@ -0,0 +1,44 @@
+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..e50e968 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
@@ -16,14 +16,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/mockup/application/ReceiveDeviceDashboardStatusApplication.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/application/ReceiveDeviceDashboardStatusApplication.java
index 303dc1c..c236b90 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
@@ -7,8 +7,9 @@
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;
@@ -34,7 +35,7 @@
*/
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()));
@@ -69,7 +70,7 @@
public String getDeviceStatus() {
// Read the status property
Map<String, Object> property = (Map<String, Object>) aasServerConnection
- .getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/status");
+ .getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/status");
// Return the value of the property
return property.get("value").toString();
}
@@ -82,7 +83,7 @@
public int getDeviceInvocationCounter() {
// Read the invocation counter for device default service
Map<String, Object> property = (Map<String, Object>) aasServerConnection
- .getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/invocations");
+ .getModelPropertyValue(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..0c20f1c 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
@@ -7,8 +7,9 @@
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;
@@ -38,7 +39,7 @@
*/
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()));
@@ -73,7 +74,7 @@
public int getDevicePartSupplyStatus() {
// Read the status property
Map<String, Object> property = (Map<String, Object>) aasServerConnection
- .getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/partAvailability");
+ .getModelPropertyValue(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/SmartBaSyxTCPDeviceMockup.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/device/SmartBaSyxTCPDeviceMockup.java
index 0846b5c..ff94cfe 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
@@ -2,19 +2,22 @@
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.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;
@@ -22,12 +25,13 @@
/**
* 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 +53,7 @@
*/
protected VABElementProxy aasServerConnection = null;
+ protected String aasPath;
@@ -68,7 +73,7 @@
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"));
+ setRegistry(new AASRegistryProxy("http://localhost:8080/" + BaSyxExamplesContext.REGISTRYURL));
setConnectionManager(new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorProvider()));
}
@@ -83,10 +88,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");
+ .getModelPropertyValue(aasPath + "/submodels/Status/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/invocations");
int invocations = (int) property.get("value");
- aasServerConnection.setModelPropertyValue("/aas/submodels/Status/" + SubmodelElementProvider.PROPERTIES + "/invocations/value", ++invocations);
+ aasServerConnection.setModelPropertyValue(aasPath + "/submodels/Status/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/invocations/value", ++invocations);
}
@@ -99,7 +103,7 @@
super.onChangedExecutionState(newExecutionState);
// Update property "properties/status" in external AAS
- aasServerConnection.setModelPropertyValue("/aas/submodels/Status/" + SubmodelElementProvider.PROPERTIES + "/status/value",
+ aasServerConnection.setModelPropertyValue(aasPath + "/submodels/Status/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/status/value",
newExecutionState.getValue());
}
@@ -121,9 +125,14 @@
// 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.setModelPropertyValue(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
@@ -141,7 +150,7 @@
invocationsProp.setIdShort("invocations");
statusSM.addSubModelElement(invocationsProp);
// - Transfer device sub model to server
- aasServerConnection.createValue("/aas/submodels", statusSM);
+ aasServerConnection.setModelPropertyValue(aasPath + "/submodels/" + statusSM.getIdShort(), statusSM);
// Register control component as local sub model
@@ -153,12 +162,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..3d36e49 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
@@ -2,18 +2,21 @@
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.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;
@@ -29,7 +32,7 @@
*
*/
public class BaSyxTCPControlManufacturingDeviceManager extends TCPControllableDeviceManagerComponent implements ControlComponentChangeListener {
-
+
/**
* Initiates a logger using the current class
*/
@@ -40,6 +43,8 @@
*/
protected VABElementProxy aasServerConnection = null;
+ protected String aasPath;
+
@@ -52,7 +57,7 @@
// 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
@@ -63,7 +68,7 @@
// 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);
}
@@ -96,6 +101,7 @@
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
@@ -117,9 +123,10 @@
// Push the AAS and submodels to the server
// - Transfer device AAS to server
- aasServerConnection.createValue("/aas", aas);
+ aasServerConnection.setModelPropertyValue(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.setModelPropertyValue(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"));
@@ -177,15 +184,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.setModelPropertyValue(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.getModelPropertyValue(aasPath + "/submodels/Status/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/invocations");
int invocations = (int) property.get("value");
- aasServerConnection.setModelPropertyValue("/aas/submodels/Status/" + SubmodelElementProvider.PROPERTIES + "/invocations/value", ++invocations);
+ aasServerConnection.setModelPropertyValue(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..52c9d82 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,5 +1,6 @@
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;
@@ -57,7 +58,7 @@
// Transfer device sub model to server
- aasServerConnection.createValue("/aas/submodels", supplySM);
+ aasServerConnection.setModelPropertyValue("/" + AASAggregatorProvider.PREFIX + "/" + lookupURN("AAS").getEncodedURN() + "/aas/submodels/" + supplySM.getIdShort(), supplySM);
}
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..99d6604 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
@@ -2,18 +2,21 @@
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.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.protocol.http.connector.HTTPConnectorProvider;
/**
@@ -57,28 +60,13 @@
// 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
@@ -89,7 +77,7 @@
// 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);
}
@@ -137,8 +125,9 @@
AssetAdministrationShell aas = new AssetAdministrationShell();
// - Populate AAS
aas.setIdShort("DeviceIDShort");
+ aas.setIdentification(lookupURN("AAS"));
// - Transfer device AAS to server
- aasServerConnection.createValue("/aas", aas);
+ aasServerConnection.setModelPropertyValue(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
@@ -157,7 +146,7 @@
invocationsProp.setIdShort("invocations");
statusSM.addSubModelElement(invocationsProp);
// - Transfer device sub model to server
- aasServerConnection.createValue("/aas/submodels/", statusSM);
+ aasServerConnection.setModelPropertyValue(AASAggregatorProvider.PREFIX + "/" + VABPathTools.encodePathElement(lookupURN("AAS").getId()) + "/aas/submodels/" + statusSM.getIdShort(), statusSM);
}
@@ -174,6 +163,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 +173,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.setModelPropertyValue(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.getModelPropertyValue(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.setModelPropertyValue(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/scenarios/cloudedgedeployment/TestCloudEdgeDeploymentScenario.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/cloudedgedeployment/TestCloudEdgeDeploymentScenario.java
index 3459103..1a49332 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,8 @@
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;
@@ -14,7 +14,9 @@
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.proxy.AASRegistryProxy;
import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -27,15 +29,22 @@
scenario = new CloudEdgeDeploymentScenario();
}
+ @AfterClass
+ public static void tearDown() {
+ scenario.stop();
+ }
+
+ private IAASRegistryService 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);
@@ -68,7 +77,7 @@
@Test
public void testAAS() throws Exception {
ConnectedAssetAdministrationShellManager manager =
- new ConnectedAssetAdministrationShellManager(scenario.registry);
+ new ConnectedAssetAdministrationShellManager(getRegistry());
IAssetAdministrationShell aas = manager.retrieveAAS(scenario.aasIdentifier);
@@ -90,7 +99,7 @@
@Test
public void testDocuSM() {
ConnectedAssetAdministrationShellManager manager =
- new ConnectedAssetAdministrationShellManager(scenario.registry);
+ new ConnectedAssetAdministrationShellManager(getRegistry());
ISubModel docuSM = manager.retrieveSubModel(scenario.aasIdentifier, scenario.docuSmIdentifier);
@@ -107,7 +116,7 @@
@Test
public void testEdgeSM() {
ConnectedAssetAdministrationShellManager manager =
- new ConnectedAssetAdministrationShellManager(scenario.registry);
+ new ConnectedAssetAdministrationShellManager(getRegistry());
ISubModel edgeSM = manager.retrieveSubModel(scenario.aasIdentifier, scenario.edgeSmIdentifier);
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..e2f6d3e 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
@@ -2,7 +2,7 @@
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;
@@ -44,7 +44,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..89fb782 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
@@ -2,7 +2,7 @@
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;
@@ -40,7 +40,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..e76244c 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
@@ -2,16 +2,18 @@
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.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.junit.ClassRule;
@@ -54,7 +56,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 +96,7 @@
// Change device operation mode
- toControlComponent.setModelPropertyValue("status/opMode", "RegularMilling");
+ toControlComponent.setModelPropertyValue(VABPathTools.concatenatePaths(ControlComponent.STATUS, ControlComponent.OP_MODE), "RegularMilling");
// - Validate device operation mode
waitfor(() -> ((ControllableTCPDeviceMockup) context.getRunnable("Device")).getOpMode().equals("RegularMilling"));
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..4d8efd5 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
@@ -2,15 +2,17 @@
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.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.junit.ClassRule;
@@ -53,7 +55,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 +89,7 @@
// Change device operation mode
- toControlComponent.setModelPropertyValue("status/opMode", "RegularMilling");
+ toControlComponent.setModelPropertyValue(VABPathTools.concatenatePaths(ControlComponent.STATUS, ControlComponent.OP_MODE), "RegularMilling");
// - Validate device control component operation mode
waitfor( () -> ((SmartBaSyxTCPDeviceMockup) context.getRunnable("Device")).getControlComponent().getOperationMode().equals("RegularMilling") );
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..31050a1
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/staticdynamic/TestStaticDynamicScenario.java
@@ -0,0 +1,58 @@
+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..1a5260c
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/AbstractSnippetTest.java
@@ -0,0 +1,76 @@
+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..4ab8821
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestAddSubmodelToAAS.java
@@ -0,0 +1,46 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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/aas/TestDeleteAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestDeleteAAS.java
new file mode 100644
index 0000000..f3d795f
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestDeleteAAS.java
@@ -0,0 +1,38 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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 {
+ RetrieveRemoteAAS.retrieveRemoteAAS(aasIdentifier, registryComponent.getRegistryPath());
+ fail();
+ } catch (ResourceNotFoundException e) {
+ }
+
+ }
+
+}
\ No newline at end of file
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..504c406
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestDeleteSubmodelFromAAS.java
@@ -0,0 +1,40 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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 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());
+
+ // Try to retrieve deleted Submodel; should throw ResourceNotFoundException
+ try {
+ RetrieveSubmodelFromAAS.retrieveSubmodelFromAAS(
+ smIdentifier, aasIdentifier, registryComponent.getRegistryPath());
+ fail();
+ } catch (ResourceNotFoundException e) {
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestLookupAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestLookupAAS.java
new file mode 100644
index 0000000..339a0cc
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestLookupAAS.java
@@ -0,0 +1,34 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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/aas/TestPushAASToServer.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestPushAASToServer.java
new file mode 100644
index 0000000..1b57fd1
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestPushAASToServer.java
@@ -0,0 +1,38 @@
+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.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/aas/TestRegisterAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestRegisterAAS.java
new file mode 100644
index 0000000..717f533
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestRegisterAAS.java
@@ -0,0 +1,40 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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/aas/TestRetrieveRemoteAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestRetrieveRemoteAAS.java
new file mode 100644
index 0000000..933eed8
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestRetrieveRemoteAAS.java
@@ -0,0 +1,33 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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 TestRetrieveRemoteAAS 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 =
+ RetrieveRemoteAAS.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/aas/TestRetrieveSubmodelFromAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestRetrieveSubmodelFromAAS.java
new file mode 100644
index 0000000..03f98a8
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestRetrieveSubmodelFromAAS.java
@@ -0,0 +1,36 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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());
+ }
+
+}
\ No newline at end of file
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/submodel/TestAddSubmodelElement.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestAddSubmodelElement.java
new file mode 100644
index 0000000..d7af892
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestAddSubmodelElement.java
@@ -0,0 +1,50 @@
+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/TestDeleteSubmodelElement.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestDeleteSubmodelElement.java
new file mode 100644
index 0000000..5da765a
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestDeleteSubmodelElement.java
@@ -0,0 +1,53 @@
+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) {
+ }
+
+ }
+
+}
\ No newline at end of file
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..6da88ae
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestExecuteOperation.java
@@ -0,0 +1,104 @@
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import static org.junit.Assert.assertEquals;
+
+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.operation.Operation;
+import org.eclipse.basyx.vab.protocol.http.server.AASHTTPServer;
+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 AASHTTPServer 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];
+ });
+ 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 AASHTTPServer(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/TestLookupSubmodel.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestLookupSubmodel.java
new file mode 100644
index 0000000..0305f12
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestLookupSubmodel.java
@@ -0,0 +1,36 @@
+package org.eclipse.basyx.examples.snippets.submodel;
+
+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/submodel/TestRegisterSubmodel.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestRegisterSubmodel.java
new file mode 100644
index 0000000..ea7c3bf
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestRegisterSubmodel.java
@@ -0,0 +1,45 @@
+package org.eclipse.basyx.examples.snippets.submodel;
+
+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.snippets.aas.RegisterAAS;
+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/TestRetrieveSubmodelElement.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestRetrieveSubmodelElement.java
new file mode 100644
index 0000000..7d8d03f
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestRetrieveSubmodelElement.java
@@ -0,0 +1,41 @@
+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());
+ }
+
+}
\ No newline at end of file
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..7130114 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
@@ -6,7 +6,7 @@
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;
@@ -43,7 +43,7 @@
.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());
-
+
/**
* The BaSyx Deployment instantiates and starts context elements for this example.
*
@@ -57,7 +57,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())
);
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..566f575 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
@@ -7,7 +7,7 @@
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;
@@ -86,7 +86,7 @@
.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());
-
+
/**
* The BaSyx Deployment instantiates and starts context elements for this example.
*
@@ -100,7 +100,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())
);
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..05c4274 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
@@ -7,7 +7,7 @@
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;
@@ -35,7 +35,7 @@
*/
public class DynamicPropertyLambda {
-
+
/**
* VAB connection manager backend
*
@@ -62,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())
);
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..7002467 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
@@ -5,7 +5,7 @@
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;
@@ -26,7 +26,7 @@
*/
public class ManualHTTPCalls {
-
+
/**
* Create VAB connection manager backend
*
@@ -53,7 +53,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())
);
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/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/cfgprovider/CFGSubModelProvider.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/CFGSubModelProvider.java
similarity index 94%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/cfgprovider/CFGSubModelProvider.java
rename to sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/CFGSubModelProvider.java
index fceb07d..e26dc5e 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/cfgprovider/CFGSubModelProvider.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/CFGSubModelProvider.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.cfgprovider;
+package org.eclipse.basyx.sandbox.components.cfgprovider;
import java.util.Map;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/cfgprovider/RawCFGSubModelProvider.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/RawCFGSubModelProvider.java
similarity index 96%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/cfgprovider/RawCFGSubModelProvider.java
rename to sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/RawCFGSubModelProvider.java
index 405f33e..4d4a2c3 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/cfgprovider/RawCFGSubModelProvider.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/RawCFGSubModelProvider.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.cfgprovider;
+package org.eclipse.basyx.sandbox.components.cfgprovider;
import java.util.HashMap;
import java.util.Map;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/AbstractCFGSubModelProviderServlet.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/AbstractCFGSubModelProviderServlet.java
similarity index 97%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/AbstractCFGSubModelProviderServlet.java
rename to sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/AbstractCFGSubModelProviderServlet.java
index c87d657..7198b6d 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/AbstractCFGSubModelProviderServlet.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/AbstractCFGSubModelProviderServlet.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.servlet.submodel.cfg;
+package org.eclipse.basyx.sandbox.components.cfgprovider.servlet;
import java.io.IOException;
import java.io.InputStream;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/CFGSubModelProviderServlet.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/CFGSubModelProviderServlet.java
similarity index 83%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/CFGSubModelProviderServlet.java
rename to sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/CFGSubModelProviderServlet.java
index 1391f89..be1b334 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/CFGSubModelProviderServlet.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/CFGSubModelProviderServlet.java
@@ -1,9 +1,9 @@
-package org.eclipse.basyx.components.servlet.submodel.cfg;
+package org.eclipse.basyx.sandbox.components.cfgprovider.servlet;
import java.util.Properties;
-import org.eclipse.basyx.components.cfgprovider.CFGSubModelProvider;
import org.eclipse.basyx.components.provider.BaseConfiguredProvider;
+import org.eclipse.basyx.sandbox.components.cfgprovider.CFGSubModelProvider;
import org.eclipse.basyx.submodel.restapi.SubModelProvider;
/**
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/RawCFGSubModelProviderServlet.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/RawCFGSubModelProviderServlet.java
similarity index 82%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/RawCFGSubModelProviderServlet.java
rename to sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/RawCFGSubModelProviderServlet.java
index 9a87495..0087b4c 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/RawCFGSubModelProviderServlet.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/RawCFGSubModelProviderServlet.java
@@ -1,8 +1,8 @@
-package org.eclipse.basyx.components.servlet.submodel.cfg;
+package org.eclipse.basyx.sandbox.components.cfgprovider.servlet;
import java.util.Properties;
-import org.eclipse.basyx.components.cfgprovider.RawCFGSubModelProvider;
+import org.eclipse.basyx.sandbox.components.cfgprovider.RawCFGSubModelProvider;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
import org.eclipse.basyx.submodel.restapi.SubModelProvider;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/AASDirectoryEntry.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/AASDirectoryEntry.java
similarity index 97%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/AASDirectoryEntry.java
rename to sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/AASDirectoryEntry.java
index 84589ef..34fdbdb 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/AASDirectoryEntry.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/AASDirectoryEntry.java
@@ -1,9 +1,9 @@
-package org.eclipse.basyx.components.directory;
+package org.eclipse.basyx.sandbox.components.registry;
import java.util.Collection;
import java.util.HashSet;
-import org.eclipse.basyx.components.directory.exception.AASDirectoryFormatException;
+import org.eclipse.basyx.sandbox.components.registry.exception.AASDirectoryFormatException;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/registry/StaticCFGDirectoryServlet.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/StaticCFGDirectoryServlet.java
similarity index 97%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/registry/StaticCFGDirectoryServlet.java
rename to sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/StaticCFGDirectoryServlet.java
index 57d0cbf..db4f329 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/registry/StaticCFGDirectoryServlet.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/StaticCFGDirectoryServlet.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.servlet.registry;
+package org.eclipse.basyx.sandbox.components.registry;
import java.io.IOException;
@@ -15,8 +15,7 @@
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.sandbox.components.registry.exception.AASDirectoryProviderException;
import org.eclipse.basyx.vab.protocol.http.server.BasysHTTPServlet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/exception/AASDirectoryFormatException.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/exception/AASDirectoryFormatException.java
similarity index 87%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/exception/AASDirectoryFormatException.java
rename to sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/exception/AASDirectoryFormatException.java
index 79aacf2..93e57a6 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/exception/AASDirectoryFormatException.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/exception/AASDirectoryFormatException.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.directory.exception;
+package org.eclipse.basyx.sandbox.components.registry.exception;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/exception/AASDirectoryProviderException.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/exception/AASDirectoryProviderException.java
similarity index 87%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/exception/AASDirectoryProviderException.java
rename to sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/exception/AASDirectoryProviderException.java
index 30edf58..ade137b 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/exception/AASDirectoryProviderException.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/exception/AASDirectoryProviderException.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.directory.exception;
+package org.eclipse.basyx.sandbox.components.registry.exception;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLPreconfiguredSubModelProvider.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLPreconfiguredSubModelProvider.java
similarity index 97%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLPreconfiguredSubModelProvider.java
rename to sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLPreconfiguredSubModelProvider.java
index 43dc58e..4360636 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLPreconfiguredSubModelProvider.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLPreconfiguredSubModelProvider.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.sqlprovider;
+package org.eclipse.basyx.sandbox.components.sqlprovider;
import java.util.Collection;
import java.util.HashMap;
@@ -8,10 +8,10 @@
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.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;
@@ -296,6 +296,7 @@
/**
* Split a whitespace delimited string
*/
+ @Override
protected Collection<String> splitString(String input) {
// Return value
HashSet<String> result = new HashSet<>();
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLProviderTestOLD.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLProviderTestOLD.java
similarity index 95%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLProviderTestOLD.java
rename to sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLProviderTestOLD.java
index 772b1ee..c2a5344 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLProviderTestOLD.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLProviderTestOLD.java
@@ -1,12 +1,12 @@
-package org.eclipse.basyx.components.sqlprovider;
+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.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;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLSubModelProvider.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLSubModelProvider.java
similarity index 97%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLSubModelProvider.java
rename to sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLSubModelProvider.java
index 59697d6..38914d3 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLSubModelProvider.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLSubModelProvider.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.sqlprovider;
+package org.eclipse.basyx.sandbox.components.sqlprovider;
import java.util.Collection;
import java.util.HashMap;
@@ -8,10 +8,10 @@
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.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;
@@ -23,7 +23,7 @@
* Asset administration shell sub model provider that connects to SQL database
*
* @author kuhn
- *
+ *
*/
public class SQLSubModelProvider extends BaseConfiguredProvider {
@@ -294,6 +294,7 @@
/**
* Split a whitespace delimited string
*/
+ @Override
protected Collection<String> splitString(String input) {
// Return value
HashSet<String> result = new HashSet<>();
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/SQLSubModelProviderServlet.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/servlet/SQLSubModelProviderServlet.java
similarity index 92%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/SQLSubModelProviderServlet.java
rename to sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/servlet/SQLSubModelProviderServlet.java
index 7de51c7..7ee2fab 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/SQLSubModelProviderServlet.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/servlet/SQLSubModelProviderServlet.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.servlet.submodel;
+package org.eclipse.basyx.sandbox.components.sqlprovider.servlet;
import java.io.IOException;
import java.io.InputStream;
@@ -8,7 +8,7 @@
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.sandbox.components.sqlprovider.SQLPreconfiguredSubModelProvider;
import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
/**
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/examples/basys.examples/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
similarity index 93%
rename from examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/code/BaSyxCreateProvideUseExampleAASSubmodel.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/code/BaSyxCreateProvideUseExampleAASSubmodel.java
index dc700af..9ca9e9d 100644
--- a/examples/basys.examples/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
@@ -7,7 +7,7 @@
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.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;
@@ -56,7 +56,7 @@
JSONConnector toDeviceManager = new JSONConnector(basyxConnector);
// - Access sub model property, check value
Map<String, Object> property = (Map<String, Object>) toDeviceManager
- .getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/status");
+ .getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/status");
assertEquals("offline", property.get("value"));
diff --git a/examples/basys.examples/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
similarity index 82%
rename from examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnection.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnection.java
index 59b886f..10a4bb7 100644
--- a/examples/basys.examples/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
@@ -16,7 +16,7 @@
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.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;
@@ -55,7 +55,7 @@
// - Add container property that holds other properties
SubmodelElementCollection container = new SubmodelElementCollection();
container.setIdShort("prop2");
- container.addElement(prop11);
+ container.addSubModelElement(prop11);
// - Add container to property map
addSubModelElement(container);
@@ -75,7 +75,7 @@
// 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/"),
+ .addSubmodelMapping("aas-001", "sm-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/submodel"),
// We connect via HTTP
new HTTPConnectorProvider());
@@ -88,7 +88,7 @@
// 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/"),
+ .addMapping("sm-001VAB", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/submodel"),
// We connect via HTTP
new HTTPConnectorProvider());
@@ -116,26 +116,26 @@
// - 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((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").get() == 123);
+ 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(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(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(SubmodelElementProvider.PROPERTIES + "/prop1/value", 456);
+ connSubModel1.setModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1/value", 456);
// - Read value back using VAB primitive
- assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1")).get("value") == 456);
+ 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").get() == 456);
+ assertTrue((int) subModel.getProperties().get("prop1").getValue() == 456);
}
}
diff --git a/examples/basys.examples/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
similarity index 82%
rename from examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnectionFull.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnectionFull.java
index 9e919e8..707398b 100644
--- a/examples/basys.examples/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
@@ -16,7 +16,7 @@
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.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;
@@ -58,7 +58,7 @@
// - Add container property that holds other properties
SubmodelElementCollection container = new SubmodelElementCollection();
container.setIdShort("prop2");
- container.addElement(prop11);
+ container.addSubModelElement(prop11);
// - Add container to property map
addSubModelElement(container);
@@ -79,10 +79,10 @@
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/")
+ .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/"),
+ .addMapping("sm-001MVAB", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModelManual/submodel"),
// We connect via HTTP
new HTTPConnectorProvider());
@@ -95,7 +95,7 @@
// 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/"),
+ .addSubmodelMapping("aas-001", "sm-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/submodel"),
// We connect via HTTP
new HTTPConnectorProvider());
@@ -123,27 +123,27 @@
// - 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((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").get() == 123);
+ 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(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(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(SubmodelElementProvider.PROPERTIES + "/prop1/value", 456);
+ connSubModel1.setModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1/value", 456);
// - Read value back using VAB primitive
- assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1")).get("value") == 456);
+ 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").get() == 456);
+ assertTrue((int) subModel.getProperties().get("prop1").getValue() == 456);
}
}
diff --git a/examples/basys.examples/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
similarity index 90%
rename from examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletConnectorConnection.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletConnectorConnection.java
index d3f4e0e..59152d1 100644
--- a/examples/basys.examples/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
@@ -57,7 +57,7 @@
// - Add container property that holds other properties
SubmodelElementCollection container = new SubmodelElementCollection();
container.setIdShort("prop2");
- container.addElement(prop11);
+ container.addSubModelElement(prop11);
// - Add container to property map
addSubModelElement(container);
@@ -78,7 +78,7 @@
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"),
+ .addSubmodelMapping("aas-001", "sm-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/submodel"),
// We connect via HTTP
new HTTPConnectorProvider());
@@ -89,7 +89,7 @@
// 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"),
+ .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());
@@ -120,13 +120,13 @@
// - 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((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").get());
+ assertEquals(123, properties.get("prop11").getValue());
}
}
diff --git a/examples/basys.examples/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
similarity index 75%
rename from examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletVABConnection.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletVABConnection.java
index 6138225..6e4e498 100644
--- a/examples/basys.examples/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
@@ -11,7 +11,7 @@
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.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;
@@ -28,8 +28,8 @@
*/
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 {
@@ -52,7 +52,7 @@
// - Add container property that holds other properties
SubmodelElementCollection container = new SubmodelElementCollection();
container.setIdShort("prop2");
- container.addElement(prop11);
+ container.addSubModelElement(prop11);
// - Add container to property map
addSubModelElement(container);
@@ -74,9 +74,9 @@
// 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"),
+ .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());
@@ -103,15 +103,15 @@
// 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);
+ 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(SubmodelElementProvider.PROPERTIES + "/prop1/value", 456);
+ connSubModel1.setModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1/value", 456);
// - Read value back using VAB primitive
- assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1/value")).get("value") == 456);
+ assertTrue((Integer) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1/value") == 456);
}
}
diff --git a/examples/basys.examples/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
similarity index 97%
rename from examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASDynamicOperationSnippet.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASDynamicOperationSnippet.java
index cd59adf..bd0243c 100644
--- a/examples/basys.examples/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
@@ -7,7 +7,7 @@
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.submodel.metamodel.map.SubModel;
@@ -48,7 +48,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())
);
diff --git a/examples/basys.examples/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
similarity index 97%
rename from examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASManualHTTPOperationsSnippet.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASManualHTTPOperationsSnippet.java
index 8da4b52..3be7c43 100644
--- a/examples/basys.examples/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
@@ -5,7 +5,7 @@
import java.util.Map;
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.submodel.metamodel.map.SubModel;
@@ -46,7 +46,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())
);
diff --git a/examples/basys.examples/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
similarity index 97%
rename from examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASPropertiesCRUDAccessSnippet.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASPropertiesCRUDAccessSnippet.java
index 74adbfa..8f7d879 100644
--- a/examples/basys.examples/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
@@ -4,7 +4,7 @@
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.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;
@@ -45,7 +45,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())
);
diff --git a/examples/basys.examples/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
similarity index 97%
rename from examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASTailoredSupplierSnippet.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASTailoredSupplierSnippet.java
index 379a696..d08cd3b 100644
--- a/examples/basys.examples/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
@@ -7,7 +7,7 @@
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.submodel.metamodel.map.SubModel;
@@ -85,7 +85,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())
);
diff --git a/examples/basys.examples/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
similarity index 96%
rename from examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASManualHTTPOperationsSnippet.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASManualHTTPOperationsSnippet.java
index 3fb38c5..b643870 100644
--- a/examples/basys.examples/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
@@ -5,7 +5,7 @@
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;
@@ -43,7 +43,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())
);
diff --git a/examples/basys.examples/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
similarity index 96%
rename from examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASPropertiesSnippet.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASPropertiesSnippet.java
index ed3a544..730cfd5 100644
--- a/examples/basys.examples/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
@@ -6,7 +6,7 @@
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;
@@ -45,7 +45,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())
);
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProvider.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProvider.java
similarity index 96%
rename from components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProvider.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProvider.java
index 655af40..ffa29dc 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProvider.java
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProvider.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.regression.cfgprovider;
+package org.eclipse.basyx.sandbox.regression.components.cfgprovider;
import static org.junit.Assert.assertEquals;
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProviderPropertyMetaData.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProviderPropertyMetaData.java
similarity index 97%
rename from components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProviderPropertyMetaData.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProviderPropertyMetaData.java
index 4af91ac..22f824e 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProviderPropertyMetaData.java
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProviderPropertyMetaData.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.regression.cfgprovider;
+package org.eclipse.basyx.sandbox.regression.components.cfgprovider;
import static org.junit.Assert.assertEquals;
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProviderSubmodelMetaData.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProviderSubmodelMetaData.java
similarity index 96%
rename from components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProviderSubmodelMetaData.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProviderSubmodelMetaData.java
index d38a7de..a3dfb92 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProviderSubmodelMetaData.java
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProviderSubmodelMetaData.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.regression.cfgprovider;
+package org.eclipse.basyx.sandbox.regression.components.cfgprovider;
import static org.junit.Assert.assertEquals;
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestAASDirectoryEntry.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestAASDirectoryEntry.java
similarity index 97%
rename from components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestAASDirectoryEntry.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestAASDirectoryEntry.java
index 662b48f..7ad49ce 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestAASDirectoryEntry.java
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestAASDirectoryEntry.java
@@ -1,9 +1,9 @@
-package org.eclipse.basyx.regression.directory.file;
+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.components.directory.AASDirectoryEntry;
+import org.eclipse.basyx.sandbox.components.registry.AASDirectoryEntry;
import org.junit.Test;
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestStaticDirectoryFileProvider.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestStaticDirectoryFileProvider.java
similarity index 97%
rename from components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestStaticDirectoryFileProvider.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestStaticDirectoryFileProvider.java
index 9449904..0395d56 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestStaticDirectoryFileProvider.java
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestStaticDirectoryFileProvider.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.regression.directory.file;
+package org.eclipse.basyx.sandbox.regression.components.directory.file;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestStaticDirectoryFileProviderExceptions.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestStaticDirectoryFileProviderExceptions.java
similarity index 96%
rename from components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestStaticDirectoryFileProviderExceptions.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestStaticDirectoryFileProviderExceptions.java
index 54e4749..369c60d 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestStaticDirectoryFileProviderExceptions.java
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestStaticDirectoryFileProviderExceptions.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.regression.directory.file;
+package org.eclipse.basyx.sandbox.regression.components.directory.file;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderAAS.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderAAS.java
similarity index 96%
rename from components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderAAS.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderAAS.java
index 1ef899b..c113a3f 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderAAS.java
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderAAS.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.regression.rawcfgprovider;
+package org.eclipse.basyx.sandbox.regression.components.rawcfgprovider;
import static org.junit.Assert.assertEquals;
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderAASNewModel.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderAASNewModel.java
similarity index 96%
rename from components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderAASNewModel.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderAASNewModel.java
index 8f9efc0..784ed50 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderAASNewModel.java
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderAASNewModel.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.regression.rawcfgprovider;
+package org.eclipse.basyx.sandbox.regression.components.rawcfgprovider;
import static org.junit.Assert.assertEquals;
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderSimpleValues.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderSimpleValues.java
similarity index 94%
rename from components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderSimpleValues.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderSimpleValues.java
index ef95857..4863157 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderSimpleValues.java
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderSimpleValues.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.regression.rawcfgprovider;
+package org.eclipse.basyx.sandbox.regression.components.rawcfgprovider;
import static org.junit.Assert.assertEquals;
@@ -56,7 +56,7 @@
// Get property value
Map<String, Object> value1 = (Map<String, Object>) connSubModel
- .getModelPropertyValue("/aas/submodels/rawSampleCFG/submodelElements/cfgProperty1/value");
+ .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");
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..68639c3
--- /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 "xsd::boolean";
+ case type::valueType::Int:
+ return "xsd::integer";
+ case type::valueType::Float:
+ return "xsd::float";
+ case type::valueType::String:
+ return "xsd::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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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/map_v2/SubModel.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/SubModel.h
index 7611de1..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;
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 7fa8855..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;
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 c972137..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
@@ -23,7 +23,10 @@
public virtual vab::ElementMap
{
public:
- using asset_t = basyx::submodel::map::Asset;
+ struct Path {
+ static constexpr char Submodels[] = "submodels";
+ static constexpr char Asset[] = "asset";
+ };
private:
Reference derivedFrom;
Asset asset;
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 84eaea1..4d7b630 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
@@ -16,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
{
@@ -99,7 +103,7 @@
auto & obj = objectList.at(n);
// Get id of object and create temporary
- const auto & id = obj.getProperty(map::Identifiable::Path::IdShort).template Get<std::string&>();
+ const auto & id = obj.getProperty(ElementContainerPath::IdShort).Get<std::string&>();
return this->getElement(id);
};
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 2dc836b..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,19 +32,15 @@
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")
- .template Get<std::string&>();
-
- return ModelTypes_::from_string(model_type);
+ auto model_type = this->map.getProperty(ModelTypePath::ModelType).getProperty(ModelTypePath::Name).Get<std::string&>();
+ return ModelTypes_::from_string(model_type);
};
}
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 276eddd..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
@@ -17,6 +17,11 @@
public virtual vab::ElementMap
{
public:
+ struct Path {
+ static constexpr char Dependencies[] = "dependencies";
+ };
+
+public:
using vab::ElementMap::ElementMap;
Formula();
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 efa29ec..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
@@ -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:
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 634de08..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
@@ -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);
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 09cae0a..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
@@ -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);
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 4d03ade..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
@@ -19,6 +19,12 @@
, 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;
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
index b85b2d6..c3aa385 100644
--- 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
@@ -16,6 +16,12 @@
, 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);
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 47b55fa..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
@@ -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:
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 694ec37..b50fb5a 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
@@ -13,6 +13,13 @@
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[] = "identifier";
+ };
private:
map::AdministrativeInformation administrativeInformation;
public:
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 37b1f7d..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
@@ -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);
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 ff60434..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
@@ -14,11 +14,17 @@
namespace map {
class SubmodelElement
- : public virtual api::ISubmodelElement,
- public virtual vab::ElementMap,
- public virtual Qualifiable,
- public Referable,
- public HasDataSpecification {
+ : public virtual api::ISubmodelElement
+ , public virtual vab::ElementMap
+ , public virtual Qualifiable
+ , public Referable
+ , public HasDataSpecification
+{
+public:
+ struct Path {
+ static constexpr char Kind[] = "kind";
+ static constexpr char SemanticId[] = "semanticId";
+ };
private:
Reference semanticId;
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 a149778..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;
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..670ad91 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;
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 62fbad3..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;
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 042adfe..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
@@ -5,6 +5,7 @@
#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>
@@ -12,78 +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 virtual Qualifiable
- , 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");
- }
-
- virtual const Reference * const getValueId() const override
- {
- if (&this->valueId)
+ // or if it's a primitive type, not null or object
+ if (object.GetObjectType() == type::objectType::Primitive)
{
- return this->valueId.get();
+ 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()));
}
- return nullptr;
- }
+ }
- virtual void setValueId(const api::IReference & valueId) override
- {
- this->valueId = util::make_unique<Reference>(valueId);
- this->map.insertKey("valueId", this->valueId->getMap());
- }
+ virtual basyx::object getObject() override
+ {
+ return this->map.getProperty(PropertyPath::Value);
+ }
- virtual KeyElements getKeyElementType() const override { return KeyElements::Property; };
+ 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 77d6001..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
@@ -14,6 +14,11 @@
public SubmodelElement,
public ModelType<ModelTypes::ReferenceElement>
{
+public:
+ struct Path {
+ static constexpr char Value[] = "value";
+ static constexpr char Kind[] = "kind";
+ };
private:
Reference value;
public:
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/submodelelement/property/Property.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/submodelelement/property/Property.h
index 53eb81a..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
@@ -69,6 +69,8 @@
{
this->valueId = valueId;
}
+
+ virtual KeyElements getKeyElementType() const override { return KeyElements::Property; };
};
}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/CMakeLists.txt b/sdks/c++/basys.sdk.cc/src/submodel/CMakeLists.txt
index da4b7eb..10ad2b5 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/CMakeLists.txt
+++ b/sdks/c++/basys.sdk.cc/src/submodel/CMakeLists.txt
@@ -23,6 +23,8 @@
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
@@ -67,6 +69,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
@@ -151,6 +165,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
@@ -197,6 +212,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
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 dd88992..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,14 +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.getKeyMap());
- 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 a9f1c49..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;
+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
index 226e10b..5a35320 100644
--- 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
@@ -7,38 +7,41 @@
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("version", version);
- this->map.insertKey("revision", revision);
+ this->map.insertKey(Path::Version, version);
+ this->map.insertKey(Path::Revision, revision);
}
void AdministrativeInformation::setVersion(const std::string &version)
{
- this->map.insertKey("version", version);
+ this->map.insertKey(Path::Version, version);
}
void AdministrativeInformation::setRevision(const std::string &revision)
{
- this->map.insertKey("revision", revision);
+ this->map.insertKey(Path::Revision, revision);
}
bool AdministrativeInformation::hasVersion() const
{
- return not this->map.getProperty("version").IsNull();
+ return not this->map.getProperty(Path::Version).IsNull();
}
bool AdministrativeInformation::hasRevision() const
{
- return not this->map.getProperty("revision").IsNull();
+ return not this->map.getProperty(Path::Revision).IsNull();
}
const std::string * const AdministrativeInformation::getVersion() const
{
- auto version = this->map.getProperty("version");
+ auto version = this->map.getProperty(Path::Version);
if (version.IsNull())
return nullptr;
@@ -47,7 +50,7 @@
const std::string * const AdministrativeInformation::getRevision() const
{
- auto revision = this->map.getProperty("revision");
+ auto revision = this->map.getProperty(Path::Revision);
if (revision.IsNull())
return nullptr;
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..fafd9df 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, basyx::object::make_object_ref(&dataSpecification));
}
void HasDataSpecification::addDataSpecification(const simple::Reference & reference)
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 32ce682..c6abe71 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,37 +4,32 @@
using namespace basyx::submodel::map;
using namespace basyx::submodel::api;
-struct IdentifierPath {
- static constexpr char IdType[] = "idType";
- static constexpr char Id[] = "id";
- static constexpr char AdministrativeInformation[] = "AdministrativeInformation";
-};
-
-constexpr char IdentifierPath::IdType[];
-constexpr char IdentifierPath::Id[];
-constexpr char IdentifierPath::AdministrativeInformation[];
+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 not this->map.getProperty(IdentifierPath::AdministrativeInformation).IsNull();
+ 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&>()
};
}
@@ -51,5 +46,5 @@
void Identifiable::setAdministrativeInformation(const AdministrativeInformation &administrativeInformation)
{
this->administrativeInformation = administrativeInformation;
- this->map.insertKey(IdentifierPath::AdministrativeInformation, this->administrativeInformation.getMap());
+ 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 131eaf3..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("qualifiers", 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("qualifiers").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("qualifiers").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("qualifiers").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("qualifiers").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/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 049df97..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,15 +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("invokable", this->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/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/tests/regression/submodel/CMakeLists.txt b/sdks/c++/basys.sdk.cc/tests/regression/submodel/CMakeLists.txt
index 5ba14b3..7caa12e 100644
--- a/sdks/c++/basys.sdk.cc/tests/regression/submodel/CMakeLists.txt
+++ b/sdks/c++/basys.sdk.cc/tests/regression/submodel/CMakeLists.txt
@@ -27,6 +27,7 @@
api/parts/test_View.cpp
api/property/test_Property.cpp
api/common/test_LangStringSet.cpp
+ api/property/test_Property.cpp
map_v2/test_Submodel.cpp
map_v2/common/test_ElementContainer.cpp
map_v2/dataspecification/test_DataSpecification.cpp
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
index 93911bc..23144ad 100644
--- 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
@@ -10,20 +10,23 @@
using namespace basyx::submodel;
-using ImplTypes = ::testing::Types<map::AssetAdministrationShell, simple::AssetAdministrationShell>;
+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 = Impl;
+ 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>("testAas",
+ aas = util::make_unique<impl_t>("testAas",
simple::Identifier::Custom("testAas"),
- typename Impl::asset_t{ "testAsset", simple::Identifier::Custom("testAsset") }
+ asset_t{ "testAsset", simple::Identifier::Custom("testAsset") }
);
}
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
index 6cac43c..f0de4ca 100644
--- 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
@@ -1,6 +1,7 @@
#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;
@@ -56,5 +57,259 @@
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("xsd:anyURI"));
+}
+
+TYPED_TEST(PropertyTest, TestSafeDateTime)
+{
+ map::Property<simple::DateTime> dateTime_property("test id");
+ std::string valueType = dateTime_property.getValueType();
+ ASSERT_EQ(valueType, std::string("xsd: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("xsd: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("xsd: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("xsd: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("xsd: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("xsd: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("xsd: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("xsd: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("xsd: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("xsd: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/java/basys.sdk/pom.xml b/sdks/java/basys.sdk/pom.xml
index 534a2a9..9fd83b1 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>0.1.0-SNAPSHOT</version>
<name>BaSyx SDK</name>
<packaging>jar</packaging>
@@ -175,4 +175,5 @@
<version>2.7.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..966a1d2 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
@@ -8,10 +8,13 @@
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.IAASRegistryService;
import org.eclipse.basyx.aas.restapi.AASModelProvider;
import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
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.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
/**
* An implementation of the IAASAggregator interface using maps internally
@@ -23,6 +26,24 @@
protected Map<String, VABMultiSubmodelProvider> aasProviderMap = new HashMap<>();
+ protected IAASRegistryService registry;
+
+ /**
+ * Constructs default AAS Aggregator
+ */
+ public AASAggregator() {
+ }
+
+ /**
+ * Constructs AAS Aggregator using the passed registry. This registry is used to
+ * resolve requests for remote submodels
+ *
+ * @param registry
+ */
+ public AASAggregator(IAASRegistryService registry) {
+ this.registry = registry;
+ }
+
@SuppressWarnings("unchecked")
@Override
public Collection<IAssetAdministrationShell> getAASList() {
@@ -43,14 +64,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.getModelPropertyValue("/aas");
IAssetAdministrationShell aas = AssetAdministrationShell.createAsFacade(aasMap);
return aas;
@@ -58,12 +75,16 @@
@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 VABMultiSubmodelProvider createMultiSubmodelProvider(AssetAdministrationShell aas) {
+ return new VABMultiSubmodelProvider(new AASModelProvider(aas), registry, new HTTPConnectorProvider());
}
@Override
@@ -71,7 +92,14 @@
aasProviderMap.remove(aasId.getId());
}
- public VABMultiSubmodelProvider getProviderForAASId(String aasId) {
- return aasProviderMap.get(aasId);
+ @Override
+ public IModelProvider getAASProvider(IIdentifier aasId) {
+ VABMultiSubmodelProvider 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..600014f 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
@@ -5,6 +5,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 +31,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 +53,7 @@
*
* @param aas the updated AAS
*/
- public void updateAAS(AssetAdministrationShell aas);
+ public void updateAAS(AssetAdministrationShell aas) throws ResourceNotFoundException;
/**
* Deletes a specific Asset Administration Shell
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..f14a1a0 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
@@ -5,12 +5,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 +30,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,7 +40,20 @@
* @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) {
+ if (!url.endsWith(AASAggregatorProvider.PREFIX)) {
+ url = url + AASAggregatorProvider.PREFIX;
+ }
+ return url;
}
@SuppressWarnings("unchecked")
@@ -45,32 +61,60 @@
public Collection<IAssetAdministrationShell> getAASList() {
Collection<Map<String, Object>> collection = (Collection<Map<String, Object>>) provider.getModelPropertyValue("");
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.getModelPropertyValue("");
+ 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.setModelPropertyValue(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.setModelPropertyValue(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..4b0ca6b 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,17 @@
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,22 +23,22 @@
*
*/
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);
@@ -50,57 +49,57 @@
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 {
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).getModelPropertyValue(restPath);
}
}
}
@@ -108,28 +107,30 @@
@Override
public void setModelPropertyValue(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).setModelPropertyValue(restPath, newValue);
}
} else {
throw new MalformedRequestException("Set with empty path is not supported by aggregator");
@@ -139,22 +140,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 +157,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 +185,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/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..0034015
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/json/JSONToMetamodelConverter.java
@@ -0,0 +1,72 @@
+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.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 parse JSON to Metamodel Objects
+ *
+ * @author conradi
+ *
+ */
+public class JSONToMetamodelConverter {
+
+ private Map<String, Object> root;
+
+ @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() {
+ return ((List<Object>) root.get(MetamodelToJSONConverter.ASSET_ADMINISTRATION_SHELLS)).stream()
+ .map(i -> AssetAdministrationShell.createAsFacade((Map<String, Object>) i)).collect(Collectors.toList());
+ }
+
+ /**
+ * 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..59ba7a4
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/json/MetamodelToJSONConverter.java
@@ -0,0 +1,64 @@
+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);
+ }
+}
\ 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..2d2c381 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,6 +10,7 @@
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;
@@ -21,6 +22,7 @@
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.restapi.SubModelProvider;
import org.eclipse.basyx.vab.exception.FeatureNotImplementedException;
import org.eclipse.basyx.vab.factory.java.ModelProxyFactory;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
@@ -64,11 +66,8 @@
@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());
+ // look up SM descriptor in the registry
+ SubmodelDescriptor smDescriptor = aasDirectory.lookupSubmodel(aasId, smId);
// get address of the submodel descriptor
String addr = smDescriptor.getFirstEndpoint();
@@ -78,9 +77,9 @@
}
@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
@@ -99,23 +98,16 @@
}
@Override
+ @Deprecated
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");
- }
+ createAAS(aas, endpoint);
}
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 +120,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) {
// 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 +154,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 = connectorProvider.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..af0cf1e 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
@@ -31,12 +31,22 @@
/**
* Creates an AAS on a remote server.
*/
+ @Deprecated
void createAAS(AssetAdministrationShell aas, IIdentifier aasId, String endpoint);
/**
+ * Creates an AAS on a remote server
+ *
+ * @param aas
+ * @param aasId
+ * @param 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
@@ -50,6 +60,14 @@
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);
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..6e1ebe8
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/IAasEnv.java
@@ -0,0 +1,18 @@
+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..78a9a21 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
@@ -9,6 +9,7 @@
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.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;
@@ -25,7 +26,7 @@
/**
* Return all registered submodels of this AAS
*
- * @return
+ * @return IdShort -> ISubmodel
*/
public Map<String, ISubModel> getSubModels();
@@ -37,7 +38,7 @@
public Collection<IReference> getSubmodelReferences();
/**
- * Add a sub model to the AAS
+ * Add a submodel to the AAS
*
* @param subModel
* The added sub model
@@ -45,6 +46,20 @@
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.
*
* @return
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..20e2fc8 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,7 +1,9 @@
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;
@@ -22,6 +24,8 @@
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.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;
@@ -29,29 +33,47 @@
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
- * and path
*
- * @param path
* @param proxy
* @param manager
*/
+ @Deprecated
public ConnectedAssetAdministrationShell(VABElementProxy proxy, ConnectedAssetAdministrationShellManager manager) {
super(proxy);
- this.manager = 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 an already cached local copy
+ *
+ * @param proxy
+ * @param localCopy
+ */
+ public ConnectedAssetAdministrationShell(VABElementProxy proxy, AssetAdministrationShell localCopy) {
+ super(proxy);
}
/**
@@ -118,15 +140,28 @@
return set.stream().map(ConceptDictionary::createAsFacade).collect(Collectors.toSet());
}
+ @SuppressWarnings("unchecked")
@Override
public Map<String, ISubModel> getSubModels() {
- return manager.retrieveSubmodels(getIdentification());
+ Collection<Map<String, Object>> submodelCollection = (Collection<Map<String, Object>>) getProxy().getModelPropertyValue(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) {
subModel.setParent(getReference());
- getProxy().createValue("/submodels", subModel);
+ Map<String, Object> convertedMap = SubmodelElementMapCollectionConverter.smToMap(subModel);
+ String accessPath = VABPathTools.concatenatePaths(AssetAdministrationShell.SUBMODELS, subModel.getIdShort());
+ getProxy().setModelPropertyValue(accessPath, convertedMap);
}
@Override
@@ -169,4 +204,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/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..379e956
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/AasEnv.java
@@ -0,0 +1,148 @@
+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..3fc447c 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
@@ -35,6 +35,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;
@@ -61,7 +62,7 @@
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
@@ -69,6 +70,18 @@
public AssetAdministrationShell() {
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) {
@@ -289,6 +302,13 @@
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
*
@@ -322,7 +342,7 @@
private void addSubmodelReferences(SubModel submodel) {
addSubmodelReference(submodel.getReference());
}
-
+
private KeyElements getKeyElement() {
return KeyElements.ASSETADMINISTRATIONSHELL;
}
@@ -342,4 +362,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..d4a6ef2 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
@@ -14,6 +14,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 +23,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 +31,10 @@
*/
public AASDescriptor(Map<String, Object> map) {
super(map);
+ validate(map);
+
+ // Set map again
+ putAll(map);
}
protected AASDescriptor() {
@@ -96,6 +101,7 @@
// Add new sub model descriptor to list
submodelDescriptors.add(desc);
+ put(AssetAdministrationShell.SUBMODELS, submodelDescriptors);
// Enable method chaining
return this;
@@ -112,6 +118,17 @@
}
}
+ @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()) {
+ // Don't use getSubmodelDescriptors here since it returns a copy
+ ((Collection<Object>) get(AssetAdministrationShell.SUBMODELS)).remove(toRemove.get());
+ }
+ }
+
/**
* Retrieves a submodel descriptor based on the globally unique id of the
* submodel
@@ -179,5 +196,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..6c0964b
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/CustomId.java
@@ -0,0 +1,22 @@
+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..48b8b72 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
@@ -12,6 +12,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;
/**
@@ -105,6 +106,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(AssetAdministrationShell.ENDPOINTS) || !(map.get(AssetAdministrationShell.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/SubmodelDescriptor.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/SubmodelDescriptor.java
index 2149eda..bb272e8 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
@@ -4,8 +4,11 @@
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 +19,7 @@
* @author kuhn
*
*/
-public class SubmodelDescriptor extends ModelDescriptor {
+public class SubmodelDescriptor extends ModelDescriptor implements IHasSemantics {
public static final String MODELTYPE = "SubmodelDescriptor";
@@ -25,6 +28,7 @@
*/
public SubmodelDescriptor(Map<String, Object> map) {
super(map);
+ validate(map);
}
/**
@@ -42,7 +46,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 +56,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..148030e 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
@@ -49,8 +49,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);
}
/**
@@ -122,6 +134,10 @@
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);
}
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..90e2d4f 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
@@ -36,6 +36,15 @@
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());
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..9ad20a4 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
@@ -45,6 +45,15 @@
// Default values
put(CONTAINEDELEMENT, new HashSet<Reference>());
}
+
+ /**
+ * Constructor accepting only mandatory attribute
+ * @param idShort
+ */
+ public View(String idShort) {
+ this();
+ setIdShort(idShort);
+ }
/**
*
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
index 2dc8ede..6ff18e4 100644
--- 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
@@ -36,7 +36,7 @@
/**
* Delete SM descriptor from registry
*/
- public void delete(IIdentifier aasId, String smIdShort) throws ProviderException;
+ public void delete(IIdentifier aasId, IIdentifier smId) throws ProviderException;
/**
* Lookup AAS
@@ -49,5 +49,28 @@
* @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/memory/AASRegistry.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/AASRegistry.java
index 6a2e7f5..1ac6c8d 100644
--- 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
@@ -1,11 +1,13 @@
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.IAASRegistryService;
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;
@@ -63,32 +65,60 @@
@Override
public void register(IIdentifier aas, SubmodelDescriptor smDescriptor) {
try {
- delete(aas, smDescriptor.getIdShort());
+ 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, String smIdShort) {
+ 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.getSubmodelDescriptorFromIdShort(smIdShort) == null) {
+ 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(smIdShort);
+ desc.removeSubmodelDescriptor(smId);
handler.update(desc);
- logger.debug("Deleted submodel " + smIdShort + " from AAS " + aasId.getId());
+ 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/proxy/AASRegistryProxy.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/proxy/AASRegistryProxy.java
index a84b403..15ace7c 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
@@ -27,7 +27,7 @@
/**
* Local proxy class that hides HTTP calls to BaSys registry
*
- * @author kuhn
+ * @author kuhn, schnicke
*
*/
public class AASRegistryProxy extends VABDirectoryProxy implements IAASRegistryService {
@@ -41,7 +41,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(DirectoryModelProvider.PREFIX)) {
+ url = url.substring(0, url.length() - DirectoryModelProvider.PREFIX.length());
+ }
+ return url;
}
/**
@@ -130,7 +143,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.setModelPropertyValue(VABPathTools.concatenatePaths(buildSubmodelPath(aas), URLEncoder.encode(smDescriptor.getIdentifier().getId(), "UTF-8")), smDescriptor);
} catch (Exception e) {
if (e instanceof ProviderException) {
throw (ProviderException) e;
@@ -141,9 +154,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;
@@ -158,5 +171,36 @@
String encodedAASId = VABPathTools.encodePathElement(aas.getId());
return VABPathTools.concatenatePaths(encodedAASId, DirectoryModelProvider.SUBMODELS);
}
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public List<SubmodelDescriptor> lookupSubmodels(IIdentifier aasId) throws ProviderException {
+ try {
+ Object result = provider.getModelPropertyValue(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.getModelPropertyValue(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/DirectoryModelProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/restapi/DirectoryModelProvider.java
index f2072d0..fffe50d 100644
--- 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
@@ -211,7 +211,16 @@
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));
+ 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);
@@ -246,12 +255,13 @@
ModelUrn aasId = retrieveModelURN(splitted[0]);
SubmodelDescriptor smDescriptor = createSMDescriptorFromMap(newEntity);
+ String smId = smDescriptor.getIdentifier().getId();
//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() +
+ getSmDescriptorFromAAS(aasId, smId);
+ throw new ResourceAlreadyExistsException("A Submodel with id '" + smId +
"' already exists in aas '" + splitted[0] + "'. Try update instead.");
} catch (ResourceNotFoundException e) {
registry.register(aasId, smDescriptor);
@@ -285,11 +295,12 @@
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) {
+ 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, smId);
+ registry.delete(aasId, smDesc.getIdentifier());
} else {
throw new MalformedRequestException("Delete with empty path is not supported by registry");
}
@@ -337,7 +348,7 @@
throw new ResourceNotFoundException("Specified AASId '" + aasId.getId() + "' does not exist.");
}
- SubmodelDescriptor smDescriptor = aasDescriptor.getSubmodelDescriptorFromIdShort(smId);
+ SubmodelDescriptor smDescriptor = aasDescriptor.getSubModelDescriptorFromIdentifierId(smId);
if (smDescriptor == null) {
throw new ResourceNotFoundException("Specified SMId '" + smId + "' for AAS " + aasId.getId() + " does not exist.");
}
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
index 2ae86be..879c230 100644
--- 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
@@ -2,7 +2,9 @@
import java.util.HashMap;
+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;
@@ -43,81 +45,67 @@
@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);
+ VABMultiSubmodelProvider provider = aas_providers.get(aasId);
+ if (provider == null) {
+ throw new ResourceNotFoundException("AAS with ID \"" + aasId + "\" does not exist.");
}
- return null;
+ String subPath = getSubPath(path, aasId);
+ return provider.getModelPropertyValue(subPath);
}
@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);
+ VABMultiSubmodelProvider provider = aas_providers.get(aasId);
+ if (provider == null) {
+ throw new ResourceNotFoundException("AAS with ID \"" + aasId + "\" does not exist.");
}
+ 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);
+ VABMultiSubmodelProvider provider = aas_providers.get(aasId);
+ if (provider == null) {
+ throw new ResourceNotFoundException("AAS with ID \"" + aasId + "\" does not exist.");
}
+ 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);
+ VABMultiSubmodelProvider provider = aas_providers.get(aasId);
+ if (provider == null) {
+ throw new ResourceNotFoundException("AAS with ID \"" + aasId + "\" does not exist.");
}
+ 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);
+ VABMultiSubmodelProvider provider = aas_providers.get(aasId);
+ if (provider == null) {
+ throw new ResourceNotFoundException("AAS with ID \"" + aasId + "\" does not exist.");
}
+ 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);
+ VABMultiSubmodelProvider provider = aas_providers.get(aasId);
+ if (provider == null) {
+ throw new ResourceNotFoundException("AAS with ID \"" + aasId + "\" does not exist.");
}
- return null;
+ String subPath = getSubPath(path, aasId);
+ return provider.invokeOperation(subPath, parameter);
}
/**
@@ -131,7 +119,7 @@
*/
private String getId(String path) {
if (path == null) {
- return null;
+ throw new MalformedRequestException("No AASId specified.");
}
String[] elements = VABPathTools.splitPath(path);
@@ -139,7 +127,7 @@
String aasId = elements[0];
return aasId;
} else {
- return null;
+ throw new MalformedRequestException("No AASId specified.");
}
}
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
index c4a401a..02cf8d9 100644
--- 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
@@ -3,15 +3,24 @@
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.IAASRegistryService;
+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.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.IConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
/**
* Provider class that implements the AssetAdministrationShellServices <br />
@@ -75,11 +84,26 @@
* 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 IAASRegistryService registry = null;
+
+ /**
+ * Store HTTP Connector
+ */
+ protected IConnectorProvider connectorProvider = null;
/**
* Constructor
@@ -104,6 +128,29 @@
// Store content provider
addSubmodel(smID, contentProvider);
}
+
+ /**
+ * Constructor that accepts a registry and a connection provider
+ * @param registry
+ * @param provider
+ */
+ public VABMultiSubmodelProvider(IAASRegistryService registry, IConnectorProvider provider) {
+ this();
+ this.registry = registry;
+ this.connectorProvider = provider;
+ }
+
+ /**
+ * Constructor that accepts a aas provider, a registry and a connection provider
+ * @param contentProvider
+ * @param registry
+ * @param provider
+ */
+ public VABMultiSubmodelProvider(AASModelProvider contentProvider, IAASRegistryService registry, HTTPConnectorProvider provider) {
+ this(contentProvider);
+ this.registry = registry;
+ this.connectorProvider = provider;
+ }
/**
* Set an AAS for this provider
@@ -113,9 +160,11 @@
* @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.getModelPropertyValue("")).getIdentification();
}
/**
@@ -127,6 +176,7 @@
* Model content provider
*/
@SuppressWarnings("unchecked")
+ @Deprecated
public void addSubmodel(String elementId, SubModelProvider modelContentProvider) {
// Add model provider
submodel_providers.put(elementId, modelContentProvider);
@@ -137,6 +187,15 @@
aas_provider.createValue("/submodels", sm);
}
+ @SuppressWarnings("unchecked")
+ public void addSubmodel(SubModelProvider modelContentProvider) {
+ SubModel sm = SubModel.createAsFacade((Map<String, Object>) modelContentProvider.getModelPropertyValue("/"));
+ submodel_providers.put(sm.getIdShort(), modelContentProvider);
+
+ // Adds a new submodel to the registered AAS
+ aas_provider.createValue("/submodels", sm);
+ }
+
/**
* Remove a provider
*
@@ -154,75 +213,104 @@
@Override
public Object getModelPropertyValue(String path) throws ProviderException {
VABPathTools.checkPathForNull(path);
+ path = VABPathTools.stripSlashes(path);
String[] pathElements = VABPathTools.splitPath(path);
- if (pathElements.length == 0) { // e.g. "/"
- return null;
- } else if (pathElements[0].equals("aas")) {
+ if (pathElements.length > 0 && 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;
+ return retrieveSubmodels();
} else {
- IModelProvider hashmapProvider = submodel_providers.get(pathElements[2]);
+ IModelProvider provider = submodel_providers.get(pathElements[2]);
- if(hashmapProvider == null) {
- throw new ResourceNotFoundException("Submodel with id " + pathElements[2] + " does not exist");
+ if (provider == null) {
+ // Get a model provider for the submodel in the registry
+ provider = getModelProvider(pathElements[2]);
}
// - Retrieve submodel or property value
- return hashmapProvider.getModelPropertyValue(VABPathTools.buildPath(pathElements, 3));
+ return provider.getModelPropertyValue(VABPathTools.buildPath(pathElements, 4));
}
} else {
// Handle access to AAS
return aas_provider.getModelPropertyValue(VABPathTools.buildPath(pathElements, 1));
}
} else {
- return null;
+ 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.getModelPropertyValue("")));
+ }
+
+ // Check for remote submodels
+ if (registry != null) {
+ AASDescriptor desc = registry.lookupAAS(aasId);
+ 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<SubModel> remoteSms = missingIds.stream().map(id -> desc.getSubModelDescriptorFromIdentifierId(id.getId())).
+ map(smDesc -> smDesc.getFirstEndpoint()).map(endpoint -> connectorProvider.getConnector(endpoint)).
+ map(p -> (Map<String, Object>) p.getModelPropertyValue("")).map(m -> SubModel.createAsFacade(m)).collect(Collectors.toList());
+ submodels.addAll(remoteSms);
+ }
+ }
+
+ return submodels;
+ }
+
+ /**
* Change a model property value
*/
@Override
public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
- VABPathTools.checkPathForNull(path);
+ 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'
- submodel_providers.get(pathElements[2]).setModelPropertyValue(propertyPath, newValue);
+
+ 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);
+ }
+
+ IModelProvider provider;
+ try {
+ 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.setModelPropertyValue(propertyPath, newValue);
+ } catch (ResourceNotFoundException e) {
+ createSubModel(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);
- }
- }
- }
+ throw new MalformedRequestException("Create is not supported by VABMultiSubmodelProvider. Path was: " + path);
}
- 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) {
@@ -235,7 +323,7 @@
// Adds a new submodel to the registered AAS
SubModel sm = SubModel.createAsFacade((Map<String, Object>) newSM);
- addSubmodel(sm.getIdShort(), new SubModelProvider(sm));
+ addSubmodel(new SubModelProvider(sm));
}
@@ -243,14 +331,15 @@
@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 (!submodel_providers.containsKey(smIdShort)) {
- return;
+ if (!isSubmodelLocal(smIdShort)) {
+ return;
}
// Delete submodel reference from aas
@@ -261,26 +350,99 @@
// Remove submodel provider
submodel_providers.remove(smIdShort);
} else if (propertyPath.length() > 0) {
- submodel_providers.get(pathElements[2]).deleteValue(propertyPath);
+ 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 {
- 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);
+ 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
- return submodel_providers.get(pathElements[2]).invokeOperation(operationPath, parameter);
+ 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 connectorProvider.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);
}
}
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..a0dc960 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
@@ -17,6 +17,7 @@
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.valuetypedef.PropertyValueTypeDefHelper;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -50,7 +51,7 @@
//The IQualifiable object has to be treated as Map here, as the Interface has no Setters
Map<String, Object> qualifierObj = (Map<String, Object>) xmlObject.get(QUALIFIER);
- qualifiable.put(Qualifiable.CONSTRAINTS, parseConstraints(qualifierObj));
+ qualifiable.put(Qualifiable.QUALIFIERS, parseConstraints(qualifierObj));
}
@@ -126,7 +127,7 @@
qualifier.setType(type);
qualifier.setValue(value);
qualifier.setValueId(ref);
- qualifier.setValueType(valueType);
+ qualifier.setValueType(PropertyValueTypeDefHelper.fromName(valueType));
return qualifier;
}
@@ -143,10 +144,10 @@
* @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);
@@ -209,7 +210,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/submodelelement/SubmodelElementCollectionXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/SubmodelElementCollectionXMLConverter.java
index 38cfc77..af6f74d 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
@@ -67,7 +67,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..5b3bf55 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
@@ -38,9 +38,9 @@
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;
@@ -50,7 +50,7 @@
/**
* 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
*
@@ -61,6 +61,7 @@
public static final String SUBMODEL_ELEMENT = "aas:submodelElement";
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 +69,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 +79,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,7 +101,7 @@
* 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) {
@@ -191,7 +192,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
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..d8f3dff 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
@@ -15,7 +15,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 +23,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..f44b4b8 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
@@ -3,8 +3,11 @@
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.slf4j.Logger;
@@ -14,7 +17,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,6 +35,7 @@
* @param xmlObject the Map with the content of XML tag <aas:property>
* @return the parsed Property
*/
+ @SuppressWarnings("unchecked")
public static Property parsePropery(Map<String, Object> xmlObject) {
Property property = new Property();
@@ -41,9 +45,15 @@
String valueType = XMLHelper.getString(xmlObject.get(SubmodelElementXMLConverter.VALUE_TYPE));
String value = XMLHelper.getString(xmlObject.get(SubmodelElementXMLConverter.VALUE));
+ Map<String, Object> xmlValueId = (Map<String, Object>) xmlObject.get(VALUE_ID);
+ Reference valueId = ReferenceXMLConverter.parseReference(xmlValueId);
+
property.set(value, PropertyValueTypeDefHelper.fromName(valueType));
- //FIXME the XML-ELement valueId has no corresponding field in Property
+ if(valueId != null) {
+ property.setValueId(valueId);
+ }
+
return property;
}
@@ -62,12 +72,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 +95,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));
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..6580fa7 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
@@ -5,7 +5,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.valuetypedef.PropertyValueTypeDefHelper;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.Range;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -33,7 +34,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(PropertyValueTypeDefHelper.fromName(valueType), min, max);
populateSubmodelElement(xmlObject, range);
return range;
}
@@ -68,7 +69,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/metamodel/api/IElementContainer.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/IElementContainer.java
index 093e1b2..8e72294 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
@@ -41,4 +41,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
index 2f716ab..2ab51af 100644
--- 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
@@ -1,5 +1,7 @@
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;
@@ -20,4 +22,12 @@
*
*/
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/qualifier/qualifiable/IQualifiable.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IQualifiable.java
index 28b33f7..302d175 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
@@ -9,5 +9,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..143667d 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
@@ -2,6 +2,7 @@
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.valuetypedef.PropertyValueTypeDef;
/**
* Interface for Qualifier
@@ -13,9 +14,9 @@
public interface IQualifier extends IHasSemantics, IConstraint {
public String getType();
- public String getValue();
+ public Object getValue();
public IReference getValueId();
- public String getValueType();
+ public PropertyValueTypeDef getValueType();
}
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..542be10 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
@@ -16,4 +16,8 @@
*/
public interface ISubmodelElement extends IElement, IHasDataSpecification, IReferable, IQualifiable, IHasSemantics, IHasKind {
public String getModelType();
+
+ public Object getValue();
+
+ public void setValue(Object value);
}
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..ef185cd 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,8 @@
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 +12,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 +33,7 @@
*
* @return
*/
+ @Override
public Map<String, ISubmodelElement> getSubmodelElements();
/**
@@ -42,6 +41,7 @@
*
* @return
*/
+ @Override
public Map<String, IProperty> getProperties();
/**
@@ -49,5 +49,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/dataelement/IProperty.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IProperty.java
index 20d1381..71d91a7 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
@@ -2,6 +2,7 @@
import org.eclipse.basyx.submodel.metamodel.api.IElement;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDef;
import org.eclipse.basyx.vab.exception.provider.ProviderException;
/**
@@ -12,11 +13,13 @@
*/
public interface IProperty extends IElement, IDataElement {
/**
+ * Will be replaced by getValue()
* Get property value
*
* @return Property value
* @throws Exception
*/
+ @Deprecated
public Object get() throws Exception;
/**
@@ -31,7 +34,7 @@
*
* @return
*/
- public String getValueType();
+ public PropertyValueTypeDef 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..f9f4015 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,7 @@
package org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDef;
+
/**
* A range data element is a data element that defines a range with min and max.
*
@@ -12,7 +14,7 @@
*
* @return
*/
- String getValueType();
+ PropertyValueTypeDef getValueType();
/**
* Returns the minimum value of the range. <br />
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..3f1c95b
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IAsyncInvocation.java
@@ -0,0 +1,26 @@
+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..98b56d6 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
@@ -43,4 +43,13 @@
* @throws Exception
*/
public Object invoke(Object... params) throws Exception;
+
+ /**
+ * Invoke operation with given parameter asynchronously
+ *
+ * @param params
+ * Operation parameter
+ * @return An IAsyncInvocation
+ */
+ public IAsyncInvocation invokeAsync(Object... params);
}
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..fc4964e 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
@@ -16,7 +16,7 @@
public class ConnectedElement implements IElement {
private VABElementProxy proxy;
- private VABModelMap<Object> cached;
+ protected VABModelMap<Object> cached;
public VABElementProxy getProxy() {
return proxy;
@@ -57,6 +57,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
index 5d0a57a..b1a56b3 100644
--- 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
@@ -12,11 +12,11 @@
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.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;
@@ -24,10 +24,12 @@
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.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;
/**
@@ -42,19 +44,29 @@
super(proxy);
}
- protected KeyElements getKeyElement() {
- return KeyElements.SUBMODELELEMENT;
+ /**
+ * 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;
}
- @SuppressWarnings("unchecked")
+ protected KeyElements getKeyElement() {
+ return KeyElements.SUBMODEL;
+ }
+
@Override
public IReference getSemanticId() {
- return Reference.createAsFacade((Map<String, Object>) getElem().get(HasSemantics.SEMANTICID));
+ return HasSemantics.createAsFacade(getElem()).getSemanticId();
}
@Override
public IAdministrativeInformation getAdministration() {
- return AdministrativeInformation.createAsFacade(getElem());
+ return Identifiable.createAsFacade(getElem(), getKeyElement()).getAdministration();
}
@Override
@@ -92,52 +104,94 @@
return Referable.createAsFacade(getElem(), getKeyElement()).getDescription();
}
- @SuppressWarnings("unchecked")
@Override
public IReference getParent() {
- return Reference.createAsFacade((Map<String, Object>) getElem().getPath(Referable.PARENT));
+ return Referable.createAsFacade(getElem(), getKeyElement()).getParent();
}
@Override
- public Collection<IConstraint> getQualifier() {
- return Qualifiable.createAsFacade(getElem()).getQualifier();
+ 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().setModelPropertyValue(path, converted);
+ return;
+ }
}
-
- 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);
- }
+ getProxy().setModelPropertyValue(path, element);
}
@Override
public Map<String, IProperty> getProperties() {
- return ConnectedSubmodelElementFactory.getProperties(getProxy(), SubmodelElementProvider.PROPERTIES,
- SubmodelElementProvider.PROPERTIES);
+ return ConnectedSubmodelElementFactory.getProperties(getProxy(), MultiSubmodelElementProvider.ELEMENTS,
+ MultiSubmodelElementProvider.ELEMENTS);
}
@Override
public Map<String, IOperation> getOperations() {
- return ConnectedSubmodelElementFactory.getOperations(getProxy(), SubmodelElementProvider.OPERATIONS,
- SubmodelElementProvider.OPERATIONS);
+ return ConnectedSubmodelElementFactory.getOperations(getProxy(), MultiSubmodelElementProvider.ELEMENTS,
+ MultiSubmodelElementProvider.ELEMENTS);
}
@Override
public Map<String, ISubmodelElement> getSubmodelElements() {
return ConnectedSubmodelElementFactory.getConnectedSubmodelElements(getProxy(),
- SubmodelElementProvider.ELEMENTS, SubmodelElementProvider.ELEMENTS);
+ MultiSubmodelElementProvider.ELEMENTS, MultiSubmodelElementProvider.ELEMENTS);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Map<String, Object> getValues() {
+ return (Map<String, Object>) getProxy().getModelPropertyValue(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().getModelPropertyValue(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/ConnectedSubmodelElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElement.java
index a56d67e..e5b2318 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
@@ -17,6 +17,7 @@
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.restapi.MultiSubmodelElementProvider;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
/**
@@ -54,8 +55,8 @@
}
@Override
- public Collection<IConstraint> getQualifier() {
- return Qualifiable.createAsFacade(getElem()).getQualifier();
+ public Collection<IConstraint> getQualifiers() {
+ return Qualifiable.createAsFacade(getElem()).getQualifiers();
}
@Override
@@ -89,4 +90,9 @@
public IReference getReference() {
return Referable.createAsFacade(getElem(), getKeyElement()).getReference();
}
+
+ @Override
+ public void setValue(Object value) {
+ getProxy().setModelPropertyValue(MultiSubmodelElementProvider.VALUE, value);
+ }
}
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..6ebc44e 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,5 @@
package org.eclipse.basyx.submodel.metamodel.connected.submodelelement;
-import java.util.Collection;
import java.util.Map;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
@@ -8,6 +7,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 +25,8 @@
}
@Override
- public Collection<ISubmodelElement> getValue() {
- return getSubmodelElements().values();
+ public Map<String, ISubmodelElement> getValue() {
+ return getSubmodelElements();
}
@Override
@@ -57,4 +58,47 @@
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().getModelPropertyValue(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().setModelPropertyValue(element.getIdShort(), converted);
+ return;
+ }
+ }
+
+ getProxy().setModelPropertyValue(element.getIdShort(), element);
+ }
}
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..f74e68e 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
@@ -25,9 +25,9 @@
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;
@@ -99,7 +99,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);
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..c5b4f5c 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,7 +1,5 @@
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.IBlob;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Blob;
@@ -19,13 +17,11 @@
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();
+ return (byte[]) getProxy().getModelPropertyValue(Property.VALUE);
}
@Override
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..b2210ec 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
@@ -20,4 +20,9 @@
protected KeyElements getKeyElement() {
return KeyElements.DATAELEMENT;
}
+
+ @Override
+ public Object getValue() {
+ throw new UnsupportedOperationException("getValue is only possible in specific Element");
+ }
}
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..83768af 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,5 @@
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 +17,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().getModelPropertyValue(Property.VALUE);
}
@Override
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..28d81f5 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
@@ -6,8 +6,8 @@
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.PropertyValueTypeDef;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDefHelper;
import org.eclipse.basyx.vab.exception.provider.ProviderException;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
@@ -27,30 +27,28 @@
@Override
public Object get() throws Exception {
- return retrieveObject();
+ return getValue();
}
@Override
public void set(Object newValue) throws ProviderException {
- getProxy().setModelPropertyValue(Property.VALUE, newValue);
+ getProxy().setModelPropertyValue(Property.VALUE, PropertyValueTypeDefHelper.prepareForSerialization(newValue));
}
- @SuppressWarnings({ "unchecked" })
@Override
- public String getValueType() {
- Object o = getProxy().getModelPropertyValue("");
- return PropertyValueTypeDefHelper.readTypeDef(((Map<String, Object>) o).get(Property.VALUETYPE)).toString();
+ public PropertyValueTypeDef getValueType() {
+ return PropertyValueTypeDefHelper.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>) getProxy().getModelPropertyValue(Property.VALUEID));
}
@SuppressWarnings("unchecked")
protected <T> T retrieveObject() {
- return (T) ((Map<String, Object>) getProxy().getModelPropertyValue(Property.VALUE)).get(Property.VALUE);
+ return (T) getProxy().getModelPropertyValue(Property.VALUE);
}
@Override
@@ -58,4 +56,19 @@
return KeyElements.PROPERTY;
}
+ @Override
+ public Object getValue() {
+ Object value = retrieveObject();
+ if(value instanceof String) {
+ return PropertyValueTypeDefHelper.getJavaObject(value, getValueType());
+ }else {
+ return value;
+ }
+ }
+
+ @Override
+ public void setValue(Object value) {
+ this.set(value);
+ }
+
}
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..4e8bf61 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,14 @@
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.valuetypedef.PropertyValueTypeDef;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDefHelper;
+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 +23,49 @@
}
@Override
- public String getValueType() {
- return (String) getElem().getPath(Range.VALUETYPE);
+ public PropertyValueTypeDef getValueType() {
+ return PropertyValueTypeDefHelper.readTypeDef(getElem().getPath(Range.VALUETYPE));
}
@Override
public Object getMin() {
- return getElem().getPath(Range.MIN);
+ Object min = getElem().getPath(Range.MIN);
+ return PropertyValueTypeDefHelper.getJavaObject(min, getValueType());
}
@Override
public Object getMax() {
- return getElem().getPath(Range.MAX);
+ Object max = getElem().getPath(Range.MAX);
+ return PropertyValueTypeDefHelper.getJavaObject(max, getValueType());
}
@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 rangeValue = RangeValue.createAsFacade((Map<String, Object>) value);
+ Object minRaw = rangeValue.getMin();
+ Object maxRaw = rangeValue.getMax();
+
+ RangeValue prepared = new RangeValue(
+ PropertyValueTypeDefHelper.prepareForSerialization(minRaw),
+ PropertyValueTypeDefHelper.prepareForSerialization(maxRaw)
+ );
+
+
+ getProxy().setModelPropertyValue(MultiSubmodelElementProvider.VALUE, prepared);
+ } else {
+ throw new IllegalArgumentException("Given object " + value + " is not a RangeValue");
+ }
+ }
}
\ No newline at end of file
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..e3def17 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
@@ -31,4 +31,9 @@
protected KeyElements getKeyElement() {
return KeyElements.BASICEVENT;
}
+
+ @Override
+ public IReference getValue() {
+ return getObserved();
+ }
}
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..69393bf
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/operation/ConnectedAsyncInvocation.java
@@ -0,0 +1,111 @@
+package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.operation;
+
+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.restapi.OperationProvider;
+import org.eclipse.basyx.submodel.restapi.operation.OperationResult;
+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;
+
+ public ConnectedAsyncInvocation(VABElementProxy proxy, String operationId, Object... parameters) {
+ this.proxy = proxy;
+ this.operationId = operationId;
+ requestId = (String) proxy.invokeOperation(Operation.INVOKE + OperationProvider.ASYNC, parameters);
+ }
+
+ @Override
+ public Object getResult() {
+
+ // Wait for Operation to finish
+ while(!isFinished()) {
+ try {
+ Thread.sleep(50);
+ } catch (InterruptedException e) {
+ }
+ }
+
+ if(!resultRetrieved) {
+ // If the result was not already retrieved, do it now
+
+ try {
+ result = proxy.getModelPropertyValue(getListPath());
+ } catch (Exception e) {
+ // Save the Exception as result for later handling
+ result = e;
+ }
+ }
+
+ if(result instanceof Exception || result.equals(OperationResult.EXECUTION_ERROR.toString())) {
+ throw new OperationExecutionErrorException("Exception while executing Invocation '"
+ + requestId + "' of Operation '" + operationId + "'");
+ } else {
+ return result;
+ }
+
+ }
+
+ @Override
+ public boolean isFinished() {
+
+ if(resultRetrieved) {
+ // If the result was already retrieved the Operation is done
+ return true;
+ }
+
+ try {
+ result = proxy.getModelPropertyValue(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;
+ return true;
+ } else {
+ // If it is something else -> rethrow it
+ throw e;
+ }
+ }
+
+ if(result.equals(OperationResult.EXECUTION_NOT_YET_FINISHED.toString())) {
+ return false;
+ }
+
+ resultRetrieved = true;
+ return true;
+ }
+
+ 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..21d7141 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
@@ -43,26 +43,56 @@
/**
* Invoke a remote operation TODO C# includes idShort
*/
- @SuppressWarnings("unchecked")
@Override
public Object invoke(Object... params) throws Exception {
+ // Invoke operation passing an empty string, since the used proxy already points
+ // to the operation
+ Object result = getProxy().invokeOperation(Operation.INVOKE, wrapParameters(params));
+
+ return unwrapResult(result);
+ }
+
+ @Override
+ public ConnectedAsyncInvocation invokeAsync(Object... params) {
+ ConnectedAsyncInvocation invocation =
+ new ConnectedAsyncInvocation(getProxy(), getIdShort(), wrapParameters(params));
+ return invocation;
+ }
+
+ @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");
+ }
+
+ private Object[] wrapParameters(Object[] parameters) {
+ Object[] result = new Object[parameters.length];
+
// Wrap parameter with valuetype information
int i = 0;
- for (Object param : params) {
+ for (Object param : parameters) {
HashMap<String, Object> valueWrapper = new HashMap<>();
valueWrapper.put(Property.VALUETYPE, PropertyValueTypeDefHelper.getTypeWrapperFromObject(param));
valueWrapper.put(Property.VALUE, param);
- params[i] = valueWrapper;
+ result[i] = valueWrapper;
i++;
}
-
- // Invoke operation passing an empty string, since the used proxy already points
- // to the operation
- Object result = getProxy().invokeOperation("", params);
-
- // Unwrap result value
+ return result;
+ }
+
+ @SuppressWarnings("unchecked")
+ private Object unwrapResult(Object result) {
if (result instanceof Collection<?>) {
Collection<Object> coll = (Collection<Object>) result;
if (coll.isEmpty()) {
@@ -72,16 +102,10 @@
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);
}
}
}
-
return result;
}
-
- @Override
- protected KeyElements getKeyElement() {
- return KeyElements.OPERATION;
- }
}
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..05b3271 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
@@ -8,6 +8,7 @@
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.relationship.RelationshipElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElementValue;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
/**
@@ -47,4 +48,9 @@
protected KeyElements getKeyElement() {
return KeyElements.RELATIONSHIPELEMENT;
}
+
+ @Override
+ public RelationshipElementValue getValue() {
+ return new RelationshipElementValue(getFirst(), getSecond());
+ }
}
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..5599c61
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelElementMapCollectionConverter.java
@@ -0,0 +1,188 @@
+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;
+ }
+
+}
\ No newline at end of file
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..01f09ab
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelValuesHelper.java
@@ -0,0 +1,56 @@
+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;
+
+/**
+ * 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) {
+ if(value instanceof Collection<?>) {
+ 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..ca0984a 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
@@ -3,14 +3,13 @@
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;
@@ -31,34 +30,32 @@
* @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 (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");
}
}
+
}
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
index 93c3f8b..0d0fd0e 100644
--- 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
@@ -20,7 +20,9 @@
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.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;
@@ -58,9 +60,6 @@
* Constructor
*/
public SubModel() {
- // Add model type
- putAll(new ModelType(MODELTYPE));
-
// Add qualifiers
putAll(new HasSemantics());
putAll(new Identifiable());
@@ -68,8 +67,23 @@
putAll(new HasDataSpecification());
putAll(new HasKind());
- // Attributes
+ // 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);
}
@@ -78,6 +92,7 @@
*/
public SubModel(HasSemantics semantics, Identifiable identifiable, Qualifiable qualifiable,
HasDataSpecification specification, HasKind hasKind) {
+ this();
// Add qualifiers
putAll(semantics);
putAll(identifiable);
@@ -107,41 +122,12 @@
}
- @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;
+ return SubmodelElementMapCollectionConverter.mapToSM(map);
}
@Override
@@ -167,6 +153,10 @@
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);
}
@@ -299,13 +289,44 @@
public Map<String, ISubmodelElement> getSubmodelElements() {
return (Map<String, ISubmodelElement>) get(SUBMODELELEMENT);
}
+
@Override
- public Collection<IConstraint> getQualifier() {
- return Qualifiable.createAsFacade(this).getQualifier();
+ 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/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..6c82e2e
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/helper/ElementContainerHelper.java
@@ -0,0 +1,29 @@
+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/parts/ConceptDescription.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/parts/ConceptDescription.java
index 986e30c..daa41e0 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
@@ -42,6 +42,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
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..6ec650b 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
@@ -33,6 +33,17 @@
// 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());
+ setAdministration(new AdministrativeInformation());
+ }
/**
* Constructor that accepts values for most relevant properties
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..543fe04 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
@@ -12,7 +12,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 +44,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..3bdcee2 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
@@ -65,6 +65,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);
+ }
/**
*
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..646e008 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
@@ -48,6 +48,14 @@
// Reference to the parent of this element (Referable)
put(PARENT, null);
}
+
+ /**
+ * Constructor with mandatory attribute
+ * @param idShort
+ */
+ public Referable(String idShort) {
+ setIdShort(idShort);
+ }
/**
* Constructor with idShort, category and description
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..678601b 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
@@ -16,7 +16,7 @@
*
*/
public class Qualifiable extends VABModelMap<Object> implements IQualifiable {
- public static final String CONSTRAINTS = "constraints";
+ public static final String QUALIFIERS = "qualifiers";
/**
* Constructor
@@ -24,7 +24,7 @@
public Qualifiable() {
// The instance of an element may be further qualified by one or more
// qualifiers.
- put(CONSTRAINTS, null);
+ put(QUALIFIERS, null);
}
/**
@@ -38,16 +38,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 +67,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..8bbb38e 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
@@ -7,6 +7,8 @@
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.valuetypedef.PropertyValueTypeDef;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDefHelper;
/**
* Qualifier class
@@ -41,7 +43,16 @@
put(TYPE, "");
put(VALUE, null);
put(VALUEID, null);
- put(VALUETYPE, "");
+ put(VALUETYPE, null);
+ }
+
+ /**
+ * 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) {
@@ -50,9 +61,9 @@
// Default values
put(TYPE,type);
- put(VALUE, value);
+ put(VALUE, PropertyValueTypeDefHelper.prepareForSerialization(value));
put(VALUEID, valueId);
- put(VALUETYPE, valueType);
+ put(VALUETYPE, PropertyValueTypeDefHelper.getWrapper(PropertyValueTypeDefHelper.fromName(valueType)));
}
/**
@@ -81,13 +92,22 @@
return (String) get(Qualifier.TYPE);
}
- public void setValue(String obj) {
- put(Qualifier.VALUE, obj);
+ public void setValue(Object obj) {
+ put(Qualifier.VALUE, PropertyValueTypeDefHelper.prepareForSerialization(obj));
+ // Value type is only set if it is not set before
+ if(getValueType() == null) {
+ put(Qualifier.VALUETYPE, PropertyValueTypeDefHelper.getTypeWrapperFromObject(obj));
+ }
}
@Override
- public String getValue() {
- return (String) get(Qualifier.VALUE);
+ public Object getValue() {
+ Object value = get(Qualifier.VALUE);
+ if(value instanceof String) {
+ return PropertyValueTypeDefHelper.getJavaObject(value, getValueType());
+ }else {
+ return value;
+ }
}
public void setValueId(IReference obj) {
@@ -100,13 +120,13 @@
return Reference.createAsFacade((Map<String, Object>) get(Qualifier.VALUEID));
}
- public void setValueType(String obj) {
- put(Qualifier.VALUETYPE, obj);
+ public void setValueType(PropertyValueTypeDef obj) {
+ put(Qualifier.VALUETYPE, PropertyValueTypeDefHelper.getWrapper(obj));
}
@Override
- public String getValueType() {
- return (String) get(Qualifier.VALUETYPE);
+ public PropertyValueTypeDef getValueType() {
+ return PropertyValueTypeDefHelper.readTypeDef(get(Qualifier.VALUETYPE));
}
@Override
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..38fdd97 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
@@ -79,6 +79,31 @@
ret.setMap(map);
return ret;
}
+
+ @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..265e94f 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
@@ -92,6 +92,21 @@
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/submodelelement/SubmodelElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/SubmodelElement.java
index f1a81bb..c01628d 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
@@ -31,12 +31,16 @@
protected SubmodelElement() {
// Add model type
putAll(new ModelType(MODELTYPE));
-
- putAll(new HasDataSpecification());
- putAll(new Referable());
- putAll(new Qualifiable());
- putAll(new HasSemantics());
- putAll(new HasKind());
+ setModelingKind(ModelingKind.INSTANCE);
+ }
+
+ /**
+ * Constructor with only mandatory attribute
+ * @param idShort
+ */
+ protected SubmodelElement(String idShort) {
+ this();
+ setIdShort(idShort);
}
/**
@@ -109,13 +113,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
@@ -146,4 +150,14 @@
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");
+ }
}
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..10d1978 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
@@ -3,16 +3,17 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
+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 +28,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 +42,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 +79,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 +91,11 @@
* @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;
+ }
+
+ return SubmodelElementMapCollectionConverter.mapToSmECollection(obj);
}
/**
@@ -86,8 +104,21 @@
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)));
+ }
+
+ /**
+ * Adds an element to the SubmodelElementCollection
+ * @param elem
+ *
+ * @deprecated
+ * This method is deprecated. Use addSubModelElement instead
+ * which does the same work
+ */
+ @Deprecated
+ public void addElement(ISubmodelElement elem) {
+ addSubModelElement(elem);
}
/**
@@ -96,11 +127,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 +161,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 (getSubmodelElements()).values();
}
public void setOrdered(boolean value) {
@@ -164,38 +190,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,16 +222,39 @@
@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() {
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..ab1c677 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,5 +1,7 @@
package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
@@ -15,7 +17,7 @@
*/
public class Blob extends DataElement implements IBlob {
public static final String MIMETYPE="mimeType";
- public static final String MODELTYPE = "blob";
+ public static final String MODELTYPE = "Blob";
/**
* Creates an empty Blob object
@@ -24,6 +26,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
@@ -62,17 +75,43 @@
// 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 void setValue(Object value) {
+ if(value instanceof byte[]) {
+ List<Byte> list = new ArrayList<>();
+
+ byte[] bytes = (byte[]) value;
+
+ for (int i = 0; i < bytes.length; i++) {
+ list.add(bytes[i]);
+ }
+
+ put(Property.VALUE, list);
+ }
+ else {
+ throw new IllegalArgumentException("Given Object is not a byte[]");
+ }
+
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
public byte[] getValue() {
- return ((String) get(Property.VALUE)).getBytes();
+ if(!containsKey(Property.VALUE)) {
+ return null;
+ }
+ List<Number> list = (List<Number>) get(Property.VALUE);
+ byte[] ret = new byte[list.size()];
+
+ for(int i = 0; i < list.size(); i++) {
+ ret[i] = list.get(i).byteValue();
+ }
+
+ return ret;
}
public void setMimeType(String mimeType) {
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..6e3793b 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
@@ -7,6 +7,7 @@
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,6 +16,17 @@
// 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));
+ }
/**
* Returns true if the given submodel element map is recognized as a data element
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..5aeec79 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
@@ -26,6 +26,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
@@ -67,11 +76,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) {
+ put(Property.VALUE, (String) value);
+ }
+ else {
+ throw new IllegalArgumentException("Given Object is not a String");
+ }
+
}
@Override
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..05f8031 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
@@ -28,6 +28,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);
@@ -53,8 +63,8 @@
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 +83,15 @@
protected KeyElements getKeyElement() {
return KeyElements.MULTILANGUAGEPROPERTY;
}
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void setValue(Object value) {
+ if(LangStrings.isLangStrings(value)) {
+ put(VALUE, LangStrings.createAsFacade((Collection<Map<String, Object>>) value));
+ }
+ else {
+ throw new IllegalArgumentException("Given Object is not a LangStrings");
+ }
+ }
}
\ No newline at end of file
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..a4298dc 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
@@ -62,15 +62,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,6 +75,17 @@
return Reference.createAsFacade((Map<String, Object>) get(Property.VALUE));
}
+ @SuppressWarnings("unchecked")
+ @Override
+ public void setValue(Object value) {
+ if(Reference.isReference(value)) {
+ put(Property.VALUE, Reference.createAsFacade((Map<String, Object>) value));
+ }
+ else {
+ throw new IllegalArgumentException("Given Object is not a Reference");
+ }
+ }
+
@Override
protected KeyElements getKeyElement() {
return KeyElements.REFERENCEELEMENT;
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..33c63c8 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
@@ -39,6 +39,24 @@
put(Property.VALUE, null);
put(Property.VALUEID, null);
}
+
+ /**
+ * Constructor accepting only mandatory attribute
+ * @param idShort
+ * @param valueType
+ */
+ public Property(String idShort, PropertyValueTypeDef valueType) {
+ super(idShort);
+ setValueType(valueType);
+ setIdShort(idShort);
+
+ // Add model type
+ putAll(new ModelType(MODELTYPE));
+
+ // Put attributes
+ put(Property.VALUE, null);
+ put(Property.VALUEID, null);
+ }
/**
* Creates a Property object from a map
@@ -59,7 +77,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)));
}
/**
@@ -108,8 +126,11 @@
@Override
public void set(Object value) {
- put(Property.VALUE, value);
- put(Property.VALUETYPE, PropertyValueTypeDefHelper.getTypeWrapperFromObject(value));
+ put(Property.VALUE, PropertyValueTypeDefHelper.prepareForSerialization(value));
+ // Value type is only set if it is not set before
+ if(getValueType() == null) {
+ put(Property.VALUETYPE, PropertyValueTypeDefHelper.getTypeWrapperFromObject(value));
+ }
}
/**
@@ -124,13 +145,17 @@
@Override
public Object get() {
- return get(Property.VALUE);
+ Object value = get(Property.VALUE);
+ if(value instanceof String) {
+ return PropertyValueTypeDefHelper.getJavaObject(value, getValueType());
+ }else {
+ return value;
+ }
}
@Override
- public String getValueType() {
- PropertyValueTypeDef def = PropertyValueTypeDefHelper.readTypeDef(get(Property.VALUETYPE));
- return def!=null ? def.toString() : "";
+ public PropertyValueTypeDef getValueType() {
+ return PropertyValueTypeDefHelper.readTypeDef(get(Property.VALUETYPE));
}
/**
@@ -149,4 +174,14 @@
protected KeyElements getKeyElement() {
return KeyElements.PROPERTY;
}
+
+ @Override
+ public Object getValue() {
+ return get();
+ }
+
+ @Override
+ public void setValue(Object value) {
+ set(value);
+ }
}
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
index 61c4022..12204b0 100644
--- 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
@@ -12,7 +12,16 @@
*
*/
public enum PropertyValueTypeDef implements StandardizedLiteralEnum {
- Double("double"), Float("float"), Integer("int"), String("string"), Boolean("boolean"), Void("void"), Null("null");
+ 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;
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
index 4025801..936a2c0 100644
--- 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
@@ -1,8 +1,17 @@
package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef;
+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.valuetypedef.PropertyValueTypeDef
@@ -62,13 +71,29 @@
PropertyValueTypeDef objectType;
if (obj == null) {
- objectType = PropertyValueTypeDef.Null;
+ objectType = PropertyValueTypeDef.None;
} else {
Class<?> c = obj.getClass();
- if (c == int.class || c == Integer.class) {
+ if(c == byte.class || c == Byte.class) {
+ objectType = PropertyValueTypeDef.Int8;
+ }else if(c == short.class || c == Short.class) {
+ objectType = PropertyValueTypeDef.Int16;
+ }else if (c == int.class || c == Integer.class) {
objectType = PropertyValueTypeDef.Integer;
+ } else if (c == long.class || c == Long.class) {
+ objectType = PropertyValueTypeDef.Int64;
+ } else if (c == BigInteger.class) {
+ BigInteger tmp = (BigInteger) obj;
+ if (tmp.compareTo(new BigInteger("0")) > 0) {
+ objectType = PropertyValueTypeDef.PositiveInteger;
+ } else if (tmp.compareTo(new BigInteger("0")) < 0) {
+ objectType = PropertyValueTypeDef.NegativeInteger;
+ } else {
+ objectType = PropertyValueTypeDef.NonNegativeInteger;
+ }
+
} else if (c == void.class || c == Void.class) {
- objectType = PropertyValueTypeDef.Void;
+ objectType = PropertyValueTypeDef.None;
} else if (c == boolean.class || c == Boolean.class) {
objectType = PropertyValueTypeDef.Boolean;
} else if (c == float.class || c == Float.class) {
@@ -78,6 +103,14 @@
objectType = PropertyValueTypeDef.Double;
} else if (c == String.class) {
objectType = PropertyValueTypeDef.String;
+ } else if (c == Duration.class) {
+ objectType = PropertyValueTypeDef.Duration;
+ } else if (c == Period.class) {
+ objectType = PropertyValueTypeDef.YearMonthDuration;
+ } else if (c == QName.class) {
+ objectType = PropertyValueTypeDef.QName;
+ } else if (c == XMLGregorianCalendar.class) {
+ objectType = PropertyValueTypeDef.DateTime;
} else {
throw new RuntimeException("Cannot map object " + obj + " to any PropertyValueTypeDef");
}
@@ -86,6 +119,116 @@
}
/**
+ * Map the PropertyValueType to Java type
+ *
+ */
+ public static Object getJavaObject(Object value, PropertyValueTypeDef 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;
+
+ }
+
+ /**
* Creates the appropriate type map for a given type
*
* @param type
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..ec21f31
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/range/Range.java
@@ -0,0 +1,133 @@
+package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range;
+
+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;
+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;
+
+/**
+ * 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(PropertyValueTypeDef valueType) {
+ this();
+ setValueType(valueType);
+ }
+
+ /**
+ * Constructor accepting only mandatory attribute
+ * @param idShort
+ * @param valueType
+ */
+ public Range(String idShort, PropertyValueTypeDef valueType) {
+ super(idShort);
+ // Add model type
+ putAll(new ModelType(MODELTYPE));
+ put(VALUETYPE, valueType);
+ }
+
+ public Range(PropertyValueTypeDef 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)
+ || (modelType == null && (map.containsKey(MIN) && map.containsKey(MAX) && map.containsKey(VALUETYPE)));
+ }
+
+ private void setValueType(PropertyValueTypeDef valueType) {
+ put(Range.VALUETYPE, PropertyValueTypeDefHelper.getWrapper(valueType));
+ }
+
+ @Override
+ public PropertyValueTypeDef getValueType() {
+ return PropertyValueTypeDefHelper.readTypeDef(get(Range.VALUETYPE));
+ }
+
+ @Override
+ public Object getMin() {
+ Object value = get(MIN);
+ if(value instanceof String) {
+ return PropertyValueTypeDefHelper.getJavaObject(value, getValueType());
+ }else {
+ return value;
+ }
+ }
+
+ @Override
+ public Object getMax() {
+ Object value = get(MAX);
+ if(value instanceof String) {
+ return PropertyValueTypeDefHelper.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);
+ Object minValue = rv.getMin();
+ Object maxValue = rv.getMax();
+
+ put(Range.MIN, PropertyValueTypeDefHelper.prepareForSerialization(minValue));
+ put(Range.MAX, PropertyValueTypeDefHelper.prepareForSerialization(maxValue));
+ if(getValueType() == null) {
+ setValueType(PropertyValueTypeDefHelper.getType(minValue));
+ }
+ } else {
+ throw new IllegalArgumentException("Given Object is not a RangeValue");
+ }
+ }
+
+}
\ No newline at end of file
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..a6b537c
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/range/RangeValue.java
@@ -0,0 +1,56 @@
+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) {
+ 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..ce89290 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
@@ -32,6 +32,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 +64,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
*
@@ -91,4 +110,21 @@
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");
+ }
+ }
}
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..bf60341
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/entity/EntityValue.java
@@ -0,0 +1,80 @@
+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) {
+ 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..a67eab7 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
@@ -30,6 +30,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;
@@ -53,7 +66,7 @@
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 +74,20 @@
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");
+ }
+ }
}
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..ded8eca
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/AsyncInvocation.java
@@ -0,0 +1,69 @@
+package org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.function.Function;
+
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IAsyncInvocation;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+
+/**
+ * Local implementation of IAsyncInvocation
+ *
+ * @author conradi
+ *
+ */
+public class AsyncInvocation implements IAsyncInvocation {
+
+ private static final String DEFAULT_REQUEST_ID = "0";
+
+ private String operationId;
+ private String requestId;
+
+ private CompletableFuture<Object> future;
+
+
+ @SuppressWarnings("unchecked")
+ public AsyncInvocation(Operation operation, String requestId, Object... parameters) {
+ operationId = operation.getIdShort();
+ this.requestId = requestId;
+
+ Function<Object[], Object> invokable = (Function<Object[], Object>) operation.get(Operation.INVOKABLE);
+ future = CompletableFuture.supplyAsync(() -> invokable.apply(parameters));
+ }
+
+ public AsyncInvocation(Operation operation, Object... parameters) {
+ this(operation, DEFAULT_REQUEST_ID, parameters);
+ }
+
+ public AsyncInvocation(IModelProvider provider, String operationId, String requestId, Object... parameters) {
+ this.operationId = operationId;
+ this.requestId = requestId;
+
+ future = CompletableFuture.supplyAsync(() -> provider.invokeOperation("", parameters));
+ }
+
+ @Override
+ public Object getResult() {
+ try {
+ return future.get();
+ } catch (Exception e) {
+ // Some RuntimeException occured in the executed function
+ throw new OperationExecutionErrorException("Exception while executing Invocation '"
+ + requestId + "' of Operation '" + operationId + "'", e.getCause());
+ }
+ }
+
+ @Override
+ public boolean isFinished() {
+ return future.isDone();
+ }
+
+ public String getRequestId() {
+ return requestId;
+ }
+
+ 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..7d80755 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
@@ -29,6 +29,8 @@
public static final String INVOKABLE = "invokable";
public static final String MODELTYPE = "Operation";
+
+ public static final String INVOKE = "invoke";
/**
* Constructor
@@ -49,6 +51,28 @@
// Extension of DAAS specification for function storage
put(INVOKABLE, null);
}
+
+ /**
+ * Constructor accepting only mandatory attribute
+ * @param idShort
+ */
+ public Operation(String idShort) {
+ super(idShort);
+ // Add model type
+ putAll(new ModelType(MODELTYPE));
+
+ // Input variables
+ setInputVariables(new ArrayList<OperationVariable>());
+
+ // Output variables
+ setOutputVariables(new ArrayList<OperationVariable>());
+
+ // Variables, that are input and output
+ setInOutputVariables(new ArrayList<OperationVariable>());
+
+ // Extension of DAAS specification for function storage
+ setInvocable(null);
+ }
/**
*
@@ -108,10 +132,18 @@
/**
* 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
@@ -149,6 +181,12 @@
return ((Function<Object[], Object>) get(INVOKABLE)).apply(params);
}
+ @Override
+ public AsyncInvocation invokeAsync(Object... params) {
+ AsyncInvocation invocation = new AsyncInvocation(this, params);
+ return invocation;
+ }
+
public void setInputVariables(Collection<OperationVariable> in) {
put(Operation.IN, in);
}
@@ -194,4 +232,14 @@
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");
+ }
}
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..24242a4
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationExecutionErrorException.java
@@ -0,0 +1,51 @@
+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/relationship/RelationshipElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/RelationshipElement.java
index bb9d5c6..39d7a15 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
@@ -41,7 +41,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,6 +50,17 @@
}
/**
+ * 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
@@ -67,7 +78,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) {
@@ -96,4 +107,22 @@
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);
+ setFirst(rev.getFirst());
+ setSecond(rev.getSecond());
+ } else {
+ throw new IllegalArgumentException("Given Object is not an RelationshipElementValue");
+ }
+ }
}
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..f29ecfc
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/RelationshipElementValue.java
@@ -0,0 +1,61 @@
+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> {
+
+ private 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) {
+ 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/MultiSubmodelElementProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/MultiSubmodelElementProvider.java
new file mode 100644
index 0000000..9b3c0b9
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/MultiSubmodelElementProvider.java
@@ -0,0 +1,166 @@
+package org.eclipse.basyx.submodel.restapi;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+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.
+ *
+ * @author espen, conradi
+ *
+ */
+public class MultiSubmodelElementProvider extends MetaModelProvider {
+ // 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.getModelPropertyValue("");
+ 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).getModelPropertyValue(subPath);
+ } else {
+ throw new MalformedRequestException("Given path '" + path + "' does not start with /submodelElements");
+ }
+ }
+
+ @Override
+ public Object getModelPropertyValue(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 setModelPropertyValue(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).setModelPropertyValue(subPath, newValue);
+ }
+
+ @Override
+ 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");
+ }
+
+ if (pathElements.length == 2) {
+ 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..ad6afe0 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
@@ -3,8 +3,10 @@
import java.util.Map;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.restapi.operation.AsyncOperationHandler;
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;
@@ -17,6 +19,10 @@
public class OperationProvider extends MetaModelProvider {
IModelProvider modelProvider;
+
+ public static final String ASYNC = "?async=true";
+ public static final String INVOCATION_LIST = "invocationList";
+
public OperationProvider(IModelProvider modelProvider) {
this.modelProvider = modelProvider;
@@ -24,49 +30,78 @@
@Override
public Object getModelPropertyValue(String path) throws ProviderException {
+ String[] splitted = VABPathTools.splitPath(path);
if (path.isEmpty()) {
return modelProvider.getModelPropertyValue("");
+ } else if (splitted[0].equals(INVOCATION_LIST) && splitted.length == 2) {
+ String requestId = splitted[1];
+ String operationId = getIdShort(modelProvider.getModelPropertyValue(""));
+ return AsyncOperationHandler.retrieveResult(operationId, requestId);
+
} 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");
+ 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 {
+
+ boolean async = path.endsWith(ASYNC);
+
+ // remove the "invoke" from the end of the path
+ path = VABPathTools.stripInvokeFromPath(path);
+
// Unwrap parameters, if they are wrapped
for (int i = 0; i < parameters.length; i++) {
parameters[i] = unwrapParameter(parameters[i]);
}
+ String operationId = "";
// Invoke /invokable instead of an Operation property if existent
Object childElement = modelProvider.getModelPropertyValue(path);
- if (childElement instanceof Map<?, ?> && ((Map<?, ?>) childElement).containsKey(Operation.INVOKABLE)) {
+ if (Operation.isOperation(childElement)) {
path = VABPathTools.concatenatePaths(path, Operation.INVOKABLE);
+ operationId = getIdShort(childElement);
}
-
- // Forward call to model provider
- return modelProvider.invokeOperation(path, parameters);
+
+ if(async) {
+ return AsyncOperationHandler.invokeAsync(new VABElementProxy(path, modelProvider), operationId, parameters);
+ } else {
+ // Forward call to model provider
+ return modelProvider.invokeOperation(path, parameters);
+ }
+ }
+
+ @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");
+ }
}
}
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..875105e 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,6 +1,5 @@
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;
@@ -31,20 +30,10 @@
// Handle "/value" path
if (path.equals(Property.VALUE)) {
- // Build map containing value & valueType
+ // return value
Map<String, Object> p = (Map<String, Object>) proxy.getModelPropertyValue("");
- Map<String, Object> ret = new HashMap<>();
- Object o = p.get(Property.VALUE);
+ 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("");
@@ -62,28 +51,28 @@
proxy.setModelPropertyValue(Property.VALUE, newValue);
proxy.setModelPropertyValue(Property.VALUETYPE, PropertyValueTypeDefHelper.getTypeWrapperFromObject(newValue));
} 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
index 97ebf4f..2669bcd 100644
--- 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
@@ -5,6 +5,8 @@
import java.util.List;
import java.util.Map;
+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;
@@ -34,6 +36,9 @@
*/
public class SubModelProvider extends MetaModelProvider {
+ public static final String VALUES = "values";
+ public static final String SUBMODEL = "submodel";
+
ISubmodelAPI submodelAPI;
/**
@@ -75,9 +80,10 @@
*/
private String removeSubmodelPrefix(String path) {
path = VABPathTools.stripSlashes(path);
- if (path.startsWith("submodel/")) {
+ String submodelWithSlash = SUBMODEL + "/";
+ if (path.startsWith(submodelWithSlash)) {
path = path.replaceFirst("submodel/", "");
- } else if (path.equals("submodel")) {
+ } else if (path.equals(SUBMODEL)) {
path = "";
}
path = VABPathTools.stripSlashes(path);
@@ -89,31 +95,41 @@
VABPathTools.checkPathForNull(path);
path = removeSubmodelPrefix(path);
if (path.isEmpty()) {
- return submodelAPI.getSubmodel();
+ 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);
- 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();
- }
+ // 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
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);
+ return submodelAPI.getSubmodelElementValue(idShort);
+ } 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, splitted[splitted.length - 1]);
} 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);
+ return submodelAPI.getNestedSubmodelElementValue(idShorts);
} else {
return submodelAPI.getNestedSubmodelElement(idShorts);
}
@@ -127,7 +143,7 @@
// Create list from array and wrap it in ArrayList to ensure modifiability
List<String> idShorts = new ArrayList<>(Arrays.asList(splitted));
- // Drop inital "submodels"
+ // Drop inital "submodelElements"
idShorts.remove(0);
// If value is contained in path, remove it
@@ -138,7 +154,7 @@
}
private boolean isPropertyValuePath(String[] splitted) {
- return splitted.length == 3 && splitted[0].equals(SubmodelElementProvider.PROPERTIES) && endsWithValue(splitted);
+ return splitted.length == 3 && splitted[0].equals(MultiSubmodelElementProvider.ELEMENTS) && endsWithValue(splitted);
}
private boolean endsWithValue(String[] splitted) {
@@ -146,9 +162,14 @@
}
private boolean isSubmodelElementListPath(String[] splitted) {
- return splitted.length > 2 && splitted[0].equals(SubmodelElementProvider.ELEMENTS);
+ return splitted.length > 2 && splitted[0].equals(MultiSubmodelElementProvider.ELEMENTS);
}
+ private boolean isInvocationListPath(String[] splitted) {
+ return splitted.length > 2 && splitted[splitted.length - 2].equals(OperationProvider.INVOCATION_LIST);
+ }
+
+ @SuppressWarnings("unchecked")
@Override
public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
path = removeSubmodelPrefix(path);
@@ -156,25 +177,25 @@
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);
+ if (endsWithValue(splitted)) {
+ submodelAPI.updateNestedSubmodelElement(getIdShorts(splitted), newValue);
} else {
- throw new MalformedRequestException("Update on path " + path + " not supported");
+
+ 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(getIdShorts(splitted), element);
}
}
}
- @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));
- }
+ throw new MalformedRequestException("POST (create) on '" + path + "' not allowed. Use PUT (set) instead.");
}
@Override
@@ -182,9 +203,12 @@
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);
+ if (isQualifier(splitted[0])) {
+ if (splitted.length > 2) {
+ submodelAPI.deleteNestedSubmodelElement(getIdShorts(splitted));
+ } else {
+ submodelAPI.deleteSubmodelElement(splitted[1]);
+ }
} else {
throw new MalformedRequestException("Path " + path + " not supported for delete");
}
@@ -194,7 +218,7 @@
}
private boolean isQualifier(String str) {
- return str.equals(SubmodelElementProvider.ELEMENTS) || str.equals(SubmodelElementProvider.OPERATIONS) || str.equals(SubmodelElementProvider.PROPERTIES);
+ return str.equals(MultiSubmodelElementProvider.ELEMENTS);
}
@Override
@@ -206,14 +230,19 @@
public Object invokeOperation(String path, Object... parameters) throws ProviderException {
path = removeSubmodelPrefix(path);
if (path.isEmpty()) {
- throw new MalformedRequestException("Invalid access");
+ throw new MalformedRequestException("Given path must not be empty");
} else {
String[] splitted = VABPathTools.splitPath(path);
- if (splitted.length == 2 && splitted[0].equals(SubmodelElementProvider.OPERATIONS)) {
- String idShort = splitted[1];
- return submodelAPI.invokeOperation(idShort, parameters);
+ if (VABPathTools.isOperationInvokationPath(path)) {
+ if(path.endsWith(OperationProvider.ASYNC)) {
+ List<String> idShorts = getIdShorts(splitted);
+ idShorts.remove(idShorts.size() - 1);
+ return submodelAPI.invokeNestedOperationAsync(idShorts, parameters);
+ } else {
+ return submodelAPI.invokeNestedOperation(getIdShorts(splitted), parameters);
+ }
} else {
- throw new MalformedRequestException("Unknown path " + path);
+ throw new MalformedRequestException("Given path '" + path + "' does not end in /invoke");
}
}
}
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..014fab3 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,22 +1,19 @@
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 {
@@ -27,55 +24,57 @@
}
/**
- * 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 {
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.getModelPropertyValue(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.getModelPropertyValue(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);
}
}
+ @SuppressWarnings("unchecked")
@Override
public void setModelPropertyValue(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.setModelPropertyValue(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.setModelPropertyValue(path, value);
} else {
// Directly access an element inside of the collection
String idShort = pathElements[0];
@@ -89,8 +88,9 @@
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);
+ proxy.createValue(valuePath, newEntity);
} else {
// Directly access an element inside of the collection
String idShort = pathElements[0];
@@ -101,22 +101,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 +130,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..7a9bfe9 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,145 @@
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";
- // 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();
+ @SuppressWarnings("unchecked")
+ public static IModelProvider getElementProvider(IModelProvider proxy) {
+ Map<String, Object> elementMap = (Map<String, Object>) proxy.getModelPropertyValue("");
+ 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 {
- // No other qualifier in a submodel element container can be directly accessed
- throw getUnknownPathException(path);
+ return proxy;
}
}
- /**
- * 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);
+ path = VABPathTools.stripSlashes(path);
+
+ if (path.equals(MultiSubmodelElementProvider.VALUE)) {
+ // Handle "/value" path
+ // return value
+
+ if(specializedProvider) {
+ return proxy.getModelPropertyValue(path);
+ }
+
+ Map<String, Object> elementMap = (Map<String, Object>) proxy.getModelPropertyValue("");
+
+ 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 {
- return handleDetailGet(path);
+ // Path has more Elements -> pass it to Provider below
+ return proxy.getModelPropertyValue(path);
}
}
@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");
+ path = VABPathTools.stripSlashes(path);
+
+ if(!path.endsWith(MultiSubmodelElementProvider.VALUE)) {
+ throw new MalformedRequestException("The given path '" + path + "' does not end in /value.");
}
-
- 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 (!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.getModelPropertyValue("");
+
+ 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.setModelPropertyValue("", element);
+
} 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
+ proxy.setModelPropertyValue(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/api/ISubmodelAPI.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/api/ISubmodelAPI.java
index 214e7b7..116dca1 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
@@ -5,7 +5,6 @@
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;
/**
@@ -24,38 +23,49 @@
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 idShorts
+ * the idShort path to the submodelElement
+ * @param elem
+ * the submodelElement to be added
+ */
+ public void addSubmodelElement(List<String> idShorts, ISubmodelElement elem);
+
+ /**
+ * Retrieves a submodelElement
*
* @param idShort
- * of the submodel element
- * @return the submodel element
+ * of the submodelElement
+ * @return the submodelElement
*/
public ISubmodelElement getSubmodelElement(String idShort);
/**
- * Removes a submodel element from the submodel
+ * Removes a submodelElement from the submodel
*
* @param idShort
- * of the element to be removed
+ * of the submodelElement to be removed
*/
public void deleteSubmodelElement(String idShort);
/**
+ * Removes a submodelElement from a SubmodelElementCollection
+ *
+ * @param idShort
+ * of the submodelElement to be removed
+ */
+ public void deleteNestedSubmodelElement(List<String> idShorts);
+
+ /**
* Helper function for quick access of operations
*
* @return all operations contained by the submodel
@@ -63,44 +73,54 @@
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
+ * of 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 idShort, Object newValue);
/**
- * Retrieves the value of a property
- *
- * @param idShort
- * of the property
- * @return property value
- */
- public Object getPropertyValue(String idShort);
-
- /**
- * Retrieves the value of a property nested inside a SubmodelElementCollection.
+ * Updates the value of a submodelElement nested inside a SubmodelElementCollection.
*
* @param idShorts
- * the idShort path to the property
+ * the idShort path to the submodelElement
+ * @param newValue
+ * new value of the submodelElement
*/
- public Object getNestedPropertyValue(List<String> idShorts);
+ public void updateNestedSubmodelElement(List<String> idShorts, Object newValue);
+
+ /**
+ * Retrieves the value of a submodelElement
+ *
+ * @param idShort
+ * of the submodelElement
+ * @return submodelElement value
+ */
+ public Object getSubmodelElementValue(String idShort);
+
+ /**
+ * Retrieves the value of a submodelElement nested inside a SubmodelElementCollection.
+ *
+ * @param idShorts
+ * the idShort path to the submodelElement
+ */
+ public Object getNestedSubmodelElementValue(List<String> idShorts);
/**
* Retrieves a submodel element nested inside a SubmodelElementCollection
*
* @param idShorts
- * the idShort path to the property
+ * the idShort path to the submodelElement
* @return
*/
public ISubmodelElement getNestedSubmodelElement(List<String> idShorts);
@@ -115,4 +135,38 @@
* @return the result of the operation
*/
public Object invokeOperation(String idShort, Object... params);
+
+ /**
+ * Invokes an operation
+ *
+ * @param idShorts
+ * the idShort path to the operation
+ * @param params
+ * to be passed to the operation
+ * @return the result of the operation
+ */
+ public Object invokeNestedOperation(List<String> idShorts, Object... params);
+
+ /**
+ * Invokes an operation asynchronously
+ *
+ * @param idShorts
+ * the idShort path to the operation
+ * @param params
+ * to be passed to the operation
+ * @return the requestId of the invocation
+ */
+ public Object invokeNestedOperationAsync(List<String> idShorts, Object... params);
+
+ /**
+ * Gets the result of an asynchronously invoked operation
+ *
+ * @param idShorts
+ * the idShort path to 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(List<String> idShorts, String requestId);
+
}
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..b7a1b39
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/AsyncOperationHandler.java
@@ -0,0 +1,94 @@
+package org.eclipse.basyx.submodel.restapi.operation;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.AsyncInvocation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationExecutionErrorException;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+
+/**
+ * Helperclass used to keep the asynchronously operations
+ * This class is used in a static way. As each request is handled by new Providers
+ *
+ * @author conradi
+ *
+ */
+public class AsyncOperationHandler {
+
+ private static int count = 0;
+
+ private static Map<String, AsyncInvocation> map = new HashMap<>();
+
+ /**
+ * Invokes an Operation and returns its requestId
+ *
+ * @param operation the Operation to be invoked
+ * @param parameters to be given to the operation
+ * @return the requestId
+ */
+ public static String invokeAsync(IModelProvider provider, String operationId, Object... parameters) {
+ String requestId = getRequestId();
+ AsyncInvocation invocation = new AsyncInvocation(provider, operationId, requestId, parameters);
+ synchronized (map) {
+ map.put(requestId, invocation);
+ }
+ return requestId;
+ }
+
+ /**
+ * 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 operationIdShort, String requestId) {
+ if(!map.containsKey(requestId)) {
+ throw new ResourceNotFoundException("RequestId '" + requestId + "' not found.");
+ }
+
+ AsyncInvocation invocation = map.get(requestId);
+
+ if(!(invocation.getOperationId().equals(operationIdShort) || invocation.getOperationId().isEmpty())) {
+ throw new ResourceNotFoundException(
+ "RequestId '" + requestId + "' does not belong to Operation '" + operationIdShort + "'");
+ }
+
+ if(!invocation.isFinished()) {
+ return OperationResult.EXECUTION_NOT_YET_FINISHED.toString();
+ }
+
+ // Remove the Invocation if it is finished and its result was retrieved
+ synchronized (map) {
+ map.remove(requestId);
+ }
+
+
+ try {
+ return invocation.getResult();
+ } catch (OperationExecutionErrorException e) {
+ return OperationResult.EXECUTION_ERROR.toString();
+ }
+ }
+
+ /**
+ * Checks if a given requestId exists
+ *
+ * @param requestId the id to be checked
+ * @return if the id exists
+ */
+ public static synchronized boolean hasRequestId(String requestId) {
+ return map.containsKey(requestId);
+ }
+
+ /**
+ * Generates a unique requestId
+ *
+ * @return a unique requestId
+ */
+ private static synchronized String getRequestId() {
+ return Integer.toString(count++);
+ }
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/OperationResult.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/OperationResult.java
new file mode 100644
index 0000000..0c4b5f7
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/OperationResult.java
@@ -0,0 +1,6 @@
+package org.eclipse.basyx.submodel.restapi.operation;
+
+public enum OperationResult {
+ EXECUTION_ERROR, EXECUTION_NOT_YET_FINISHED;
+
+}
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..a094e8d 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,20 +1,20 @@
package org.eclipse.basyx.submodel.restapi.vab;
import java.util.Collection;
-import java.util.HashSet;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
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.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;
@@ -50,9 +50,9 @@
* @return returns the SubmodelElementProvider pointing to the contained
* submodelelements
*/
- private SubmodelElementProvider getElementProvider() {
+ private MultiSubmodelElementProvider getElementProvider() {
IModelProvider elementProxy = new VABElementProxy(SubModel.SUBMODELELEMENT, modelProvider);
- return new SubmodelElementProvider(elementProxy);
+ return new MultiSubmodelElementProvider(elementProxy);
}
@SuppressWarnings("unchecked")
@@ -61,83 +61,87 @@
// For access on the container property root, return the whole model
Map<String, Object> map = (Map<String, Object>) modelProvider.getModelPropertyValue("");
- // 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);
+ }
+
+ @Override
+ public void addSubmodelElement(List<String> idShorts, ISubmodelElement elem) {
+ getElementProvider().createValue(buildNestedElementPath(idShorts), elem);
}
@Override
public void deleteSubmodelElement(String idShort) {
- getElementProvider().deleteValue(SubmodelElementProvider.ELEMENTS + "/" + idShort);
+ getElementProvider().deleteValue(MultiSubmodelElementProvider.ELEMENTS + "/" + idShort);
+ }
+
+ @Override
+ public void deleteNestedSubmodelElement(List<String> idShorts) {
+ getElementProvider().deleteValue(buildNestedElementPath(idShorts));
+ }
+
+ @Override
+ public Collection<IOperation> getOperations() {
+ return getSubmodelElements().stream().filter(e -> e instanceof IOperation).map(e -> (IOperation) e).collect(Collectors.toList());
}
@SuppressWarnings("unchecked")
@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()));
- }
- }
-
- @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()
+ .getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS);
+ return elements.stream().map(SubmodelElement::createAsFacade).collect(Collectors.toList());
}
@Override
- public void updateProperty(String idShort, Object newValue) {
+ public void updateSubmodelElement(String idShort, Object newValue) {
getElementProvider().setModelPropertyValue(buildValuePathForProperty(idShort), newValue);
}
@Override
- public Object getPropertyValue(String idShort) {
+ public void updateNestedSubmodelElement(List<String> idShorts, Object newValue) {
+ getElementProvider().setModelPropertyValue(buildNestedElementPath(idShorts) + "/" + Property.VALUE, newValue);
+ }
+
+ @Override
+ public Object getSubmodelElementValue(String idShort) {
return getElementProvider().getModelPropertyValue(buildValuePathForProperty(idShort));
}
@SuppressWarnings("unchecked")
@Override
public ISubmodelElement getSubmodelElement(String idShort) {
- return SubmodelElement.createAsFacade((Map<String, Object>) getElementProvider().getModelPropertyValue(SubmodelElementProvider.ELEMENTS + "/" + idShort));
+ return SubmodelElement.createAsFacade((Map<String, Object>) getElementProvider().getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/" + idShort));
}
@Override
public Object invokeOperation(String idShort, Object... params) {
- return getElementProvider().invokeOperation(SubmodelElementProvider.OPERATIONS + "/" + idShort, params);
+ return getElementProvider().invokeOperation(MultiSubmodelElementProvider.ELEMENTS + "/" + idShort, params);
+ }
+
+ @Override
+ public Object invokeNestedOperation(List<String> idShorts, Object... params) {
+ return getElementProvider().invokeOperation(buildNestedElementPath(idShorts), params);
+ }
+
+ @Override
+ public Object invokeNestedOperationAsync(List<String> idShorts, Object... params) {
+ return getElementProvider().invokeOperation(buildNestedElementPath(idShorts) + "/" + Operation.INVOKE + OperationProvider.ASYNC, params);
}
private String buildValuePathForProperty(String idShort) {
- return SubmodelElementProvider.PROPERTIES + "/" + idShort + "/" + Property.VALUE;
+ return MultiSubmodelElementProvider.ELEMENTS + "/" + idShort + "/" + Property.VALUE;
}
@Override
- public Object getNestedPropertyValue(List<String> idShorts) {
+ public Object getNestedSubmodelElementValue(List<String> idShorts) {
return getElementProvider().getModelPropertyValue(buildNestedElementPath(idShorts) + "/" + Property.VALUE);
}
@@ -147,12 +151,18 @@
Map<String, Object> map = (Map<String, Object>) getElementProvider().getModelPropertyValue(buildNestedElementPath(idShorts));
return SubmodelElement.createAsFacade(map);
}
+
+ @Override
+ public Object getOperationResult(List<String> idShorts, String requestId) {
+ return getElementProvider().getModelPropertyValue(buildNestedElementPath(idShorts) + "/" + OperationProvider.INVOCATION_LIST + "/" + requestId);
+ }
/**
* @param idShorts
* @return
*/
private String buildNestedElementPath(List<String> idShorts) {
- return SubmodelElementProvider.ELEMENTS + "/" + VABPathTools.concatenatePaths(idShorts.toArray(new String[1]));
+ return MultiSubmodelElementProvider.ELEMENTS + "/" + VABPathTools.concatenatePaths(idShorts.toArray(new String[0]));
}
+
}
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..31119fc 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
@@ -2,6 +2,7 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.UUID;
import org.eclipse.basyx.vab.coder.json.metaprotocol.IMetaProtocolHandler;
import org.eclipse.basyx.vab.coder.json.metaprotocol.MetaprotocolHandler;
@@ -12,6 +13,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 +27,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
@@ -83,7 +89,17 @@
String message = provider.getModelPropertyValue(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
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..6a3dd15 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,8 @@
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 +114,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 +146,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,7 +166,7 @@
* 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
@@ -171,7 +176,7 @@
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 +191,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 {
@@ -198,7 +203,7 @@
providerBackend.setModelPropertyValue(path, parameter);
// Send response
- outputStream.write("");
+ outputStream.write("".getBytes(StandardCharsets.UTF_8));
} catch (Exception e) {
sendException(outputStream, e);
@@ -211,7 +216,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 +249,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 +265,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 +280,7 @@
}
// Send response
- outputStream.write("");
+ outputStream.write("".getBytes(StandardCharsets.UTF_8));
} catch (Exception e) {
sendException(outputStream, e);
@@ -291,7 +296,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 +306,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/GSONTools.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/GSONTools.java
index 34f1eec..beb438f 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
@@ -7,6 +7,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;
@@ -98,7 +99,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 +150,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 +171,7 @@
}
}
+
/**
* Serializes either string, number or boolean to a JsonPrimitive
*
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..408604d 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
@@ -35,6 +35,12 @@
}
+ public ProviderException(String message, Throwable cause) {
+ super(cause);
+ this.message = message;
+ }
+
+
/**
* Return detailed message
*/
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..1454e07 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
@@ -23,7 +23,7 @@
*/
public class VABModelMap<V extends Object> implements Map<String, V> {
- Map<String, V> map;
+ protected Map<String, V> map;
/**
* Default constructor
@@ -183,6 +183,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) {
@@ -199,14 +205,49 @@
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 testEquivalence(thisMap, otherMap);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private boolean testEquivalence(Map<String, Object> a, Map<String, Object> b) {
+ if (a.size() != b.size()) {
+ return false;
+ }
+
+ for (String k : a.keySet()) {
+ Object aVal = a.get(k);
+ Object bVal = b.get(k);
+ if (aVal instanceof Map<?, ?> && !(bVal instanceof Map<?, ?>)) {
return false;
+ } else if (aVal instanceof Map<?, ?> && bVal instanceof Map<?, ?>) {
+ return testEquivalence((Map<String, Object>) aVal, (Map<String, Object>) bVal);
+ } else {
+ if (aVal == null) {
+ return bVal == null;
+ } else {
+ if (aVal.equals(bVal)) {
+ return true;
+ } else {
+ if (aVal instanceof Collection<?> && bVal instanceof Collection<?>) {
+ Collection<?> aCol = (Collection<?>) aVal;
+ Collection<?> bCol = (Collection<?>) bVal;
+ return aCol.size() == bCol.size() && aCol.containsAll(bCol);
+ } else {
+ return false;
+ }
+ }
+ }
}
}
return true;
}
+
+ @Override
+ public String toString() {
+ return map.toString();
+ }
}
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..89642a4 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
@@ -6,6 +6,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 +230,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 +241,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 +364,22 @@
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;
+ }
}
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..6a35c57 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
@@ -99,6 +99,9 @@
@SuppressWarnings("unchecked")
@Override
public Object invokeOperation(String path, Object... parameters) {
+
+ path = VABPathTools.stripInvokeFromPath(path);
+
Object childElement = getModelPropertyValue(path);
// Invoke operation for function interfaces
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..fe7c99f 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
@@ -67,4 +67,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/basyx/connector/BaSyxConnector.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/connector/BaSyxConnector.java
index bb0f851..d9fc5f0 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
@@ -278,4 +278,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/server/VABBaSyxTCPInterface.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/server/VABBaSyxTCPInterface.java
index a33e8da..74819af 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
@@ -2,7 +2,6 @@
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 +80,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 +105,7 @@
// Send response frame
output.flush();
- sendResponseFrame(byteArrayOutput);
+ sendResponseFrame(output);
break;
}
@@ -133,7 +131,7 @@
// Send response frame
output.flush();
- sendResponseFrame(byteArrayOutput);
+ sendResponseFrame(output);
break;
}
@@ -159,7 +157,7 @@
// Send response frame
output.flush();
- sendResponseFrame(byteArrayOutput);
+ sendResponseFrame(output);
break;
}
@@ -194,7 +192,7 @@
// Send response frame
output.flush();
- sendResponseFrame(byteArrayOutput);
+ sendResponseFrame(output);
break;
}
@@ -219,7 +217,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..7c14785 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,5 +1,6 @@
package org.eclipse.basyx.vab.protocol.http.connector;
+import javax.ws.rs.ProcessingException;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
@@ -15,6 +16,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import io.netty.handler.codec.http.HttpMethod;
+
/**
* HTTP connector class
*
@@ -44,7 +47,7 @@
}
public HTTPConnector(String address) {
- this(address, MediaType.APPLICATION_JSON);
+ this(address, MediaType.APPLICATION_JSON + ";charset=UTF-8");
}
public HTTPConnector(String address, String mediaType) {
@@ -125,7 +128,6 @@
// Build request, set JSON encoding
Builder request = resource.request();
request.accept(mediaType);
-
// Return JSON request
return request;
}
@@ -159,7 +161,12 @@
Builder request = retrieveBuilder(servicePath);
// Perform request
- Response rsp = request.get();
+ Response rsp;
+ try {
+ rsp = request.get();
+ } catch (ProcessingException e) {
+ throw this.handleProcessingException(HttpMethod.GET, e);
+ }
// Return response message (header)
return rsp.readEntity(String.class);
@@ -171,7 +178,12 @@
Builder request = retrieveBuilder(servicePath);
// Perform request
- Response rsp = request.put(Entity.entity(newValue, mediaType));
+ Response rsp;
+ try {
+ rsp = request.put(Entity.entity(newValue, mediaType));
+ } catch (ProcessingException e) {
+ throw this.handleProcessingException(HttpMethod.PUT, e);
+ }
// Return response message (header)
return rsp.readEntity(String.class);
@@ -185,7 +197,12 @@
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;
+ try {
+ rsp = client.target(VABPathTools.concatenatePaths(address, servicePath)).request().build("PATCH", Entity.text(newValue)).property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true).invoke();
+ } catch (ProcessingException e) {
+ throw this.handleProcessingException(HttpMethod.PATCH, e);
+ }
// Return response message (header)
return rsp.readEntity(String.class);
@@ -197,7 +214,12 @@
Builder request = retrieveBuilder(servicePath);
// Perform request
- Response rsp = request.post(Entity.entity(parameter, mediaType));
+ Response rsp;
+ try {
+ rsp = request.post(Entity.entity(parameter, mediaType));
+ } catch (ProcessingException e) {
+ throw this.handleProcessingException(HttpMethod.POST, e);
+ }
// Return response message (header)
return rsp.readEntity(String.class);
@@ -209,7 +231,12 @@
Builder request = retrieveBuilder(servicePath);
// Perform request
- Response rsp = request.delete();
+ Response rsp;
+ try {
+ rsp = request.delete();
+ } catch (ProcessingException e) {
+ throw this.handleProcessingException(HttpMethod.DELETE, e);
+ }
// Return response message (header)
return rsp.readEntity(String.class);
@@ -231,4 +258,17 @@
return buildRequest(client, VABPathTools.concatenatePaths(address, servicePath));
}
+ private ProviderException handleProcessingException(HttpMethod method, ProcessingException e) {
+ return new ProviderException("[HTTP " + method.name() + "] Failed to request " + this.address + " with mediatype " + this.mediaType);
+ }
+
+ /**
+ * 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/server/VABHTTPInterface.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/VABHTTPInterface.java
index 692305b..313a135 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,7 @@
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 +10,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 +21,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 +94,6 @@
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- PrintWriter responseWriter = resp.getWriter();
-
try {
String path = extractPath(req);
@@ -103,12 +104,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 +119,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 +144,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 +156,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 +179,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 +186,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 +200,6 @@
*/
@Override
protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- PrintWriter responseWriter = resp.getWriter();
-
try {
String path = extractPath(req);
@@ -222,12 +209,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 +290,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/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..cc30ccc 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
@@ -8,10 +8,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 +30,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 +45,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 +70,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 +149,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 +185,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/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..0b53ac6
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregatorProxy.java
@@ -0,0 +1,86 @@
+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
+ assertTrue((boolean) ((IOperation) sm.getSubmodelElement(op.getIdShort())).invoke());
+
+ // 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/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..140cecb
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/json/TestJSONConverter.java
@@ -0,0 +1,120 @@
+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.get());
+ }
+
+ 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..842f4a8 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
@@ -4,7 +4,6 @@
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;
@@ -47,9 +46,10 @@
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.valuetypedef.PropertyValueTypeDef;
+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;
@@ -66,101 +66,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) {
@@ -355,7 +324,7 @@
assertNotNull(submodel);
checkDefaultEmbeddedDataSpecification(submodel);
assertEquals("3s7plfdrs35_submodel1", submodel.getIdShort());
- Collection<IConstraint> constraints = submodel.getQualifier();
+ Collection<IConstraint> constraints = submodel.getQualifiers();
assertEquals(2, constraints.size());
checkSubmodelElements(submodel);
}
@@ -370,19 +339,22 @@
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.get());
+ assertEquals(PropertyValueTypeDef.Double, property.getValueType());
assertEquals("rotationSpeed", property.getIdShort());
element = submodelElements.get("emptyDouble");
assertTrue(element instanceof Property);
property = (Property) element;
- assertEquals("double", property.getValueType());
+ assertEquals(PropertyValueTypeDef.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 +380,7 @@
element = submodelElements.get("range_id");
assertTrue(element instanceof Range);
Range range = (Range) element;
- assertEquals("int", range.getValueType());
+ assertEquals(PropertyValueTypeDef.Integer, range.getValueType());
assertEquals("1", range.getMin());
assertEquals("10", range.getMax());
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..6e661f8 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
@@ -52,7 +52,7 @@
InMemoryDirectory directory = new InMemoryDirectory();
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 +62,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);
@@ -115,7 +115,7 @@
// 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..5fc2233 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,13 +1,19 @@
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.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
import org.eclipse.basyx.aas.restapi.AASModelProvider;
@@ -20,6 +26,8 @@
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;
@@ -57,17 +65,16 @@
// Register AAS at directory
IIdentifier aasId = new Identifier(IdentifierType.CUSTOM, "aasId");
String aasIdShort = "aasName";
- connectorProvider.addMapping("", new AASAggregatorProvider(new AASAggregator()));
-
+ IModelProvider provider = new AASAggregatorProvider(new AASAggregator());
+ prepareConnectorProvider(provider);
+
// Create an AAS containing a reference to the created SubModel
- AssetAdministrationShell aas = new AssetAdministrationShell();
- aas.setIdentification(aasId);
- aas.setIdShort(aasIdShort);
- manager.createAAS(aas, aasId, "");
+ 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,6 +83,7 @@
assertEquals(aasId.getIdType(), connectedAAS.getIdentification().getIdType());
}
+
@Test
public void testCreateSubModel() throws Exception {
IIdentifier aasId = new Identifier(IdentifierType.CUSTOM, "aasId");
@@ -114,9 +122,124 @@
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) {
+ VABElementProxy proxy = new VABElementProxy("/shells", provider);
+ connectorProvider.addMapping("shells", proxy);
+ connectorProvider.addMapping("", proxy);
+ }
+
+ 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..da56305 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
@@ -5,11 +5,14 @@
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.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;
@@ -25,6 +28,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.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDef;
import org.junit.Test;
@@ -72,9 +76,7 @@
* implicitly
*/
// Create an AAS containing a reference to the created SubModel
- AssetAdministrationShell aas = new AssetAdministrationShell();
- aas.setIdShort(AASIDSHORT);
- aas.setIdentification(AASID);
+ 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);
@@ -100,10 +102,8 @@
Property p = new Property(PROPVAL);
p.setIdShort(PROPID);
- SubModel sm = new SubModel();
+ SubModel sm = new SubModel(SMIDSHORT, SMID);
sm.addSubModelElement(p);
- sm.setIdShort(SMIDSHORT);
- sm.setIdentification(SMID.getIdType(), SMID.getId());
return sm;
}
@@ -142,7 +142,7 @@
// Check if the submodel has been retrieved correctly
ISubModel sm = shell.getSubModels().get(SMIDSHORT);
IProperty prop = sm.getProperties().get(PROPID);
- assertEquals(PROPVAL, prop.get());
+ assertEquals(PROPVAL, prop.getValue());
}
/**
@@ -167,9 +167,10 @@
// 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", PropertyValueTypeDef.String);
+ prop.setValue("testProperty");
+ subModel.addSubModelElement(prop);
//Retrieve the aas
IAssetAdministrationShell shell = retrieveShell();
@@ -184,7 +185,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..ef6c8c2 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,5 +1,8 @@
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;
@@ -10,12 +13,15 @@
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.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
@@ -36,14 +42,14 @@
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();
// 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 +71,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..547e339
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/TestAasEnv.java
@@ -0,0 +1,95 @@
+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.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.map.SubModel;
+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.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");
+
+ Map<String, Object> assetAdministrationShell = new HashMap<>();
+ assetAdministrationShell.put(ModelType.MODELTYPE, AssetAdministrationShell.MODELTYPE);
+ assetAdministrationShell.put(Referable.IDSHORT, "TestAssetAdministrationShell");
+
+ Map<String, Object> submodel = new HashMap<>();
+ submodel.put(ModelType.MODELTYPE, SubModel.MODELTYPE);
+ submodel.put(Referable.IDSHORT, "TestSubmodel");
+ submodel.put(SubModel.SUBMODELELEMENT, new ArrayList<Object>());
+
+ Map<String, Object> conceptDescription = new HashMap<>();
+ submodel.put(ModelType.MODELTYPE, ConceptDescription.MODELTYPE);
+ submodel.put(Referable.IDSHORT, "TestConceptDescription");
+
+
+ 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..0ded0b6 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
@@ -6,7 +6,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;
@@ -22,10 +21,12 @@
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.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.valuetypedef.PropertyValueTypeDef;
import org.eclipse.basyx.testsuite.regression.aas.metamodel.AssetAdministrationShellSuite;
import org.junit.Before;
import org.junit.Test;
@@ -63,17 +64,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);
@@ -119,12 +109,15 @@
@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", PropertyValueTypeDef.String);
+ prop1.setValue("testProperty1");
+ subModel1.addSubModelElement(prop1);
+
+ SubModel subModel2 = new SubModel("newSubmodelId2", new Identifier(IdentifierType.CUSTOM, "smId2"));
+ Property prop2 = new Property("prop2Id", PropertyValueTypeDef.String);
+ prop2.setValue("testProperty2");
+ subModel2.addSubModelElement(prop2);
// create a collection of descriptors and add the above descriptors
Collection<SubModel> submodels = new ArrayList<SubModel>();
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..59e31ae 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,22 @@
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.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,6 +26,17 @@
*
*/
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(AssetAdministrationShell.ENDPOINTS, Arrays.asList(new HashMap<String, String>()));
+ map.put(AssetAdministrationShell.SUBMODELS, new HashSet<SubmodelDescriptor>());
+ }
/**
* Tests retrieval of all registered submodel descriptors
@@ -35,4 +57,76 @@
// Assert correct retrieval
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(AssetAdministrationShell.ENDPOINTS);
+ new AASDescriptor(map);
+ }
+
+ @Test(expected = MalformedRequestException.class)
+ public void testValidateNullEndpoints() {
+ map.put(AssetAdministrationShell.ENDPOINTS, null);
+ new AASDescriptor(map);
+ }
+
+ @Test(expected = MalformedRequestException.class)
+ public void testValidateWrongEndpoints() {
+ map.put(AssetAdministrationShell.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/TestSubmodelDescriptor.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestSubmodelDescriptor.java
index 55adcb4..49a7e73 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
@@ -31,7 +31,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);
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 f64cbc7..60ea076 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
@@ -45,8 +45,8 @@
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;
/**
@@ -152,6 +152,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 +201,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 +208,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,20 +223,6 @@
} catch (ResourceNotFoundException e) {
// expected
}
-
- // 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
- }
}
/**
@@ -239,12 +252,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");
+ proxy.delete(aasId1, new Identifier(IdentifierType.CUSTOM, "nonExistentSubModelId"));
}
@Test(expected = ResourceNotFoundException.class)
@@ -252,12 +265,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());
@@ -277,17 +303,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/restapi/MultiAASProviderTest.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiAASProviderTest.java
index a37c034..801b73b 100644
--- 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
@@ -4,16 +4,13 @@
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.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
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;
@@ -37,7 +34,7 @@
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()));
+ aasProvider.addSubmodel(new SubModelProvider(new SimpleAASSubmodel()));
provider = new MultiAASProvider();
provider.addMultiSubmodelProvider("a1", aasProvider);
stub.addProvider(urn, "", provider);
@@ -47,50 +44,61 @@
@Test
public void clearTest() {
provider.clear();
- Object result = proxy.getModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/");
- assertNull(result);
+
+ // test if AAS is deleted
+ try {
+ proxy.getModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/");
+ fail();
+ } catch(ResourceNotFoundException e) {}
}
- @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));
+ Integer result = (Integer) proxy
+ .getModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty/value");
+ assertEquals(123, result.intValue());
// test reading from an invalid aas
- assertNull(proxy.getModelPropertyValue("A1/aas/submodels/SimpleAASSubmodel/"));
+ try {
+ proxy.getModelPropertyValue("A1/aas/submodels/SimpleAASSubmodel/submodel");
+ fail();
+ } catch(ResourceNotFoundException e) {}
}
- @SuppressWarnings("unchecked")
@Test
public void setTest() {
// test setting in a valid aas
- proxy.setModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty/value", 100);
+ proxy.setModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty/value", 100);
// test setting in an invalid aas
- proxy.setModelPropertyValue("A1/aas/submodels/SimpleAASSubmodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty/value", 200);
+ try {
+ proxy.setModelPropertyValue("A1/aas/submodels/SimpleAASSubmodel/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty/value", 200);
+ fail();
+ } catch(ResourceNotFoundException e) {}
// 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));
+ Integer result = (Integer) proxy
+ .getModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty/value");
+ assertEquals(100, result.intValue());
}
- @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));
+ try {
+ proxy.deleteValue("A1/aas/submodels/SimpleAASSubmodel/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty/value");
+ fail();
+ } catch(ResourceNotFoundException e) {}
+
+ Integer result = (Integer) proxy
+ .getModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty/value");
+ assertEquals(123, result.intValue());
// test deleting from a valid aas
- proxy.deleteValue("a1/aas/submodels/SimpleAASSubmodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty");
+ proxy.deleteValue("a1/aas/submodels/SimpleAASSubmodel/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty");
try {
- proxy.getModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty/");
+ proxy.getModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty/");
fail();
} catch (ResourceNotFoundException e) {
}
@@ -100,14 +108,14 @@
public void invokeExceptionTest() {
// Invoke exception1
try {
- proxy.invokeOperation("a1/aas/submodels/SimpleAASSubmodel/operations/exception1");
+ proxy.invokeOperation("a1/aas/submodels/SimpleAASSubmodel/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/exception1/" + Operation.INVOKE);
fail();
} catch (ProviderException e) {
assertEquals(NullPointerException.class, e.getCause().getClass());
}
// Invoke exception2
try {
- proxy.invokeOperation("a1/aas/submodels/SimpleAASSubmodel/operations/exception2", "prop1");
+ proxy.invokeOperation("a1/aas/submodels/SimpleAASSubmodel/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/exception2/" + Operation.INVOKE, "prop1");
fail();
} catch (ProviderException e) {
assertEquals("Exception description", e.getMessage());
@@ -117,10 +125,13 @@
@Test
public void invokeTest() {
// test invoking from an invalid aas
- assertNull(proxy.invokeOperation("A1/aas/submodels/SimpleAASSubmodel/operations/complex", 10, 3));
+ try {
+ proxy.invokeOperation("A1/aas/submodels/SimpleAASSubmodel/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/complex/" + Operation.INVOKE, 10, 3);
+ fail();
+ } catch(ResourceNotFoundException e) {}
// 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"));
+ assertEquals(7, proxy.invokeOperation("a1/aas/submodels/SimpleAASSubmodel/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/complex/" + Operation.INVOKE, 10, 3));
+ assertEquals(true, proxy.invokeOperation("a1/aas/submodels/SimpleAASSubmodel/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/simple/" + Operation.INVOKE));
}
}
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..2069216
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiSubmodelProviderRemoteInvocationTest.java
@@ -0,0 +1,192 @@
+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 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.IAASRegistryService;
+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.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.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnectorProvider;
+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 VABMultiSubmodelProvider provider;
+
+ @Before
+ public void init() {
+ // Creating a new AAS Registry
+ IAASRegistryService registry = new InMemoryRegistry();
+
+
+ // 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 VABMultiSubmodelProvider(registry, new BaSyxConnectorProvider());
+
+ // 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.getModelPropertyValue("/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);
+ }
+
+ /**
+ * 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.setModelPropertyValue(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.setModelPropertyValue(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.getModelPropertyValue(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..fd10b96 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.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.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.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;
@@ -48,12 +51,11 @@
VABConnectionManagerStub stub = new VABConnectionManagerStub();
String urn = "urn:fhg:es.iese:aas:1:1:submodel";
VABMultiSubmodelProvider provider = new VABMultiSubmodelProvider();
+
// 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,8 +81,8 @@
@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")
@@ -96,12 +98,12 @@
public void createDeleteSubmodelTest() {
SubModel sm = new SimpleAASSubmodel("TestSM");
sm.setIdentification(IdentifierType.CUSTOM, "TestId");
- proxy.createValue("/aas/submodels", sm);
+ proxy.setModelPropertyValue("/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());
@@ -120,15 +122,14 @@
}
}
- @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
+ .getModelPropertyValue("/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.getModelPropertyValue("/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..021c22b 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
@@ -32,7 +32,7 @@
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/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..86db069
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/TestSubmodelSuite.java
@@ -0,0 +1,347 @@
+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.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.IBlob;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.relationship.IRelationshipElement;
+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.dataelement.property.valuetypedef.PropertyValueTypeDef;
+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 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));
+
+ public SubModel getReferenceSubmodel() {
+
+ // Create a simple value property
+ Property propertyMeta = new Property(PROP, PropertyValueTypeDef.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.get(), 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(3, values.size());
+
+ // Check if all expected Values are present
+ assertEquals(100, values.get(PROP));
+
+ 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(BLOB_ID));
+ }
+
+ /**
+ * 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);
+
+ Property byteProp = new Property();
+ byteProp.setIdShort("byte_prop01");
+ Byte byteNumber = Byte.parseByte("2");
+ byteProp.set(byteNumber);
+ ret.put(byteProp.getIdShort(), byteProp);
+
+ Property durationProp = new Property();
+ durationProp.setIdShort("duration_prop01");
+ Duration duration = Duration.ofSeconds(10);
+ durationProp.set(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.set(p);
+ ret.put(periodProp.getIdShort(), periodProp);
+
+ Property bigNumberProp = new Property();
+ bigNumberProp.setIdShort("bignumber_prop01");
+ BigInteger bignumber = new BigInteger("9223372036854775817");
+ property.set(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 Blob to use as Value for smECollection
+ Blob blob = new Blob(BLOB_ID, "text/json");
+ blob.setValue(new byte[] { 1, 2, 3 });
+
+ List<ISubmodelElement> values = new ArrayList<>();
+ values.add(blob);
+
+ smECollection.setValue(values);
+ ret.put(smECollection.getIdShort(), smECollection);
+
+ 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);
+
+ 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 acutalProperty = (IProperty) actual.get(PROPERTY_ID);
+ assertNotNull(acutalProperty);
+ try {
+ assertEquals(expectedProperty.getValue(), acutalProperty.getValue());
+ assertEquals(expectedProperty.getValueType(), acutalProperty.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
+ for (ISubmodelElement iSubmodelElement : elements) {
+ assertTrue(iSubmodelElement instanceof IBlob);
+ }
+
+ assertEquals(expectedCollection.getSubmodelElements().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());
+ }
+
+ /**
+ * 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/connected/TestConnectedProperty.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedProperty.java
index 5fceb14..698f91b 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
@@ -8,7 +8,7 @@
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedProperty;
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.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;
@@ -31,7 +31,7 @@
// Create PropertySingleValued containing the simple value
Property propertyMeta = new Property(VALUE);
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
@@ -40,10 +40,10 @@
propertyMeta.setValueType(PropertyValueTypeDef.String);
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());
+ assertEquals("content", prop.getValue());
}
/**
@@ -53,7 +53,7 @@
*/
@Test
public void testGet() throws Exception {
- int val = (int) prop.get();
+ int val = (int) prop.getValue();
assertEquals(VALUE, val);
}
@@ -64,8 +64,8 @@
*/
@Test
public void testValueTypeRetrieval() {
- String valueType = prop.getValueType();
- assertEquals(PropertyValueTypeDef.Integer.toString(), valueType);
+ PropertyValueTypeDef valueType = prop.getValueType();
+ assertEquals(PropertyValueTypeDef.Integer, valueType);
}
/**
@@ -76,7 +76,7 @@
@Test
public void testSet() throws Exception {
prop.set(123);
- int val = (int) prop.get();
+ int val = (int) prop.getValue();
assertEquals(123, val);
}
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
index 3a1580e..c24f6a2 100644
--- 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
@@ -1,36 +1,21 @@
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.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.TypeDestroyingProvider;
@@ -38,80 +23,40 @@
import org.junit.Test;
/**
- * Tests if a SubModel can be created and used correctly
+ * Tests if a ConnectSubmodel can be created and used correctly
*
* @author schnicke
*
*/
-public class TestConnectedSubModel {
+public class TestConnectedSubModel extends TestSubmodelSuite {
// 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));
+ private final String OPERATION_ID = "operation_id";
ConnectedSubModel submodel;
@Before
public void build() {
- // Create a simple value property
- Property propertyMeta = new Property(100);
- propertyMeta.setIdShort(PROP);
+ SubModel reference = getReferenceSubmodel();
// Create an operation
Operation op = new Operation((Function<Object[], Object> & Serializable) obj -> {
return (int) obj[0] + (int) obj[1];
});
op.setIdShort(OP);
+ reference.addSubModelElement(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)));
+ 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 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
@@ -126,206 +71,57 @@
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()) {
+ 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);
+ public void testGetLocalCopy() {
+ assertEquals(getReferenceSubmodel(), submodel.getLocalCopy());
}
-
- /**
- * 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());
+
+ @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..f025c26 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
@@ -2,17 +2,22 @@
import static org.junit.Assert.assertEquals;
+import java.util.ArrayList;
+import java.util.Collection;
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.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.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 +34,7 @@
private static final String PROP = "prop";
private static final String OPERATION = "sum";
- ISubmodelElementCollection prop;
+ ConnectedSubmodelElementCollection prop;
@Before
public void build() {
@@ -45,17 +50,21 @@
// Create ComplexDataProperty containing the created operation and property
SubmodelElementCollection complex = new SubmodelElementCollection();
- complex.addElement(propertyMeta);
- complex.addElement(operation);
+ 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 +84,7 @@
IProperty prop = props.get(PROP);
// Check contained values
- assertEquals(4, prop.get());
+ assertEquals(4, prop.getValue());
}
/**
@@ -95,4 +104,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..32b73ab 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
@@ -25,14 +25,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.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.MultiSubmodelElementProvider;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
import org.eclipse.basyx.vab.support.TypeDestroyingProvider;
@@ -76,8 +76,6 @@
Map<String, Object> values = new HashMap<>();
- values.put(SubmodelElementProvider.PROPERTIES, dataElements);
- values.put(SubmodelElementProvider.OPERATIONS, operations);
values.put(SubModel.SUBMODELELEMENT, submodelElements);
proxy = new VABElementProxy("", new SubModelProvider(new TypeDestroyingProvider(new VABLambdaProvider(values))));
@@ -161,7 +159,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 +172,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);
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..ccf3dd4 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
@@ -8,7 +8,7 @@
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;
@@ -33,7 +33,7 @@
blob.setMimeType("mimeType");
VABConnectionManagerStub manager = new VABConnectionManagerStub(
- new PropertyProvider(new TypeDestroyingProvider(new VABLambdaProvider(blob))));
+ new SubmodelElementProvider(new TypeDestroyingProvider(new VABLambdaProvider(blob))));
connectedBlob = new ConnectedBlob(manager.connectToVABElement(""));
}
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..5821c60 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
@@ -4,7 +4,7 @@
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;
@@ -29,7 +29,7 @@
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 +50,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..77e1987 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
@@ -9,7 +9,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 +36,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..6474af1 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
@@ -3,8 +3,10 @@
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.valuetypedef.PropertyValueTypeDef;
+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 +26,10 @@
@Before
public void build() {
- range = new Range("valueType", new Integer(1), new Integer(10));
+ range = new Range(PropertyValueTypeDef.Integer, new Integer(1), new Integer(10));
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 +57,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..85fe35d 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
@@ -8,7 +8,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 +34,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(""));
}
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..da6bca5 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
@@ -8,7 +8,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 +34,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..c262015 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,16 @@
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 +19,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/TestConnectedRelationshipElement.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/relationship/TestConnectedRelationshipElement.java
index 95dd6a3..8fff134 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
@@ -8,7 +8,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.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 +36,7 @@
VABConnectionManagerStub manager = new VABConnectionManagerStub(
- new PropertyProvider(new TypeDestroyingProvider(new VABLambdaProvider(relElem))));
+ new SubmodelElementProvider(new TypeDestroyingProvider(new VABLambdaProvider(relElem))));
connectedRelElem = new ConnectedRelationshipElement(manager.connectToVABElement(""));
}
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..6ec3506
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/facade/TestSubmodelElementMapCollectionConverter.java
@@ -0,0 +1,70 @@
+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.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();
+ property.setIdShort(ID_SHORT);
+
+ 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..d52f739 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
@@ -3,26 +3,20 @@
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.submodel.metamodel.api.identifier.IdentifierType;
-import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
+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.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.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.testsuite.regression.submodel.metamodel.TestSubmodelSuite;
+import org.junit.Before;
import org.junit.Test;
/**
@@ -31,38 +25,25 @@
* @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", PropertyValueTypeDef.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());
}
/**
@@ -87,4 +68,9 @@
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/qualifier/TestLangStrings.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestLangStrings.java
index 5f02fb9..89edc55 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,8 @@
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 +77,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/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..408b67f 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
@@ -29,7 +29,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 +39,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..6f58b0c 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
@@ -7,6 +7,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.valuetypedef.PropertyValueTypeDef;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDefHelper;
import org.junit.Before;
import org.junit.Test;
@@ -22,7 +24,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 +40,7 @@
public void testConstructor() {
assertEquals(TYPE, qualifier.getType());
assertEquals(VALUE, qualifier.getValue());
- assertEquals(VALUE_TYPE, qualifier.getValueType());
+ assertEquals(PropertyValueTypeDefHelper.fromName(VALUE_TYPE), qualifier.getValueType());
assertEquals(VALUE_ID, qualifier.getValueId());
}
@@ -65,7 +67,7 @@
@Test
public void testSetValueType() {
- String newValueTypeString = "newValueType";
+ PropertyValueTypeDef newValueTypeString = PropertyValueTypeDef.AnyType;
qualifier.setValueType(newValueTypeString);
assertEquals(newValueTypeString, qualifier.getValueType());
}
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..81b3c7d 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,7 @@
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 +84,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..cb11931 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,8 @@
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 +79,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/TestSubmodelmodelElement.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelElement.java
similarity index 94%
rename from sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelmodelElement.java
rename to sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelElement.java
index 226081f..f1df49b 100644
--- 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/TestSubmodelElement.java
@@ -28,7 +28,7 @@
* @author haque
*
*/
-public class TestSubmodelmodelElement {
+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))));
@@ -36,8 +36,7 @@
@Before
public void buidSubmodelElement() {
- Property property = new Property("testId");
- submodelElement = SubmodelElement.createAsFacade(property);
+ submodelElement = new Property("testId");
}
@Test
@@ -84,8 +83,8 @@
@Test
public void testSetQualifier() {
- submodelElement.setQualifier(Collections.singleton(FORMULA));
- assertEquals(Collections.singleton(FORMULA), submodelElement.getQualifier());
+ submodelElement.setQualifiers(Collections.singleton(FORMULA));
+ assertEquals(Collections.singleton(FORMULA), submodelElement.getQualifiers());
}
@Test
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..66a632a 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
@@ -28,6 +28,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;
@@ -64,15 +65,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 +91,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
@@ -136,17 +146,45 @@
@Test
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
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..694bf1c 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
@@ -2,8 +2,12 @@
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;
@@ -21,6 +25,7 @@
import org.junit.Before;
import org.junit.Test;
+
/**
* Tests constructor, getter and setter of {@link Property} for their
* correctness
@@ -30,7 +35,7 @@
*/
public class TestProperty {
private static final String VALUE = "testValue";
- private static final String STRING_TYPE = "string";
+ private static final PropertyValueTypeDef STRING_TYPE = PropertyValueTypeDef.String;
private Property property;
@Before
@@ -39,14 +44,14 @@
}
@Test
- public void testConstructor1() {
+ public void testConstructor1(){
assertEquals(VALUE, property.get());
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)))));
@@ -63,35 +68,46 @@
}
@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.set(isSomething);
+ assertEquals(isSomething, booleanProp.get());
+ assertEquals(isSomething, booleanProp.getValue());
+ assertEquals(PropertyValueTypeDef.Boolean, booleanProp.getValueType());
+
+ Byte byteNumber = new Byte("2");
+ Property byteProp = new Property();
+ byteProp.set(byteNumber);
+ assertEquals(byteNumber, byteProp.get());
+ assertEquals(PropertyValueTypeDef.Int8, byteProp.getValueType());
+
+ Duration duration = Duration.ofSeconds(10);
+ Property durationProp = new Property();
+ durationProp.set(duration);
+ assertEquals(duration, durationProp.get());
+ assertEquals(PropertyValueTypeDef.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.set(p);
+ assertEquals(p, periodProp.get());
+ assertEquals(PropertyValueTypeDef.YearMonthDuration, periodProp.getValueType());
+
+ Property bigNumberProp = new Property();
+ BigInteger bignumber = new BigInteger("9223372036854775817");
+ bigNumberProp.set(bignumber);
+ assertEquals(bignumber, bigNumberProp.get());
+ assertEquals(PropertyValueTypeDef.PositiveInteger, bigNumberProp.getValueType());
}
@Test
- public void testSetCustom() {
+ public void testSetCustom(){
property.set(null, PropertyValueTypeDef.String);
assertEquals(null, property.get());
- assertEquals(PropertyValueTypeDef.String.getStandardizedLiteral(), property.getValueType());
+ assertEquals(PropertyValueTypeDef.String, property.getValueType());
}
@Test
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..f42434f
--- /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,39 @@
+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.valuetypedef.PropertyValueTypeDef;
+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(PropertyValueTypeDef.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..89e0934
--- /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,74 @@
+package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.operation;
+
+import java.util.function.Function;
+
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+
+/**
+ * Helperclass for testing async invocations of Operations
+ *
+ * @author conradi
+ *
+ */
+public class AsyncOperationHelper {
+
+ public static final String ASYNC_OP_ID = "asyncOperation";
+ public static final String ASYNC_EXCEPTION_OP_ID = "asyncExceptionOperation";
+
+ private Object waitObject = new Object();
+ private boolean shouldWait = true;
+
+ 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);
+ 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(10);
+ } 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..1724d93 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
@@ -10,108 +10,60 @@
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);
+
assertEquals(1, operation.invoke(3,2));
}
@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..aa81f1a
--- /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,141 @@
+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.Collections;
+import java.util.function.Function;
+
+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.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.OperationVariable;
+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 final Collection<OperationVariable> IN = Collections.singletonList(new OperationVariable(new Property(IN_VALUE)));
+ protected static final Collection<OperationVariable> OUT = Collections.singletonList(new OperationVariable(new Property(OUT_VALUE)));
+ protected static final Collection<OperationVariable> INOUT = Collections.singletonList(new OperationVariable(new Property(INOUT_VALUE)));
+
+ 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() {
+ 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 {
+ operationException.invoke();
+ fail();
+ } catch (Exception e) {
+ // Exceptions from ConnectedOperation are wrapped in ProviderException
+ assertTrue(e instanceof NullPointerException
+ || e.getCause() instanceof NullPointerException);
+ }
+ }
+
+ @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 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() {
+ Object value = getValueFromOpVariable(operation.getInputVariables());
+ assertEquals(IN_VALUE, value);
+ }
+
+ @Test
+ public void testOutputVariables() {
+ Object value = getValueFromOpVariable(operation.getOutputVariables());
+ assertEquals(OUT_VALUE, value);
+ }
+
+ @Test
+ public void testInOutputVariables() {
+ Object value = getValueFromOpVariable(operation.getInOutputVariables());
+ assertEquals(INOUT_VALUE, value);
+ }
+
+ /**
+ * Gets the Value from the OperationVariable in a collection
+ */
+ private Object getValueFromOpVariable(Collection<IOperationVariable> vars) {
+ assertEquals(1, vars.size());
+ 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/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..cdc2d1f 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
@@ -8,6 +8,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 +48,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..9865d18 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
@@ -6,7 +6,7 @@
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.restapi.SubmodelElementProvider;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
import org.junit.Test;
@@ -31,11 +31,11 @@
});
// 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();
+ PropertyValueTypeDef expectedType = PropertyValueTypeDef.Double;
assertEquals(expectedType, connectedProperty.getValueType());
// Check value is correctly retrievable by property
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..4d7bb8d 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
@@ -2,6 +2,7 @@
import java.util.function.Function;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
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;
@@ -16,6 +17,10 @@
*
*/
public class SimpleAASSubmodel extends SubModel {
+
+ public static final String INTPROPIDSHORT = "integerProperty";
+ public static final String OPERATIONSIMPLEIDSHORT = "simple";
+
public SimpleAASSubmodel() {
this("SimpleAASSubmodel");
}
@@ -27,9 +32,10 @@
// Create sub model
setIdShort(idShort);
+ setIdentification(new ModelUrn("simpleAASSubmodelUrn"));
Property intProp = new Property(123);
- intProp.setIdShort("integerProperty");
+ intProp.setIdShort(INTPROPIDSHORT);
addSubModelElement(intProp);
Property stringProp = new Property("Test");
@@ -50,7 +56,7 @@
Operation simple = new Operation((Function<Object[], Object>) v -> {
return true;
});
- simple.setIdShort("simple");
+ simple.setIdShort(OPERATIONSIMPLEIDSHORT);
addSubModelElement(simple);
// Create example operations
@@ -68,13 +74,19 @@
exception2.setIdShort("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);
+ 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
index 3a6a7c4..c87cf69 100644
--- 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
@@ -1,30 +1,41 @@
package org.eclipse.basyx.testsuite.regression.submodel.restapi;
import static org.junit.Assert.assertEquals;
+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.valuetypedef.PropertyValueTypeDefHelper;
+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.SubmodelElementProvider;
+import org.eclipse.basyx.submodel.restapi.operation.OperationResult;
+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.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 static final String submodelAddr = "urn:fhg:es.iese:aas:1:1:submodel";
protected VABConnectionManager getConnectionManager() {
if (connManager == null) {
@@ -60,7 +71,6 @@
/**
* Test creating single property
*/
- @SuppressWarnings("unchecked")
@Test
public void testCreateProperty() {
VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
@@ -68,12 +78,38 @@
// Create element
Property prop = new Property(500);
prop.setIdShort("newProperty");
- submodelElement.createValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "", prop);
+ submodelElement.setModelPropertyValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/newProperty", prop);
// Read back value
- Map<String, Object> result = (Map<String, Object>) submodelElement
- .getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/newProperty/value");
- assertEquals(500, result.get(Property.VALUE));
+ Integer result = (Integer) submodelElement
+ .getModelPropertyValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/newProperty/value");
+ assertEquals(500, 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.setModelPropertyValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/newProperty", prop);
+
+ // Read back value
+ Integer result = (Integer) submodelElement
+ .getModelPropertyValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/newProperty/value");
+ assertEquals(500, result.intValue());
+
+
+ submodelElement.setModelPropertyValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/container/newProperty", prop);
+
+ // Read back value
+ result = (Integer) submodelElement
+ .getModelPropertyValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/container/newProperty/value");
+ assertEquals(500, result.intValue());
}
/**
@@ -85,36 +121,49 @@
VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
// Read list of properties
- Object result = submodelElement.getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "");
+ Object result = submodelElement.getModelPropertyValue("/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.getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty");
+ result = submodelElement.getModelPropertyValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty");
property = (Map<String, Object>) result;
assertEquals(123, property.get(Property.VALUE));
// Read idShort
- result = submodelElement.getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/stringProperty");
+ result = submodelElement.getModelPropertyValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/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));
+ String resString = (String) submodelElement
+ .getModelPropertyValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/stringProperty/value");
+ assertEquals("Test", resString);
// Read null value
- resMap = (Map<String, Object>) submodelElement
- .getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/nullProperty/value");
- assertEquals(null, resMap.get(Property.VALUE));
+ Object resObject = submodelElement
+ .getModelPropertyValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/nullProperty/value");
+ assertEquals(null, resObject);
// 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)));
+
+ // 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")).get());
// Read nested property
String pathToNestedContainer = "/submodel/submodelElements/containerRoot/container";
@@ -132,41 +181,63 @@
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);
+ submodelElement.setModelPropertyValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty/value", 3);
// Check result
Map<String, Object> result = (Map<String, Object>) submodelElement
- .getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty");
+ .getModelPropertyValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty");
assertEquals(3, result.get(Property.VALUE));
}
-
+
/**
- * Test reading all properties of the submodel
+ * Test updating a SubmodelElementCollection
*/
@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());
+ 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.setModelPropertyValue(path + "/value", smElements);
+
+ // read back the collection
+ Map<String, Object> map = (Map<String, Object>) submodelElement
+ .getModelPropertyValue(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 reading all operations of the submodel
+ * Test updating a Property inside a SubmodelElementCollection
*/
- @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());
+ public void testUpdateElementInSmElementCollection() {
+ VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+
+ String path = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS,
+ "containerRoot", "container", "integerProperty", "value");
+
+ Integer value = (Integer) submodelElement.getModelPropertyValue(path);
+ assertEquals(123, value.intValue());
+
+ submodelElement.setModelPropertyValue(path, 321);
+
+ value = (Integer) submodelElement.getModelPropertyValue(path);
+ assertEquals(321, value.intValue());
}
/**
@@ -176,8 +247,27 @@
@Test
public void testReadSingleOperation() {
VABElementProxy submodel = getConnectionManager().connectToVABElement(submodelAddr);
- Map<String, Object> operation = (Map<String, Object>) submodel.getModelPropertyValue("/submodel/operations/simple");
+ Map<String, Object> operation = (Map<String, Object>) submodel.getModelPropertyValue("/submodel/submodelElements/simple");
assertEquals("simple", operation.get(Identifiable.IDSHORT));
+
+ try {
+ submodel.getModelPropertyValue("/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.getModelPropertyValue("/submodel");
+ Object o = smMap.get(SubModel.SUBMODELELEMENT);
+ assertTrue(o instanceof Collection<?>);
}
/**
@@ -200,11 +290,11 @@
VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
// Delete property
- submodelElement.deleteValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty");
+ submodelElement.deleteValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty");
// Test, if it has been deleted
try {
- submodelElement.getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty");
+ submodelElement.getModelPropertyValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty");
fail();
} catch (ResourceNotFoundException e) {}
}
@@ -217,11 +307,51 @@
VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
// Delete operation
- submodelElement.deleteValue("/submodel/operations/simple");
+ submodelElement.deleteValue("/submodel/submodelElements/simple");
// Test, if it has been deleted
try {
- submodelElement.getModelPropertyValue("/submodel/operations/simple");
+ submodelElement.getModelPropertyValue("/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.getModelPropertyValue(path));
+
+ // Delete property
+ submodelElement.deleteValue(path);
+
+ // Test if parent Collection is still there
+ assertNotNull(submodelElement.getModelPropertyValue(VABPathTools.getParentPath(path)));
+
+ // Test, if it has been deleted
+ try {
+ submodelElement.getModelPropertyValue(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.getModelPropertyValue(VABPathTools.getParentPath(path)));
+
+ // Test, if it has been deleted
+ try {
+ submodelElement.getModelPropertyValue(path);
fail();
} catch (ResourceNotFoundException e) {}
}
@@ -234,21 +364,147 @@
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));
+ 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/operations/complex", param1, param2);
+ Object result = submodelElement.invokeOperation("/submodel/submodelElements/complex/invoke", param1, param2);
assertEquals(3, result);
// Invoke operation on parent element
- result = submodelElement.invokeOperation("/submodel/operations/simple");
+ 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.getModelPropertyValue("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"));
+ }
+
+ @Test
+ public void testInvokeAsync() throws Exception {
+ VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+ AsyncOperationHelper helper = new AsyncOperationHelper();
+
+ String path = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS, AsyncOperationHelper.ASYNC_OP_ID);
+ submodelElement.setModelPropertyValue(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");
+ String requestId = (String) submodelElement.invokeOperation(path, param1, param2);
+
+ String listPath = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS, AsyncOperationHelper.ASYNC_OP_ID, OperationProvider.INVOCATION_LIST);
+
+ // Try correct operationId, wrong requestId
+ try {
+ submodelElement.getModelPropertyValue(VABPathTools.append(listPath, "nonexistent"));
+ fail();
+ } catch (ResourceNotFoundException e) {
+ }
+
+ // Try wrong operationId, correct requestId
+ try {
+ submodelElement.getModelPropertyValue("/submodel/submodelElements/simple/invocationList/" + requestId);
+ fail();
+ } catch (ResourceNotFoundException e) {
+ }
+
+ String requestPath = VABPathTools.append(listPath, requestId);
+
+ // Check that it has not finished yet
+ Object result = submodelElement.getModelPropertyValue(requestPath);
+ assertEquals(result, OperationResult.EXECUTION_NOT_YET_FINISHED.toString());
+
+ helper.releaseWaitingOperation();
+
+ result = submodelElement.getModelPropertyValue(requestPath);
+ assertEquals(7, result);
+
+ // Check if the async-invocation is deleted after retrieving its result
+ try {
+ submodelElement.getModelPropertyValue(requestPath);
+ fail();
+ } catch (ResourceNotFoundException e) {
+ }
+ }
+
+ @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.setModelPropertyValue(path, helper.getAsyncExceptionOperation());
+
+ path = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS,
+ AsyncOperationHelper.ASYNC_EXCEPTION_OP_ID, "invoke?async=true");
+
+ String requestId = (String) submodelElement.invokeOperation(path);
+
+ String requestPath = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS,
+ AsyncOperationHelper.ASYNC_EXCEPTION_OP_ID, OperationProvider.INVOCATION_LIST, requestId);
+
+ // Check that it has not finished yet
+ Object result = submodelElement.getModelPropertyValue(requestPath);
+ assertEquals(result, OperationResult.EXECUTION_NOT_YET_FINISHED.toString());
+
+ helper.releaseWaitingOperation();
+
+
+ result = submodelElement.getModelPropertyValue(requestPath);
+ assertEquals(result, OperationResult.EXECUTION_ERROR.toString());
+
+ // Check if the async-invocation is deleted after retrieving its result
+ try {
+ submodelElement.getModelPropertyValue(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, PropertyValueTypeDefHelper.getTypeWrapperFromObject(value));
+ return param;
+ }
}
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..dfcc438 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,13 @@
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 +20,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) {
@@ -34,18 +32,14 @@
*/
@Override
public String getModelPropertyValue(String path) {
- try {
- PrintWriterStub outputstream = new PrintWriterStub("test.txt", "ignore");
+ 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;
}
/**
@@ -54,16 +48,14 @@
*/
@Override
public String setModelPropertyValue(String path, String newValue) throws ProviderException {
- try {
- PrintWriterStub outputstream = new PrintWriterStub("test.txt", "ignore");
+ 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 +64,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 +80,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 +97,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 +113,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/TestJson.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/TestJson.java
index f42432d..70cb8ad 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
@@ -7,6 +7,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;
@@ -61,6 +62,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
*/
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..583d0a3 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
@@ -22,6 +22,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/model/VABModelMapTest.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/model/VABModelMapTest.java
index 7361dd6..4004ed9 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,7 @@
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 +48,19 @@
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);
}
}
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..c2d245a 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
@@ -58,7 +58,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/MapInvoke.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapInvoke.java
index df62326..0dc1511 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
@@ -3,6 +3,7 @@
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 +23,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 +54,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/VABPathToolsTest.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABPathToolsTest.java
index 79efe0d..d895c92 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
@@ -169,15 +169,25 @@
@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));
+ }
+
+ @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(""));
}
}
\ No newline at end of file
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..d2639d9
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/resources/aas/factory/json/aasJsonSchemaV2.0.1_Example.json
@@ -0,0 +1,561 @@
+{
+ "assetAdministrationShells": [
+ {
+ "asset": {
+ "keys": [
+ {
+ "type": "Asset",
+ "local": true,
+ "value": "http://customer.com/assets/KHBVZJSQKIY",
+ "idType": "IRI"
+ }
+ ]
+ },
+ "submodels": [
+ {
+ "keys": [
+ {
+ "type": "Submodel",
+ "local": true,
+ "value": "http.//i40.customer.com/type/1/1/7A7104BDAB57E184",
+ "idType": "IRI"
+ }
+ ]
+ },
+ {
+ "keys": [
+ {
+ "type": "Submodel",
+ "local": true,
+ "value": "http://i40.customer.com/instance/1/1/AC69B1CB44F07935",
+ "idType": "IRI"
+ }
+ ]
+ },
+ {
+ "keys": [
+ {
+ "type": "Submodel",
+ "local": true,
+ "value": "http://i40.customer.com/type/1/1/1A7B62B529F19152",
+ "idType": "IRI"
+ }
+ ]
+ }
+ ],
+ "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": {
+ "dataObjectType": {
+ "name": "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": {
+ "dataObjectType": {
+ "name": "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": {
+ "dataObjectType": {
+ "name": "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..4bd09b2 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
@@ -253,7 +253,7 @@
</aas:valueId>
<aas:value>qualifierValue</aas:value>
<aas:type>qualifierType</aas:type>
- <aas:valueType>valueType</aas:valueType>
+ <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>
@@ -307,7 +307,7 @@
</aas:valueId>
<aas:value>qualifierValue</aas:value>
<aas:type>qualifierType</aas:type>
- <aas:valueType>valueType</aas:valueType>
+ <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>
@@ -341,6 +341,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 +388,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 +413,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>
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..45897f7
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppExceptions.java
@@ -0,0 +1,61 @@
+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..680a3a2
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppMapInvoke.java
@@ -0,0 +1,72 @@
+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..14d4af4
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppMapRead.java
@@ -0,0 +1,86 @@
+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..0a3b03e
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppMapUpdate.java
@@ -0,0 +1,77 @@
+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..1b3754c
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppTestCollectionProperty.java
@@ -0,0 +1,115 @@
+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..a3d8b8b
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppTestProvider.java
@@ -0,0 +1,53 @@
+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/components/basyx.tck/basyx.tck.AASAggregator/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorTestApplication.java b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppVABTestApplication.java
similarity index 69%
rename from components/basyx.tck/basyx.tck.AASAggregator/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorTestApplication.java
rename to sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppVABTestApplication.java
index 99b430f..976296b 100644
--- a/components/basyx.tck/basyx.tck.AASAggregator/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorTestApplication.java
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppVABTestApplication.java
@@ -1,17 +1,18 @@
-package org.eclipse.basyx.testsuite.regression.aas.aggregator;
+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 concrete test suite of the registry provider
+ * The main class that executes the test provider.
+ * Structure is based on the TCK
*
- * @author zhangzai
+ * @author espen
*
*/
-public class AASAggregatorTestApplication {
-
+public class CppVABTestApplication {
public static void main(String[] args) {
// First argument is the inserted url
@@ -20,7 +21,7 @@
JUnitCore junit = new JUnitCore();
junit.addListener(new TextListener(System.out));
- AASAggregatorSuiteWithDefinedURL.url = url;
+ VABClientTest.url = url;
Result result = junit.run(AASAggregatorSuite.class);
System.out.println("Finished. Result: Failures: " +
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..3a4f65a
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/VABClientTest.java
@@ -0,0 +1,31 @@
+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..8d36c9e
--- /dev/null
+++ b/sdks/java/basys.vabServer/src/main/java/org/eclipse/basyx/vab/ServerApplication.java
@@ -0,0 +1,32 @@
+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..7627622
--- /dev/null
+++ b/sdks/java/basys.vabServer/src/main/java/org/eclipse/basyx/vab/SimpleVABElement.java
@@ -0,0 +1,65 @@
+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..2554222
--- /dev/null
+++ b/sdks/java/basys.vabServer/src/main/java/org/eclipse/basyx/vab/SimpleVABProvider.java
@@ -0,0 +1,41 @@
+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);
+ }
+ }
+}