Skip to content

Commit 1baf5a8

Browse files
authored
Refactors AASEnvironment and implements auth for upload endpoint (#232)
* Fixes upload endpoint not working with auth Signed-off-by: Mohammad Ghazanfar Ali Danish <[email protected]> * test Signed-off-by: Mohammad Ghazanfar Ali Danish <[email protected]> * Refactors AASEnvironment and implements auth for upload endpoint Signed-off-by: Mohammad Ghazanfar Ali Danish <[email protected]> * Updates the rbac_rules Signed-off-by: Mohammad Ghazanfar Ali Danish <[email protected]> * Refactors code Signed-off-by: Mohammad Ghazanfar Ali Danish <[email protected]> * Minor refactoring Signed-off-by: Mohammad Ghazanfar Ali Danish <[email protected]> * Refactors variable names Signed-off-by: Mohammad Ghazanfar Ali Danish <[email protected]> --------- Signed-off-by: Mohammad Ghazanfar Ali Danish <[email protected]>
1 parent 1c26c01 commit 1baf5a8

File tree

27 files changed

+801
-350
lines changed

27 files changed

+801
-350
lines changed

basyx.aasenvironment/Readme.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,11 @@ Furthermore, if Identifiables (AAS, Submodels, ConceptDescriptions) are already
3838

3939
For examples, see [application.properties](./basyx.aasenvironment.component/src/main/resources/application.properties)
4040

41-
4241
## AAS Environment Upload Endpoint
4342

4443
AAS environments (e.g. XML, JSON, AASX) can be uploaded to the `/upload` endpoint.
4544

4645
The upload follows the same rules as the preconfiguration in terms of handling existing AAS, submodels and concept descriptions. In order for the file to be recognized correctly, please make sure that its MIME type is properly configured.
46+
47+
## AAS Environment Features
48+
* [AAS Environment Authorization](basyx.aasenvironment-feature-authorization)

basyx.aasenvironment/basyx.aasenvironment-core/src/main/java/org/eclipse/digitaltwin/basyx/aasenvironment/AasEnvironment.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.List;
2929

3030
import org.eclipse.digitaltwin.aas4j.v3.dataformat.core.SerializationException;
31+
import org.eclipse.digitaltwin.basyx.aasenvironment.environmentloader.CompleteEnvironment;
3132

3233
/**
3334
* Specifies the overall AasEnvironment API
@@ -51,4 +52,6 @@ public interface AasEnvironment {
5152
public String createXMLAASEnvironmentSerialization(List<String> aasIds, List<String> submodelIds, boolean includeConceptDescriptions) throws SerializationException;
5253

5354
public byte[] createAASXAASEnvironmentSerialization(List<String> aasIds, List<String> submodelIds, boolean includeConceptDescriptions) throws SerializationException, IOException;
55+
56+
public void loadEnvironment(CompleteEnvironment completeEnvironment);
5457
}

basyx.aasenvironment/basyx.aasenvironment-core/src/main/java/org/eclipse/digitaltwin/basyx/aasenvironment/base/DefaultAASEnvironment.java

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,25 +24,38 @@
2424
******************************************************************************/
2525
package org.eclipse.digitaltwin.basyx.aasenvironment.base;
2626

27+
import java.io.ByteArrayInputStream;
2728
import java.io.ByteArrayOutputStream;
2829
import java.io.IOException;
30+
import java.util.ArrayList;
2931
import java.util.List;
3032
import java.util.Objects;
33+
import java.util.Optional;
3134
import java.util.Set;
3235
import java.util.stream.Collectors;
3336

37+
import org.apache.commons.io.FilenameUtils;
3438
import org.eclipse.digitaltwin.aas4j.v3.dataformat.aasx.AASXSerializer;
39+
import org.eclipse.digitaltwin.aas4j.v3.dataformat.aasx.InMemoryFile;
3540
import org.eclipse.digitaltwin.aas4j.v3.dataformat.core.SerializationException;
3641
import org.eclipse.digitaltwin.aas4j.v3.dataformat.json.JsonSerializer;
3742
import org.eclipse.digitaltwin.aas4j.v3.dataformat.xml.XmlSerializer;
3843
import org.eclipse.digitaltwin.aas4j.v3.model.AssetAdministrationShell;
3944
import org.eclipse.digitaltwin.aas4j.v3.model.ConceptDescription;
4045
import org.eclipse.digitaltwin.aas4j.v3.model.Environment;
4146
import org.eclipse.digitaltwin.aas4j.v3.model.Submodel;
47+
import org.eclipse.digitaltwin.aas4j.v3.model.SubmodelElement;
4248
import org.eclipse.digitaltwin.aas4j.v3.model.impl.DefaultEnvironment;
4349
import org.eclipse.digitaltwin.basyx.aasenvironment.AasEnvironment;
4450
import org.eclipse.digitaltwin.basyx.aasenvironment.ConceptDescriptionIdCollector;
51+
import org.eclipse.digitaltwin.basyx.aasenvironment.FileElementPathCollector;
52+
import org.eclipse.digitaltwin.basyx.aasenvironment.IdShortPathBuilder;
4553
import org.eclipse.digitaltwin.basyx.aasenvironment.MetamodelCloneCreator;
54+
import org.eclipse.digitaltwin.basyx.aasenvironment.environmentloader.CompleteEnvironment;
55+
import org.eclipse.digitaltwin.basyx.aasenvironment.environmentloader.IdentifiableUploader;
56+
import org.eclipse.digitaltwin.basyx.aasenvironment.environmentloader.IdentifiableAssertion;
57+
import org.eclipse.digitaltwin.basyx.aasenvironment.environmentloader.IdentifiableUploader.DelegatingIdentifiableRepository;
58+
import org.eclipse.digitaltwin.basyx.aasenvironment.environmentloader.IdentifiableUploader.IdentifiableRepository;
4659
import org.eclipse.digitaltwin.basyx.aasrepository.AasRepository;
4760
import org.eclipse.digitaltwin.basyx.conceptdescriptionrepository.ConceptDescriptionRepository;
4861
import org.eclipse.digitaltwin.basyx.core.exceptions.ElementDoesNotExistException;
@@ -68,6 +81,7 @@ public class DefaultAASEnvironment implements AasEnvironment {
6881
private XmlSerializer xmlSerializer = new XmlSerializer();
6982
private AASXSerializer aasxSerializer = new AASXSerializer();
7083
private MetamodelCloneCreator cloneCreator = new MetamodelCloneCreator();
84+
private IdentifiableAssertion checker = new IdentifiableAssertion();
7185

7286
public DefaultAASEnvironment(AasRepository aasRepository, SubmodelRepository submodelRepository, ConceptDescriptionRepository conceptDescriptionRepository) {
7387
this.aasRepository = aasRepository;
@@ -96,6 +110,108 @@ public byte[] createAASXAASEnvironmentSerialization(@Valid List<String> aasIds,
96110
aasxSerializer.write(aasEnvironment, null, outputStream);
97111
return outputStream.toByteArray();
98112
}
113+
114+
public void loadEnvironment(CompleteEnvironment completeEnvironment) {
115+
Environment environment = completeEnvironment.getEnvironment();
116+
117+
if (environment == null)
118+
return;
119+
120+
checker.assertNoDuplicateIds(environment);
121+
122+
createShellsOnRepositoryFromEnvironment(environment);
123+
createSubmodelsOnRepositoryFromEnvironment(environment, completeEnvironment.getRelatedFiles());
124+
createConceptDescriptionsOnRepositoryFromEnvironment(environment);
125+
}
126+
127+
private void createConceptDescriptionsOnRepositoryFromEnvironment(Environment environment) {
128+
IdentifiableRepository<ConceptDescription> repo = new DelegatingIdentifiableRepository<ConceptDescription>(conceptDescriptionRepository::getConceptDescription, conceptDescriptionRepository::updateConceptDescription,
129+
conceptDescriptionRepository::createConceptDescription);
130+
IdentifiableUploader<ConceptDescription> uploader = new IdentifiableUploader<ConceptDescription>(repo);
131+
for (ConceptDescription conceptDescription : environment.getConceptDescriptions()) {
132+
boolean success = uploader.upload(conceptDescription);
133+
logSuccessConceptDescription(conceptDescription.getId(), success);
134+
}
135+
}
136+
137+
private void createSubmodelsOnRepositoryFromEnvironment(Environment environment, List<InMemoryFile> relatedFiles) {
138+
List<Submodel> submodels = environment.getSubmodels();
139+
140+
createSubmodelsOnRepository(submodels);
141+
142+
if (relatedFiles == null || relatedFiles.isEmpty())
143+
return;
144+
145+
for (Submodel submodel : submodels) {
146+
List<List<SubmodelElement>> idShortElementPathsOfAllFileSMEs = new FileElementPathCollector(submodel).collect();
147+
148+
idShortElementPathsOfAllFileSMEs.stream().forEach(fileSMEIdShortPath -> setFileToFileElement(submodel.getId(), fileSMEIdShortPath, relatedFiles));
149+
}
150+
}
151+
152+
private void setFileToFileElement(String submodelId, List<SubmodelElement> fileSMEIdShortPathElements, List<InMemoryFile> relatedFiles) {
153+
String fileSMEIdShortPath = new IdShortPathBuilder(new ArrayList<>(fileSMEIdShortPathElements)).build();
154+
155+
org.eclipse.digitaltwin.aas4j.v3.model.File fileSME = (org.eclipse.digitaltwin.aas4j.v3.model.File) submodelRepository.getSubmodelElement(submodelId, fileSMEIdShortPath);
156+
157+
InMemoryFile inMemoryFile = getAssociatedInMemoryFile(relatedFiles, fileSME.getValue());
158+
159+
if (inMemoryFile == null) {
160+
logger.info("Unable to set file to the SubmodelElement File with IdShortPath '{}' because it does not exist in the AASX file.", fileSMEIdShortPath);
161+
162+
return;
163+
}
164+
165+
submodelRepository.setFileValue(submodelId, fileSMEIdShortPath, getFileName(inMemoryFile.getPath()), new ByteArrayInputStream(inMemoryFile.getFileContent()));
166+
}
167+
168+
private String getFileName(String path) {
169+
return FilenameUtils.getName(path);
170+
}
171+
172+
private InMemoryFile getAssociatedInMemoryFile(List<InMemoryFile> relatedFiles, String value) {
173+
174+
Optional<InMemoryFile> inMemoryFile = relatedFiles.stream().filter(file -> file.getPath().equals(value)).findAny();
175+
176+
if (inMemoryFile.isEmpty())
177+
return null;
178+
179+
return inMemoryFile.get();
180+
}
181+
182+
private void createShellsOnRepositoryFromEnvironment(Environment environment) {
183+
IdentifiableRepository<AssetAdministrationShell> repo = new DelegatingIdentifiableRepository<AssetAdministrationShell>(aasRepository::getAas, aasRepository::updateAas, aasRepository::createAas);
184+
IdentifiableUploader<AssetAdministrationShell> uploader = new IdentifiableUploader<>(repo);
185+
for (AssetAdministrationShell shell : environment.getAssetAdministrationShells()) {
186+
boolean success = uploader.upload(shell);
187+
logSuccess("shell", shell.getId(), success);
188+
}
189+
}
190+
191+
private void createSubmodelsOnRepository(List<Submodel> submodels) {
192+
IdentifiableRepository<Submodel> repo = new DelegatingIdentifiableRepository<Submodel>(submodelRepository::getSubmodel, submodelRepository::updateSubmodel, submodelRepository::createSubmodel);
193+
IdentifiableUploader<Submodel> uploader = new IdentifiableUploader<>(repo);
194+
for (Submodel submodel : submodels) {
195+
boolean success = uploader.upload(submodel);
196+
logSuccess("submodel", submodel.getId(), success);
197+
}
198+
}
199+
200+
private void logSuccess(String resourceName, String id, boolean success) {
201+
if (success) {
202+
logger.info("Uploading " + resourceName + " " + id + " was successful!");
203+
} else {
204+
logger.warn("Uploading " + resourceName + " " + id + " was not successful!");
205+
}
206+
}
207+
208+
private void logSuccessConceptDescription(String conceptDescriptionId, boolean success) {
209+
if (!success) {
210+
logger.warn("Colliding Ids detected for ConceptDescription: " + conceptDescriptionId + ". If they are not identical, this is an error. Please note that the already existing ConceptDescription was not updated.");
211+
} else {
212+
logSuccess("conceptDescription", conceptDescriptionId, success);
213+
}
214+
}
99215

100216
private Environment createEnvironment(List<String> aasIds, List<String> submodelIds, boolean includeConceptDescriptions) {
101217
List<AssetAdministrationShell> shells = aasIds.stream().map(aasRepository::getAas).collect(Collectors.toList());

basyx.aasenvironment/basyx.aasenvironment-core/src/main/java/org/eclipse/digitaltwin/basyx/aasenvironment/environmentloader/AasEnvironmentLoader.java

Lines changed: 0 additions & 171 deletions
This file was deleted.

basyx.aasenvironment/basyx.aasenvironment-core/src/main/java/org/eclipse/digitaltwin/basyx/aasenvironment/environmentloader/IndentifiableAssertion.java renamed to basyx.aasenvironment/basyx.aasenvironment-core/src/main/java/org/eclipse/digitaltwin/basyx/aasenvironment/environmentloader/IdentifiableAssertion.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
* @author Gerhard Sonnenberg DFKI GmbH
3939
*
4040
*/
41-
public class IndentifiableAssertion {
41+
public class IdentifiableAssertion {
4242

4343
private final Set<String> currentShellIds = new HashSet<>();
4444
private final Set<String> currentSubmodelIds = new HashSet<>();

basyx.aasenvironment/basyx.aasenvironment-core/src/main/java/org/eclipse/digitaltwin/basyx/aasenvironment/preconfiguration/AasEnvironmentPreconfigurationLoader.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333

3434
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
3535
import org.eclipse.digitaltwin.aas4j.v3.dataformat.core.DeserializationException;
36-
import org.eclipse.digitaltwin.basyx.aasenvironment.environmentloader.AasEnvironmentLoader;
36+
import org.eclipse.digitaltwin.basyx.aasenvironment.AasEnvironment;
3737
import org.eclipse.digitaltwin.basyx.aasenvironment.environmentloader.CompleteEnvironment;
3838
import org.eclipse.digitaltwin.basyx.aasenvironment.environmentloader.CompleteEnvironment.EnvironmentType;
3939
import org.slf4j.Logger;
@@ -70,7 +70,7 @@ public boolean shouldLoadPreconfiguredEnvironment() {
7070
return pathsToLoad != null;
7171
}
7272

73-
public void loadPreconfiguredEnvironments(AasEnvironmentLoader environmentLoader)
73+
public void loadPreconfiguredEnvironments(AasEnvironment aasEnvironment)
7474
throws IOException, DeserializationException, InvalidFormatException {
7575
List<File> files = scanForEnvironments(pathsToLoad);
7676

@@ -82,7 +82,7 @@ public void loadPreconfiguredEnvironments(AasEnvironmentLoader environmentLoader
8282

8383
for (File file : files) {
8484
logLoadingProcess(currenFileIndex++, filesCount, file.getName());
85-
environmentLoader.loadEnvironment(CompleteEnvironment.fromFile(file));
85+
aasEnvironment.loadEnvironment(CompleteEnvironment.fromFile(file));
8686
}
8787
}
8888

0 commit comments

Comments
 (0)