Skip to content

Commit 85d55f2

Browse files
Merge pull request #116 from eclipse-basyx/release/1.2.0
Release/1.2.0
2 parents 0f27ca1 + dfcd5e5 commit 85d55f2

File tree

51 files changed

+1620
-198
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1620
-198
lines changed

basyx.components/basyx.components.docker/basyx.components.AASServer/Dockerfile

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
# Add java runtime environment for execution
2-
FROM alpine
1+
FROM openjdk:8-jdk-slim-bullseye
32

4-
RUN apk update && apk add openjdk8 && apk add bash && apk add jq
3+
# Install dependency for wait-for-it-env.sh
4+
RUN apt update && apt install -y jq && apt clean
55

66
# Copy built jar to image using the jar name specified in the pom.xml (JAR_FILE)
77
ARG JAR_FILE
@@ -36,5 +36,9 @@ ENV ${CONTEXT_CONFIG_KEY} "/usr/share/config/context.properties"
3636
ARG MONGODB_CONFIG_KEY
3737
ENV ${MONGODB_CONFIG_KEY} "/usr/share/config/mongodb.properties"
3838

39+
# Set the path for the mqtt configuration file
40+
ARG MQTT_CONFIG_KEY
41+
ENV ${MQTT_CONFIG_KEY} "/usr/share/config/mqtt.properties"
42+
3943
# Start the jar
40-
CMD ./wait-for-it-env.sh && java -jar "/usr/share/basyxExecutable.jar"
44+
CMD ./wait-for-it-env.sh && java -jar "/usr/share/basyxExecutable.jar"

basyx.components/basyx.components.docker/basyx.components.AASServer/pom.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<parent>
88
<groupId>org.eclipse.basyx</groupId>
99
<artifactId>basyx.components.docker</artifactId>
10-
<version>1.1.0</version>
10+
<version>1.2.0</version>
1111
</parent>
1212

1313
<artifactId>basyx.components.AASServer</artifactId>
@@ -116,7 +116,7 @@
116116
<dependency>
117117
<groupId>org.eclipse.basyx</groupId>
118118
<artifactId>basyx.components.registry</artifactId>
119-
<version>1.1.0</version>
119+
<version>1.2.0</version>
120120
<scope>test</scope>
121121
</dependency>
122122
</dependencies>
@@ -142,8 +142,8 @@
142142

143143
<!-- Build the docker image -->
144144
<plugin>
145-
<groupId>com.spotify</groupId>
146-
<artifactId>dockerfile-maven-plugin</artifactId>
145+
<groupId>io.fabric8</groupId>
146+
<artifactId>docker-maven-plugin</artifactId>
147147
</plugin>
148148

149149
<!-- Create integration test environment -->

basyx.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/AASServerComponent.java

Lines changed: 156 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import java.util.Collections;
3333
import java.util.HashSet;
3434
import java.util.List;
35+
import java.util.Map;
3536
import java.util.Set;
3637

3738
import javax.xml.parsers.ParserConfigurationException;
@@ -48,10 +49,14 @@
4849
import org.eclipse.basyx.aas.factory.aasx.SubmodelFileEndpointLoader;
4950
import org.eclipse.basyx.aas.factory.json.JSONAASBundleFactory;
5051
import org.eclipse.basyx.aas.factory.xml.XMLAASBundleFactory;
52+
import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
53+
import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
54+
import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
5155
import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
5256
import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
5357
import org.eclipse.basyx.aas.registration.api.IAASRegistry;
5458
import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
59+
import org.eclipse.basyx.aas.restapi.MultiSubmodelProvider;
5560
import org.eclipse.basyx.components.IComponent;
5661
import org.eclipse.basyx.components.aas.aascomponent.IAASServerDecorator;
5762
import org.eclipse.basyx.components.aas.aascomponent.IAASServerFeature;
@@ -72,8 +77,12 @@
7277
import org.eclipse.basyx.extensions.aas.aggregator.aasxupload.AASAggregatorAASXUpload;
7378
import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
7479
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
80+
import org.eclipse.basyx.submodel.metamodel.map.Submodel;
81+
import org.eclipse.basyx.vab.exception.provider.ProviderException;
7582
import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
7683
import org.eclipse.basyx.vab.modelprovider.VABPathTools;
84+
import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
85+
import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
7786
import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
7887
import org.eclipse.basyx.vab.protocol.http.server.BaSyxHTTPServer;
7988
import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
@@ -86,7 +95,7 @@
8695
* remote. It uses the Aggregator API, i.e. AAS should be pushed to
8796
* ${URL}/shells
8897
*
89-
* @author schnicke, espen, fried, fischer
98+
* @author schnicke, espen, fried, fischer, danish
9099
*
91100
*/
92101
@SuppressWarnings("deprecation")
@@ -107,8 +116,13 @@ public class AASServerComponent implements IComponent {
107116
// Initial AASBundle
108117
protected Collection<AASBundle> aasBundles;
109118

119+
private IAASAggregator aggregator;
110120
// Watcher for AAS Aggregator functionality
111121
private boolean isAASXUploadEnabled = false;
122+
123+
private static final String PREFIX_SUBMODEL_PATH = "/aas/submodels/";
124+
125+
private ConnectedAssetAdministrationShellManager manager;
112126

113127
/**
114128
* Constructs an empty AAS server using the passed context
@@ -181,13 +195,37 @@ public void setRegistry(IAASRegistry registry) {
181195
this.registry = registry;
182196
}
183197

198+
/**
199+
* Explicitly sets AAS bundles that should be loaded during startup
200+
*
201+
* @param aasBundles
202+
* The bundles that will be loaded during startup
203+
*/
204+
public void setAASBundles(Collection<AASBundle> aasBundles) {
205+
this.aasBundles = aasBundles;
206+
}
207+
208+
/**
209+
* Explicitly sets an AAS bundle that should be loaded during startup
210+
*
211+
* @param aasBundle
212+
* The bundle that will be loaded during startup
213+
*/
214+
public void setAASBundle(AASBundle aasBundle) {
215+
this.aasBundles = Collections.singleton(aasBundle);
216+
}
217+
184218
/**
185219
* Starts the AASX component at http://${hostName}:${port}/${path}
186220
*/
187221
@Override
188222
public void startComponent() {
189223
logger.info("Create the server...");
190224
registry = createRegistryFromConfig(aasConfig);
225+
226+
IConnectorFactory connectorFactory = new HTTPConnectorFactory();
227+
228+
manager = new ConnectedAssetAdministrationShellManager(registry, connectorFactory);
191229

192230
loadAASServerFeaturesFromConfig();
193231
initializeAASServerFeatures();
@@ -210,6 +248,63 @@ public void startComponent() {
210248
logger.info("Start the server");
211249
server = new BaSyxHTTPServer(context);
212250
server.start();
251+
252+
registerPreexistingAASAndSMIfPossible();
253+
}
254+
255+
private void registerPreexistingAASAndSMIfPossible() {
256+
if(!shouldRegisterPreexistingAASAndSM()) {
257+
return;
258+
}
259+
260+
aggregator.getAASList().stream().forEach(this::registerAASAndSubmodels);
261+
}
262+
263+
private boolean shouldRegisterPreexistingAASAndSM() {
264+
return isMongoDBBackend() && registry != null;
265+
}
266+
267+
private void registerAASAndSubmodels(IAssetAdministrationShell aas) {
268+
registerAAS(aas);
269+
270+
registerSubmodels(aas);
271+
}
272+
273+
private void registerAAS(IAssetAdministrationShell aas) {
274+
try {
275+
manager.createAAS((AssetAdministrationShell) aas, getURL());
276+
logger.info("The AAS " + aas.getIdShort() + " is Successfully Registered from DB");
277+
} catch(Exception e) {
278+
logger.info("The AAS " + aas.getIdShort() + " could not be Registered from DB" + e);
279+
}
280+
}
281+
282+
private void registerSubmodels(IAssetAdministrationShell aas) {
283+
List<ISubmodel> submodels = getSubmodelFromAggregator(aggregator, aas.getIdentification());
284+
try {
285+
submodels.stream().forEach(submodel -> manager.createSubmodel(aas.getIdentification(), (Submodel) submodel));
286+
logger.info("The submodels from AAS " + aas.getIdShort() + " are Successfully Registered from DB");
287+
} catch(Exception e) {
288+
logger.info("The submodel from AAS " + aas.getIdShort() + " could not be Registered from DB " + e);
289+
}
290+
}
291+
292+
private List<ISubmodel> getSubmodelFromAggregator(IAASAggregator aggregator, IIdentifier iIdentifier) {
293+
MultiSubmodelProvider aasProvider = (MultiSubmodelProvider) aggregator.getAASProvider(iIdentifier);
294+
295+
@SuppressWarnings("unchecked")
296+
List<Object> submodelObject = (List<Object>) aasProvider.getValue(PREFIX_SUBMODEL_PATH);
297+
298+
List<ISubmodel> persistentSubmodelList = new ArrayList<>();
299+
300+
submodelObject.stream().map(this::getSubmodel).forEach(persistentSubmodelList::add);
301+
302+
return persistentSubmodelList;
303+
}
304+
305+
@SuppressWarnings("unchecked")
306+
private ISubmodel getSubmodel(Object submodelObject) {
307+
return Submodel.createAsFacade((Map<String, Object>) submodelObject);
213308
}
214309

215310
private void loadAASServerFeaturesFromConfig() {
@@ -239,13 +334,57 @@ public String getURL() {
239334

240335
@Override
241336
public void stopComponent() {
242-
243-
// Remove all AASs/SMs that were registered on startup
244-
AASBundleHelper.deregister(registry, aasBundles);
337+
deregisterAASAndSmAddedDuringRuntime();
338+
245339
cleanUpAASServerFeatures();
246340

247341
server.shutdown();
248342
}
343+
344+
private void deregisterAASAndSmAddedDuringRuntime() {
345+
if(registry == null) {
346+
return;
347+
}
348+
349+
try {
350+
aggregator.getAASList().stream().forEach(this::deregisterAASAndAccompanyingSM);
351+
} catch(RuntimeException e) {
352+
logger.info("The resource could not be found in the aggregator " + e);
353+
}
354+
355+
}
356+
357+
private void deregisterAASAndAccompanyingSM(IAssetAdministrationShell aas) {
358+
getSubmodelDescriptors(aas.getIdentification()).stream().forEach(submodelDescriptor -> deregisterSubmodel(aas.getIdentification(), submodelDescriptor));
359+
360+
deregisterAAS(aas.getIdentification());
361+
}
362+
363+
private List<SubmodelDescriptor> getSubmodelDescriptors(IIdentifier aasIdentifier) {
364+
try {
365+
return registry.lookupSubmodels(aasIdentifier);
366+
} catch(ResourceNotFoundException e) {
367+
return Collections.emptyList();
368+
}
369+
}
370+
371+
private void deregisterSubmodel(IIdentifier aasIdentifier, SubmodelDescriptor submodelDescriptor) {
372+
try {
373+
registry.delete(aasIdentifier, submodelDescriptor.getIdentifier());
374+
logger.info("The SM '" + submodelDescriptor.getIdShort() + "' successfully deregistered.");
375+
} catch (ProviderException e) {
376+
logger.info("The SM '" + submodelDescriptor.getIdShort() + "' can't be deregistered. It was not found in registry.");
377+
}
378+
}
379+
380+
private void deregisterAAS(IIdentifier aasIdentifier) {
381+
try {
382+
registry.delete(aasIdentifier);
383+
logger.info("The AAS '" + aasIdentifier.getId() + "' successfully deregistered.");
384+
} catch (ProviderException e) {
385+
logger.info("The AAS '" + aasIdentifier.getId() + "' can't be deregistered. It was not found in registry.");
386+
}
387+
}
249388

250389
public void addAASServerFeature(IAASServerFeature aasServerFeature) {
251390
aasServerFeatureList.add(aasServerFeature);
@@ -303,9 +442,9 @@ private static Set<AASBundle> loadBundleFromAASX(String aasxPath) throws IOExcep
303442
}
304443

305444
private VABHTTPInterface<?> createAggregatorServlet() {
306-
IAASAggregator aggregator = createAASAggregator();
307-
aasBundles = loadAASFromSource(aasConfig.getAASSourceAsList());
308-
445+
aggregator = createAASAggregator();
446+
loadAASBundles();
447+
309448
if (aasBundles != null) {
310449
AASBundleHelper.integrate(aggregator, aasBundles);
311450
}
@@ -327,7 +466,7 @@ private IAASAggregator createAASAggregator() {
327466
private boolean isMongoDBBackend() {
328467
return aasConfig.getAASBackend().equals(AASServerBackend.MONGODB);
329468
}
330-
469+
331470
private BaSyxMongoDBConfiguration createMongoDbConfiguration() {
332471
BaSyxMongoDBConfiguration config;
333472
if (this.mongoDBConfig == null) {
@@ -349,6 +488,15 @@ private List<IAASServerDecorator> createAASServerDecoratorList() {
349488
return aasServerDecoratorList;
350489
}
351490

491+
private void loadAASBundles() {
492+
if (aasBundles != null) {
493+
return;
494+
}
495+
496+
List<String> aasSources = aasConfig.getAASSourceAsList();
497+
aasBundles = loadAASFromSource(aasSources);
498+
}
499+
352500
private Set<AASBundle> loadAASFromSource(List<String> aasSources) {
353501
if (aasSources.isEmpty()) {
354502
return Collections.emptySet();

basyx.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/aascomponent/MongoDBAASServerComponentFactory.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,14 @@
3232
import org.eclipse.basyx.components.aas.mongodb.MongoDBAASAPIFactory;
3333
import org.eclipse.basyx.components.aas.mongodb.MongoDBAASAggregatorFactory;
3434
import org.eclipse.basyx.components.aas.mongodb.MongoDBSubmodelAPIFactory;
35+
import org.eclipse.basyx.components.aas.mongodb.MongoDBSubmodelAggregatorFactory;
3536
import org.eclipse.basyx.components.configuration.BaSyxMongoDBConfiguration;
36-
import org.eclipse.basyx.submodel.aggregator.SubmodelAggregatorFactory;
3737
import org.eclipse.basyx.submodel.aggregator.api.ISubmodelAggregatorFactory;
3838
import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPIFactory;
3939

40+
import com.mongodb.client.MongoClient;
41+
import com.mongodb.client.MongoClients;
42+
4043
/**
4144
*
4245
* Factory building the AASAggregator for the AASComponent with given decorators
@@ -48,31 +51,38 @@
4851
public class MongoDBAASServerComponentFactory extends AbstractAASServerComponentFactory {
4952

5053
private BaSyxMongoDBConfiguration mongoDBConfig;
54+
private MongoClient client;
5155

5256
public MongoDBAASServerComponentFactory(BaSyxMongoDBConfiguration config, List<IAASServerDecorator> decorators, IAASRegistry aasServerRegistry) {
5357
this.mongoDBConfig = config;
5458
this.aasServerRegistry = aasServerRegistry;
5559
this.aasServerDecorators = decorators;
60+
this.client = MongoClients.create(config.getConnectionUrl());
5661
}
5762

5863
public MongoDBAASServerComponentFactory(BaSyxMongoDBConfiguration config, IAASRegistry aasServerRegistry) {
5964
this.mongoDBConfig = config;
6065
this.aasServerRegistry = aasServerRegistry;
66+
this.client = MongoClients.create(config.getConnectionUrl());
6167
}
6268

69+
@Override
6370
protected ISubmodelAPIFactory createSubmodelAPIFactory() {
64-
return new MongoDBSubmodelAPIFactory(mongoDBConfig);
71+
return new MongoDBSubmodelAPIFactory(mongoDBConfig, client);
6572
}
6673

74+
@Override
6775
protected ISubmodelAggregatorFactory createSubmodelAggregatorFactory(ISubmodelAPIFactory submodelAPIFactory) {
68-
return new SubmodelAggregatorFactory(submodelAPIFactory);
76+
return new MongoDBSubmodelAggregatorFactory(mongoDBConfig, submodelAPIFactory, client);
6977
}
7078

79+
@Override
7180
protected IAASAPIFactory createAASAPIFactory() {
72-
return new MongoDBAASAPIFactory(mongoDBConfig);
81+
return new MongoDBAASAPIFactory(mongoDBConfig, client);
7382
}
7483

84+
@Override
7585
protected IAASAggregatorFactory createAASAggregatorFactory(IAASAPIFactory aasAPIFactory, ISubmodelAggregatorFactory submodelAggregatorFactory) {
76-
return new MongoDBAASAggregatorFactory(mongoDBConfig, aasServerRegistry, aasAPIFactory, submodelAggregatorFactory);
86+
return new MongoDBAASAggregatorFactory(mongoDBConfig, aasServerRegistry, aasAPIFactory, submodelAggregatorFactory, client);
7787
}
7888
}

basyx.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/executable/AASServerExecutable.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
* at
4242
* <i>localhost:4000/aasServer/shells/${aasId}/aas/submodels/${submodelId}/submodel</i><br>
4343
*
44-
* @author schnicke, espen
44+
* @author schnicke, espen, danish
4545
*/
4646
public class AASServerExecutable {
4747
// Creates a Logger based on the current class
@@ -67,5 +67,16 @@ public static void main(String[] args) throws URISyntaxException {
6767
component.startComponent();
6868

6969
logger.info("BaSyx AAS Server component started");
70+
71+
addShutdownHook(component);
72+
}
73+
74+
private static void addShutdownHook(AASServerComponent component) {
75+
Thread shutdownListener = new Thread(){
76+
public void run(){
77+
component.stopComponent();
78+
}
79+
};
80+
Runtime.getRuntime().addShutdownHook(shutdownListener);
7081
}
7182
}

0 commit comments

Comments
 (0)