Skip to content

Commit

Permalink
Merge pull request #116 from eclipse-basyx/release/1.2.0
Browse files Browse the repository at this point in the history
Release/1.2.0
  • Loading branch information
FrankSchnicke authored Jul 29, 2022
2 parents 0f27ca1 + dfcd5e5 commit 85d55f2
Show file tree
Hide file tree
Showing 51 changed files with 1,620 additions and 198 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Add java runtime environment for execution
FROM alpine
FROM openjdk:8-jdk-slim-bullseye

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

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

# Set the path for the mqtt configuration file
ARG MQTT_CONFIG_KEY
ENV ${MQTT_CONFIG_KEY} "/usr/share/config/mqtt.properties"

# Start the jar
CMD ./wait-for-it-env.sh && java -jar "/usr/share/basyxExecutable.jar"
CMD ./wait-for-it-env.sh && java -jar "/usr/share/basyxExecutable.jar"
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<groupId>org.eclipse.basyx</groupId>
<artifactId>basyx.components.docker</artifactId>
<version>1.1.0</version>
<version>1.2.0</version>
</parent>

<artifactId>basyx.components.AASServer</artifactId>
Expand Down Expand Up @@ -116,7 +116,7 @@
<dependency>
<groupId>org.eclipse.basyx</groupId>
<artifactId>basyx.components.registry</artifactId>
<version>1.1.0</version>
<version>1.2.0</version>
<scope>test</scope>
</dependency>
</dependencies>
Expand All @@ -142,8 +142,8 @@

<!-- Build the docker image -->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
</plugin>

<!-- Create integration test environment -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.parsers.ParserConfigurationException;
Expand All @@ -48,10 +49,14 @@
import org.eclipse.basyx.aas.factory.aasx.SubmodelFileEndpointLoader;
import org.eclipse.basyx.aas.factory.json.JSONAASBundleFactory;
import org.eclipse.basyx.aas.factory.xml.XMLAASBundleFactory;
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.AASDescriptor;
import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
import org.eclipse.basyx.aas.registration.api.IAASRegistry;
import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
import org.eclipse.basyx.aas.restapi.MultiSubmodelProvider;
import org.eclipse.basyx.components.IComponent;
import org.eclipse.basyx.components.aas.aascomponent.IAASServerDecorator;
import org.eclipse.basyx.components.aas.aascomponent.IAASServerFeature;
Expand All @@ -72,8 +77,12 @@
import org.eclipse.basyx.extensions.aas.aggregator.aasxupload.AASAggregatorAASXUpload;
import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
import org.eclipse.basyx.submodel.metamodel.map.Submodel;
import org.eclipse.basyx.vab.exception.provider.ProviderException;
import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
import org.eclipse.basyx.vab.modelprovider.VABPathTools;
import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
import org.eclipse.basyx.vab.protocol.http.server.BaSyxHTTPServer;
import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
Expand All @@ -86,7 +95,7 @@
* remote. It uses the Aggregator API, i.e. AAS should be pushed to
* ${URL}/shells
*
* @author schnicke, espen, fried, fischer
* @author schnicke, espen, fried, fischer, danish
*
*/
@SuppressWarnings("deprecation")
Expand All @@ -107,8 +116,13 @@ public class AASServerComponent implements IComponent {
// Initial AASBundle
protected Collection<AASBundle> aasBundles;

private IAASAggregator aggregator;
// Watcher for AAS Aggregator functionality
private boolean isAASXUploadEnabled = false;

private static final String PREFIX_SUBMODEL_PATH = "/aas/submodels/";

private ConnectedAssetAdministrationShellManager manager;

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

/**
* Explicitly sets AAS bundles that should be loaded during startup
*
* @param aasBundles
* The bundles that will be loaded during startup
*/
public void setAASBundles(Collection<AASBundle> aasBundles) {
this.aasBundles = aasBundles;
}

/**
* Explicitly sets an AAS bundle that should be loaded during startup
*
* @param aasBundle
* The bundle that will be loaded during startup
*/
public void setAASBundle(AASBundle aasBundle) {
this.aasBundles = Collections.singleton(aasBundle);
}

/**
* Starts the AASX component at http://${hostName}:${port}/${path}
*/
@Override
public void startComponent() {
logger.info("Create the server...");
registry = createRegistryFromConfig(aasConfig);

IConnectorFactory connectorFactory = new HTTPConnectorFactory();

manager = new ConnectedAssetAdministrationShellManager(registry, connectorFactory);

loadAASServerFeaturesFromConfig();
initializeAASServerFeatures();
Expand All @@ -210,6 +248,63 @@ public void startComponent() {
logger.info("Start the server");
server = new BaSyxHTTPServer(context);
server.start();

registerPreexistingAASAndSMIfPossible();
}

private void registerPreexistingAASAndSMIfPossible() {
if(!shouldRegisterPreexistingAASAndSM()) {
return;
}

aggregator.getAASList().stream().forEach(this::registerAASAndSubmodels);
}

private boolean shouldRegisterPreexistingAASAndSM() {
return isMongoDBBackend() && registry != null;
}

private void registerAASAndSubmodels(IAssetAdministrationShell aas) {
registerAAS(aas);

registerSubmodels(aas);
}

private void registerAAS(IAssetAdministrationShell aas) {
try {
manager.createAAS((AssetAdministrationShell) aas, getURL());
logger.info("The AAS " + aas.getIdShort() + " is Successfully Registered from DB");
} catch(Exception e) {
logger.info("The AAS " + aas.getIdShort() + " could not be Registered from DB" + e);
}
}

private void registerSubmodels(IAssetAdministrationShell aas) {
List<ISubmodel> submodels = getSubmodelFromAggregator(aggregator, aas.getIdentification());
try {
submodels.stream().forEach(submodel -> manager.createSubmodel(aas.getIdentification(), (Submodel) submodel));
logger.info("The submodels from AAS " + aas.getIdShort() + " are Successfully Registered from DB");
} catch(Exception e) {
logger.info("The submodel from AAS " + aas.getIdShort() + " could not be Registered from DB " + e);
}
}

private List<ISubmodel> getSubmodelFromAggregator(IAASAggregator aggregator, IIdentifier iIdentifier) {
MultiSubmodelProvider aasProvider = (MultiSubmodelProvider) aggregator.getAASProvider(iIdentifier);

@SuppressWarnings("unchecked")
List<Object> submodelObject = (List<Object>) aasProvider.getValue(PREFIX_SUBMODEL_PATH);

List<ISubmodel> persistentSubmodelList = new ArrayList<>();

submodelObject.stream().map(this::getSubmodel).forEach(persistentSubmodelList::add);

return persistentSubmodelList;
}

@SuppressWarnings("unchecked")
private ISubmodel getSubmodel(Object submodelObject) {
return Submodel.createAsFacade((Map<String, Object>) submodelObject);
}

private void loadAASServerFeaturesFromConfig() {
Expand Down Expand Up @@ -239,13 +334,57 @@ public String getURL() {

@Override
public void stopComponent() {

// Remove all AASs/SMs that were registered on startup
AASBundleHelper.deregister(registry, aasBundles);
deregisterAASAndSmAddedDuringRuntime();

cleanUpAASServerFeatures();

server.shutdown();
}

private void deregisterAASAndSmAddedDuringRuntime() {
if(registry == null) {
return;
}

try {
aggregator.getAASList().stream().forEach(this::deregisterAASAndAccompanyingSM);
} catch(RuntimeException e) {
logger.info("The resource could not be found in the aggregator " + e);
}

}

private void deregisterAASAndAccompanyingSM(IAssetAdministrationShell aas) {
getSubmodelDescriptors(aas.getIdentification()).stream().forEach(submodelDescriptor -> deregisterSubmodel(aas.getIdentification(), submodelDescriptor));

deregisterAAS(aas.getIdentification());
}

private List<SubmodelDescriptor> getSubmodelDescriptors(IIdentifier aasIdentifier) {
try {
return registry.lookupSubmodels(aasIdentifier);
} catch(ResourceNotFoundException e) {
return Collections.emptyList();
}
}

private void deregisterSubmodel(IIdentifier aasIdentifier, SubmodelDescriptor submodelDescriptor) {
try {
registry.delete(aasIdentifier, submodelDescriptor.getIdentifier());
logger.info("The SM '" + submodelDescriptor.getIdShort() + "' successfully deregistered.");
} catch (ProviderException e) {
logger.info("The SM '" + submodelDescriptor.getIdShort() + "' can't be deregistered. It was not found in registry.");
}
}

private void deregisterAAS(IIdentifier aasIdentifier) {
try {
registry.delete(aasIdentifier);
logger.info("The AAS '" + aasIdentifier.getId() + "' successfully deregistered.");
} catch (ProviderException e) {
logger.info("The AAS '" + aasIdentifier.getId() + "' can't be deregistered. It was not found in registry.");
}
}

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

private VABHTTPInterface<?> createAggregatorServlet() {
IAASAggregator aggregator = createAASAggregator();
aasBundles = loadAASFromSource(aasConfig.getAASSourceAsList());

aggregator = createAASAggregator();
loadAASBundles();
if (aasBundles != null) {
AASBundleHelper.integrate(aggregator, aasBundles);
}
Expand All @@ -327,7 +466,7 @@ private IAASAggregator createAASAggregator() {
private boolean isMongoDBBackend() {
return aasConfig.getAASBackend().equals(AASServerBackend.MONGODB);
}

private BaSyxMongoDBConfiguration createMongoDbConfiguration() {
BaSyxMongoDBConfiguration config;
if (this.mongoDBConfig == null) {
Expand All @@ -349,6 +488,15 @@ private List<IAASServerDecorator> createAASServerDecoratorList() {
return aasServerDecoratorList;
}

private void loadAASBundles() {
if (aasBundles != null) {
return;
}

List<String> aasSources = aasConfig.getAASSourceAsList();
aasBundles = loadAASFromSource(aasSources);
}

private Set<AASBundle> loadAASFromSource(List<String> aasSources) {
if (aasSources.isEmpty()) {
return Collections.emptySet();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,14 @@
import org.eclipse.basyx.components.aas.mongodb.MongoDBAASAPIFactory;
import org.eclipse.basyx.components.aas.mongodb.MongoDBAASAggregatorFactory;
import org.eclipse.basyx.components.aas.mongodb.MongoDBSubmodelAPIFactory;
import org.eclipse.basyx.components.aas.mongodb.MongoDBSubmodelAggregatorFactory;
import org.eclipse.basyx.components.configuration.BaSyxMongoDBConfiguration;
import org.eclipse.basyx.submodel.aggregator.SubmodelAggregatorFactory;
import org.eclipse.basyx.submodel.aggregator.api.ISubmodelAggregatorFactory;
import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPIFactory;

import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;

/**
*
* Factory building the AASAggregator for the AASComponent with given decorators
Expand All @@ -48,31 +51,38 @@
public class MongoDBAASServerComponentFactory extends AbstractAASServerComponentFactory {

private BaSyxMongoDBConfiguration mongoDBConfig;
private MongoClient client;

public MongoDBAASServerComponentFactory(BaSyxMongoDBConfiguration config, List<IAASServerDecorator> decorators, IAASRegistry aasServerRegistry) {
this.mongoDBConfig = config;
this.aasServerRegistry = aasServerRegistry;
this.aasServerDecorators = decorators;
this.client = MongoClients.create(config.getConnectionUrl());
}

public MongoDBAASServerComponentFactory(BaSyxMongoDBConfiguration config, IAASRegistry aasServerRegistry) {
this.mongoDBConfig = config;
this.aasServerRegistry = aasServerRegistry;
this.client = MongoClients.create(config.getConnectionUrl());
}

@Override
protected ISubmodelAPIFactory createSubmodelAPIFactory() {
return new MongoDBSubmodelAPIFactory(mongoDBConfig);
return new MongoDBSubmodelAPIFactory(mongoDBConfig, client);
}

@Override
protected ISubmodelAggregatorFactory createSubmodelAggregatorFactory(ISubmodelAPIFactory submodelAPIFactory) {
return new SubmodelAggregatorFactory(submodelAPIFactory);
return new MongoDBSubmodelAggregatorFactory(mongoDBConfig, submodelAPIFactory, client);
}

@Override
protected IAASAPIFactory createAASAPIFactory() {
return new MongoDBAASAPIFactory(mongoDBConfig);
return new MongoDBAASAPIFactory(mongoDBConfig, client);
}

@Override
protected IAASAggregatorFactory createAASAggregatorFactory(IAASAPIFactory aasAPIFactory, ISubmodelAggregatorFactory submodelAggregatorFactory) {
return new MongoDBAASAggregatorFactory(mongoDBConfig, aasServerRegistry, aasAPIFactory, submodelAggregatorFactory);
return new MongoDBAASAggregatorFactory(mongoDBConfig, aasServerRegistry, aasAPIFactory, submodelAggregatorFactory, client);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
* at
* <i>localhost:4000/aasServer/shells/${aasId}/aas/submodels/${submodelId}/submodel</i><br>
*
* @author schnicke, espen
* @author schnicke, espen, danish
*/
public class AASServerExecutable {
// Creates a Logger based on the current class
Expand All @@ -67,5 +67,16 @@ public static void main(String[] args) throws URISyntaxException {
component.startComponent();

logger.info("BaSyx AAS Server component started");

addShutdownHook(component);
}

private static void addShutdownHook(AASServerComponent component) {
Thread shutdownListener = new Thread(){
public void run(){
component.stopComponent();
}
};
Runtime.getRuntime().addShutdownHook(shutdownListener);
}
}
Loading

0 comments on commit 85d55f2

Please sign in to comment.