Skip to content

Commit 63b79ad

Browse files
authored
Merge pull request #207 from bci-oss/199-load-model-upon-validation
Load model on successful validation to prevent false positives
2 parents dd45d29 + 8d3ea02 commit 63b79ad

File tree

8 files changed

+112
-18
lines changed

8 files changed

+112
-18
lines changed

core/sds-aspect-meta-model-java/src/main/java/io/openmanufacturing/sds/metamodel/loader/AspectModelLoader.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ private static Try<Aspect> load( final VersionedModel versionedModel ) {
7777
final Aspect aspect = modelElementFactory.create( Aspect.class, iterator.nextStatement().getSubject() );
7878
return Try.success( aspect );
7979
} catch ( final RuntimeException exception ) {
80-
return Try.failure( new InvalidModelException( "Could not load Aspect model, please make sure the model is valid.", exception ) );
80+
return Try.failure( new InvalidModelException( "Could not load Aspect model, please make sure the model is valid", exception ) );
8181
}
8282
}
8383

core/sds-aspect-model-validator/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@
7474
<artifactId>sds-test-resources</artifactId>
7575
<scope>test</scope>
7676
</dependency>
77+
<dependency>
78+
<groupId>io.openmanufacturing</groupId>
79+
<artifactId>sds-aspect-meta-model-java</artifactId>
80+
</dependency>
7781
</dependencies>
7882

7983
<build>

core/sds-aspect-model-validator/src/main/java/io/openmanufacturing/sds/aspectmodel/validation/report/ValidationError.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ public static class Processing extends ValidationError {
124124

125125
@Override
126126
public String toString() {
127-
return "The Aspect Model could not be validated: " + message;
127+
return "An error occured while trying to validate the Aspect Model: " + message;
128128
}
129129

130130
@Override

core/sds-aspect-model-validator/src/main/java/io/openmanufacturing/sds/aspectmodel/validation/services/AspectModelValidator.java

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Copyright (c) 2021 Robert Bosch Manufacturing Solutions GmbH
33
*
44
* See the AUTHORS file(s) distributed with this work for additional
5-
* information regarding authorship.
5+
* information regarding authorship.
66
*
77
* This Source Code Form is subject to the terms of the Mozilla Public
88
* License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -13,12 +13,15 @@
1313

1414
package io.openmanufacturing.sds.aspectmodel.validation.services;
1515

16-
import static io.vavr.API.*;
16+
import static io.vavr.API.$;
17+
import static io.vavr.API.Case;
18+
import static io.vavr.API.Match;
1719
import static io.vavr.Predicates.instanceOf;
1820

1921
import java.io.FileNotFoundException;
2022
import java.util.ArrayList;
2123
import java.util.Collection;
24+
import java.util.List;
2225
import java.util.Optional;
2326

2427
import org.apache.jena.query.ARQ;
@@ -46,6 +49,8 @@
4649
import io.openmanufacturing.sds.aspectmodel.validation.report.ValidationError;
4750
import io.openmanufacturing.sds.aspectmodel.validation.report.ValidationReport;
4851
import io.openmanufacturing.sds.aspectmodel.validation.report.ValidationReportBuilder;
52+
import io.openmanufacturing.sds.metamodel.Aspect;
53+
import io.openmanufacturing.sds.metamodel.loader.AspectModelLoader;
4954
import io.vavr.control.Try;
5055

5156
/**
@@ -114,31 +119,55 @@ public ValidationReport validate( final Try<VersionedModel> versionedModel ) {
114119
final Model dataModel = model.getModel();
115120

116121
final Try<KnownVersion> metaModelVersion = KnownVersion
117-
.fromVersionString( model.getVersion().toString() ).map( Try::success )
122+
.fromVersionString( model.getVersion().toString() )
123+
.map( Try::success )
118124
.orElse( Try.failure( new UnsupportedVersionException( model.getVersion() ) ) );
119125

120126
return metaModelVersion
121127
.flatMap( aspectMetaModelResourceResolver::loadShapesModel ).map( shapesModel -> {
122128
final Resource report = ValidationUtil.validateModel( dataModel, shapesModel, true );
123129

124130
if ( report.getProperty( SH.conforms ).getObject().asLiteral().getBoolean() ) {
131+
// The SHACL validation succeeded. But to catch false positives, also try to load the model
132+
final Try<Aspect> aspects = AspectModelLoader.fromVersionedModel( model );
133+
if ( aspects.isFailure() ) {
134+
return new ValidationReportBuilder()
135+
.withValidationErrors( List.of( new ValidationError.Processing(
136+
"Validation succeeded, but an error was found while processing the model. "
137+
+ "This indicates an error in the model validation; please consider reporting this issue including the model "
138+
+ "at https://github.com/OpenManufacturingPlatform/sds-bamm-aspect-meta-model/issues -- "
139+
+ buildCauseMessage( aspects.getCause() ) ) ) )
140+
.buildInvalidReport();
141+
}
125142
return new ValidationReportBuilder().buildValidReport();
126143
}
127144

128-
return new ValidationReportBuilder().withValidationErrors( buildSemanticValidationErrors(
129-
report ) ).buildInvalidReport();
145+
return new ValidationReportBuilder()
146+
.withValidationErrors( buildSemanticValidationErrors( report ) )
147+
.buildInvalidReport();
130148
} );
131149
} ).recover( failure -> Match( failure ).of(
132150
riotExceptionHandler, invalidVersionExceptionHandler, unsupportedVersionExceptionHandler,
133151
modelResolutionExceptionHandler )
134152
).get();
135153
}
136154

155+
private String buildCauseMessage( final Throwable throwable ) {
156+
final StringBuilder builder = new StringBuilder();
157+
Throwable t = throwable;
158+
while ( t != null ) {
159+
builder.append( t.getMessage() );
160+
builder.append( ": " );
161+
t = t.getCause();
162+
}
163+
return builder.toString();
164+
}
165+
137166
private String getValidationResultField( final Resource validationResultResource, final Property property ) {
138167
return Optional.ofNullable( validationResultResource.getProperty( property ) )
139-
.map( Statement::getObject )
140-
.map( RDFNode::toString )
141-
.orElse( "" );
168+
.map( Statement::getObject )
169+
.map( RDFNode::toString )
170+
.orElse( "" );
142171
}
143172

144173
private Collection<ValidationError.Semantic> buildSemanticValidationErrors( final Resource report ) {
@@ -155,4 +184,8 @@ private Collection<ValidationError.Semantic> buildSemanticValidationErrors( fina
155184
}
156185
return semanticValidationErrors;
157186
}
187+
188+
private Collection<ValidationError.Processing> buildLoadingFailureError( final String errorMessage ) {
189+
return List.of( new ValidationError.Processing( errorMessage ) );
190+
}
158191
}

core/sds-aspect-model-validator/src/test/java/io/openmanufacturing/sds/aspectmodel/validation/services/AspectModelValidatorTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,25 @@ public void testValidAspect( final KnownVersion metaModelVersion ) {
6060
assertThat( result.getValidationErrors() ).hasSize( 0 );
6161
}
6262

63+
/**
64+
* Test for a model that passes validation via BAMM's SHACL shapes but is actually invalid and can not be loaded using
65+
* {@link io.openmanufacturing.sds.metamodel.loader.AspectModelLoader#fromVersionedModel(VersionedModel)}.
66+
* This method and the corresponding test model should be removed once
67+
* <a href="https://github.com/OpenManufacturingPlatform/sds-bamm-aspect-meta-model/issues/173">BAMM-173</a> has been addressed
68+
* @param metaModelVersion the meta model version
69+
*/
70+
@ParameterizedTest
71+
@MethodSource( value = "versionsStartingWith2_0_0" )
72+
public void testFalsePositiveValidation( final KnownVersion metaModelVersion ) {
73+
final TestModel testModel = InvalidTestAspect.ASPECT_WITH_FALSE_POSITIVE_VALIDATION;
74+
final Try<VersionedModel> aspectModel = TestResources.getModel( testModel, metaModelVersion );
75+
final ValidationReport result = service.validate( aspectModel );
76+
77+
System.out.println( result.getValidationErrors().iterator().next() );
78+
assertThat( result.conforms() ).isFalse();
79+
assertThat( result.getValidationErrors().iterator().next() ).isOfAnyClassIn( ValidationError.Processing.class );
80+
}
81+
6382
@ParameterizedTest
6483
@EnumSource( value = TestAspect.class, mode = EnumSource.Mode.EXCLUDE, names = {
6584
"ASPECT_WITH_CONSTRAINTS",

core/sds-test-aspect-models/src/main/java/io/openmanufacturing/sds/test/InvalidTestAspect.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Copyright (c) 2021 Robert Bosch Manufacturing Solutions GmbH
33
*
44
* See the AUTHORS file(s) distributed with this work for additional
5-
* information regarding authorship.
5+
* information regarding authorship.
66
*
77
* This Source Code Form is subject to the terms of the Mozilla Public
88
* License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -19,8 +19,9 @@ public enum InvalidTestAspect implements TestModel {
1919
ACTUALLY_JSON,
2020
ASPECT_MISSING_NAME_AND_PROPERTIES,
2121
ASPECT_MISSING_PROPERTIES,
22-
ASPECT_WITH_RECURSIVE_PROPERTY,
22+
ASPECT_WITH_FALSE_POSITIVE_VALIDATION,
2323
ASPECT_WITH_INVALID_VERSION,
24+
ASPECT_WITH_RECURSIVE_PROPERTY,
2425
INVALID_SYNTAX,
2526
MISSING_ASPECT_DECLARATION;
2627

core/sds-test-aspect-models/src/main/java/io/openmanufacturing/sds/test/TestAspect.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ public enum TestAspect implements TestModel {
2121
ASPECT_WITHOUT_PROPERTIES_AND_OPERATIONS,
2222
ASPECT_WITHOUT_SEE_ATTRIBUTE,
2323
ASPECT_WITH_ABSTRACT_ENTITY,
24-
ASPECT_WITH_COLLECTION_WITH_ABSTRACT_ENTITY,
2524
ASPECT_WITH_ABSTRACT_SINGLE_ENTITY,
2625
ASPECT_WITH_ALL_BASE_ATTRIBUTES,
2726
ASPECT_WITH_BINARY,
@@ -38,6 +37,7 @@ public enum TestAspect implements TestModel {
3837
ASPECT_WITH_COLLECTION_AND_SIMPLE_ELEMENT_CHARACTERISTIC,
3938
ASPECT_WITH_COLLECTION_OF_SIMPLE_TYPE,
4039
ASPECT_WITH_COLLECTION_WITHOUT_SEE_ATTRIBUTE,
40+
ASPECT_WITH_COLLECTION_WITH_ABSTRACT_ENTITY,
4141
ASPECT_WITH_COLLECTION_WITH_ELEMENT_CHARACTERISTIC,
4242
ASPECT_WITH_COLLECTION_WITH_ELEMENT_CONSTRAINT,
4343
ASPECT_WITH_COLLECTION_WITH_MULTIPLE_SEE_ATTRIBUTES,
@@ -70,7 +70,6 @@ public enum TestAspect implements TestModel {
7070
ASPECT_WITH_ENGLISH_AND_GERMAN_DESCRIPTION,
7171
ASPECT_WITH_ENGLISH_DESCRIPTION,
7272
ASPECT_WITH_ENTITY,
73-
ASPECT_WITH_ENTITY_WITHOUT_PROPERTY,
7473
ASPECT_WITH_ENTITY_COLLECTION,
7574
ASPECT_WITH_ENTITY_ENUMERATION,
7675
ASPECT_WITH_ENTITY_ENUMERATION_AND_LANG_STRING,
@@ -82,14 +81,15 @@ public enum TestAspect implements TestModel {
8281
ASPECT_WITH_ENTITY_INSTANCE_WITH_SCALAR_LIST_PROPERTY,
8382
ASPECT_WITH_ENTITY_INSTANCE_WITH_SCALAR_PROPERTIES,
8483
ASPECT_WITH_ENTITY_LIST,
84+
ASPECT_WITH_ENTITY_WITHOUT_PROPERTY,
8585
ASPECT_WITH_ENTITY_WITH_MULTIPLE_PROPERTIES,
86-
ASPECT_WITH_ENUM_AND_OPTIONAL_ENUM_PROPERTIES,
8786
ASPECT_WITH_ENUMERATION,
8887
ASPECT_WITH_ENUMERATION_WITHOUT_SCALAR_VARIABLE,
8988
ASPECT_WITH_ENUMERATION_WITHOUT_SEE_ATTRIBUTE,
9089
ASPECT_WITH_ENUMERATION_WITH_MULTIPLE_SEE_ATTRIBUTES,
9190
ASPECT_WITH_ENUMERATION_WITH_SCALAR_VARIABLE,
9291
ASPECT_WITH_ENUMERATION_WITH_SEE_ATTRIBUTE,
92+
ASPECT_WITH_ENUM_AND_OPTIONAL_ENUM_PROPERTIES,
9393
ASPECT_WITH_ENUM_HAVING_NESTED_ENTITIES,
9494
ASPECT_WITH_ERROR_COLLECTION,
9595
ASPECT_WITH_EVENT,
@@ -104,11 +104,11 @@ public enum TestAspect implements TestModel {
104104
ASPECT_WITH_LANGUAGE_CONSTRAINT,
105105
ASPECT_WITH_LENGTH_CONSTRAINT,
106106
ASPECT_WITH_LIST,
107-
ASPECT_WITH_LIST_WITH_LENGTH_CONSTRAINT,
108107
ASPECT_WITH_LIST_AND_ADDITIONAL_PROPERTY,
109108
ASPECT_WITH_LIST_AND_ELEMENT_CHARACTERISTIC,
110109
ASPECT_WITH_LIST_AND_ELEMENT_CONSTRAINT,
111110
ASPECT_WITH_LIST_ENTITY_ENUMERATION,
111+
ASPECT_WITH_LIST_WITH_LENGTH_CONSTRAINT,
112112
ASPECT_WITH_MEASUREMENT,
113113
ASPECT_WITH_MEASUREMENT_WITH_UNIT,
114114
ASPECT_WITH_MULTIPLE_COLLECTIONS_OF_SIMPLE_TYPE,
@@ -132,19 +132,19 @@ public enum TestAspect implements TestModel {
132132
ASPECT_WITH_OPTIONAL_PROPERTIES_WITH_ENTITY,
133133
ASPECT_WITH_OPTIONAL_PROPERTY,
134134
ASPECT_WITH_OPTIONAL_PROPERTY_WITH_PAYLOAD_NAME,
135-
ASPECT_WITH_PROPERTY_WITH_PAYLOAD_NAME,
136135
ASPECT_WITH_PREFERRED_NAMES,
137136
ASPECT_WITH_PROPERTY,
138137
ASPECT_WITH_PROPERTY_WITH_ALL_BASE_ATTRIBUTES,
139138
ASPECT_WITH_PROPERTY_WITH_DESCRIPTIONS,
139+
ASPECT_WITH_PROPERTY_WITH_PAYLOAD_NAME,
140140
ASPECT_WITH_PROPERTY_WITH_PREFERRED_NAMES,
141141
ASPECT_WITH_PROPERTY_WITH_SEE,
142142
ASPECT_WITH_QUANTIFIABLE_AND_UNIT,
143143
ASPECT_WITH_QUANTIFIABLE_WITHOUT_UNIT,
144144
ASPECT_WITH_QUANTIFIABLE_WITH_UNIT,
145145
ASPECT_WITH_RANGE_CONSTRAINT,
146-
ASPECT_WITH_RANGE_CONSTRAINT_ON_CONSTRAINED_NUMERIC_TYPE,
147146
ASPECT_WITH_RANGE_CONSTRAINT_INCL_BOUND_DEFINITION_PROPERTIES,
147+
ASPECT_WITH_RANGE_CONSTRAINT_ON_CONSTRAINED_NUMERIC_TYPE,
148148
ASPECT_WITH_RANGE_CONSTRAINT_WITHOUT_MIN_MAX_DOUBLE_VALUE,
149149
ASPECT_WITH_RANGE_CONSTRAINT_WITHOUT_MIN_MAX_INTEGER_VALUE,
150150
ASPECT_WITH_RANGE_CONSTRAINT_WITH_BOUND_DEFINITION_ATTRIBUTES,
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Copyright (c) 2021 Robert Bosch Manufacturing Solutions GmbH
2+
#
3+
# See the AUTHORS file(s) distributed with this work for additional
4+
# information regarding authorship.
5+
#
6+
# This Source Code Form is subject to the terms of the Mozilla Public
7+
# License, v. 2.0. If a copy of the MPL was not distributed with this
8+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
9+
#
10+
# SPDX-License-Identifier: MPL-2.0
11+
12+
# This model reproduces the problem reported in
13+
# https://github.com/OpenManufacturingPlatform/sds-sdk/issues/139
14+
# and
15+
# https://github.com/OpenManufacturingPlatform/sds-sdk/issues/198
16+
17+
@prefix : <urn:bamm:io.openmanufacturing.test:1.0.0#> .
18+
@prefix bamm: <urn:bamm:io.openmanufacturing:meta-model:2.0.0#> .
19+
@prefix bamm-c: <urn:bamm:io.openmanufacturing:characteristic:2.0.0#> .
20+
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
21+
@prefix unit: <urn:bamm:io.openmanufacturing:unit:2.0.0#> .
22+
23+
:AspectWithFalsePositiveValidation a bamm:Aspect ;
24+
bamm:preferredName "Test Aspect"@en ;
25+
bamm:description "This is a test description"@en ;
26+
bamm:properties ( :testProperty ) ;
27+
bamm:operations ( ) .
28+
29+
:testProperty a bamm:Property ;
30+
bamm:characteristic [
31+
a bamm-c:SingleEntity ;
32+
bamm:dataType :Quantity ;
33+
] ;
34+
bamm:exampleValue "invalid"^^:Quantity .
35+
36+
:Quantity a bamm:Entity ;
37+
bamm:properties ( ) .

0 commit comments

Comments
 (0)