Skip to content

Commit

Permalink
Adds support for arbitrary SME (#255)
Browse files Browse the repository at this point in the history

Signed-off-by: Mohammad Ghazanfar Ali Danish <[email protected]>
  • Loading branch information
mdanish98 authored Sep 22, 2023
1 parent 547163e commit 8e97e38
Show file tree
Hide file tree
Showing 14 changed files with 554 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@
import org.apache.camel.spi.UriParam;
import org.apache.camel.spi.UriPath;
import org.apache.camel.support.DefaultEndpoint;
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedProperty;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedDataElement;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueTypeHelper;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
Expand All @@ -55,8 +57,9 @@
public class AASEndpoint extends DefaultEndpoint {
private static final Logger logger = LoggerFactory.getLogger(AASEndpoint.class);

private ConnectedProperty connectedProperty;
private ConnectedDataElement connectedDataElement;
private static final String API_V3_SUFFIX = "/$value";
private static final String BASYX_API_SUFFIX = "/value";

@UriPath
@Metadata(required = true)
Expand Down Expand Up @@ -148,11 +151,19 @@ protected void connectToElement() {
String proxyUrl = getFullProxyUrl();
IModelProvider provider = factory.getConnector(proxyUrl);
VABElementProxy proxy = new VABElementProxy("", provider);
this.connectedProperty = new ConnectedProperty(proxy);
this.connectedDataElement = new ConnectedDataElement(proxy);
}

private void setPropertyValueUsingBaSyxAPI(Object messageBody) {
connectedProperty.setValue(getContent(messageBody));
private void setPropertyValueUsingBaSyxAPI(Object messageBody) throws IOException {
if (!connectedDataElement.getModelType().equals(KeyElements.PROPERTY.getStandardizedLiteral())) {
HTTPRequest.putRequest(getFullProxyUrl() + BASYX_API_SUFFIX, messageBody.toString());

return;
}

ValueType valueType = Property.createAsFacade(connectedDataElement.getLocalCopy()).getValueType();

connectedDataElement.setValue(getContent(messageBody, valueType));
}

private void setPropertyValueUsingDotAasV3Api(String content) throws IOException {
Expand Down Expand Up @@ -182,12 +193,11 @@ private String wrapStringValue(String content) {
return "\"" + content + "\"";
}

private Object getContent(Object messageBody) {
if (connectedProperty.getValueType().equals(ValueType.String)) {
private Object getContent(Object messageBody, ValueType propertyValueType) {
if (propertyValueType.equals(ValueType.String))
return removeQuotesFromString(messageBody.toString());
}

return ValueTypeHelper.getJavaObject(messageBody, connectedProperty.getValueType());
return ValueTypeHelper.getJavaObject(messageBody, propertyValueType);
}

private static String removeQuotesFromString(String messageBody) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
Expand Down Expand Up @@ -62,5 +63,25 @@ private static HttpPatch createPatchRequest(String url, String content) throws U

return patchRequest;
}

public static void putRequest(String url, String content) throws IOException {
CloseableHttpClient client = HttpClientBuilder.create().build();
HttpPut httpPutRequest = createPutRequest(url, content);

HttpResponse response = client.execute(httpPutRequest);

HttpEntity responseEntity = response.getEntity();

EntityUtils.consume(responseEntity);
}

private static HttpPut createPutRequest(String url, String content) throws UnsupportedEncodingException {
HttpPut putRequest = new HttpPut(url);

putRequest.setHeader("Content-type", "application/json");
putRequest.setEntity(new StringEntity(content));

return putRequest;
}

}
123 changes: 123 additions & 0 deletions databridge.examples/databridge.examples.mqtt-aas_range_and_mlp/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.eclipse.digitaltwin.basyx</groupId>
<artifactId>databridge.examples</artifactId>
<version>${revision}</version>
</parent>

<artifactId>databridge.examples.mqtt-aas_range_and_mlp</artifactId>
<name>MQTT AAS[Range_And_MultiLanguageProperty]</name>
<description>An example to demonstrate the integration of MultiLanguageProperty and Range elements of AAS</description>


<packaging>jar</packaging>

<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>

<!-- 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>
<version>3.2.1</version>
</plugin>
</plugins>
</build>

<dependencies>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-simple -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.7</version>
</dependency>

<dependency>
<groupId>org.eclipse.digitaltwin.basyx</groupId>
<artifactId>databridge.core</artifactId>
<version>${revision}</version>
</dependency>

<dependency>
<groupId>org.eclipse.digitaltwin.basyx</groupId>
<artifactId>databridge.camel-paho</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>

<dependency>
<groupId>org.eclipse.digitaltwin.basyx</groupId>
<artifactId>databridge.camel-aas</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>

<!-- BaSyx SDK -->
<dependency>
<groupId>org.eclipse.basyx</groupId>
<artifactId>basyx.sdk</artifactId>
<version>1.2.0</version>
</dependency>

<!-- BaSyx SDK tests -->
<dependency>
<groupId>org.eclipse.basyx</groupId>
<artifactId>basyx.sdk</artifactId>
<version>1.4.0</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>

<!-- Depends on the components library -->
<dependency>
<groupId>org.eclipse.basyx</groupId>
<artifactId>basyx.components.lib</artifactId>
<version>1.4.0</version>
</dependency>

<dependency>
<groupId>org.eclipse.basyx</groupId>
<artifactId>basyx.components.AASServer</artifactId>
<version>1.2.0</version>
</dependency>

<!-- JUnit 4 for running JUnit tests -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>

<!-- Moquette MQTT broker for testing MQTT events -->
<dependency>
<groupId>io.moquette</groupId>
<artifactId>moquette-broker</artifactId>
<version>0.16</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<version>4.2.0</version>
<scope>test</scope>
</dependency>

</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# #############################
# AAS Server configuration file
# #############################

# #############################
# Backend
# #############################
# Specifies the backend that loads the AAS and Submodels

# InMemory - does not persist AAS or submodels
aas.backend=InMemory

# MongoDB - persists data within a MongoDB
# See connection configuration in mongodb.properties
# aas.backend=MongoDB

# #############################
# Source
# #############################
# Possible to load an AAS Environment from a file

aas.source=

# Other examples (Currently supported: *.xml, *.json and *.aasx):
# aas.source=aasx/myAAS.aasx
# aas.source=aasx/myAAS.xml
# aas.source=aasx/myAAS.json
# Or when encapsulated in the docker volume for this container:
# aas.source=/usr/share/config/myAAS.aasx

# #############################
# MQTT
# #############################
# Possible to enable MQTT events

aas.events=NONE
# aas.events=MQTT

# #############################
# AASX Upload
# #############################
# Possible to enable AASX Upload

aas.aasxUpload=Disabled
# aas.aasxUpload=Enabled


# #############################
# Registry
# #############################
# If specified, can directly registers the AAS that has been loaded from the source file

# Path specifies the registry endpoint
# registry.path=http://localhost:4000/registry/

# Hostpath specifies the endpoint of the deployed AAS component
# If hostpath is empty, the registered AAS endpoint is derived from the context properties
# registry.hostpath=

# If one or more submodels are specified here, only the submodels will be registered at the
# registry. This can be used for distributed submodel deployments
# In case of an empty or no list, this does not have an effect. By default, all submodels
# are registered at a given registry.
# registry.submodels=["smId1","smId2"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[
{
"uniqueId": "ConnectedSubmodel/ConnectedMLP",
"submodelEndpoint": "http://localhost:4001/shells/TestUpdatedDeviceAAS/aas/submodels/ConnectedSubmodel/submodel",
"idShortPath": "ConnectedMLP",
"api": "BaSyx"
},
{
"uniqueId": "ConnectedSubmodel/ConnectedRange",
"submodelEndpoint": "http://localhost:4001/shells/TestUpdatedDeviceAAS/aas/submodels/ConnectedSubmodel/submodel",
"idShortPath": "ConnectedRange",
"api": "BaSyx"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# ###############################
# HTTP Context configuration file
# ###############################

# ###############################
# Context Path
# ###############################
# Specifies the subpath in the url for this server context

contextPath=/aasServer

# ###############################
# Hostname
# ###############################
# Specifies the hostname for this server context

contextHostname=localhost

# ###############################
# Port
# ###############################
# Specifies the port for this server context

contextPort=4001
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?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>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[
{
"uniqueId": "property1",
"serverUrl": "localhost",
"serverPort": 1884,
"topic": "ConnectedMLP"
},
{
"uniqueId": "property2",
"serverUrl": "localhost",
"serverPort": 1884,
"topic": "ConnectedRange"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[
{
"datasource": "property1",
"transformers": [],
"datasinks": ["ConnectedSubmodel/ConnectedMLP"],
"trigger": "event"
},
{
"datasource": "property2",
"transformers": [],
"datasinks": ["ConnectedSubmodel/ConnectedRange"],
"trigger": "event"
}
]
Loading

0 comments on commit 8e97e38

Please sign in to comment.