blob: 466192f022737aa3b4859884a181158e979fc79f [file] [log] [blame]
package org.eclipse.basyx.regression.AASServer;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.eclipse.basyx.aas.factory.aasx.AASXFactory;
import org.eclipse.basyx.aas.factory.aasx.InMemoryFile;
import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
import org.eclipse.basyx.components.aas.aasx.AASXPackageManager;
import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
import org.eclipse.basyx.submodel.metamodel.api.parts.IConceptDescription;
import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
import org.eclipse.basyx.submodel.metamodel.map.SubModel;
import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDef;
import org.eclipse.basyx.support.bundle.AASBundle;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.xml.sax.SAXException;
/**
* J-Unit tests for AASx package explorer. This test checks the parsing of aas,
* submodels, assets and concept-descriptions. it also checks whether the aas
* have correct references to the asets and submodels
*
* @author zhangzai, conradi
*
*/
public class TestAASXPackageManager {
/**
* path to the aasx package
*/
private static final String aasxPath = "aasx/01_Festo.aasx";
private static final String CREATED_AASX_PATH = "test.aasx";
/**
* the aasx package converter
*/
private static AASXPackageManager packageConverter;
/**
* this string array is used to check the refs to submodels of aas
*/
private String[] submodelids = { "www.company.com/ids/sm/6053_5072_7091_5102", "smart.festo.com/demo/sm/instance/1/1/13B7CCD9BF7A3F24", "www.company.com/ids/sm/4343_5072_7091_3242", "www.company.com/ids/sm/2543_5072_7091_2660",
"www.company.com/ids/sm/6563_5072_7091_4267"
};
/**
* Files that are unzipped
*/
private static String[] unzipFiles = { "target/files/aasx/Document/docu.pdf", "target/files/icon.png"
};
/**
* AAS bundle which will be generated by the XMLAASBundleFactory
*/
private Set<AASBundle> aasBundles;
/**
* Submodels parsed by the converter
*/
private Set<ISubModel> submodels;
/**
* Initialize the AASX package converter
*/
@BeforeClass
public static void setup() {
// Create the aasx package converter with the path to the aasx package
packageConverter = new AASXPackageManager(aasxPath);
}
/**
* Test parsing of aas, assets, submodels and concept-descriptions
*/
@Test
public void testCheckAasxConverter() {
// Parse aas from the XML and create the AAS Bundle with refs to submodels
try {
aasBundles = packageConverter.retrieveAASBundles();
} catch (ParserConfigurationException | SAXException | IOException | InvalidFormatException e) {
e.printStackTrace();
}
// check the information in the aas bundles
checkAASs(aasBundles);
// Check the submodels
checkSubmodels(submodels);
}
/**
* Creates a new .aasx using the AASXFactory and tries to parse it
*/
@Test
public void testLoadGeneratedAASX()
throws InvalidFormatException, IOException, ParserConfigurationException, SAXException, TransformerException, URISyntaxException {
List<IAssetAdministrationShell> aasList = new ArrayList<>();
List<ISubModel> submodelList = new ArrayList<>();
List<IAsset> assetList = new ArrayList<>();
List<IConceptDescription> conceptDescriptionList = new ArrayList<>();
List<InMemoryFile> fileList = new ArrayList<>();
Asset asset = new Asset("asset-id", new ModelUrn("ASSET_IDENTIFICATION"), AssetKind.INSTANCE);
AssetAdministrationShell aas = new AssetAdministrationShell("aasIdShort", new ModelUrn("aasId"), asset);
aas.setAssetReference((Reference) asset.getReference());
SubModel sm = new SubModel("smIdShort", new ModelUrn("smId"));
// Create File SubmodelElements
File file1 = new File("/icon.png", "image/png");
file1.setIdShort("file1");
File file2 = new File("/aasx/Document/docu.pdf", "application/pdf");
file2.setIdShort("file2");
SubmodelElementCollection collection = new SubmodelElementCollection("Marking_RCM");
collection.addSubModelElement(file1);
sm.addSubModelElement(collection);
sm.addSubModelElement(file2);
aas.addSubModel(sm);
aasList.add(aas);
submodelList.add(sm);
assetList.add(asset);
// Build InMemoryFiles for .aasx
byte[] content1 = {5,6,7,8,9};
InMemoryFile file = new InMemoryFile(content1, "/icon.png");
fileList.add(file);
byte[] content2 = {10,11,12,13,14};
file = new InMemoryFile(content2, "aasx/Document/docu.pdf");
fileList.add(file);
// Build AASX
FileOutputStream out = new FileOutputStream(CREATED_AASX_PATH);
AASXFactory.buildAASX(aasList, assetList, conceptDescriptionList, submodelList, fileList, out);
AASXPackageManager packageManager = new AASXPackageManager(CREATED_AASX_PATH);
checkBundle(packageManager.retrieveAASBundles(), aas, sm);
// Unzip files from the .aasx
packageManager.unzipRelatedFiles();
// Check if all expected files are present
for(String path: unzipFiles) {
assertTrue(new java.io.File(path).exists());
}
}
private void checkBundle(Set<AASBundle> bundles, IAssetAdministrationShell aas, ISubModel sm) {
assertEquals(1, bundles.size());
AASBundle bundle = bundles.stream().findFirst().get();
IAssetAdministrationShell parsedAAS = bundle.getAAS();
assertEquals(aas.getIdShort(), parsedAAS.getIdShort());
assertEquals(aas.getIdentification().getId(), parsedAAS.getIdentification().getId());
assertEquals(1, bundle.getSubmodels().size());
ISubModel parsedSubmodel = bundle.getSubmodels().stream().findFirst().get();
assertEquals(sm.getIdShort(), parsedSubmodel.getIdShort());
assertEquals(sm.getIdentification().getId(), parsedSubmodel.getIdentification().getId());
assertEquals(sm.getSubmodelElements().size(), parsedSubmodel.getSubmodelElements().size());
}
/**
* Check the parsed aas with expected ones
*
* @param aasList
*/
private void checkAASs(Set<AASBundle> aasBundles) {
assertEquals(2, aasBundles.size());
IAssetAdministrationShell aas = null;
// select the AAS with a specific ID from the list
Optional<AASBundle> testAASBundleOptional = aasBundles.stream().filter(b -> b.getAAS().getIdShort().equals("Festo_3S7PM0CP4BD")).findFirst();
// verify there exist one aas with this ID
assertTrue(testAASBundleOptional.isPresent());
// Get the aasbundle from the filtered results
AASBundle testAASBundle = testAASBundleOptional.get();
aas = testAASBundle.getAAS();
// get submodels of this aas
submodels = testAASBundle.getSubmodels();
// verify short id
assertEquals("Festo_3S7PM0CP4BD", aas.getIdShort());
assertEquals("CONSTANT", aas.getCategory());
// verify id and id-type
assertEquals("smart.festo.com/demo/aas/1/1/454576463545648365874", aas.getIdentification().getId());
assertEquals(IdentifierType.IRI, aas.getIdentification().getIdType());
// Get submodel references
Collection<IReference> references = aas.getSubmodelReferences();
// this aas has 5 submodels
assertEquals(5, references.size());
List<IReference> referencelist = new ArrayList<>();
referencelist.addAll(references);
// sort the list for later assertion
// list is sorted by the last two characters of the id
referencelist.sort((x, y) -> {
String idx = x.getKeys().get(0).getValue();
String idy = y.getKeys().get(0).getValue();
String idx_end = idx.substring(idx.length() - 2);
int idxint = Integer.parseInt(idx_end);
String idy_end = idy.substring(idy.length() - 2);
int idyint = Integer.parseInt(idy_end);
return idxint - idyint;
});
// get First submodel reference
for (int i = 0; i < referencelist.size(); i++) {
IReference ref = referencelist.get(i);
List<IKey> refKeys = ref.getKeys();
// assert the submodel id
assertEquals(submodelids[i], refKeys.get(0).getValue());
// assert the id type
assertEquals("IRI", refKeys.get(0).getIdType().name());
// assert the model type
assertEquals("SUBMODEL", refKeys.get(0).getType().name());
// submodels are local
assertEquals(true, refKeys.get(0).isLocal());
}
}
/**
* Check parsed submodels with expected ones
*
* @param submodels
*/
private void checkSubmodels(Set<ISubModel> submodels) {
assertEquals(5, submodels.size());
// filter the submodel with id "Nameplate"
Optional<ISubModel> sm1Optional = submodels.stream().filter(s -> s.getIdShort().equals("Nameplate")).findFirst();
assertTrue(sm1Optional.isPresent());
ISubModel sm1 = sm1Optional.get();
// verify short id, id-type, id and model-kind of the submodel
assertEquals("Nameplate", sm1.getIdShort());
assertEquals("IRI", sm1.getIdentification().getIdType().name());
assertEquals("www.company.com/ids/sm/4343_5072_7091_3242", sm1.getIdentification().getId());
assertEquals("Instance", sm1.getModelingKind().toString());
// ---------------------------------------------
// get 1st submodel element
// Get submodel elements
Map<String, ISubmodelElement> smElements = sm1.getSubmodelElements();
// get element manufacturing name
ISubmodelElement sele = smElements.get("ManufacturerName");
// verify short id
assertEquals("ManufacturerName", sele.getIdShort());
// verify category and model-kind, value and value-type
assertEquals("PARAMETER", sele.getCategory());
assertTrue(sele.getModelingKind().name().equalsIgnoreCase("Instance"));
Property prop = (Property) sele;
assertEquals("Festo AG & Co. KG", prop.get());
assertEquals(PropertyValueTypeDef.String, prop.getValueType());
// get semantic id
IReference semantic = sele.getSemanticId();
IKey semanticKey = semantic.getKeys().get(0);
assertTrue(semanticKey.getType().name().equalsIgnoreCase("ConceptDescription"));
assertEquals("IRDI", semanticKey.getIdType().name());
assertEquals("0173-1#02-AAO677#002", semanticKey.getValue());
assertEquals(true, semanticKey.isLocal());
/// ---------------------------------------------
// get 2nd submodel element
// Get submodel elements
sele = smElements.get("ManufacturerProductDesignation");
assertEquals("ManufacturerProductDesignation", sele.getIdShort());
assertEquals("PARAMETER", sele.getCategory());
assertTrue(sele.getModelingKind().name().equalsIgnoreCase("Instance"));
prop = (Property) sele;
assertEquals("OVEL Vacuum generator", prop.get());
assertEquals(PropertyValueTypeDef.String, prop.getValueType());
// get semantic id
semantic = sele.getSemanticId();
semanticKey = semantic.getKeys().get(0);
assertTrue(semanticKey.getType().name().equalsIgnoreCase("ConceptDescription"));
assertEquals("IRDI", semanticKey.getIdType().name());
assertEquals("0173-1#02-AAW338#001", semanticKey.getValue());
assertEquals(true, semanticKey.isLocal());
// ---------------------------------------------
// get 3rd submodel element
// Get submodel elements
sele = smElements.get("PhysicalAddress");
assertEquals("PhysicalAddress", sele.getIdShort());
assertEquals("PARAMETER", sele.getCategory());
assertTrue(sele.getModelingKind().name().equalsIgnoreCase("Instance"));
// get semantic id
semantic = sele.getSemanticId();
semanticKey = semantic.getKeys().get(0);
assertTrue(semanticKey.getType().name().equalsIgnoreCase("ConceptDescription"));
assertEquals("IRI", semanticKey.getIdType().name());
assertEquals("https://www.hsu-hh.de/aut/aas/physicaladdress", semanticKey.getValue());
assertEquals(true, semanticKey.isLocal());
// get values
assertTrue(sele.getModelType().equalsIgnoreCase("SubmodelElementCollection"));
SubmodelElementCollection collection = (SubmodelElementCollection) sele;
Map<String, ISubmodelElement> smElemMap = collection.getSubmodelElements();
assertEquals(5, smElemMap.size());
Property prop1 = (Property) smElemMap.get("CountryCode");
assertEquals("CountryCode", prop1.getIdShort());
assertEquals("DE", prop1.get());
Property prop2 = (Property) smElemMap.get("Street");
assertEquals("Street", prop2.getIdShort());
assertEquals("Ruiter Straße 82", prop2.get());
}
/**
* Delete created files
*/
@AfterClass
public static void cleanUp() {
for(String path: unzipFiles) {
new java.io.File(path).delete();
}
new java.io.File(CREATED_AASX_PATH).delete();
}
}