Skip to content

Commit cd3f2bf

Browse files
committed
Incorporate new error reporting .
1 parent b3d5b5c commit cd3f2bf

File tree

5 files changed

+57
-20
lines changed

5 files changed

+57
-20
lines changed

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

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@
1313

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

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

2119
import java.io.FileNotFoundException;
@@ -165,8 +163,14 @@ public List<Violation> validateModel( final Try<VersionedModel> versionedModel )
165163
.flatMap( element -> shaclValidator.validateElement( element ).stream() )
166164
.toList();
167165

168-
// The SHACL validation succeeded. But to catch false positives, also try to load the model
169166
if ( result.isEmpty() ) {
167+
// The SHACL validation succeeded, check for cycles in the model.
168+
final List<Violation> cycleDetectionReport = new ModelCycleDetector().validateModel( model );
169+
if ( !cycleDetectionReport.isEmpty() ) {
170+
return cycleDetectionReport;
171+
}
172+
173+
// To catch false positives, also try to load the model
170174
final Try<Aspect> aspects = AspectModelLoader.fromVersionedModel( model );
171175
if ( aspects.isFailure() && !(aspects.getCause() instanceof InvalidRootElementCountException) ) {
172176
return List.of( new ProcessingViolation(
@@ -216,7 +220,7 @@ public ValidationReport validate( final Try<VersionedModel> versionedModel ) {
216220
final Resource report = ValidationUtil.validateModel( dataModel, shapesModel, false );
217221

218222
if ( report.getProperty( SH.conforms ).getObject().asLiteral().getBoolean() ) {
219-
// The SHACL validation succeeded. But to catch false positives, also try to load the model
223+
// To catch false positives, also try to load the model.
220224
final Try<Aspect> aspects = AspectModelLoader.fromVersionedModel( model );
221225
if ( aspects.isFailure() && !(aspects.getCause() instanceof InvalidRootElementCountException) ) {
222226
return new ValidationReportBuilder()

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

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,8 @@
3939

4040
import io.openmanufacturing.sds.aspectmetamodel.KnownVersion;
4141
import io.openmanufacturing.sds.aspectmodel.resolver.services.VersionedModel;
42-
import io.openmanufacturing.sds.aspectmodel.validation.report.ValidationError;
43-
import io.openmanufacturing.sds.aspectmodel.validation.report.ValidationReport;
44-
import io.openmanufacturing.sds.aspectmodel.validation.report.ValidationReportBuilder;
42+
import io.openmanufacturing.sds.aspectmodel.shacl.violation.ProcessingViolation;
43+
import io.openmanufacturing.sds.aspectmodel.shacl.violation.Violation;
4544
import io.openmanufacturing.sds.aspectmodel.vocabulary.BAMM;
4645

4746
/**
@@ -72,12 +71,12 @@ public class ModelCycleDetector {
7271
private BAMM bamm;
7372
private Model model;
7473

75-
List<ValidationError.Semantic> cycleReports = new ArrayList<>();
74+
List<Violation> cycleDetectionReport = new ArrayList<>();
7675

77-
public ValidationReport validateModel( final VersionedModel versionedModel ) {
76+
public List<Violation> validateModel( final VersionedModel versionedModel ) {
7877
discovered.clear();
7978
finished.clear();
80-
cycleReports.clear();
79+
cycleDetectionReport.clear();
8180

8281
model = versionedModel.getModel();
8382
final Optional<KnownVersion> metaModelVersion = KnownVersion.fromVersionString( versionedModel.getVersion().toString() );
@@ -98,10 +97,8 @@ public ValidationReport validateModel( final VersionedModel versionedModel ) {
9897
}
9998
}
10099
}
101-
102-
return cycleReports.isEmpty() ?
103-
new ValidationReport.ValidReport() :
104-
new ValidationReportBuilder().withValidationErrors( cycleReports ).buildInvalidReport();
100+
101+
return cycleDetectionReport;
105102
}
106103

107104
private void depthFirstTraversal( final Resource currentProperty, final BiConsumer<String, Set<String>> cycleHandler ) {
@@ -188,7 +185,7 @@ private void reportCycle( final String backEdgePropertyName, final Set<String> c
188185
}
189186

190187
private void reportCycle( final String cyclePath ) {
191-
cycleReports.add( new ValidationError.Semantic( String.format( ERR_CYCLE_DETECTED, cyclePath ), "", "", "ERROR", "" ) );
188+
cycleDetectionReport.add( new ProcessingViolation( String.format( ERR_CYCLE_DETECTED, cyclePath ), null ) );
192189
}
193190

194191
private void initializeQuery( final KnownVersion metaModelVersion ) {

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import static org.assertj.core.api.Assertions.assertThat;
1717

18+
import java.util.ArrayList;
1819
import java.util.Arrays;
1920
import java.util.List;
2021
import java.util.Map;
@@ -260,4 +261,36 @@ public void testValidationWithMultipleAspects( final KnownVersion metaModelVersi
260261
final List<Violation> violations = service.get( metaModelVersion ).validateModel( model );
261262
assertThat( violations ).isEmpty();
262263
}
264+
265+
@ParameterizedTest
266+
@MethodSource( value = "allVersions" )
267+
void testCycleDetection( final KnownVersion metaModelVersion ) {
268+
final Try<VersionedModel> versionedModel = TestResources.getModel( TestAspect.MODEL_WITH_CYCLES, metaModelVersion );
269+
final List<Violation> report = service.get( metaModelVersion ).validateModel( versionedModel );
270+
report.forEach( System.out::println );
271+
assertThat( report.size() ).isEqualTo( 6 );
272+
assertThat( report ).containsAll( cycles(
273+
":a -> :b -> :a",
274+
":e -> :f -> :g -> :e",
275+
":h -> :h",
276+
":h -> :i -> :h",
277+
":l -> :l",
278+
// TimeSeries are handled differently between v1 and v2 meta models.
279+
metaModelVersion.isOlderThan( KnownVersion.BAMM_2_0_0 ) ? ":n -> :refinedValue -> :n" : ":n -> :NTimeSeriesEntity|bamm-e:value -> :n" ) );
280+
}
281+
282+
@ParameterizedTest
283+
@MethodSource( value = "allVersions" )
284+
void testCycleDetectionWithCycleBreakers( final KnownVersion metaModelVersion ) {
285+
final Try<VersionedModel> versionedModel = TestResources.getModel( TestAspect.MODEL_WITH_BROKEN_CYCLES, metaModelVersion );
286+
final List<Violation> report = service.get( metaModelVersion ).validateModel( versionedModel );
287+
report.forEach( System.out::println );
288+
assertThat( report.isEmpty() ).isTrue();
289+
}
290+
291+
private List<Violation> cycles( final String... cycles ) {
292+
final List<Violation> errors = new ArrayList<>();
293+
Arrays.stream( cycles ).forEach( cycle -> errors.add( new ProcessingViolation( String.format( ModelCycleDetector.ERR_CYCLE_DETECTED, cycle ), null ) ) );
294+
return errors;
295+
}
263296
}

core/sds-test-aspect-models/src/main/resources/valid/bamm_1_0_0/io.openmanufacturing.test/1.0.0/ModelWithBrokenCycles.ttl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
1616

1717
:ModelWithBrokenCycles a bamm:Aspect ;
18-
bamm:name "" ;
18+
bamm:name "ModelWithBrokenCycles" ;
1919
bamm:properties ( :a :e :h ) ;
2020
bamm:operations ( ) .
2121

core/sds-test-aspect-models/src/main/resources/valid/bamm_1_0_0/io.openmanufacturing.test/1.0.0/ModelWithCycles.ttl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,10 +160,13 @@
160160
bamm:name "NTimeSeries" ;
161161
bamm:dataType :NTimeSeriesEntity .
162162

163-
:NTimeSeriesEntity a bamm:Entity ;
163+
:NTimeSeriesEntity bamm:refines bamm-e:TimeSeriesEntity ;
164164
bamm:name "NTimeSeriesEntity" ;
165-
bamm:extends bamm-e:TimeSeriesEntity ;
166-
bamm:properties ( [ bamm:extends bamm-e:value ; bamm:characteristic :oCharacteristic ] ) .
165+
bamm:properties ( :refinedValue ) .
166+
167+
:refinedValue bamm:refines bamm-e:value ;
168+
bamm:name "refinedValue" ;
169+
bamm:characteristic :oCharacteristic .
167170

168171
:oCharacteristic a bamm:Characteristic;
169172
bamm:name "mCharacteristic" ;

0 commit comments

Comments
 (0)