eclipse-basyx / basyx-java-sdk

java-sdk
MIT License
26 stars 33 forks source link

Values of SubmodelElementCollection inside Entity are serialized as Map instead of List #68

Closed alexgordtop closed 2 years ago

alexgordtop commented 2 years ago

Given this test, the Property p1111 inside SubmodelElementCollection sec111 is rendered in json within a map instead of within a list...

Applies to development branch.

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.eclipse.basyx.aas.factory.json.MetamodelToJSONConverter;
import org.eclipse.basyx.aas.metamodel.map.AasEnv;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.entity.EntityType;
import org.eclipse.basyx.submodel.metamodel.map.Submodel;
import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.entity.Entity;
import org.eclipse.basyx.vab.coder.json.serialization.DefaultTypeFactory;
import org.eclipse.basyx.vab.coder.json.serialization.GSONTools;
import org.junit.Test;

public class BaSyxEntitySerializationTests {

    @Test
    public void testBaSyxSerialization() {
         GSONTools gsonTools = new GSONTools(new DefaultTypeFactory(), true, false);

         Submodel submodel = new Submodel("TestBaSyxSerialization", new Identifier(IdentifierType.CUSTOM, "blub"));

         SubmodelElementCollection sec1 = new SubmodelElementCollection("sec1"); 
         submodel.addSubmodelElement(sec1);

         Entity e11 = new Entity("e11", EntityType.COMANAGEDENTITY);
         sec1.addSubmodelElement(e11);

         SubmodelElementCollection sec111 = new SubmodelElementCollection("sec111");
         List<ISubmodelElement> statements = new ArrayList<>();
         statements.add(sec111);
         e11.setStatements(statements);

         Property p1111 = new Property("p1111", ValueType.String);
         sec111.addSubmodelElement(p1111);

         AasEnv aasEnv = new AasEnv(Arrays.asList(), Arrays.asList(), Arrays.asList(), Arrays.asList(submodel));
         String serialized = MetamodelToJSONConverter.convertToJSON(aasEnv);
         System.out.println(serialized);
    }
}

Broken:

{
    "assetAdministrationShells": [],
    "submodels": [
        {
            "idShort": "TestBaSyxSerialization",
            "identification": {"idType": "Custom", "id": "blub"},
            "dataSpecification": [],
            "embeddedDataSpecifications": [],
            "modelType": {"name": "Submodel"},
            "kind": "Instance",
            "submodelElements": [
                {
                    "modelType": {"name": "SubmodelElementCollection"},
                    "kind": "Instance",
                    "idShort": "sec1",
                    "value": [
                        {
                            "modelType": {"name": "Entity"},
                            "kind": "Instance",
                            "idShort": "e11",
                            "entityType": "CoManagedEntity",
                            "parent": {
                                "keys": [
                                    {"type": "Submodel", "local": true, "value": "blub", "idType": "Custom"},
                                    {"type": "SubmodelElementCollection", "local": true, "value": "sec1", "idType": "IdShort"}
                                ]
                            },
                            "statement": [
                                {
                                    "modelType": {"name": "SubmodelElementCollection"},
                                    "kind": "Instance",
                                    "idShort": "sec111",
                                    "value": {
                                        "p1111": {
                                            "modelType": {"name": "Property"},
                                            "kind": "Instance",
                                            "idShort": "p1111",
                                            "valueType": "string",
                                            "parent": {"keys": [{"type": "SubmodelElementCollection", "local": true, "value": "sec111", "idType": "IdShort"}]}
                                        }
                                    },
                                    "ordered": true,
                                    "allowDuplicates": true
                                }
                            ]
                        }
                    ],
                    "ordered": true,
                    "allowDuplicates": true,
                    "parent": {"keys": [{"type": "Submodel", "local": true, "value": "blub", "idType": "Custom"}]}
                }
            ]
        }
    ],
    "assets": [],
    "conceptDescriptions": []
}

Should be:

{
    "assetAdministrationShells": [],
    "submodels": [
        {
            "idShort": "TestBaSyxSerialization",
            "identification": {"idType": "Custom", "id": "blub"},
            "dataSpecification": [],
            "embeddedDataSpecifications": [],
            "modelType": {"name": "Submodel"},
            "kind": "Instance",
            "submodelElements": [
                {
                    "modelType": {"name": "SubmodelElementCollection"},
                    "kind": "Instance",
                    "idShort": "sec1",
                    "value": [
                        {
                            "modelType": {"name": "Entity"},
                            "kind": "Instance",
                            "idShort": "e11",
                            "entityType": "CoManagedEntity",
                            "parent": {
                                "keys": [
                                    {"type": "Submodel", "local": true, "value": "blub", "idType": "Custom"},
                                    {"type": "SubmodelElementCollection", "local": true, "value": "sec1", "idType": "IdShort"}
                                ]
                            },
                            "statement": [
                                {
                                    "modelType": {"name": "SubmodelElementCollection"},
                                    "kind": "Instance",
                                    "idShort": "sec111",
                                    "value": [
                                        {
                                            "modelType": {"name": "Property"},
                                            "kind": "Instance",
                                            "idShort": "p1111",
                                            "valueType": "string",
                                            "parent": {"keys": [{"type": "SubmodelElementCollection", "local": true, "value": "sec111", "idType": "IdShort"}]}
                                        }
                                    ],
                                    "ordered": true,
                                    "allowDuplicates": true
                                }
                            ]
                        }
                    ],
                    "ordered": true,
                    "allowDuplicates": true,
                    "parent": {"keys": [{"type": "Submodel", "local": true, "value": "blub", "idType": "Custom"}]}
                }
            ]
        }
    ],
    "assets": [],
    "conceptDescriptions": []
}
FrankSchnicke commented 2 years ago

The GSONTools class is used on VAB level communication and thus does not perform the necessary transformation of the VAB representation of the Submodel (i.e., containing maps of SubmodelElements) to the HTTP/REST API conformant representation (i.e., containing Lists of SubmodelElements).

AAS conformant JSON serialization is done by MetamodelToJSONConverter.

alexgordtop commented 2 years ago

@FrankSchnicke You're right - but that doesn't fix the issue... (updated description)

FrankSchnicke commented 2 years ago

Thanks for updating the description. Thus, the issue only persists for the statement of the Entity element?

Edit: I missed the updated title - question answered.