Skip to content

Commit b1bd2b6

Browse files
Merge pull request #388 from eclipse-basyx/development
Updates Version to 1.5.0
2 parents 1a2112a + f0b3dba commit b1bd2b6

File tree

52 files changed

+2014
-1205
lines changed

Some content is hidden

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

52 files changed

+2014
-1205
lines changed

.github/workflows/maven-publish-snapshot.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ jobs:
3737
packages: write
3838

3939
steps:
40-
- uses: actions/checkout@v3
40+
- uses: actions/checkout@v4
4141
- name: Set up JDK 11
4242
uses: actions/setup-java@v3
4343
with:

.github/workflows/maven-run-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ jobs:
4949
- 27017:27017
5050

5151
steps:
52-
- uses: actions/checkout@v3
52+
- uses: actions/checkout@v4
5353
- name: Set up JDK 11
5454
uses: actions/setup-java@v3
5555
with:

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
.lck
22
*.class
3+
/basyx.components/basyx.components.docker/basyx.components.AASServer/fileSmeIdShort.xml
4+
/basyx.components/basyx.components.docker/basyx.components.AASServer/mySubmodelId-fileSmeIdShort.xml
5+
/basyx.components/basyx.components.docker/basyx.components.registry/.moquette_uuid
6+
37
/components/basys.components/WebContent/WEB-INF/lib/jdbc/postgresql-42.2.2.jar
48
/components/basys.components/WebContent/WEB-INF/lib/jersey/ext/aopalliance-repackaged-2.5.0-b42.jar
59
/components/basys.components/WebContent/WEB-INF/lib/jersey/ext/cdi-api-1.1.jar

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

Lines changed: 6 additions & 6 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.4.0</version>
10+
<version>1.5.0</version>
1111
</parent>
1212

1313
<artifactId>basyx.components.AASServer</artifactId>
@@ -80,14 +80,14 @@
8080
<dependency>
8181
<groupId>org.mongodb</groupId>
8282
<artifactId>mongodb-driver-sync</artifactId>
83-
<version>4.9.0</version>
83+
<version>4.10.2</version>
8484
</dependency>
8585

8686
<!-- Use Spring Data MongoDB for db data management -->
8787
<dependency>
8888
<groupId>org.springframework.data</groupId>
8989
<artifactId>spring-data-mongodb</artifactId>
90-
<version>3.4.10</version>
90+
<version>3.4.15</version>
9191
</dependency>
9292

9393
<!-- Adds additional classes of the BaSys SDK for tests -->
@@ -108,7 +108,7 @@
108108
<dependency>
109109
<groupId>io.moquette</groupId>
110110
<artifactId>moquette-broker</artifactId>
111-
<version>0.16</version>
111+
<version>0.17</version>
112112
<scope>test</scope>
113113
<exclusions>
114114
<exclusion>
@@ -121,14 +121,14 @@
121121
<dependency>
122122
<groupId>org.eclipse.basyx</groupId>
123123
<artifactId>basyx.components.registry</artifactId>
124-
<version>1.4.0</version>
124+
<version>1.5.0</version>
125125
<scope>test</scope>
126126
</dependency>
127127
<dependency>
128128
<groupId>com.tngtech.keycloakmock</groupId>
129129
<artifactId>mock</artifactId>
130130
<scope>test</scope>
131-
<version>0.13.0</version>
131+
<version>0.15.2</version>
132132
</dependency>
133133

134134
<dependency>

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

Lines changed: 103 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,24 @@
2424
******************************************************************************/
2525
package org.eclipse.basyx.components.aas;
2626

27+
import java.io.File;
2728
import java.io.IOException;
2829
import java.net.URISyntaxException;
2930
import java.nio.charset.StandardCharsets;
3031
import java.util.ArrayList;
3132
import java.util.Collection;
3233
import java.util.Collections;
33-
import java.util.HashSet;
3434
import java.util.List;
3535
import java.util.Map;
3636
import java.util.Set;
3737

38+
import javax.servlet.http.HttpServlet;
3839
import javax.xml.parsers.ParserConfigurationException;
3940

41+
import org.apache.catalina.Context;
42+
import org.apache.catalina.core.StandardContext;
4043
import org.apache.catalina.servlets.DefaultServlet;
44+
import org.apache.catalina.startup.Tomcat;
4145
import org.apache.commons.io.IOUtils;
4246
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
4347
import org.eclipse.basyx.aas.aggregator.AASAggregatorAPIHelper;
@@ -61,7 +65,6 @@
6165
import org.eclipse.basyx.components.aas.aascomponent.IAASServerFeature;
6266
import org.eclipse.basyx.components.aas.aascomponent.InMemoryAASServerComponentFactory;
6367
import org.eclipse.basyx.components.aas.aascomponent.MongoDBAASServerComponentFactory;
64-
import org.eclipse.basyx.components.aas.aasx.AASXPackageManager;
6568
import org.eclipse.basyx.components.aas.authorization.AuthorizedAASServerFeature;
6669
import org.eclipse.basyx.components.aas.authorization.internal.AuthorizedAASServerFeatureFactory;
6770
import org.eclipse.basyx.components.aas.authorization.internal.AuthorizedDefaultServlet;
@@ -93,6 +96,7 @@
9396
import org.eclipse.basyx.vab.exception.provider.ProviderException;
9497
import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
9598
import org.eclipse.basyx.vab.modelprovider.VABPathTools;
99+
import org.eclipse.basyx.vab.protocol.http.server.BaSyxChildContext;
96100
import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
97101
import org.eclipse.basyx.vab.protocol.http.server.BaSyxHTTPServer;
98102
import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
@@ -107,7 +111,6 @@
107111
*
108112
* @author schnicke, espen, fried, fischer, danish, wege
109113
*/
110-
@SuppressWarnings("deprecation")
111114
public class AASServerComponent implements IComponent {
112115
private static Logger logger = LoggerFactory.getLogger(AASServerComponent.class);
113116

@@ -121,16 +124,17 @@ public class AASServerComponent implements IComponent {
121124
private BaSyxMongoDBConfiguration mongoDBConfig;
122125
private BaSyxSecurityConfiguration securityConfig;
123126

124-
private List<IAASServerFeature> aasServerFeatureList = new ArrayList<IAASServerFeature>();
125-
126-
// Initial AASBundle
127-
protected Collection<AASBundle> aasBundles;
127+
private List<IAASServerFeature> aasServerFeatureList = new ArrayList<>();
128+
protected List<Collection<AASBundle>> aasBundles = new ArrayList<>();
128129

129130
private IAASAggregator aggregator;
130131
// Watcher for AAS Aggregator functionality
131132
private boolean isAASXUploadEnabled = false;
132133

133134
private static final String PREFIX_SUBMODEL_PATH = "/aas/submodels/";
135+
private static final String AASX_RES_FILE_CONTEXT_PATH = AASXToMetamodelConverter.TEMP_DIRECTORY;
136+
private static final String AASX_RES_FILE_DOCBASE_PATH = VABPathTools.append(System.getProperty("java.io.tmpdir"), AASX_RES_FILE_CONTEXT_PATH);
137+
private static final String AASX_RES_FILE_SERVLET_MAPPING_PATTERN = "/*";
134138

135139
/**
136140
* Constructs an empty AAS server using the passed context
@@ -210,7 +214,8 @@ public void setRegistry(IAASRegistry registry) {
210214
* The bundles that will be loaded during startup
211215
*/
212216
public void setAASBundles(Collection<AASBundle> aasBundles) {
213-
this.aasBundles = aasBundles;
217+
this.aasBundles = new ArrayList<>();
218+
this.aasBundles.add(aasBundles);
214219
}
215220

216221
/**
@@ -220,7 +225,9 @@ public void setAASBundles(Collection<AASBundle> aasBundles) {
220225
* The bundle that will be loaded during startup
221226
*/
222227
public void setAASBundle(AASBundle aasBundle) {
223-
this.aasBundles = Collections.singleton(aasBundle);
228+
this.aasBundles = new ArrayList<>();
229+
Collection<AASBundle> firstBundleSet = Collections.singleton(aasBundle);
230+
this.aasBundles.add(firstBundleSet);
224231
}
225232

226233
/**
@@ -251,11 +258,12 @@ public void startComponent() {
251258

252259
// An initial AAS has been loaded from the drive?
253260
if (aasBundles != null) {
254-
// 1. Also provide the files
255-
context.addServletMapping("/files/*", createDefaultServlet());
261+
createBasyxResourceDirectoryIfNotExists();
262+
263+
addAasxFilesResourceServlet(context);
256264

257265
// 2. Fix the file paths according to the servlet configuration
258-
modifyFilePaths(contextConfig.getHostname(), contextConfig.getPort(), contextConfig.getContextPath());
266+
modifyFilePaths(contextConfig.getHostname(), contextConfig.getPort(), getRootFilePathWithContext(contextConfig.getContextPath()));
259267

260268
registerWhitelistedSubmodels();
261269
}
@@ -267,6 +275,10 @@ public void startComponent() {
267275
registerPreexistingAASAndSMIfPossible();
268276
}
269277

278+
private String getRootFilePathWithContext(String contextPath) {
279+
return VABPathTools.append(contextPath, AASX_RES_FILE_CONTEXT_PATH);
280+
}
281+
270282
private DefaultServlet createDefaultServlet() {
271283
if (aasConfig.isAuthorizationEnabled()) {
272284
final AuthorizedDefaultServletParams<?> params = getAuthorizedDefaultServletParams();
@@ -543,17 +555,18 @@ private Set<AASBundle> loadBundleFromJSON(String jsonPath) throws IOException {
543555
return new JSONAASBundleFactory(jsonContent).create();
544556
}
545557

546-
private static Set<AASBundle> loadBundleFromAASX(String aasxPath) throws IOException, ParserConfigurationException, SAXException, InvalidFormatException, URISyntaxException {
558+
private static Set<AASBundle> loadBundleFromAASX(String aasxPath, String childFilePath) throws IOException, ParserConfigurationException, SAXException, InvalidFormatException, URISyntaxException {
547559
logger.info("Loading aas from aasx \"" + aasxPath + "\"");
548560

549561
// Instantiate the aasx package manager
550-
AASXToMetamodelConverter packageManager = new AASXPackageManager(aasxPath);
551-
552-
// Unpack the files referenced by the aas
553-
packageManager.unzipRelatedFiles();
562+
try (AASXToMetamodelConverter packageManager = new AASXToMetamodelConverter(aasxPath)) {
563+
// Unpack the files referenced by the aas
564+
packageManager.unzipRelatedFilesToChildPath(childFilePath);
554565

555-
// Retrieve the aas from the package
556-
return packageManager.retrieveAASBundles();
566+
// Retrieve the aas from the package
567+
return packageManager.retrieveAASBundles();
568+
}
569+
557570
}
558571

559572
private void addAASServerFeaturesToContext(BaSyxContext context) {
@@ -562,13 +575,21 @@ private void addAASServerFeaturesToContext(BaSyxContext context) {
562575
}
563576
}
564577

578+
private Collection<AASBundle> getFlatAASBundles() {
579+
Collection<AASBundle> result = new ArrayList<AASBundle>();
580+
for (Collection<AASBundle> bundle : this.aasBundles) {
581+
result.addAll(bundle);
582+
}
583+
return result;
584+
}
585+
565586
private VABHTTPInterface<?> createAggregatorServlet() {
566587
aggregator = createAASAggregator();
567588
loadAASBundles();
568589

569590
if (aasBundles != null) {
570591
try (final var ignored = ElevatedCodeAuthentication.enterElevatedCodeAuthenticationArea()) {
571-
AASBundleHelper.integrate(aggregator, aasBundles);
592+
AASBundleHelper.integrate(aggregator, getFlatAASBundles());
572593
}
573594
}
574595

@@ -614,30 +635,39 @@ private List<IAASServerDecorator> createAASServerDecoratorList() {
614635
}
615636

616637
private void loadAASBundles() {
617-
if (aasBundles != null) {
638+
if (!aasBundles.isEmpty()) {
618639
return;
619640
}
620641

621642
List<String> aasSources = aasConfig.getAASSourceAsList();
622643
aasBundles = loadAASFromSource(aasSources);
623644
}
624645

625-
private Set<AASBundle> loadAASFromSource(List<String> aasSources) {
646+
private List<Collection<AASBundle>> loadAASFromSource(List<String> aasSources) {
626647
if (aasSources.isEmpty()) {
627-
return Collections.emptySet();
648+
return new ArrayList<>();
628649
}
629650

630-
Set<AASBundle> aasBundlesSet = new HashSet<>();
651+
List<Collection<AASBundle>> aasBundlesSet = new ArrayList<>();
631652

632-
aasSources.stream().map(this::loadBundleFromFile).forEach(aasBundlesSet::addAll);
653+
for (int i = 0; i < aasSources.size(); i++) {
654+
String aasSource = aasSources.get(i);
655+
String subFilePath = getAASXFileSubPath(i);
656+
Set<AASBundle> loadedBundles = loadBundleFromFile(aasSource, subFilePath);
657+
aasBundlesSet.add(loadedBundles);
658+
}
633659

634660
return aasBundlesSet;
635661
}
636662

637-
private Set<AASBundle> loadBundleFromFile(String aasSource) {
663+
private String getAASXFileSubPath(int aasxIndex) {
664+
return "aasx" + Integer.toString(aasxIndex);
665+
}
666+
667+
private Set<AASBundle> loadBundleFromFile(String aasSource, String childFilePath) {
638668
try {
639669
if (aasSource.endsWith(".aasx")) {
640-
return loadBundleFromAASX(aasSource);
670+
return loadBundleFromAASX(aasSource, childFilePath);
641671
} else if (aasSource.endsWith(".json")) {
642672
return loadBundleFromJSON(aasSource);
643673
} else if (aasSource.endsWith(".xml")) {
@@ -730,7 +760,8 @@ private String getSMEndpoint(IIdentifier smId) {
730760
}
731761

732762
private String getSMIdShortFromSMId(IIdentifier smId) {
733-
for (AASBundle bundle : aasBundles) {
763+
Collection<AASBundle> flatAasBundles = getFlatAASBundles();
764+
for (AASBundle bundle : flatAasBundles) {
734765
for (ISubmodel sm : bundle.getSubmodels()) {
735766
if (smId.getId().equals(sm.getIdentification().getId())) {
736767
return sm.getIdShort();
@@ -741,7 +772,8 @@ private String getSMIdShortFromSMId(IIdentifier smId) {
741772
}
742773

743774
private String getAASIdFromSMId(IIdentifier smId) {
744-
for (AASBundle bundle : aasBundles) {
775+
Collection<AASBundle> flatAasBundles = getFlatAASBundles();
776+
for (AASBundle bundle : flatAasBundles) {
745777
for (ISubmodel sm : bundle.getSubmodels()) {
746778
if (smId.getId().equals(sm.getIdentification().getId())) {
747779
return bundle.getAAS().getIdentification().getId();
@@ -756,11 +788,18 @@ private String getAASIdFromSMId(IIdentifier smId) {
756788
* configuration
757789
*/
758790
private void modifyFilePaths(String hostName, int port, String rootPath) {
759-
rootPath = rootPath + "/files";
760-
for (AASBundle bundle : aasBundles) {
791+
for (int i = 0; i < aasBundles.size(); i++) {
792+
Collection<AASBundle> bundleSet = aasBundles.get(i);
793+
String bundleFileRootPath = VABPathTools.concatenatePaths(rootPath, getAASXFileSubPath(i), "files");
794+
modifyFilePathsInBundleSet(bundleSet, hostName, port, bundleFileRootPath);
795+
}
796+
}
797+
798+
private void modifyFilePathsInBundleSet(Collection<AASBundle> bundleSet, String hostName, int port, String bundleFileRootPath) {
799+
for (AASBundle bundle : bundleSet) {
761800
Set<ISubmodel> submodels = bundle.getSubmodels();
762801
for (ISubmodel sm : submodels) {
763-
SubmodelFileEndpointLoader.setRelativeFileEndpoints(sm, hostName, port, rootPath);
802+
SubmodelFileEndpointLoader.setRelativeFileEndpoints(sm, hostName, port, bundleFileRootPath);
764803
}
765804
}
766805
}
@@ -769,10 +808,41 @@ private String getMqttAASClientId() {
769808
if (aasBundles == null || aasBundles.isEmpty()) {
770809
return "defaultNoShellId";
771810
}
772-
return aasBundles.stream().findFirst().get().getAAS().getIdShort();
811+
Collection<AASBundle> firstBundleSet = aasBundles.get(0);
812+
if (firstBundleSet == null || firstBundleSet.isEmpty()) {
813+
return "defaultNoShellId";
814+
}
815+
return firstBundleSet.stream().findFirst().get().getAAS().getIdShort();
773816
}
774817

775818
private String getMqttSubmodelClientId() {
776819
return getMqttAASClientId() + "/submodelAggregator";
777820
}
821+
822+
private void addAasxFilesResourceServlet(BaSyxContext context) {
823+
HttpServlet httpServlet = createDefaultServlet();
824+
825+
String childContextPath = VABPathTools.append(contextConfig.getContextPath(), AASX_RES_FILE_CONTEXT_PATH);
826+
Context childContext = createChildContextForAasxResourceFiles(childContextPath, AASX_RES_FILE_DOCBASE_PATH);
827+
828+
context.addChildContext(new BaSyxChildContext(childContext, httpServlet, AASX_RES_FILE_SERVLET_MAPPING_PATTERN));
829+
}
830+
831+
private Context createChildContextForAasxResourceFiles(String childContextPath, String childDocbasePath) {
832+
Context childContext = new StandardContext();
833+
childContext.setPath(childContextPath);
834+
childContext.setDocBase(childDocbasePath);
835+
childContext.addLifecycleListener(new Tomcat.FixContextListener());
836+
return childContext;
837+
}
838+
839+
private void createBasyxResourceDirectoryIfNotExists() {
840+
File directory = new File(AASX_RES_FILE_DOCBASE_PATH);
841+
842+
if (directory.exists())
843+
return;
844+
845+
directory.mkdir();
846+
}
847+
778848
}

0 commit comments

Comments
 (0)