eclipse-esmf / esmf-sdk

Load Aspect Models and their artifacts as Java code; share components to realize SAMM as code
https://eclipse-esmf.github.io/esmf-developer-guide/index.html
Mozilla Public License 2.0
25 stars 12 forks source link

[BUG] sldt-semantic-hub - ESMF SDK backward compatibility issue - AspectModelResolver.resolveAspectModel method failing with TripleStoreResolutionStrategy: definition for urn:samm:org.eclipse.tractusx.xxxxx_urns_X:X.X.X#XXX not found #437

Closed shijinrajbosch closed 10 months ago

shijinrajbosch commented 11 months ago

Describe the bug Test case works with sds-aspect-model-starter 2.1.3 & esmf-aspect-model-starter 2.2.3 and failing with - esmf-aspect-model-starter 2.3.1 & 2.3.2

Test class : org.eclipse.tractusx.semantics.hub.ModelsApiTest Test method : testDependentModelTransitionForBAMM()

Semantic-hub Github : https://github.com/bci-oss/sldt-semantic-hub.git (for esmf-aspect-model-starter 2.3.1) Branch - bug/SAMM_BAMM_support

Semantic-hub Github : https://github.com/bci-oss/sldt-semantic-hub.git (for esmf-aspect-model-starter 2.3.2) Branch - SAMM_BAMM_Support-ESMF_SDK_2.3.2

Where Test class : org.eclipse.tractusx.semantics.hub.ModelsApiTest Test method : testDependentModelTransitionForBAMM()

Semantic-hub Github : https://github.com/bci-oss/sldt-semantic-hub.git Branch - bug/SAMM_BAMM_support

Additional context Steps to reproduce the issue :


String urnPrefix = "urn:bamm:org.eclipse.tractusx.model.status.transitionWithDependency:1.0.0#";

Model model = TurtleLoader
.loadTurtle( new ByteArrayInputStream( bytes ) )
.getOrElseThrow( cause -> new InvalidAspectModelException( cause.getMessage() ) );

StmtIterator stmtIterator = model.listStatements( null, RDF.type, (RDFNode) null );

AspectModelUrn modelUrn = StreamSupport.stream( Spliterators.spliteratorUnknownSize( stmtIterator, ORDERED ), false )
.filter( statement -> statement.getObject().isURIResource() )
.filter( statement -> statement.getObject().asResource().toString().matches( SparqlQueries.SAMM_ASPECT_URN_REGEX ))
.map( org.apache.jena.rdf.model.Statement::getSubject )
.map( org.apache.jena.rdf.model.Resource::toString )
.map( org.eclipse.esmf.aspectmodel.urn.AspectModelUrn::fromUrn )
.findAny()
.orElseThrow( () -> new InvalidAspectModelException( "Unable to parse Aspect Model URN" ) );

Function<String, Model> tripleStoreRequester = this::findContainingModelByUrn ;

org.eclipse.esmf.aspectmodel.resolver.ResolutionStrategy resolutionStrategy =
new TripleStoreResolutionStrategy( tripleStoreRequester);

VersionNumber knownVersion = new AspectMetaModelResourceResolver()
            .getMetaModelVersion( rawModel )
            .onFailure( MissingMetaModelVersionException.class,
                  e -> {
                     throw new InvalidAspectModelException( MESSAGE_MISSING_METAMODEL_VERSION );
                  } )
            .onFailure( MultipleMetaModelVersionsException.class,
                  e -> {
                     throw new InvalidAspectModelException( MESSAGE_MULTIPLE_METAMODEL_VERSIONS );
                  } )
            .onFailure( UnsupportedVersionException.class,
                  e -> {
                     throw new InvalidAspectModelException( MESSAGE_SAMM_VERSION_NOT_SUPPORTED );
                  } ).get();

Try<VersionedModel> versionedModel = org.eclipse.esmf.aspectmodel.resolver.services.AspectMetaModelResourceResolver.mergeMetaModelIntoRawModel(model, knownVersion);

org.eclipse.esmf.aspectmodel.resolver.ResolutionStrategy firstPayloadThenTripleStore = new org.eclipse.esmf.aspectmodel.resolver.EitherStrategy( new SelfResolutionStrategy( versionedModel.get().getRawModel() ),resolutionStrategy );

StmtIterator stmtIterator = model.listStatements( null, RDF.type, (RDFNode) null );
AspectModelUrn modelUrn = AspectModelUrn modelUrn = StreamSupport.stream( Spliterators.spliteratorUnknownSize( stmtIterator, ORDERED ), false )
.filter( statement -> statement.getObject().isURIResource() )
.filter( statement -> statement.getObject().asResource().toString().matches( SparqlQueries.SAMM_ASPECT_URN_REGEX ))
.map( org.apache.jena.rdf.model.Statement::getSubject )
.map( org.apache.jena.rdf.model.Resource::toString )
.map( org.eclipse.esmf.aspectmodel.urn.AspectModelUrn::fromUrn )
.findAny()
.orElseThrow( () -> new InvalidAspectModelException( "Unable to parse Aspect Model URN" ) );

Try<VersionedModel> resolvedModel = versionedModel.flatMap( loadedModel ->
            aspectModelResolver.resolveAspectModel( firstPayloadThenTripleStore, modelUrn ) );

private Model findContainingModelByUrn( final String urn ) {
final Query query = buildFindModelElementClosureQuery( urn );
try ( final RDFConnection rdfConnection = rdfConnectionRemoteBuilder.build() ) {
return rdfConnection.queryConstruct( query );
}
}

public static Query buildFindModelElementClosureQuery( final String urn ) {
      final ParameterizedSparqlString pss = create( FIND_MODEL_ELEMENT_CLOSURE );
      pss.setNsPrefix( "ns", urn );
      return pss.asQuery();
   }

private static final String FIND_MODEL_ELEMENT_CLOSURE =
         "CONSTRUCT {\n"
               + " ?s ?p ?o .\n"
               + "} WHERE {\n"
               + "    bind( ns: as ?urn )\n"
               + "    ?urn (<>|!<>)* ?s .\n"
               + "    ?s ?p ?o .\n"
               + "}";`

private static final String AUXILIARY_NAMESPACE = "urn:bamm:io.openmanufacturing:aspect-model:aux#";

private static org.apache.jena.query.ParameterizedSparqlString create( final String query ) {
      final org.apache.jena.query.ParameterizedSparqlString pss = new ParameterizedSparqlString();
      pss.setCommandText( query );
      pss.setNsPrefix( "aux", AUXILIARY_NAMESPACE );
      return pss;
   }

-----------------------------------------------------------------------------------------------
public static class TripleStoreResolutionStrategy implements ResolutionStrategy {

      private final Function<String, Model> tripleStoreRequester;
      private final List<String> alreadyLoadedNamespaces = new ArrayList<>();

      public TripleStoreResolutionStrategy( final Function<String, Model> tripleStoreRequester ) {
         this.tripleStoreRequester = tripleStoreRequester;
      }

      @Override
      public Try<Model> apply( final AspectModelUrn aspectModelUrn ) {
         final String namespace = aspectModelUrn.getNamespace();
         if ( alreadyLoadedNamespaces.contains( namespace ) ) {
            return Try.success( ModelFactory.createDefaultModel() );
         }
         alreadyLoadedNamespaces.add( namespace );

         final Resource resource = org.apache.jena.rdf.model.ResourceFactory.createResource( aspectModelUrn.getUrn().toASCIIString() );
         final org.apache.jena.rdf.model.Model model = tripleStoreRequester.apply( aspectModelUrn.getUrn().toString() );
         if ( model == null ) {
            return Try.failure( new ResourceDefinitionNotFoundException( getClass().getSimpleName(), resource ) );
         }
         return model.contains( resource, RDF.type, (RDFNode) null ) ?
               Try.success( model ) :
               Try.failure( new ResourceDefinitionNotFoundException( getClass().getSimpleName(), resource ) );
      }
   }
-----------------------------------------------------------------------------------------------
static class SelfResolutionStrategy implements ResolutionStrategy {

      private final Model model;

      public SelfResolutionStrategy( final Model model ) {
         this.model = model;
      }

      @Override
      public Try<Model> apply( final AspectModelUrn aspectModelUrn ) {
         final Resource resource = ResourceFactory.createResource( aspectModelUrn.getUrn().toString() );
         return model.contains( resource, RDF.type, (RDFNode) null ) ?
               Try.success( model ) :
               Try.failure( new ResourceDefinitionNotFoundException( getClass().getSimpleName(), resource ) );
      }
   }
-----------------------------------------------------------------------------------------------

resolvedModel.isFailure() is true with resolvedModel.getCause().getMessage() as "TripleStoreResolutionStrategy: definition for urn:samm:org.eclipse.tractusx.test_model_list_by_urns_1:1.0.0#Movement not found"

shijinrajbosch commented 11 months ago

Test TTL file used is available here

shijinrajbosch commented 11 months ago

The below test cases also failing in Semantic-hub - Test class : org.eclipse.tractusx.semantics.hub.ModelsApiTest Test Methods : testAasxEndpointExpectErrorForBAMM() testSaveValidModelExpectSuccessForBAMM() testExampleGenerateExamplePayloadJsonExpectSuccessForBAMM() testGenerateJsonSchemaExpectSuccessForBAMM() testSaveInvalidModelExpectSuccess() testGenerateOpenApiEndpointSpecExpectSuccessForBAMM() testSaveModelWithExternalReferencesExpectSuccessForBAMM() testGetModelListByMultipleUrnsForBAMM() testGetModelsExpectSuccessForBAMM() testSaveInvalidModelExpectSuccessForBAMM() testDependentModelBAMM() testAasxEndpointExpectSuccessForBAMM() testModelStatusTransitionForPostForBAMM() testDependentModelTransitionForBAMM() testModelStatusTransitionForPutForBAMM()

shijinrajbosch commented 10 months ago

We have upgraded to ESMF SDK 2.4.2 and resolved the issues.