diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-lineage/legend-engine-xt-analytics-lineage-pure/src/main/resources/META-INF/services/org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepositoryProvider b/legend-engine-xts-analytics/legend-engine-xts-analytics-lineage/legend-engine-xt-analytics-lineage-pure/src/main/resources/META-INF/services/org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepositoryProvider
index 91ac69dcfc0..8ed7aa74ab8 100644
--- a/legend-engine-xts-analytics/legend-engine-xts-analytics-lineage/legend-engine-xt-analytics-lineage-pure/src/main/resources/META-INF/services/org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepositoryProvider
+++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-lineage/legend-engine-xt-analytics-lineage-pure/src/main/resources/META-INF/services/org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepositoryProvider
@@ -14,52 +14,4 @@
# limitations under the License.
#
-#
-# Copyright 2022 Goldman Sachs
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-#
-# Copyright 2022 Goldman Sachs
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-#
-# Copyright 2022 Goldman Sachs
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
org.finos.legend.pure.code.core.CoreExternalLineageAnalysisCodeRepositoryProvider
\ No newline at end of file
diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-api/pom.xml b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-api/pom.xml
index 994a4f3d20b..5ed696a580a 100644
--- a/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-api/pom.xml
+++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-api/pom.xml
@@ -5,7 +5,7 @@
legend-engine
org.finos.legend.engine
- 4.37.4-SNAPSHOT
+ 4.39.1-SNAPSHOT
../../../pom.xml
4.0.0
@@ -17,36 +17,69 @@
swagger-annotations
- io.swagger
- swagger-annotations
+ com.fasterxml.jackson.core
+ jackson-annotations
com.fasterxml.jackson.core
jackson-databind
+
+ org.pac4j.jax-rs
+ core
+
+
+ junit
+ junit
+
+
+ org.pac4j
+ pac4j-core
+ compile
+
+
+ org.eclipse.collections
+ eclipse-collections
+
+
+ org.eclipse.collections
+ eclipse-collections-api
+
+
+ javax.ws.rs
+ javax.ws.rs-api
+
+
+
org.finos.legend.pure
- legend-pure-runtime-java-engine-interpreted
+ legend-pure-runtime-java-engine-compiled
org.finos.legend.pure
legend-pure-m3-core
+
+
- javax.ws.rs
- javax.ws.rs-api
+ org.finos.legend.engine
+ legend-engine-language-pure-modelManager
- junit
- junit
+ org.finos.legend.engine
+ legend-engine-shared-core
org.finos.legend.engine
- legend-engine-language-pure-compiler
+ legend-engine-language-pure-grammar
org.finos.legend.engine
- legend-engine-language-pure-modelManager
+ legend-engine-xt-analytics-quality-pure
+
+
+ org.finos.legend.engine
+ legend-engine-language-pure-compiler
org.finos.legend.engine
@@ -56,19 +89,38 @@
org.finos.legend.engine
legend-engine-protocol-pure
+
+
org.finos.legend.engine
- legend-engine-shared-core
+ legend-engine-xt-data-space-grammar
+ test
org.finos.legend.engine
- legend-engine-xt-data-space-compiler
+ legend-engine-xt-data-space-pure-metamodel
+ test
org.finos.legend.engine
legend-engine-xt-data-space-protocol
test
+
+ org.finos.legend.engine
+ legend-engine-pure-platform-java
+ test
+
+
+ org.finos.legend.engine
+ legend-engine-xt-data-space-compiler
+ test
+
+
+ org.finos.legend.engine
+ legend-engine-pure-runtime-compiler
+ test
+
org.glassfish.jersey.core
jersey-common
diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-api/src/main/java/org/finos/legend/engine/api/analytics/DataspaceQualityAnalytics.java b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-api/src/main/java/org/finos/legend/engine/api/analytics/DataspaceQualityAnalytics.java
index 14a34932886..71982d3ff45 100644
--- a/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-api/src/main/java/org/finos/legend/engine/api/analytics/DataspaceQualityAnalytics.java
+++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-api/src/main/java/org/finos/legend/engine/api/analytics/DataspaceQualityAnalytics.java
@@ -14,44 +14,33 @@
package org.finos.legend.engine.api.analytics;
-import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
-import org.eclipse.collections.api.RichIterable;
+import io.swagger.annotations.ApiParam;
+import org.eclipse.collections.api.list.MutableList;
import org.finos.legend.engine.language.pure.compiler.toPureGraph.PureModel;
import org.finos.legend.engine.language.pure.modelManager.ModelManager;
import org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContextData;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.PackageableElement;
-import org.finos.legend.engine.shared.core.ObjectMapperFactory;
-import org.finos.legend.pure.generated.Root_meta_analytics_quality_model_CheckResult;
-import org.finos.legend.pure.generated.Root_meta_pure_functions_collection_List_Impl;
-import org.finos.legend.pure.generated.core_analytics_quality_associationChecks;
-import org.finos.legend.pure.generated.core_analytics_quality_classChecks;
-import org.finos.legend.pure.generated.core_analytics_quality_enumerationChecks;
-import org.finos.legend.pure.generated.core_analytics_quality_functionChecks;
-import org.finos.legend.pure.generated.core_analytics_quality_propertyChecks;
-import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.ConcreteFunctionDefinition;
-import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.property.Property;
-import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.Class;
-import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.Enum;
-import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.Enumeration;
-import org.finos.legend.pure.runtime.java.compiled.execution.CompiledExecutionSupport;
+import org.finos.legend.engine.shared.core.kerberos.ProfileManagerHelper;
+import org.finos.legend.engine.shared.core.operational.http.InflateInterceptor;
+import org.pac4j.core.profile.CommonProfile;
+import org.pac4j.core.profile.ProfileManager;
+import org.pac4j.jax.rs.annotations.Pac4JProfileManager;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-import java.util.ArrayList;
import java.util.List;
-import java.util.stream.Collectors;
@Api(tags = "Analytics - Quality")
@Path("pure/v1/analytics/quality")
public class DataspaceQualityAnalytics
{
private final ModelManager modelManager;
- private List messages;
public DataspaceQualityAnalytics(ModelManager modelManager)
{
@@ -59,184 +48,17 @@ public DataspaceQualityAnalytics(ModelManager modelManager)
}
@POST
- @Path("check")
- @ApiOperation("Checks the quality of provided Data space")
- @Consumes(MediaType.APPLICATION_JSON)
- public Response checkDataSpaceConstraints(PureModelContextData pureModelContextData)
+ @Path("checkDataspaceQuality")
+ @ApiOperation("Checks the quality of provided Data space using PMCD")
+ @Consumes({MediaType.APPLICATION_JSON, InflateInterceptor.APPLICATION_ZLIB})
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response checkDataSpaceConstraints(DataspaceQualityCheckInput input, @ApiParam(hidden = true)
+ @Pac4JProfileManager ProfileManager pm)
{
- messages = new ArrayList<>();
- PureModel pureModel = this.modelManager.loadModel(pureModelContextData, null, null, null);
-
- List classes = pureModelContextData.getElements().stream().filter(e -> e instanceof org.finos.legend.engine.protocol.pure.v1.model.packageableElement.domain.Class).collect(Collectors.toList());
- List associations = pureModelContextData.getElements().stream().filter(e -> e instanceof org.finos.legend.engine.protocol.pure.v1.model.packageableElement.domain.Association).collect(Collectors.toList());
- List enumerations = pureModelContextData.getElements().stream().filter(e -> e instanceof org.finos.legend.engine.protocol.pure.v1.model.packageableElement.domain.Enumeration).collect(Collectors.toList());
- List functions = pureModelContextData.getElements().stream().filter(e -> e instanceof org.finos.legend.engine.protocol.pure.v1.model.packageableElement.domain.Function).collect(Collectors.toList());
-
- CompiledExecutionSupport es = pureModel.getExecutionSupport();
-
- if (classChecks(classes, pureModel, es) && associationChecks(associations, pureModel, es) && enumerationChecks(enumerations, pureModel, es) && functionChecks(functions, pureModel, es))
- {
- return Response.ok().build();
- }
- else
- {
- return Response.status(400).entity("Dataspace does not match the constraints - " + messages).build();
- }
- }
-
- private boolean classChecks(List classes, PureModel pureModel, CompiledExecutionSupport es)
- {
- List classCheckResults = new ArrayList<>();
- boolean allPropertiesInClassAreValid = false;
- for (PackageableElement pe : classes)
- {
- Class> _class = pureModel.getContext().resolveClass(pe.getPath(), pe.sourceInformation);
- allPropertiesInClassAreValid = propertyChecks(_class, es);
- //create rules
- core_analytics_quality_classChecks.Root_meta_analytics_quality_model_domain_classRules__Rule_MANY_(es);
-
- //run checks
- RichIterable extends Root_meta_analytics_quality_model_CheckResult> upperCase_class_1__checkResult_many_ = core_analytics_quality_classChecks.Root_meta_analytics_quality_model_domain_classNameShouldStartWithUpperCase_Class_1__CheckResult_MANY_(_class, es);
- RichIterable extends Root_meta_analytics_quality_model_CheckResult> entityNameShouldNotStartWithPackageName_class_1__checkResult_many_ = core_analytics_quality_classChecks.Root_meta_analytics_quality_model_domain_entityNameShouldNotStartWithPackageName_Class_1__CheckResult_MANY_(_class, es);
- RichIterable extends Root_meta_analytics_quality_model_CheckResult> classHasAtLeastOneMandatoryProperty_class_1__checkResult_many_ = core_analytics_quality_classChecks.Root_meta_analytics_quality_model_domain_classHasAtLeastOneMandatoryProperty_Class_1__CheckResult_MANY_(_class, es);
- RichIterable extends Root_meta_analytics_quality_model_CheckResult> allEntitiesAndPropertiesShouldHaveALongDescription_class_1__checkResult_many_ = core_analytics_quality_classChecks.Root_meta_analytics_quality_model_domain_allEntitiesAndPropertiesShouldHaveALongDescription_Class_1__CheckResult_MANY_(_class, es);
-
- upperCase_class_1__checkResult_many_.forEach(classCheckResults::add);
- entityNameShouldNotStartWithPackageName_class_1__checkResult_many_.forEach(classCheckResults::add);
- classHasAtLeastOneMandatoryProperty_class_1__checkResult_many_.forEach(classCheckResults::add);
- allEntitiesAndPropertiesShouldHaveALongDescription_class_1__checkResult_many_.forEach(classCheckResults::add);
- }
-
- return checkOverallResults(classCheckResults) && allPropertiesInClassAreValid;
- }
-
- private boolean associationChecks(List associations, PureModel pureModel, CompiledExecutionSupport es)
- {
- List associationCheckResults = new ArrayList<>();
- for (PackageableElement pe : associations)
- {
- org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.relationship.Association _association = pureModel.getContext().resolveAssociation(pe.getPath(), pe.sourceInformation);
-
- //create rules
- core_analytics_quality_associationChecks.Root_meta_analytics_quality_model_domain_associationRules__Rule_MANY_(es);
-
- //run checks
- RichIterable extends Root_meta_analytics_quality_model_CheckResult> associationNameShouldStartWithUpperCase_association_1__checkResult_many_ = core_analytics_quality_associationChecks.Root_meta_analytics_quality_model_domain_associationNameShouldStartWithUpperCase_Association_1__CheckResult_MANY_(_association, es);
- associationNameShouldStartWithUpperCase_association_1__checkResult_many_.forEach(associationCheckResults::add);
- }
- return checkOverallResults(associationCheckResults);
- }
-
- private boolean enumerationChecks(List enumerations, PureModel pureModel, CompiledExecutionSupport es)
- {
- List enumerationCheckResults = new ArrayList<>();
- for (PackageableElement pe : enumerations)
- {
- Enumeration _enumeration = pureModel.getContext().resolveEnumeration(pe.getPath(), pe.sourceInformation);
-
- //create rules
- core_analytics_quality_enumerationChecks.Root_meta_analytics_quality_model_domain_enumerationRules__Rule_MANY_(es);
-
- //run checks
- RichIterable extends Root_meta_analytics_quality_model_CheckResult> enumerationName_enumeration_1__checkResult_many_ = core_analytics_quality_enumerationChecks.Root_meta_analytics_quality_model_domain_enumerationName_Enumeration_1__CheckResult_MANY_(_enumeration, es);
- RichIterable extends Root_meta_analytics_quality_model_CheckResult> enumerationValue_enumeration_1__checkResult_many_ = core_analytics_quality_enumerationChecks.Root_meta_analytics_quality_model_domain_enumerationValue_Enumeration_1__CheckResult_MANY_(_enumeration, es);
-
- enumerationName_enumeration_1__checkResult_many_.forEach(enumerationCheckResults::add);
- enumerationValue_enumeration_1__checkResult_many_.forEach(enumerationCheckResults::add);
- }
- return checkOverallResults(enumerationCheckResults);
- }
-
- private boolean functionChecks(List functions, PureModel pureModel, CompiledExecutionSupport es)
- {
- List functionCheckResults = new ArrayList<>();
-
- //create rules
- core_analytics_quality_functionChecks.Root_meta_analytics_quality_model_domain_functionRules__Rule_MANY_(es);
-
- org.finos.legend.pure.m3.coreinstance.meta.pure.functions.collection.List> functionDefinitions = resolveConcreteFunctionDefinitions(functions, pureModel);
-
- //run checks
- RichIterable extends org.finos.legend.pure.m3.coreinstance.meta.pure.functions.collection.Pair extends org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.FunctionExpression, ? extends org.finos.legend.pure.generated.Root_meta_analytics_quality_model_CheckResult>> validEqualityComparisons_list_1__pair_many_ = core_analytics_quality_functionChecks.Root_meta_analytics_quality_model_domain_validEqualityComparisons_List_1__Pair_MANY_(functionDefinitions, es);
- RichIterable extends org.finos.legend.pure.m3.coreinstance.meta.pure.functions.collection.Pair extends org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.FunctionExpression, ? extends org.finos.legend.pure.generated.Root_meta_analytics_quality_model_CheckResult>> invalidContainsComparisons_list_1__pair_many_ = core_analytics_quality_functionChecks.Root_meta_analytics_quality_model_domain_invalidContainsComparisons_List_1__Pair_MANY_(functionDefinitions, es);
- RichIterable extends org.finos.legend.pure.m3.coreinstance.meta.pure.functions.collection.Pair extends org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.FunctionExpression, ? extends org.finos.legend.pure.generated.Root_meta_analytics_quality_model_CheckResult>> badInstanceOfChecks_list_1__pair_many_ = core_analytics_quality_functionChecks.Root_meta_analytics_quality_model_domain_badInstanceOfChecks_List_1__Pair_MANY_(functionDefinitions, es);
- RichIterable extends org.finos.legend.pure.m3.coreinstance.meta.pure.functions.collection.Pair extends org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.FunctionExpression, ? extends org.finos.legend.pure.generated.Root_meta_analytics_quality_model_CheckResult>> invalidMatchUsages_list_1__pair_many_ = core_analytics_quality_functionChecks.Root_meta_analytics_quality_model_domain_invalidMatchUsages_List_1__Pair_MANY_(functionDefinitions, es);
- RichIterable extends org.finos.legend.pure.m3.coreinstance.meta.pure.functions.collection.Pair extends org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.FunctionExpression, ? extends org.finos.legend.pure.generated.Root_meta_analytics_quality_model_CheckResult>> findUnnecessaryComparisonsToTrue_list_1__pair_many_ = core_analytics_quality_functionChecks.Root_meta_analytics_quality_model_domain_findUnnecessaryComparisonsToTrue_List_1__Pair_MANY_(functionDefinitions, es);
- RichIterable extends org.finos.legend.pure.m3.coreinstance.meta.pure.functions.collection.Pair extends org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.FunctionExpression, ? extends org.finos.legend.pure.generated.Root_meta_analytics_quality_model_CheckResult>> findInvalidCastBugs_list_1__pair_many_ = core_analytics_quality_functionChecks.Root_meta_analytics_quality_model_domain_findInvalidCastBugs_List_1__Pair_MANY_(functionDefinitions, es);
- RichIterable extends org.finos.legend.pure.m3.coreinstance.meta.pure.functions.collection.Pair extends org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.FunctionDefinition extends java.lang.Object>, ? extends org.finos.legend.pure.generated.Root_meta_analytics_quality_model_CheckResult>> findUnusedPrivateProtectedFunctionBugs_list_1__pair_many_ = core_analytics_quality_functionChecks.Root_meta_analytics_quality_model_domain_findUnusedPrivateProtectedFunctionBugs_List_1__Pair_MANY_(functionDefinitions, es);
- RichIterable extends org.finos.legend.pure.m3.coreinstance.meta.pure.functions.collection.Pair extends org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.FunctionExpression, ? extends org.finos.legend.pure.generated.Root_meta_analytics_quality_model_CheckResult>> findUnnecessaryIfBugs_list_1__pair_many_ = core_analytics_quality_functionChecks.Root_meta_analytics_quality_model_domain_findUnnecessaryIfBugs_List_1__Pair_MANY_(functionDefinitions, es);
- RichIterable extends org.finos.legend.pure.m3.coreinstance.meta.pure.functions.collection.Pair extends org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.FunctionExpression, ? extends org.finos.legend.pure.generated.Root_meta_analytics_quality_model_CheckResult>> findUnnecessaryIfBugs2_list_1__pair_many_ = core_analytics_quality_functionChecks.Root_meta_analytics_quality_model_domain_findUnnecessaryIfBugs2_List_1__Pair_MANY_(functionDefinitions, es);
- RichIterable extends org.finos.legend.pure.m3.coreinstance.meta.pure.functions.collection.Pair extends org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.FunctionExpression, ? extends org.finos.legend.pure.generated.Root_meta_analytics_quality_model_CheckResult>> findUnnecessaryCasts_list_1__pair_many_ = core_analytics_quality_functionChecks.Root_meta_analytics_quality_model_domain_findUnnecessaryCasts_List_1__Pair_MANY_(functionDefinitions, es);
- RichIterable extends org.finos.legend.pure.m3.coreinstance.meta.pure.functions.collection.Pair extends org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.FunctionDefinition extends java.lang.Object>, ? extends org.finos.legend.pure.generated.Root_meta_analytics_quality_model_CheckResult>> findUnnecessaryLetFunctionsCheck_list_1__pair_many_ = core_analytics_quality_functionChecks.Root_meta_analytics_quality_model_domain_findUnnecessaryLetFunctionsCheck_List_1__Pair_MANY_(functionDefinitions, es);
- RichIterable extends org.finos.legend.pure.m3.coreinstance.meta.pure.functions.collection.Pair extends org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.FunctionExpression, ? extends org.finos.legend.pure.generated.Root_meta_analytics_quality_model_CheckResult>> findPotentiallyExpensiveAssertions_list_1__pair_many_ = core_analytics_quality_functionChecks.Root_meta_analytics_quality_model_domain_findPotentiallyExpensiveAssertions_List_1__Pair_MANY_(functionDefinitions, es);
-
- validEqualityComparisons_list_1__pair_many_.forEach(each -> functionCheckResults.add(each._second()));
- invalidContainsComparisons_list_1__pair_many_.forEach(each -> functionCheckResults.add(each._second()));
- badInstanceOfChecks_list_1__pair_many_.forEach(each -> functionCheckResults.add(each._second()));
- invalidMatchUsages_list_1__pair_many_.forEach(each -> functionCheckResults.add(each._second()));
- findUnnecessaryComparisonsToTrue_list_1__pair_many_.forEach(each -> functionCheckResults.add(each._second()));
- findInvalidCastBugs_list_1__pair_many_.forEach(each -> functionCheckResults.add(each._second()));
- findUnusedPrivateProtectedFunctionBugs_list_1__pair_many_.forEach(each -> functionCheckResults.add(each._second()));
- findUnnecessaryIfBugs_list_1__pair_many_.forEach(each -> functionCheckResults.add(each._second()));
- findUnnecessaryIfBugs2_list_1__pair_many_.forEach(each -> functionCheckResults.add(each._second()));
- findUnnecessaryCasts_list_1__pair_many_.forEach(each -> functionCheckResults.add(each._second()));
- findUnnecessaryLetFunctionsCheck_list_1__pair_many_.forEach(each -> functionCheckResults.add(each._second()));
- findPotentiallyExpensiveAssertions_list_1__pair_many_.forEach(each -> functionCheckResults.add(each._second()));
-
- return checkOverallResults(functionCheckResults);
- }
-
- private boolean propertyChecks(Class> _class, CompiledExecutionSupport es)
- {
- ArrayList propertyCheckResults = new ArrayList<>();
- RichIterable extends Property, ?>> properties = _class._properties();
- for (Property, ?> property : properties)
- {
- //create rules
- core_analytics_quality_propertyChecks.Root_meta_analytics_quality_model_domain_propertyRules__Rule_MANY_(es);
-
- //run checks
- RichIterable extends Root_meta_analytics_quality_model_CheckResult> classPropertyShouldStartWithLowerLetter_abstractProperty_1__checkResult_many_ = core_analytics_quality_propertyChecks.Root_meta_analytics_quality_model_domain_classPropertyShouldStartWithLowerLetter_AbstractProperty_1__CheckResult_MANY_(property, es);
- RichIterable extends Root_meta_analytics_quality_model_CheckResult> classPropertyShouldNotStartWithClassName_abstractProperty_1__checkResult_many_ = core_analytics_quality_propertyChecks.Root_meta_analytics_quality_model_domain_classPropertyShouldNotStartWithClassName_AbstractProperty_1__CheckResult_MANY_(property, es);
- RichIterable extends Root_meta_analytics_quality_model_CheckResult> classBooleanPropertyShouldStartWithIsOrHasOrEndsWithFlag_abstractProperty_1__checkResult_many_ = core_analytics_quality_propertyChecks.Root_meta_analytics_quality_model_domain_classBooleanPropertyShouldStartWithIsOrHasOrEndsWithFlag_AbstractProperty_1__CheckResult_MANY_(property, es);
- RichIterable extends Root_meta_analytics_quality_model_CheckResult> classPropertyStartingWithIsOrHasShouldBeBoolean_abstractProperty_1__checkResult_many_ = core_analytics_quality_propertyChecks.Root_meta_analytics_quality_model_domain_classPropertyStartingWithIsOrHasShouldBeBoolean_AbstractProperty_1__CheckResult_MANY_(property, es);
- RichIterable extends Root_meta_analytics_quality_model_CheckResult> classPropertyEndingWithFlagShouldBeBoolean_abstractProperty_1__checkResult_many_ = core_analytics_quality_propertyChecks.Root_meta_analytics_quality_model_domain_classPropertyEndingWithFlagShouldBeBoolean_AbstractProperty_1__CheckResult_MANY_(property, es);
- RichIterable extends Root_meta_analytics_quality_model_CheckResult> classPropertyWithToManyMultiplicityAreNamedCorrectly_abstractProperty_1__checkResult_many_ = core_analytics_quality_propertyChecks.Root_meta_analytics_quality_model_domain_classPropertyWithToManyMultiplicityAreNamedCorrectly_AbstractProperty_1__CheckResult_MANY_(property, es);
- RichIterable extends Root_meta_analytics_quality_model_CheckResult> classPropertyWithToOneMultiplicityAreNamedCorrectly_abstractProperty_1__checkResult_many_ = core_analytics_quality_propertyChecks.Root_meta_analytics_quality_model_domain_classPropertyWithToOneMultiplicityAreNamedCorrectly_AbstractProperty_1__CheckResult_MANY_(property, es);
- RichIterable extends Root_meta_analytics_quality_model_CheckResult> classPropertyIntegersWithToOneMultiplicityAreNamedCorrectly_abstractProperty_1__checkResult_many_ = core_analytics_quality_propertyChecks.Root_meta_analytics_quality_model_domain_classPropertyIntegersWithToOneMultiplicityAreNamedCorrectly_AbstractProperty_1__CheckResult_MANY_(property, es);
-
- classPropertyShouldStartWithLowerLetter_abstractProperty_1__checkResult_many_.forEach(propertyCheckResults::add);
- classPropertyShouldNotStartWithClassName_abstractProperty_1__checkResult_many_.forEach(propertyCheckResults::add);
- classBooleanPropertyShouldStartWithIsOrHasOrEndsWithFlag_abstractProperty_1__checkResult_many_.forEach(propertyCheckResults::add);
- classPropertyStartingWithIsOrHasShouldBeBoolean_abstractProperty_1__checkResult_many_.forEach(propertyCheckResults::add);
- classPropertyEndingWithFlagShouldBeBoolean_abstractProperty_1__checkResult_many_.forEach(propertyCheckResults::add);
- classPropertyWithToManyMultiplicityAreNamedCorrectly_abstractProperty_1__checkResult_many_.forEach(propertyCheckResults::add);
- classPropertyWithToOneMultiplicityAreNamedCorrectly_abstractProperty_1__checkResult_many_.forEach(propertyCheckResults::add);
- classPropertyIntegersWithToOneMultiplicityAreNamedCorrectly_abstractProperty_1__checkResult_many_.forEach(propertyCheckResults::add);
- }
- return checkOverallResults(propertyCheckResults);
- }
-
- private boolean checkOverallResults(List results)
- {
- for (Root_meta_analytics_quality_model_CheckResult rs : results)
- {
- if (!rs._isValid())
- {
- messages.add(rs._message());
- }
- }
- return messages.isEmpty();
- }
-
- private org.finos.legend.pure.m3.coreinstance.meta.pure.functions.collection.List> resolveConcreteFunctionDefinitions(List functions, PureModel pureModel)
- {
-
- org.finos.legend.pure.m3.coreinstance.meta.pure.functions.collection.List> cfd = new Root_meta_pure_functions_collection_List_Impl<>(pureModel.getRoot()._name());
- for (PackageableElement pe : functions)
- {
- cfd._valuesAdd(pureModel.getConcreteFunctionDefinition(pe.getPath(), pe.sourceInformation));
- }
- return cfd;
+ MutableList profiles = ProfileManagerHelper.extractProfiles(pm);
+ PureModelContextData pureModelContextData = this.modelManager.loadData(input.model, input.clientVersion, profiles);
+ PureModel pureModel = this.modelManager.loadModel(pureModelContextData, input.clientVersion, profiles, null);
+ List allElements = pureModelContextData.getElements();
+ return DataspaceQualityAnalyticsHelper.getResponse(pureModel, allElements);
}
}
diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-api/src/main/java/org/finos/legend/engine/api/analytics/DataspaceQualityAnalyticsHelper.java b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-api/src/main/java/org/finos/legend/engine/api/analytics/DataspaceQualityAnalyticsHelper.java
new file mode 100644
index 00000000000..eaa22c885a6
--- /dev/null
+++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-api/src/main/java/org/finos/legend/engine/api/analytics/DataspaceQualityAnalyticsHelper.java
@@ -0,0 +1,71 @@
+// Copyright 2022 Goldman Sachs
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.finos.legend.engine.api.analytics;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.eclipse.collections.api.RichIterable;
+import org.eclipse.collections.impl.list.mutable.FastList;
+import org.finos.legend.engine.language.pure.compiler.toPureGraph.PureModel;
+import org.finos.legend.engine.protocol.pure.v1.PureProtocolObjectMapperFactory;
+import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.PackageableElement;
+import org.finos.legend.pure.generated.Root_meta_analytics_quality_model_ViolationInstance;
+import org.finos.legend.pure.generated.core_analytics_quality_checksEngine;
+import org.finos.legend.pure.runtime.java.compiled.execution.CompiledExecutionSupport;
+
+import javax.ws.rs.core.Response;
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class DataspaceQualityAnalyticsHelper
+{
+ public static ObjectMapper getNewObjectMapper()
+ {
+ return PureProtocolObjectMapperFactory.getNewObjectMapper();
+ }
+
+ public static Response getResponse(PureModel pureModel, List allElements)
+ {
+ CompiledExecutionSupport es = pureModel.getExecutionSupport();
+
+ FastList _elements = FastList.newList();
+ allElements.forEach(elem -> _elements.add(pureModel.getContext().resolvePackageableElement(elem.getPath(), elem.sourceInformation)));
+ RichIterable extends Root_meta_analytics_quality_model_ViolationInstance>> result = core_analytics_quality_checksEngine.Root_meta_analytics_quality_model_domain_runQualityChecks_PackageableElement_MANY__ViolationInstance_MANY_(_elements, es);
+
+ if (result.isEmpty())
+ {
+ return Response.ok().build();
+ }
+ ValidationResult validationResult = calculateValidationResult(result, allElements.size());
+ return Response.ok().entity(validationResult).build();
+ }
+
+ private static ValidationResult calculateValidationResult(RichIterable extends Root_meta_analytics_quality_model_ViolationInstance>> result, int elements)
+ {
+ List totalErrors = new ArrayList<>();
+ for (Root_meta_analytics_quality_model_ViolationInstance> violationInstance : result)
+ {
+ ValidationRuleResult validationRuleResult = new ValidationRuleResult(
+ violationInstance._detail()._isValid(),
+ violationInstance._source().toString(),
+ violationInstance._rule()._id(),
+ violationInstance._detail()._message(),
+ violationInstance._rule()._description());
+ totalErrors.add(validationRuleResult);
+ }
+ int healthScore = ValidationResult.calculateHealthScore(result.size(), elements);
+ return new ValidationResult(totalErrors, healthScore);
+ }
+}
diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-api/src/main/java/org/finos/legend/engine/api/analytics/DataspaceQualityCheckInput.java b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-api/src/main/java/org/finos/legend/engine/api/analytics/DataspaceQualityCheckInput.java
new file mode 100644
index 00000000000..d7689369b3b
--- /dev/null
+++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-api/src/main/java/org/finos/legend/engine/api/analytics/DataspaceQualityCheckInput.java
@@ -0,0 +1,42 @@
+// Copyright 2022 Goldman Sachs
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.finos.legend.engine.api.analytics;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContext;
+
+public class DataspaceQualityCheckInput
+{
+ @JsonProperty
+ public String clientVersion;
+
+ @JsonProperty(required = true)
+ public String dataspace;
+
+ @JsonProperty(required = true)
+ public PureModelContext model;
+
+ @JsonCreator
+ public DataspaceQualityCheckInput(
+ @JsonProperty("clientVersion") String clientVersion,
+ @JsonProperty("dataSpace") String dataspace,
+ @JsonProperty("model") PureModelContext model)
+ {
+ this.clientVersion = clientVersion;
+ this.dataspace = dataspace;
+ this.model = model;
+ }
+}
diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-api/src/main/java/org/finos/legend/engine/api/analytics/ValidationResult.java b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-api/src/main/java/org/finos/legend/engine/api/analytics/ValidationResult.java
new file mode 100644
index 00000000000..daf00f4be95
--- /dev/null
+++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-api/src/main/java/org/finos/legend/engine/api/analytics/ValidationResult.java
@@ -0,0 +1,49 @@
+// Copyright 2022 Goldman Sachs
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.finos.legend.engine.api.analytics;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ValidationResult
+{
+ private List validationRuleResults;
+ private int healthScore;
+
+ public ValidationResult(List validationRuleResults, int healthScore)
+ {
+ this.validationRuleResults = validationRuleResults;
+ this.healthScore = healthScore;
+ }
+
+ public static int calculateHealthScore(int violations, int totalElements)
+ {
+ //TODO - weighted values to different constraints
+ int diff = totalElements - violations;
+ return (int) (Math.round((diff * 100.0 / totalElements)) / 10);
+ }
+
+ public int getHealthScore()
+ {
+ return this.healthScore;
+ }
+
+ public List getValidationRuleResultsList()
+ {
+ return this.validationRuleResults;
+ }
+}
diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-api/src/main/java/org/finos/legend/engine/api/analytics/ValidationRuleResult.java b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-api/src/main/java/org/finos/legend/engine/api/analytics/ValidationRuleResult.java
new file mode 100644
index 00000000000..9e44428a94b
--- /dev/null
+++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-api/src/main/java/org/finos/legend/engine/api/analytics/ValidationRuleResult.java
@@ -0,0 +1,84 @@
+// Copyright 2022 Goldman Sachs
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.finos.legend.engine.api.analytics;
+
+public class ValidationRuleResult
+{
+ private boolean ruleResult;
+ private String packageableElementName;
+ private String violationType;
+ private String errorMessage;
+ private String ruleDescription;
+
+ public ValidationRuleResult(boolean ruleResult, String packageableElementName, String violationType, String errorMessage, String ruleDescription)
+ {
+ this.ruleResult = ruleResult;
+ this.packageableElementName = packageableElementName;
+ this.violationType = violationType;
+ this.errorMessage = errorMessage;
+ this.ruleDescription = ruleDescription;
+ }
+
+ public void setRuleResult(boolean ruleResult)
+ {
+ this.ruleResult = ruleResult;
+ }
+
+ public void setPackageableElementName(String packageableElementName)
+ {
+ this.packageableElementName = packageableElementName;
+ }
+
+ public void setViolationType(String violationType)
+ {
+ this.violationType = violationType;
+ }
+
+ public void setErrorMessage(String errorMessage)
+ {
+ this.errorMessage = errorMessage;
+ }
+
+ public void setRuleDescription(String ruleDescription)
+ {
+ this.ruleDescription = ruleDescription;
+ }
+
+ public boolean getRuleResult()
+ {
+ return this.ruleResult;
+ }
+
+ public String getPackageableElementName()
+ {
+ return this.packageableElementName;
+ }
+
+ public String getViolationType()
+ {
+ return this.violationType;
+ }
+
+ public String getErrorMessage()
+ {
+ return this.errorMessage;
+ }
+
+ public String getRuleDescription()
+ {
+ return this.ruleDescription;
+ }
+
+}
diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-api/src/test/java/org/finos/legend/engine/api/analytics/DataspaceQualityAnalyticsTest.java b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-api/src/test/java/org/finos/legend/engine/api/analytics/DataspaceQualityAnalyticsTest.java
index e97d681cd8c..36f550ab0d7 100644
--- a/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-api/src/test/java/org/finos/legend/engine/api/analytics/DataspaceQualityAnalyticsTest.java
+++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-api/src/test/java/org/finos/legend/engine/api/analytics/DataspaceQualityAnalyticsTest.java
@@ -14,84 +14,730 @@
package org.finos.legend.engine.api.analytics;
-import com.fasterxml.jackson.databind.ObjectMapper;
+import org.finos.legend.engine.language.pure.grammar.from.PureGrammarParser;
import org.finos.legend.engine.language.pure.modelManager.ModelManager;
import org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContextData;
-import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.dataSpace.DataSpace;
-import org.finos.legend.engine.shared.core.ObjectMapperFactory;
import org.finos.legend.engine.shared.core.deployment.DeploymentMode;
import org.junit.Assert;
import org.junit.Test;
import javax.ws.rs.core.Response;
-import java.io.IOException;
-import java.util.Objects;
+import java.util.ArrayList;
+import java.util.List;
public class DataspaceQualityAnalyticsTest
{
private final DataspaceQualityAnalytics api = new DataspaceQualityAnalytics(new ModelManager(DeploymentMode.TEST));
- private static final ObjectMapper objectMapper = ObjectMapperFactory.getNewStandardObjectMapperWithPureProtocolExtensionSupports();
+ private static final String minimumPureClientVersion = "v1_20_0";
@Test
- public void testValidCheckDataSpaceConstraints() throws IOException
+ public void testValidCheckDataSpaceConstraints()
{
- objectMapper.registerSubtypes(DataSpace.class);
- PureModelContextData modelContextData = objectMapper.readValue(Objects.requireNonNull(getClass().getClassLoader().getResource("ValidDataspaceTestPMCD.json")), PureModelContextData.class);
- Assert.assertEquals(Response.Status.OK.getStatusCode(), api.checkDataSpaceConstraints(modelContextData).getStatus());
+ PureModelContextData modelData = PureGrammarParser.newInstance().parseModel(validDataspace);
+ Response response = api.checkDataSpaceConstraints(new DataspaceQualityCheckInput(minimumPureClientVersion, "model::NewDataSpace", modelData), null);
+ Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
}
@Test
- public void testDataspaceWithBadClasses() throws IOException
+ public void testDataspaceWithBadClasses()
{
- objectMapper.registerSubtypes(DataSpace.class);
- PureModelContextData modelContextData = objectMapper.readValue(Objects.requireNonNull(getClass().getClassLoader().getResource("InvalidClassesPMCD.json")), PureModelContextData.class);
- Response response = api.checkDataSpaceConstraints(modelContextData);
- Assert.assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
- String message = "Dataspace does not match the constraints - [Class name (targetCompany) does not match required standards: should start with upper case, Provide documentation for class and its properties targetCompany]";
- Assert.assertEquals(message, response.getEntity());
+ PureModelContextData modelData = PureGrammarParser.newInstance().parseModel(dataSpaceWithBadClasses);
+ Response response = api.checkDataSpaceConstraints(new DataspaceQualityCheckInput(minimumPureClientVersion, "model::NewDataSpace", modelData), null);
+ Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+
+ ValidationRuleResult targetCompany = new ValidationRuleResult(
+ false,
+ "targetCompany",
+ "Invalid Class Names",
+ "Class name (targetCompany) does not match required standards: should start with upper case",
+ "Class name should start with Upper case"
+ );
+ ValidationRuleResult targetPerson = new ValidationRuleResult(
+ false,
+ "TargetPerson",
+ "Documentation not provided for entity and/or its properties",
+ "Provide documentation for class TargetPerson and its properties",
+ "All entities and properties must have a long description."
+ );
+ List message = new ArrayList<>();
+ message.add(targetCompany);
+ message.add(targetPerson);
+ ValidationResult expectedValidationResult = new ValidationResult(message, 8);
+ ValidationResult actualValidationResult = (ValidationResult) response.getEntity();
+ Assert.assertEquals(expectedValidationResult.getHealthScore(), actualValidationResult.getHealthScore());
}
@Test
- public void testDataspaceWithBadAssociations() throws IOException
+ public void testDataspaceWithBadAssociations()
{
- objectMapper.registerSubtypes(DataSpace.class);
- PureModelContextData modelContextData = objectMapper.readValue(Objects.requireNonNull(getClass().getClassLoader().getResource("InvalidAssociationsPMCD.json")), PureModelContextData.class);
- Response response = api.checkDataSpaceConstraints(modelContextData);
- Assert.assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
- String message = "Dataspace does not match the constraints - [Check name of association targetCompany_TargetPerson]";
- Assert.assertEquals(message, response.getEntity());
+ PureModelContextData modelData = PureGrammarParser.newInstance().parseModel(dataspaceWithBadAssociation);
+ Response response = api.checkDataSpaceConstraints(new DataspaceQualityCheckInput(minimumPureClientVersion, "model::NewDataSpace", modelData), null);
+ Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+
+ List message = new ArrayList<>();
+ ValidationRuleResult targetCompany = new ValidationRuleResult(
+ false,
+ "targetCompany_TargetPerson",
+ "Invalid Association Name",
+ "Association (targetCompany_TargetPerson) does not match required standards: Camel case must be used Association name and should be upper camel case, with an underscore between both sides of the join",
+ "Camel case must be used Association name and should be upper camel case, with an underscore between both sides of the join."
+ );
+
+ message.add(targetCompany);
+ ValidationResult expectedValidationResult = new ValidationResult(message, 9);
+ ValidationResult actualValidationResult = (ValidationResult) response.getEntity();
+ Assert.assertEquals(expectedValidationResult.getHealthScore(), actualValidationResult.getHealthScore());
}
@Test
- public void testDataspaceWithBadEnumerations() throws IOException
+ public void testDataspaceWithBadEnumerations()
{
- objectMapper.registerSubtypes(DataSpace.class);
- PureModelContextData modelContextData = objectMapper.readValue(Objects.requireNonNull(getClass().getClassLoader().getResource("InvalidEnumerationsPMCD.json")), PureModelContextData.class);
- Response response = api.checkDataSpaceConstraints(modelContextData);
- Assert.assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
- String message = "Dataspace does not match the constraints - [Enumeration name (enum_TestForMyDataspace) does not match required standards: should start with upper case;should not contain '_', Enumeration name (enum_TestForMyDataspace) does not match required standards: should not contain '_';should start with upper case]";
- Assert.assertEquals(message, response.getEntity());
+ PureModelContextData modelData = PureGrammarParser.newInstance().parseModel(dataspaceWithBadEnum);
+ Response response = api.checkDataSpaceConstraints(new DataspaceQualityCheckInput(minimumPureClientVersion, "model::NewDataSpace", modelData), null);
+ Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+
+ List message = new ArrayList<>();
+
+ ValidationRuleResult e = new ValidationRuleResult(
+ false,
+ "testEnum_ForMyDataspace",
+ "Invalid Enumeration Names",
+ "Enumeration name (testEnum_ForMyDataspace) does not match required standards: should start with upper case;should not contain '_';should not contain 'Enum'",
+ "Enum name should start with Upper case, not contain underscores or the word Enum"
+ );
+ message.add(e);
+ ValidationResult expectedValidationResult = new ValidationResult(message, 9);
+ ValidationResult actualValidationResult = (ValidationResult) response.getEntity();
+ Assert.assertEquals(expectedValidationResult.getHealthScore(), actualValidationResult.getHealthScore());
}
@Test
- public void testDataspaceWithBadFunctions() throws IOException
+ public void testDataspaceWithBadFunctions()
{
- objectMapper.registerSubtypes(DataSpace.class);
- PureModelContextData modelContextData = objectMapper.readValue(Objects.requireNonNull(getClass().getClassLoader().getResource("InvalidFunctionsPMCD.json")), PureModelContextData.class);
- Response response = api.checkDataSpaceConstraints(modelContextData);
- Assert.assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
- String message = "Dataspace does not match the constraints - [Possible invalid equal check (type mismatch, String vs Integer)]";
- Assert.assertEquals(message, response.getEntity());
+ PureModelContextData modelData = PureGrammarParser.newInstance().parseModel(dataspaceWithBadFunction);
+ Response response = api.checkDataSpaceConstraints(new DataspaceQualityCheckInput(minimumPureClientVersion, "model::NewDataSpace", modelData), null);
+ Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+
+ List message = new ArrayList<>();
+ ValidationRuleResult fn = new ValidationRuleResult(
+ false,
+ "",
+ "Invalid Equality",
+ "Function (equal) does not match required standards: Possible invalid equal check (type mismatch, Integer vs String)",
+ "Check for equality checks that will always result in false due to type mismatches (e.g. \\'abc\\' == 123)"
+ );
+ message.add(fn);
+
+ ValidationRuleResult fn2 = new ValidationRuleResult(
+ false,
+ "",
+ "Invalid Contains",
+ "Possible invalid contains check (type mismatch, Integer vs String)",
+ "Check for contains / containsAll / containsAny checks that will always result in false due to type mismatches (e.g. [\\'abc\\']->contains(123))"
+ );
+ message.add(fn2);
+ ValidationResult expectedValidationResult = new ValidationResult(message, 8);
+ ValidationResult actualValidationResult = (ValidationResult) response.getEntity();
+ Assert.assertEquals(expectedValidationResult.getHealthScore(), actualValidationResult.getHealthScore());
}
@Test
- public void testDataspaceWithBadClassProperties() throws IOException
+ public void testDataspaceWithBadClassProperties()
{
- objectMapper.registerSubtypes(DataSpace.class);
- PureModelContextData modelContextData = objectMapper.readValue(Objects.requireNonNull(getClass().getClassLoader().getResource("InvalidClassPropertiesPMCD.json")), PureModelContextData.class);
- Response response = api.checkDataSpaceConstraints(modelContextData);
- Assert.assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
- String message = "Dataspace does not match the constraints - [Property name (TargetCompanyObject) does not match required standards: should start with lower case, Property name (id_TargetCompany) does not match required standards: should not contain '_']";
- Assert.assertEquals(message, response.getEntity());
+ PureModelContextData modelData = PureGrammarParser.newInstance().parseModel(dataspaceWithBadClassProperties);
+ Response response = api.checkDataSpaceConstraints(new DataspaceQualityCheckInput(minimumPureClientVersion, "model::NewDataSpace", modelData), null);
+ Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+
+ List message = new ArrayList<>();
+ ValidationRuleResult prop = new ValidationRuleResult(
+ false,
+ "id_TargetCompany",
+ "Invalid Property Names",
+ "Property name (id_TargetCompany) does not match required standards: should not contain '_'",
+ "Property name should start with lower letter and in camelCase"
+ );
+
+ ValidationRuleResult prop2 = new ValidationRuleResult(
+ false,
+ "Name",
+ "Invalid Property Names",
+ "Property name (Name) does not match required standards: should start with lower case",
+ "Property name should start with lower letter and in camelCase"
+ );
+
+ message.add(prop);
+ message.add(prop2);
+ ValidationResult expectedValidationResult = new ValidationResult(message, 8);
+ ValidationResult actualValidationResult = (ValidationResult) response.getEntity();
+ Assert.assertEquals(expectedValidationResult.getHealthScore(), actualValidationResult.getHealthScore());
}
+
+ private final String validDataspace = "###DataSpace\n" +
+ "DataSpace model::NewDataSpace\n" +
+ "{\n" +
+ " executionContexts:\n" +
+ " [\n" +
+ " {\n" +
+ " name: 'Some Context';\n" +
+ " title: 'New Execution Context';\n" +
+ " description: 'some information about the execution context';\n" +
+ " mapping: model::dummyMapping;\n" +
+ " defaultRuntime: model::dummyRuntime;\n" +
+ " }\n" +
+ " ];\n" +
+ " defaultExecutionContext: 'Some Context';\n" +
+ " elements:\n" +
+ " [\n" +
+ " model::Doc,\n" +
+ " model::TargetCompany,\n" +
+ " model::TargetPerson,\n" +
+ " pure::TargetCompany_TargetPerson,\n" +
+ " pure::TestForMyDataspace\n" +
+ " ];\n" +
+ "}\n" +
+ "\n" +
+ "\n" +
+ "###Pure\n" +
+ "Enum {meta::pure::profiles::doc.doc = 'test enum for my dataspace'} pure::TestForMyDataspace\n" +
+ "{\n" +
+ " Value1,\n" +
+ " Value2\n" +
+ "}\n" +
+ "\n" +
+ "Class {meta::pure::profiles::doc.doc = 'documentation for this class'} model::Doc\n" +
+ "{\n" +
+ " {meta::pure::profiles::doc.doc = 'target company object'} targetCompanyObject: model::TargetCompany[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'target person object'} targetPersonObject: model::TargetPerson[1];\n" +
+ "}\n" +
+ "\n" +
+ "Class {meta::pure::profiles::doc.doc = 'company object'} model::TargetCompany\n" +
+ "{\n" +
+ " <> {meta::pure::profiles::doc.doc = 'company id'} id: Integer[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'company name'} name: String[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'company address'} addressId: Integer[1];\n" +
+ "}\n" +
+ "\n" +
+ "Class {meta::pure::profiles::doc.doc = 'person object'} model::TargetPerson\n" +
+ "{\n" +
+ " <> {meta::pure::profiles::doc.doc = 'legal name'} legalName: String[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'person\\'s age'} age: Integer[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'person\\'s address'} addressId: Integer[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'decimal value'} dec: Decimal[0..1];\n" +
+ "}\n" +
+ "\n" +
+ "Association pure::TargetCompany_TargetPerson\n" +
+ "{\n" +
+ " prop1: model::TargetCompany[1];\n" +
+ " prop2: model::TargetPerson[1];\n" +
+ "}\n" +
+ "\n" +
+ "function pure::ThisIsMyFunction(): String[1]\n" +
+ "{\n" +
+ " 'test'\n" +
+ "}\n" +
+ "\n" +
+ "function pure::EqualityFunction(): Boolean[1]\n" +
+ "{\n" +
+ " 'abc' == 'abc'\n" +
+ "}\n" +
+ "\n" +
+ "function pure::ComparisonFunction(): Boolean[1]\n" +
+ "{\n" +
+ " 'a'->in(\n" +
+ " [\n" +
+ " 'a',\n" +
+ " 'c',\n" +
+ " 'c'\n" +
+ " ]\n" +
+ " )\n" +
+ "}\n" +
+ "\n" +
+ "\n" +
+ "###Mapping\n" +
+ "Mapping model::dummyMapping\n" +
+ "(\n" +
+ ")\n" +
+ "\n" +
+ "\n" +
+ "###Runtime\n" +
+ "Runtime model::dummyRuntime\n" +
+ "{\n" +
+ " mappings:\n" +
+ " [\n" +
+ " model::dummyMapping\n" +
+ " ];\n" +
+ "}\n";
+
+ private final String dataSpaceWithBadClasses = "###DataSpace\n" +
+ "DataSpace model::NewDataSpace\n" +
+ "{\n" +
+ " executionContexts:\n" +
+ " [\n" +
+ " {\n" +
+ " name: 'Some Context';\n" +
+ " title: 'New Execution Context';\n" +
+ " description: 'some information about the execution context';\n" +
+ " mapping: model::dummyMapping;\n" +
+ " defaultRuntime: model::dummyRuntime;\n" +
+ " }\n" +
+ " ];\n" +
+ " defaultExecutionContext: 'Some Context';\n" +
+ " elements:\n" +
+ " [\n" +
+ " model::Doc,\n" +
+ " model::targetCompany,\n" +
+ " model::TargetPerson,\n" +
+ " model::TargetCompany_TargetPerson,\n" +
+ " model::TestForMyDataspace\n" +
+ " ];\n" +
+ "}\n" +
+ "\n" +
+ "\n" +
+ "###Pure\n" +
+ "Enum {meta::pure::profiles::doc.doc = 'test enum for my dataspace'} model::TestForMyDataspace\n" +
+ "{\n" +
+ " Value1,\n" +
+ " Value2\n" +
+ "}\n" +
+ "\n" +
+ "Class {meta::pure::profiles::doc.doc = 'documentation for this class'} model::Doc\n" +
+ "{\n" +
+ " {meta::pure::profiles::doc.doc = 'target company object'} targetCompanyObject: model::targetCompany[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'target person object'} targetPersonObject: model::TargetPerson[1];\n" +
+ "}\n" +
+ "\n" +
+ "Class {meta::pure::profiles::doc.doc = 'company object'} model::targetCompany\n" +
+ "{\n" +
+ " <> {meta::pure::profiles::doc.doc = 'company id'} id: Integer[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'company name'} name: String[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'company address'} addressId: Integer[1];\n" +
+ "}\n" +
+ "\n" +
+ "Class {meta::pure::profiles::doc.doc = 'person object'} model::TargetPerson\n" +
+ "{\n" +
+ " <> {meta::pure::profiles::doc.doc = 'legal name'} legalName: String[1];\n" +
+ " age: Integer[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'person\\'s address'} addressId: Integer[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'decimal value'} dec: Decimal[0..1];\n" +
+ "}\n" +
+ "\n" +
+ "Association model::TargetCompany_TargetPerson\n" +
+ "{\n" +
+ " prop1: model::targetCompany[1];\n" +
+ " prop2: model::TargetPerson[1];\n" +
+ "}\n" +
+ "\n" +
+ "function pure::ThisIsMyFunction(): String[1]\n" +
+ "{\n" +
+ " 'test'\n" +
+ "}\n" +
+ "\n" +
+ "function pure::EqualityFunction(): Boolean[1]\n" +
+ "{\n" +
+ " 'abc' == 'abc'\n" +
+ "}\n" +
+ "\n" +
+ "function pure::ComparisonFunction(): Boolean[1]\n" +
+ "{\n" +
+ " 'a'->in(\n" +
+ " [\n" +
+ " 'a',\n" +
+ " 'c',\n" +
+ " 'c'\n" +
+ " ]\n" +
+ " )\n" +
+ "}\n" +
+ "\n" +
+ "\n" +
+ "###Mapping\n" +
+ "Mapping model::dummyMapping\n" +
+ "(\n" +
+ ")\n" +
+ "\n" +
+ "\n" +
+ "###Runtime\n" +
+ "Runtime model::dummyRuntime\n" +
+ "{\n" +
+ " mappings:\n" +
+ " [\n" +
+ " model::dummyMapping\n" +
+ " ];\n" +
+ "}\n";
+
+ private final String dataspaceWithBadAssociation = "###DataSpace\n" +
+ "DataSpace model::NewDataSpace\n" +
+ "{\n" +
+ " executionContexts:\n" +
+ " [\n" +
+ " {\n" +
+ " name: 'Some Context';\n" +
+ " title: 'New Execution Context';\n" +
+ " description: 'some information about the execution context';\n" +
+ " mapping: model::dummyMapping;\n" +
+ " defaultRuntime: model::dummyRuntime;\n" +
+ " }\n" +
+ " ];\n" +
+ " defaultExecutionContext: 'Some Context';\n" +
+ " elements:\n" +
+ " [\n" +
+ " model::Doc,\n" +
+ " model::TargetCompany,\n" +
+ " model::TargetPerson,\n" +
+ " pure::targetCompany_TargetPerson,\n" +
+ " pure::TestForMyDataspace\n" +
+ " ];\n" +
+ "}\n" +
+ "\n" +
+ "\n" +
+ "###Pure\n" +
+ "Enum {meta::pure::profiles::doc.doc = 'test enum for my dataspace'} pure::TestForMyDataspace\n" +
+ "{\n" +
+ " Value1,\n" +
+ " Value2\n" +
+ "}\n" +
+ "\n" +
+ "Class {meta::pure::profiles::doc.doc = 'documentation for this class'} model::Doc\n" +
+ "{\n" +
+ " {meta::pure::profiles::doc.doc = 'target company object'} targetCompanyObject: model::TargetCompany[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'target person object'} targetPersonObject: model::TargetPerson[1];\n" +
+ "}\n" +
+ "\n" +
+ "Class {meta::pure::profiles::doc.doc = 'company object'} model::TargetCompany\n" +
+ "{\n" +
+ " <> {meta::pure::profiles::doc.doc = 'company id'} id: Integer[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'company name'} name: String[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'company address'} addressId: Integer[1];\n" +
+ "}\n" +
+ "\n" +
+ "Class {meta::pure::profiles::doc.doc = 'person object'} model::TargetPerson\n" +
+ "{\n" +
+ " <> {meta::pure::profiles::doc.doc = 'legal name'} legalName: String[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'person\\'s age'} age: Integer[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'person\\'s address'} addressId: Integer[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'decimal value'} dec: Decimal[0..1];\n" +
+ "}\n" +
+ "\n" +
+ "Association pure::targetCompany_TargetPerson\n" +
+ "{\n" +
+ " prop1: model::TargetCompany[1];\n" +
+ " prop2: model::TargetPerson[1];\n" +
+ "}\n" +
+ "\n" +
+ "function pure::ThisIsMyFunction(): String[1]\n" +
+ "{\n" +
+ " 'test'\n" +
+ "}\n" +
+ "\n" +
+ "function pure::EqualityFunction(): Boolean[1]\n" +
+ "{\n" +
+ " 'abc' == 'abc'\n" +
+ "}\n" +
+ "\n" +
+ "function pure::ComparisonFunction(): Boolean[1]\n" +
+ "{\n" +
+ " 'a'->in(\n" +
+ " [\n" +
+ " 'a',\n" +
+ " 'c',\n" +
+ " 'c'\n" +
+ " ]\n" +
+ " )\n" +
+ "}\n" +
+ "\n" +
+ "\n" +
+ "###Mapping\n" +
+ "Mapping model::dummyMapping\n" +
+ "(\n" +
+ ")\n" +
+ "\n" +
+ "\n" +
+ "###Runtime\n" +
+ "Runtime model::dummyRuntime\n" +
+ "{\n" +
+ " mappings:\n" +
+ " [\n" +
+ " model::dummyMapping\n" +
+ " ];\n" +
+ "}\n";
+
+ private final String dataspaceWithBadEnum = "###DataSpace\n" +
+ "DataSpace model::NewDataSpace\n" +
+ "{\n" +
+ " executionContexts:\n" +
+ " [\n" +
+ " {\n" +
+ " name: 'Some Context';\n" +
+ " title: 'New Execution Context';\n" +
+ " description: 'some information about the execution context';\n" +
+ " mapping: model::dummyMapping;\n" +
+ " defaultRuntime: model::dummyRuntime;\n" +
+ " }\n" +
+ " ];\n" +
+ " defaultExecutionContext: 'Some Context';\n" +
+ " elements:\n" +
+ " [\n" +
+ " model::Doc,\n" +
+ " model::TargetCompany,\n" +
+ " model::TargetPerson,\n" +
+ " pure::TargetCompany_TargetPerson,\n" +
+ " pure::testEnum_ForMyDataspace\n" +
+ " ];\n" +
+ "}\n" +
+ "\n" +
+ "\n" +
+ "###Pure\n" +
+ "Enum {meta::pure::profiles::doc.doc = 'test enum for my dataspace'} pure::testEnum_ForMyDataspace\n" +
+ "{\n" +
+ " Value1,\n" +
+ " Value2\n" +
+ "}\n" +
+ "\n" +
+ "Class {meta::pure::profiles::doc.doc = 'documentation for this class'} model::Doc\n" +
+ "{\n" +
+ " {meta::pure::profiles::doc.doc = 'target company object'} targetCompanyObject: model::TargetCompany[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'target person object'} targetPersonObject: model::TargetPerson[1];\n" +
+ "}\n" +
+ "\n" +
+ "Class {meta::pure::profiles::doc.doc = 'company object'} model::TargetCompany\n" +
+ "{\n" +
+ " <> {meta::pure::profiles::doc.doc = 'company id'} id: Integer[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'company name'} name: String[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'company address'} addressId: Integer[1];\n" +
+ "}\n" +
+ "\n" +
+ "Class {meta::pure::profiles::doc.doc = 'person object'} model::TargetPerson\n" +
+ "{\n" +
+ " <> {meta::pure::profiles::doc.doc = 'legal name'} legalName: String[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'person\\'s age'} age: Integer[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'person\\'s address'} addressId: Integer[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'decimal value'} dec: Decimal[0..1];\n" +
+ "}\n" +
+ "\n" +
+ "Association pure::TargetCompany_TargetPerson\n" +
+ "{\n" +
+ " prop1: model::TargetCompany[1];\n" +
+ " prop2: model::TargetPerson[1];\n" +
+ "}\n" +
+ "\n" +
+ "function pure::ThisIsMyFunction(): String[1]\n" +
+ "{\n" +
+ " 'test'\n" +
+ "}\n" +
+ "\n" +
+ "function pure::EqualityFunction(): Boolean[1]\n" +
+ "{\n" +
+ " 'abc' == 'abc'\n" +
+ "}\n" +
+ "\n" +
+ "function pure::ComparisonFunction(): Boolean[1]\n" +
+ "{\n" +
+ " 'a'->in(\n" +
+ " [\n" +
+ " 'a',\n" +
+ " 'c',\n" +
+ " 'c'\n" +
+ " ]\n" +
+ " )\n" +
+ "}\n" +
+ "\n" +
+ "\n" +
+ "###Mapping\n" +
+ "Mapping model::dummyMapping\n" +
+ "(\n" +
+ ")\n" +
+ "\n" +
+ "\n" +
+ "###Runtime\n" +
+ "Runtime model::dummyRuntime\n" +
+ "{\n" +
+ " mappings:\n" +
+ " [\n" +
+ " model::dummyMapping\n" +
+ " ];\n" +
+ "}\n";
+
+ private final String dataspaceWithBadFunction = "###DataSpace\n" +
+ "DataSpace model::NewDataSpace\n" +
+ "{\n" +
+ " executionContexts:\n" +
+ " [\n" +
+ " {\n" +
+ " name: 'Some Context';\n" +
+ " title: 'New Execution Context';\n" +
+ " description: 'some information about the execution context';\n" +
+ " mapping: model::dummyMapping;\n" +
+ " defaultRuntime: model::dummyRuntime;\n" +
+ " }\n" +
+ " ];\n" +
+ " defaultExecutionContext: 'Some Context';\n" +
+ " elements:\n" +
+ " [\n" +
+ " model::Doc,\n" +
+ " model::TargetCompany,\n" +
+ " model::TargetPerson,\n" +
+ " pure::TargetCompany_TargetPerson,\n" +
+ " pure::TestForMyDataspace\n" +
+ " ];\n" +
+ "}\n" +
+ "\n" +
+ "\n" +
+ "###Pure\n" +
+ "Enum {meta::pure::profiles::doc.doc = 'test enum for my dataspace'} pure::TestForMyDataspace\n" +
+ "{\n" +
+ " Value1,\n" +
+ " Value2\n" +
+ "}\n" +
+ "\n" +
+ "Class {meta::pure::profiles::doc.doc = 'documentation for this class'} model::Doc\n" +
+ "{\n" +
+ " {meta::pure::profiles::doc.doc = 'target company object'} targetCompanyObject: model::TargetCompany[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'target person object'} targetPersonObject: model::TargetPerson[1];\n" +
+ "}\n" +
+ "\n" +
+ "Class {meta::pure::profiles::doc.doc = 'company object'} model::TargetCompany\n" +
+ "{\n" +
+ " <> {meta::pure::profiles::doc.doc = 'company id'} id: Integer[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'company name'} name: String[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'company address'} addressId: Integer[1];\n" +
+ "}\n" +
+ "\n" +
+ "Class {meta::pure::profiles::doc.doc = 'person object'} model::TargetPerson\n" +
+ "{\n" +
+ " <> {meta::pure::profiles::doc.doc = 'legal name'} legalName: String[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'person\\'s age'} age: Integer[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'person\\'s address'} addressId: Integer[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'decimal value'} dec: Decimal[0..1];\n" +
+ "}\n" +
+ "\n" +
+ "Association pure::TargetCompany_TargetPerson\n" +
+ "{\n" +
+ " prop1: model::TargetCompany[1];\n" +
+ " prop2: model::TargetPerson[1];\n" +
+ "}\n" +
+ "\n" +
+ "function pure::ThisIsMyFunction(): String[1]\n" +
+ "{\n" +
+ " 'test'\n" +
+ "}\n" +
+ "\n" +
+ "function pure::EqualityFunction(): Boolean[1]\n" +
+ "{\n" +
+ " 123 == 'abc'\n" +
+ "}\n" +
+ "\n" +
+ "function pure::InvalidContainsFunction(): Boolean[1]\n" +
+ "{\n" +
+ " [1,2,3,4]->contains('hello');\n" +
+ "}\n" +
+ "\n" +
+ "###Mapping\n" +
+ "Mapping model::dummyMapping\n" +
+ "(\n" +
+ ")\n" +
+ "\n" +
+ "\n" +
+ "###Runtime\n" +
+ "Runtime model::dummyRuntime\n" +
+ "{\n" +
+ " mappings:\n" +
+ " [\n" +
+ " model::dummyMapping\n" +
+ " ];\n" +
+ "}\n";
+
+ private final String dataspaceWithBadClassProperties = "###DataSpace\n" +
+ "DataSpace model::NewDataSpace\n" +
+ "{\n" +
+ " executionContexts:\n" +
+ " [\n" +
+ " {\n" +
+ " name: 'Some Context';\n" +
+ " title: 'New Execution Context';\n" +
+ " description: 'some information about the execution context';\n" +
+ " mapping: model::dummyMapping;\n" +
+ " defaultRuntime: model::dummyRuntime;\n" +
+ " }\n" +
+ " ];\n" +
+ " defaultExecutionContext: 'Some Context';\n" +
+ " elements:\n" +
+ " [\n" +
+ " model::Doc,\n" +
+ " model::TargetCompany,\n" +
+ " model::TargetPerson,\n" +
+ " pure::TargetCompany_TargetPerson,\n" +
+ " pure::TestForMyDataspace\n" +
+ " ];\n" +
+ "}\n" +
+ "\n" +
+ "\n" +
+ "###Pure\n" +
+ "Enum {meta::pure::profiles::doc.doc = 'test enum for my dataspace'} pure::TestForMyDataspace\n" +
+ "{\n" +
+ " Value1,\n" +
+ " Value2\n" +
+ "}\n" +
+ "\n" +
+ "Class {meta::pure::profiles::doc.doc = 'documentation for this class'} model::Doc\n" +
+ "{\n" +
+ " {meta::pure::profiles::doc.doc = 'target company object'} targetCompanyObject: model::TargetCompany[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'target person object'} targetPersonObject: model::TargetPerson[1];\n" +
+ "}\n" +
+ "\n" +
+ "Class {meta::pure::profiles::doc.doc = 'company object'} model::TargetCompany\n" +
+ "{\n" +
+ " <> {meta::pure::profiles::doc.doc = 'company id'} id_TargetCompany: Integer[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'company name'} Name: String[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'company address'} addressId: Integer[1];\n" +
+ "}\n" +
+ "\n" +
+ "Class {meta::pure::profiles::doc.doc = 'person object'} model::TargetPerson\n" +
+ "{\n" +
+ " <> {meta::pure::profiles::doc.doc = 'legal name'} legalName: String[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'person\\'s age'} age: Integer[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'person\\'s address'} addressId: Integer[1];\n" +
+ " {meta::pure::profiles::doc.doc = 'decimal value'} dec: Decimal[0..1];\n" +
+ "}\n" +
+ "\n" +
+ "Association pure::TargetCompany_TargetPerson\n" +
+ "{\n" +
+ " prop1: model::TargetCompany[1];\n" +
+ " prop2: model::TargetPerson[1];\n" +
+ "}\n" +
+ "\n" +
+ "function pure::ThisIsMyFunction(): String[1]\n" +
+ "{\n" +
+ " 'test'\n" +
+ "}\n" +
+ "\n" +
+ "function pure::EqualityFunction(): Boolean[1]\n" +
+ "{\n" +
+ " 'abc' == 'abc'\n" +
+ "}\n" +
+ "\n" +
+ "function pure::ComparisonFunction(): Boolean[1]\n" +
+ "{\n" +
+ " 'a'->in(\n" +
+ " [\n" +
+ " 'a',\n" +
+ " 'c',\n" +
+ " 'c'\n" +
+ " ]\n" +
+ " )\n" +
+ "}\n" +
+ "\n" +
+ "\n" +
+ "###Mapping\n" +
+ "Mapping model::dummyMapping\n" +
+ "(\n" +
+ ")\n" +
+ "\n" +
+ "\n" +
+ "###Runtime\n" +
+ "Runtime model::dummyRuntime\n" +
+ "{\n" +
+ " mappings:\n" +
+ " [\n" +
+ " model::dummyMapping\n" +
+ " ];\n" +
+ "}\n";
}
diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/pom.xml b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/pom.xml
index 87f812f9a5c..1de89e7836b 100644
--- a/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/pom.xml
+++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/pom.xml
@@ -29,6 +29,8 @@
core
core_relational
core_analytics_quality
+ core_external_compiler
+ core_data_space_metamodel
${project.basedir}/src/main/resources/core_analytics_quality.definition.json
@@ -36,7 +38,7 @@
- compile
+ generate-sources
build-pure-jar
@@ -68,7 +70,11 @@
legend-pure-m2-store-relational-grammar
${legend.pure.version}
-
+
+ org.finos.legend.pure
+ legend-pure-m3-core
+ ${legend.pure.version}
+
org.finos.legend.engine
legend-engine-pure-code-compiled-core
@@ -79,6 +85,11 @@
legend-engine-xt-relationalStore-pure
${project.version}
+
+ org.finos.legend.engine
+ legend-engine-pure-runtime-compiler
+ ${project.version}
+
@@ -116,6 +127,16 @@
legend-pure-m2-dsl-graph-grammar
${legend.pure.version}
+
+ org.finos.legend.pure
+ legend-pure-m3-core
+ ${legend.pure.version}
+
+
+ org.finos.legend.pure
+ legend-pure-m3-core
+ ${legend.pure.version}
+
org.finos.legend.pure
legend-pure-m2-dsl-path-grammar
@@ -131,7 +152,11 @@
legend-pure-m2-store-relational-grammar
${legend.pure.version}
-
+
+ org.finos.legend.pure
+ legend-pure-m3-core
+ ${legend.pure.version}
+
org.finos.legend.engine
legend-engine-pure-code-compiled-core
@@ -142,6 +167,11 @@
legend-engine-xt-relationalStore-pure
${project.version}
+
+ org.finos.legend.engine
+ legend-engine-pure-runtime-compiler
+ ${project.version}
+
diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/java/org/finos/legend/pure/code/core/CoreExternalLineageAnalysisCodeRepositoryProvider.java b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/java/org/finos/legend/pure/code/core/CoreQualityAnalysisCodeRepositoryProvider.java
similarity index 91%
rename from legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/java/org/finos/legend/pure/code/core/CoreExternalLineageAnalysisCodeRepositoryProvider.java
rename to legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/java/org/finos/legend/pure/code/core/CoreQualityAnalysisCodeRepositoryProvider.java
index 06fcb194e3b..5a9e7e82143 100644
--- a/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/java/org/finos/legend/pure/code/core/CoreExternalLineageAnalysisCodeRepositoryProvider.java
+++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/java/org/finos/legend/pure/code/core/CoreQualityAnalysisCodeRepositoryProvider.java
@@ -20,7 +20,7 @@
import org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepositoryProvider;
import org.finos.legend.pure.m3.serialization.filesystem.repository.GenericCodeRepository;
-public class CoreExternalLineageAnalysisCodeRepositoryProvider implements CodeRepositoryProvider
+public class CoreQualityAnalysisCodeRepositoryProvider implements CodeRepositoryProvider
{
@Override
public CodeRepository repository()
diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/resources/META-INF/services/org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepositoryProvider b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/resources/META-INF/services/org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepositoryProvider
index 91ac69dcfc0..1c8274f3cde 100644
--- a/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/resources/META-INF/services/org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepositoryProvider
+++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/resources/META-INF/services/org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepositoryProvider
@@ -14,52 +14,4 @@
# limitations under the License.
#
-#
-# Copyright 2022 Goldman Sachs
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-#
-# Copyright 2022 Goldman Sachs
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-#
-# Copyright 2022 Goldman Sachs
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-org.finos.legend.pure.code.core.CoreExternalLineageAnalysisCodeRepositoryProvider
\ No newline at end of file
+org.finos.legend.pure.code.core.CoreQualityAnalysisCodeRepositoryProvider
\ No newline at end of file
diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/resources/core_analytics_quality.definition.json b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/resources/core_analytics_quality.definition.json
index bf56d08f3f2..14ca97c654c 100644
--- a/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/resources/core_analytics_quality.definition.json
+++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/resources/core_analytics_quality.definition.json
@@ -9,6 +9,8 @@
"platform_store_relational",
"platform_functions_json",
"core_functions",
- "core"
+ "core",
+ "core_external_compiler",
+ "core_data_space_metamodel"
]
}
\ No newline at end of file
diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/resources/core_analytics_quality/associationChecks.pure b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/resources/core_analytics_quality/associationChecks.pure
index a1fed8f7937..fad78feb547 100644
--- a/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/resources/core_analytics_quality/associationChecks.pure
+++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/resources/core_analytics_quality/associationChecks.pure
@@ -25,7 +25,6 @@ meta::analytics::quality::model::domain::associationNameShouldStartWithUpperCase
let passed = size($tokens) == 2 &&
$tokens->at(0)->meta::pure::functions::string::substring(0,1) ->isUpperCase() &&
$tokens->at(1)->meta::pure::functions::string::substring(0,1) ->isUpperCase();
- let message ='Check name of association ' + $a.name->toOne() ;
-
+ let message ='Association (' + $a.name->toOne() + ') does not match required standards: Camel case must be used Association name and should be upper camel case, with an underscore between both sides of the join';
^CheckResult(isValid=$passed, message=$message);
}
\ No newline at end of file
diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/resources/core_analytics_quality/checksEngine.pure b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/resources/core_analytics_quality/checksEngine.pure
index 3b3de6f561e..0aedabd1ff6 100644
--- a/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/resources/core_analytics_quality/checksEngine.pure
+++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/resources/core_analytics_quality/checksEngine.pure
@@ -1,6 +1,9 @@
import meta::analytics::quality::model::*;
import meta::analytics::quality::model::domain::*;
import meta::relational::tests::*;
+import meta::pure::runtime::*;
+
+
Enum meta::analytics::quality::model::Severity
{
High, Medium, Low
diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/resources/core_analytics_quality/classChecks.pure b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/resources/core_analytics_quality/classChecks.pure
index ab1caba18c2..178e4ebe667 100644
--- a/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/resources/core_analytics_quality/classChecks.pure
+++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/resources/core_analytics_quality/classChecks.pure
@@ -77,8 +77,7 @@ meta::analytics::quality::model::domain::allEntitiesAndPropertiesShouldHaveALong
{
let passed = ($cl.taggedValues->size() != 0 && $cl.taggedValues->filter(t | $t.tag.profile == doc)->size() != 0)
&& $cl.properties->size() == $cl.properties->map(p|$p.taggedValues)-> filter(t | $t.tag.profile == doc)->size();
-
- let message ='Provide documentation for class and its properties ' + $cl.name->toOne() ;
+ let message ='Provide documentation for class ' + + $cl.name->toOne() + ' and its properties';
^CheckResult(isValid=$passed, message=$message);
}
\ No newline at end of file
diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/resources/core_analytics_quality/functionChecks.pure b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/resources/core_analytics_quality/functionChecks.pure
index aabd6f182df..512e37ed39b 100644
--- a/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/resources/core_analytics_quality/functionChecks.pure
+++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-quality/legend-engine-xt-analytics-quality-pure/src/main/resources/core_analytics_quality/functionChecks.pure
@@ -58,7 +58,7 @@ function <> meta::analytics::quality::model::domain::getLocalFunc
}
function {rule.rule = 'Invalid Contains',
- rule.description ='Check for contains / containsAll / containsAny checks that will always result in false due to type miss matches (e.g. [\'abc\']->contains(123))',
+ rule.description ='Check for contains / containsAll / containsAny checks that will always result in false due to type mismatches (e.g. [\'abc\']->contains(123))',
rule.severity = 'High',
rule.category = 'Correctness'}
meta::analytics::quality::model::domain::invalidContainsComparisons(fns:List>[1]) : Pair[*]
@@ -69,7 +69,7 @@ meta::analytics::quality::model::domain::invalidContainsComparisons(fns:Listmap(ie|
let t1 = $ie->meta::analytics::quality::model::domain::resolveParameterType(0);
let t2 = $ie->meta::analytics::quality::model::domain::resolveParameterType(1);
- let message = ('Possible invalid ' + $ie.functionName->makeString() + ' check (type miss match, ' + $t1->elementToPath() + ' vs ' + $t2->elementToPath() + ')');
+ let message = ('Possible invalid ' + $ie.functionName->makeString() + ' check (type mismatch, ' + $t1->elementToPath() + ' vs ' + $t2->elementToPath() + ')');
let result = ^CheckResult(isValid=false,message=$message);
pair($ie,$result);
);
@@ -77,7 +77,7 @@ meta::analytics::quality::model::domain::invalidContainsComparisons(fns:List>[1]) : Pair[*]
@@ -98,7 +98,7 @@ meta::analytics::quality::model::domain::validEqualityComparisons(fns:ListtoOne() + ' check (' + $t1->elementToPath() + ' vs ' + $t2->elementToPath() + ')',
- |'Possible invalid ' + $ie.functionName->toOne() + ' check (type mismatch, ' + $t1->elementToPath() + ' vs ' + $t2->elementToPath() + ')');
+ | 'Function (' + $ie.functionName->toOne() + ') does not match required standards: Possible invalid ' + $ie.functionName->toOne() + ' check (type mismatch, ' + $t1->elementToPath() + ' vs ' + $t2->elementToPath() + ')');
let result = ^CheckResult(isValid=$valid, message=$message);
pair($ie, $result);
);