diff --git a/legend-engine-config/legend-engine-extensions-collection-generation/src/test/java/org/finos/legend/engine/extensions/collection/generation/TestExtensions.java b/legend-engine-config/legend-engine-extensions-collection-generation/src/test/java/org/finos/legend/engine/extensions/collection/generation/TestExtensions.java index da2039c880d..2d51c4927c9 100644 --- a/legend-engine-config/legend-engine-extensions-collection-generation/src/test/java/org/finos/legend/engine/extensions/collection/generation/TestExtensions.java +++ b/legend-engine-config/legend-engine-extensions-collection-generation/src/test/java/org/finos/legend/engine/extensions/collection/generation/TestExtensions.java @@ -470,6 +470,9 @@ protected Iterable getExpectedCodeRepositories() .with("core_generation") .with("core_service") .with("core_functions") + .with("core_analytics_binding") + .with("core_analytics_class") + .with("core_analytics_function") .with("core_analytics_lineage") .with("core_analytics_mapping") .with("core_analytics_search") diff --git a/legend-engine-config/legend-engine-server/pom.xml b/legend-engine-config/legend-engine-server/pom.xml index 532d877188a..d65cc0dcc30 100644 --- a/legend-engine-config/legend-engine-server/pom.xml +++ b/legend-engine-config/legend-engine-server/pom.xml @@ -414,6 +414,22 @@ org.finos.legend.engine legend-engine-xt-analytics-store-entitlement + + org.finos.legend.engine + legend-engine-xt-analytics-class-api + + + org.finos.legend.engine + legend-engine-xt-analytics-function-api + + + org.finos.legend.engine + legend-engine-xt-analytics-binding-api + + + org.finos.legend.engine + legend-engine-xt-analytics-binding-api + org.finos.legend.engine legend-engine-xt-relationalStore-grammar diff --git a/legend-engine-config/legend-engine-server/src/main/java/org/finos/legend/engine/server/Server.java b/legend-engine-config/legend-engine-server/src/main/java/org/finos/legend/engine/server/Server.java index 45ea6d8881a..c0933bc6f60 100644 --- a/legend-engine-config/legend-engine-server/src/main/java/org/finos/legend/engine/server/Server.java +++ b/legend-engine-config/legend-engine-server/src/main/java/org/finos/legend/engine/server/Server.java @@ -58,8 +58,11 @@ import org.finos.legend.connection.impl.UserPasswordAuthenticationConfiguration; import org.finos.legend.connection.impl.UserPasswordCredentialBuilder; import org.finos.legend.connection.protocol.AuthenticationMechanismType; +import org.finos.legend.engine.api.analytics.BindingAnalytics; +import org.finos.legend.engine.api.analytics.ClassAnalytics; import org.finos.legend.engine.api.analytics.DataSpaceAnalytics; import org.finos.legend.engine.api.analytics.DiagramAnalytics; +import org.finos.legend.engine.api.analytics.FunctionAnalytics; import org.finos.legend.engine.api.analytics.LineageAnalytics; import org.finos.legend.engine.api.analytics.MappingAnalytics; import org.finos.legend.engine.api.analytics.StoreEntitlementAnalytics; @@ -403,6 +406,9 @@ public void run(T serverConfiguration, Environment environment) // Analytics List entitlementServiceExtensions = EntitlementServiceExtensionLoader.extensions(); environment.jersey().register(new MappingAnalytics(modelManager)); + environment.jersey().register(new ClassAnalytics(modelManager)); + environment.jersey().register(new FunctionAnalytics(modelManager)); + environment.jersey().register(new BindingAnalytics(modelManager)); environment.jersey().register(new DiagramAnalytics(modelManager)); environment.jersey().register(new DataSpaceAnalytics(modelManager, generatorExtensions, entitlementServiceExtensions)); environment.jersey().register(new LineageAnalytics(modelManager)); diff --git a/legend-engine-pure/legend-engine-pure-ide/legend-engine-pure-ide-light/src/main/java/org/finos/legend/engine/ide/PureIDELight.java b/legend-engine-pure/legend-engine-pure-ide/legend-engine-pure-ide-light/src/main/java/org/finos/legend/engine/ide/PureIDELight.java index 953743532a5..0008f70baee 100644 --- a/legend-engine-pure/legend-engine-pure-ide/legend-engine-pure-ide-light/src/main/java/org/finos/legend/engine/ide/PureIDELight.java +++ b/legend-engine-pure/legend-engine-pure-ide/legend-engine-pure-ide-light/src/main/java/org/finos/legend/engine/ide/PureIDELight.java @@ -87,6 +87,9 @@ protected MutableList buildRepositories(SourceLocationCon .with(this.buildCore("legend-engine-xts-daml/legend-engine-xt-daml-pure", "external-language-daml")) .with(this.buildCore("legend-engine-xts-changetoken/legend-engine-xt-changetoken-pure", "pure-changetoken")) .with(this.buildCore("legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure", "analytics-mapping")) + .with(this.buildCore("legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-pure", "analytics-class")) + .with(this.buildCore("legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-pure", "analytics-binding")) + .with(this.buildCore("legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-pure", "analytics-function")) .with(this.buildCore("legend-engine-xts-analytics/legend-engine-xts-analytics-lineage/legend-engine-xt-analytics-lineage-pure", "analytics-lineage")) .with(this.buildCore("legend-engine-xts-analytics/legend-engine-xts-analytics-search/legend-engine-xt-analytics-search-pure", "analytics-search")) .with(this.buildCore("legend-engine-xts-java/legend-engine-xt-javaGeneration-pure", "external-language-java")) diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-api/pom.xml b/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-api/pom.xml new file mode 100644 index 00000000000..643ae03f8f7 --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-api/pom.xml @@ -0,0 +1,147 @@ + + + + + + org.finos.legend.engine + legend-engine-xts-analytics-binding + 4.30.3-SNAPSHOT + + 4.0.0 + + legend-engine-xt-analytics-binding-api + jar + Legend Engine - XT - Analytics - Binding - API + + + + + org.finos.legend.engine + legend-engine-external-shared + + + org.finos.legend.engine + legend-engine-language-pure-modelManager + + + org.finos.legend.engine + legend-engine-protocol-pure + + + org.finos.legend.engine + legend-engine-language-pure-compiler + + + org.finos.legend.engine + legend-engine-shared-core + + + org.finos.legend.engine + legend-engine-pure-code-compiled-core + + + org.finos.legend.engine + legend-engine-xt-analytics-binding-pure + ${project.version} + + + + + + javax.ws.rs + javax.ws.rs-api + + + io.swagger + swagger-annotations + + + + + + org.pac4j.jax-rs + core + + + org.pac4j + pac4j-core + + + + + + com.fasterxml.jackson.core + jackson-annotations + + + com.fasterxml.jackson.core + jackson-databind + + + + + + org.eclipse.collections + eclipse-collections-api + + + org.eclipse.collections + eclipse-collections + + + + + + io.opentracing + opentracing-api + + + io.opentracing + opentracing-util + + + + + + junit + junit + test + + + org.finos.legend.engine + legend-engine-shared-core + test-jar + test + + + org.glassfish.jersey.core + jersey-common + test + + + org.finos.legend.engine + legend-engine-external-shared-format-model + test + + + org.finos.legend.engine + legend-engine-xt-json-model + test + + + + diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-api/src/main/java/org.finos.legend.engine.api.analytics/BindingAnalytics.java b/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-api/src/main/java/org.finos.legend.engine.api.analytics/BindingAnalytics.java new file mode 100644 index 00000000000..9dd6cb4531d --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-api/src/main/java/org.finos.legend.engine.api.analytics/BindingAnalytics.java @@ -0,0 +1,101 @@ +// Copyright 2023 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 io.opentracing.Scope; +import io.opentracing.util.GlobalTracer; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.eclipse.collections.api.RichIterable; +import org.eclipse.collections.api.list.MutableList; +import org.eclipse.collections.impl.factory.Lists; +import org.finos.legend.engine.api.analytics.model.BindingModelCoverageAnalysisInput; +import org.finos.legend.engine.external.shared.format.imports.PureModelContextDataGenerator; +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.shared.core.ObjectMapperFactory; +import org.finos.legend.engine.shared.core.api.result.ManageConstantResult; +import org.finos.legend.engine.shared.core.kerberos.ProfileManagerHelper; +import org.finos.legend.engine.shared.core.operational.errorManagement.ExceptionTool; +import org.finos.legend.engine.shared.core.operational.http.InflateInterceptor; +import org.finos.legend.engine.shared.core.operational.logs.LoggingEventType; +import org.finos.legend.pure.generated.Root_meta_analytics_binding_modelCoverage_BindingModelCoverageAnalysisResult; +import org.finos.legend.pure.generated.Root_meta_external_format_shared_binding_Binding; +import org.finos.legend.pure.generated.core_analytics_binding_modelCoverage_analytics; +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.DefaultValue; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.util.Objects; + +@Api(tags = "Analytics - Model") +@Path("pure/v1/analytics/binding") +public class BindingAnalytics +{ + private static final ObjectMapper objectMapper = ObjectMapperFactory.getNewStandardObjectMapperWithPureProtocolExtensionSupports(); + + private final ModelManager modelManager; + + public BindingAnalytics(ModelManager modelManager) + { + this.modelManager = modelManager; + } + + @POST + @Path("modelCoverage") + @ApiOperation(value = "Analyze the binding to identify models covered by the binding") + @Consumes({MediaType.APPLICATION_JSON, InflateInterceptor.APPLICATION_ZLIB}) + @Produces(MediaType.APPLICATION_JSON) + public Response analyzeBindingModelCoverage(BindingModelCoverageAnalysisInput input, + @QueryParam("includeBinding") @DefaultValue("true") boolean includeBinding, + @ApiParam(hidden = true) @Pac4JProfileManager ProfileManager pm) + { + 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); + Root_meta_external_format_shared_binding_Binding binding = (Root_meta_external_format_shared_binding_Binding) pureModel.getPackageableElement(input.binding); + RichIterable bindings = Lists.immutable.of(binding); + + try (Scope scope = GlobalTracer.get().buildSpan("Analytics: binding model coverage").startActive(true)) + { + try + { + Root_meta_analytics_binding_modelCoverage_BindingModelCoverageAnalysisResult result = core_analytics_binding_modelCoverage_analytics.Root_meta_analytics_binding_modelCoverage_getBindingModelCoverage_Binding_MANY__BindingModelCoverageAnalysisResult_1_(bindings, pureModel.getExecutionSupport()); + PureModelContextData classes = PureModelContextDataGenerator.generatePureModelContextDataFromClasses(result._classes(), input.clientVersion, pureModel.getExecutionSupport()); + PureModelContextData.Builder builder = PureModelContextData.newBuilder(); + if (includeBinding) + { + builder.addElement(Objects.requireNonNull(pureModelContextData.getElements().stream().filter(el -> input.binding.equals(el.getPath())).findFirst().get())); + } + return ManageConstantResult.manageResult(profiles, builder.build().combine(classes), objectMapper); + } + catch (Exception e) + { + return ExceptionTool.exceptionManager(e, LoggingEventType.ANALYTICS_ERROR, Response.Status.BAD_REQUEST, profiles); + } + } + } +} diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-api/src/main/java/org.finos.legend.engine.api.analytics/model/BindingModelCoverageAnalysisInput.java b/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-api/src/main/java/org.finos.legend.engine.api.analytics/model/BindingModelCoverageAnalysisInput.java new file mode 100644 index 00000000000..656d40d2ff4 --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-api/src/main/java/org.finos.legend.engine.api.analytics/model/BindingModelCoverageAnalysisInput.java @@ -0,0 +1,41 @@ +// Copyright 2023 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.model; + +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 BindingModelCoverageAnalysisInput +{ + public String clientVersion; + + @JsonProperty(required = true) + public String binding; + + @JsonProperty(required = true) + public PureModelContext model; + + @JsonCreator + public BindingModelCoverageAnalysisInput( + @JsonProperty("clientVersion") String clientVersion, + @JsonProperty("binding") String binding, + @JsonProperty("model") PureModelContext model) + { + this.clientVersion = clientVersion; + this.binding = binding; + this.model = model; + } +} \ No newline at end of file diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-api/src/test/java/org.finos.legend.engine.api.analytics.test/TestBindingAnalyticsApi.java b/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-api/src/test/java/org.finos.legend.engine.api.analytics.test/TestBindingAnalyticsApi.java new file mode 100644 index 00000000000..6fd42f506e1 --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-api/src/test/java/org.finos.legend.engine.api.analytics.test/TestBindingAnalyticsApi.java @@ -0,0 +1,44 @@ +// Copyright 2023 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.test; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.finos.legend.engine.api.analytics.BindingAnalytics; +import org.finos.legend.engine.api.analytics.model.BindingModelCoverageAnalysisInput; +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.shared.core.ObjectMapperFactory; +import org.finos.legend.engine.shared.core.deployment.DeploymentMode; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.util.Objects; + +public class TestBindingAnalyticsApi +{ + private final BindingAnalytics api = new BindingAnalytics(new ModelManager(DeploymentMode.TEST)); + private static final ObjectMapper objectMapper = ObjectMapperFactory.getNewStandardObjectMapperWithPureProtocolExtensionSupports(); + + @Test + public void testBindingModelCoverageAnalysis() throws IOException + { + PureModelContextData modelContextData = objectMapper.readValue(Objects.requireNonNull(getClass().getClassLoader().getResource("bindingModelCoverageAnalysisTestData.json")), PureModelContextData.class); + Assert.assertEquals( + "{\"_type\":\"data\",\"elements\":[{\"_type\":\"class\",\"constraints\":[],\"name\":\"Person\",\"originalMilestonedProperties\":[],\"package\":\"model\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"binding\",\"contentType\":\"application/json\",\"modelUnit\":{\"packageableElementExcludes\":[],\"packageableElementIncludes\":[\"model::Person\"]},\"name\":\"personBinding\",\"package\":\"model\"}]}", + api.analyzeBindingModelCoverage(new BindingModelCoverageAnalysisInput("vX_X_X", "model::personBinding", modelContextData), true, null).getEntity().toString()); + } +} + diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-api/src/test/resources/bindingModelCoverageAnalysisTestData.json b/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-api/src/test/resources/bindingModelCoverageAnalysisTestData.json new file mode 100644 index 00000000000..f0657fb0b0d --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-api/src/test/resources/bindingModelCoverageAnalysisTestData.json @@ -0,0 +1,399 @@ +{ + "_type": "data", + "elements": [ + { + "_type": "binding", + "contentType": "application/json", + "modelUnit": { + "packageableElementExcludes": [], + "packageableElementIncludes": [ + "model::Person" + ] + }, + "name": "personBinding", + "package": "model" + }, + { + "_type": "Enumeration", + "name": "OrgType", + "package": "model", + "stereotypes": [], + "taggedValues": [], + "values": [ + { + "stereotypes": [], + "taggedValues": [], + "value": "CORP" + }, + { + "stereotypes": [], + "taggedValues": [], + "value": "LLC" + } + ] + }, + { + "_type": "class", + "constraints": [], + "name": "Person", + "originalMilestonedProperties": [], + "package": "model", + "properties": [ + { + "multiplicity": { + "lowerBound": 1, + "upperBound": 1 + }, + "name": "firstName", + "stereotypes": [], + "taggedValues": [], + "type": "String" + }, + { + "multiplicity": { + "lowerBound": 1, + "upperBound": 1 + }, + "name": "lastName", + "stereotypes": [], + "taggedValues": [], + "type": "String" + } + ], + "qualifiedProperties": [], + "stereotypes": [], + "superTypes": [], + "taggedValues": [] + }, + { + "_type": "class", + "constraints": [], + "name": "Organization", + "originalMilestonedProperties": [], + "package": "model", + "properties": [ + { + "multiplicity": { + "lowerBound": 1, + "upperBound": 1 + }, + "name": "name", + "stereotypes": [], + "taggedValues": [], + "type": "String" + }, + { + "multiplicity": { + "lowerBound": 0 + }, + "name": "employees", + "stereotypes": [], + "taggedValues": [], + "type": "model::Person" + }, + { + "multiplicity": { + "lowerBound": 1, + "upperBound": 1 + }, + "name": "type", + "stereotypes": [], + "taggedValues": [], + "type": "String" + } + ], + "qualifiedProperties": [], + "stereotypes": [], + "superTypes": [], + "taggedValues": [] + }, + { + "_type": "class", + "constraints": [], + "name": "Trader", + "originalMilestonedProperties": [], + "package": "model", + "properties": [ + { + "multiplicity": { + "lowerBound": 1, + "upperBound": 1 + }, + "name": "fullName", + "stereotypes": [], + "taggedValues": [], + "type": "String" + } + ], + "qualifiedProperties": [], + "stereotypes": [], + "superTypes": [], + "taggedValues": [] + }, + { + "_type": "class", + "constraints": [], + "name": "Bank", + "originalMilestonedProperties": [], + "package": "model", + "properties": [ + { + "multiplicity": { + "lowerBound": 1, + "upperBound": 1 + }, + "name": "entityName", + "stereotypes": [], + "taggedValues": [], + "type": "String" + }, + { + "multiplicity": { + "lowerBound": 0 + }, + "name": "employees", + "stereotypes": [], + "taggedValues": [], + "type": "model::Trader" + }, + { + "multiplicity": { + "lowerBound": 1, + "upperBound": 1 + }, + "name": "type", + "stereotypes": [], + "taggedValues": [], + "type": "model::OrgType" + } + ], + "qualifiedProperties": [], + "stereotypes": [], + "superTypes": [], + "taggedValues": [] + }, + { + "_type": "function", + "body": [ + { + "_type": "func", + "function": "plus", + "parameters": [ + { + "_type": "collection", + "multiplicity": { + "lowerBound": 3, + "upperBound": 3 + }, + "values": [ + { + "_type": "property", + "parameters": [ + { + "_type": "var", + "name": "person" + } + ], + "property": "firstName" + }, + { + "_type": "string", + "value": " " + }, + { + "_type": "property", + "parameters": [ + { + "_type": "var", + "name": "person" + } + ], + "property": "lastName" + } + ] + } + ] + } + ], + "name": "personFullName_Person_1__String_1_", + "package": "model", + "parameters": [ + { + "_type": "var", + "class": "model::Person", + "multiplicity": { + "lowerBound": 1, + "upperBound": 1 + }, + "name": "person" + } + ], + "postConstraints": [], + "preConstraints": [], + "returnMultiplicity": { + "lowerBound": 1, + "upperBound": 1 + }, + "returnType": "String", + "stereotypes": [], + "taggedValues": [] + }, + { + "_type": "mapping", + "associationMappings": [], + "classMappings": [ + { + "_type": "pureInstance", + "class": "model::Trader", + "propertyMappings": [ + { + "_type": "purePropertyMapping", + "explodeProperty": false, + "property": { + "class": "model::Trader", + "property": "fullName" + }, + "source": "", + "transform": { + "_type": "lambda", + "body": [ + { + "_type": "func", + "function": "plus", + "parameters": [ + { + "_type": "collection", + "multiplicity": { + "lowerBound": 3, + "upperBound": 3 + }, + "values": [ + { + "_type": "property", + "parameters": [ + { + "_type": "var", + "name": "src" + } + ], + "property": "firstName" + }, + { + "_type": "string", + "value": " " + }, + { + "_type": "property", + "parameters": [ + { + "_type": "var", + "name": "src" + } + ], + "property": "lastName" + } + ] + } + ] + } + ], + "parameters": [] + } + } + ], + "root": true, + "srcClass": "model::Person" + }, + { + "_type": "pureInstance", + "class": "model::Bank", + "propertyMappings": [ + { + "_type": "purePropertyMapping", + "explodeProperty": false, + "property": { + "class": "model::Bank", + "property": "employees" + }, + "source": "", + "target": "model_Trader", + "transform": { + "_type": "lambda", + "body": [ + { + "_type": "property", + "parameters": [ + { + "_type": "var", + "name": "src" + } + ], + "property": "employees" + } + ], + "parameters": [] + } + }, + { + "_type": "purePropertyMapping", + "enumMappingId": "model_OrgType", + "explodeProperty": false, + "property": { + "class": "model::Bank", + "property": "type" + }, + "source": "", + "transform": { + "_type": "lambda", + "body": [ + { + "_type": "property", + "parameters": [ + { + "_type": "var", + "name": "src" + } + ], + "property": "type" + } + ], + "parameters": [] + } + } + ], + "root": true, + "srcClass": "model::Organization" + } + ], + "enumerationMappings": [ + { + "enumValueMappings": [ + { + "enumValue": "CORP", + "sourceValues": [ + { + "_type": "stringSourceValue", + "value": "corporation" + } + ] + }, + { + "enumValue": "LLC", + "sourceValues": [ + { + "_type": "stringSourceValue", + "value": "limitted" + } + ] + } + ], + "enumeration": "model::OrgType" + } + ], + "includedMappings": [], + "name": "mapping", + "package": "model", + "tests": [] + } + ] +} \ No newline at end of file diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-pure/pom.xml b/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-pure/pom.xml new file mode 100644 index 00000000000..814ecbe68bc --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-pure/pom.xml @@ -0,0 +1,139 @@ + + + + + + org.finos.legend.engine + legend-engine-xts-analytics-binding + 4.30.3-SNAPSHOT + + 4.0.0 + + legend-engine-xt-analytics-binding-pure + jar + Legend Engine - XT - Analytics - Binding - PAR/JAVA + + + + + org.finos.legend.pure + legend-pure-maven-generation-par + + src/main/resources + ${legend.pure.version} + + core_analytics_binding + + + ${project.basedir}/src/main/resources/core_analytics_binding.definition.json + + + + + generate-sources + + build-pure-jar + + + + + + org.finos.legend.pure + legend-pure-m2-dsl-diagram-grammar + ${legend.pure.version} + + + org.finos.legend.engine + legend-engine-pure-code-compiled-core + ${project.version} + + + + + org.finos.legend.pure + legend-pure-maven-generation-java + + + compile + + build-pure-compiled-jar + + + true + true + modular + true + + core_analytics_binding + + + + + + + org.finos.legend.pure + legend-pure-m2-dsl-diagram-grammar + ${legend.pure.version} + + + org.finos.legend.engine + legend-engine-pure-code-compiled-core + ${project.version} + + + + + + + + + + org.finos.legend.pure + legend-pure-m4 + + + org.finos.legend.pure + legend-pure-m3-core + + + org.finos.legend.pure + legend-pure-runtime-java-engine-compiled + + + + + + org.finos.legend.engine + legend-engine-pure-platform-java + + + org.finos.legend.engine + legend-engine-pure-code-compiled-core + ${project.version} + + + + + org.eclipse.collections + eclipse-collections + + + org.eclipse.collections + eclipse-collections-api + + + diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-pure/src/main/java/org.finos.legend.pure.code.core/CoreExternalBindingAnalysisCodeRepositoryProvider.java b/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-pure/src/main/java/org.finos.legend.pure.code.core/CoreExternalBindingAnalysisCodeRepositoryProvider.java new file mode 100644 index 00000000000..69082b86343 --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-pure/src/main/java/org.finos.legend.pure.code.core/CoreExternalBindingAnalysisCodeRepositoryProvider.java @@ -0,0 +1,28 @@ +// Copyright 2023 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.pure.code.core; + +import org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepository; +import org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepositoryProvider; +import org.finos.legend.pure.m3.serialization.filesystem.repository.GenericCodeRepository; + +public class CoreExternalBindingAnalysisCodeRepositoryProvider implements CodeRepositoryProvider +{ + @Override + public CodeRepository repository() + { + return GenericCodeRepository.build("core_analytics_binding.definition.json"); + } +} diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-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-binding/legend-engine-xt-analytics-binding-pure/src/main/resources/META-INF/services/org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepositoryProvider new file mode 100644 index 00000000000..32e0375435d --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-pure/src/main/resources/META-INF/services/org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepositoryProvider @@ -0,0 +1 @@ +org.finos.legend.pure.code.core.CoreExternalBindingAnalysisCodeRepositoryProvider \ No newline at end of file diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-pure/src/main/resources/core_analytics_binding.definition.json b/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-pure/src/main/resources/core_analytics_binding.definition.json new file mode 100644 index 00000000000..fd38d51e2ab --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-pure/src/main/resources/core_analytics_binding.definition.json @@ -0,0 +1,11 @@ +{ + "name": "core_analytics_binding", + "pattern": "(meta::analytics::binding)(::.*)?", + "dependencies": [ + "platform", + "platform_functions", + "core", + "core_functions", + "platform_functions_json" + ] +} diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-pure/src/main/resources/core_analytics_binding/modelCoverage/analytics.pure b/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-pure/src/main/resources/core_analytics_binding/modelCoverage/analytics.pure new file mode 100644 index 00000000000..636e39436a1 --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/legend-engine-xt-analytics-binding-pure/src/main/resources/core_analytics_binding/modelCoverage/analytics.pure @@ -0,0 +1,37 @@ +// Copyright 2023 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. + +import meta::analytics::binding::modelCoverage::*; +import meta::external::format::shared::binding::*; +import meta::pure::model::unit::*; + +Class meta::analytics::binding::modelCoverage::BindingModelCoverageAnalysisResult +{ + classes: Class[*]; +} + +function meta::analytics::binding::modelCoverage::getBindingModelCoverage(bindings: Binding[*]):BindingModelCoverageAnalysisResult[1] +{ + let coveredClasses = $bindings->map(b | $b.modelUnit->resolve().classes); + + let prunedClasses = $coveredClasses->removeDuplicates()->map(c|^Class( + name = $c.name, + package = $c.package + )); + + ^BindingModelCoverageAnalysisResult + ( + classes = $prunedClasses + ); +} \ No newline at end of file diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/pom.xml b/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/pom.xml new file mode 100644 index 00000000000..e6529bb3240 --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-binding/pom.xml @@ -0,0 +1,33 @@ + + + + + org.finos.legend.engine + legend-engine-xts-analytics + 4.30.3-SNAPSHOT + + 4.0.0 + + legend-engine-xts-analytics-binding + pom + Legend Engine - XTS - Analytics + + + legend-engine-xt-analytics-binding-pure + legend-engine-xt-analytics-binding-api + + \ No newline at end of file diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-api/pom.xml b/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-api/pom.xml new file mode 100644 index 00000000000..f93e1b2db5f --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-api/pom.xml @@ -0,0 +1,148 @@ + + + + + + org.finos.legend.engine + legend-engine-xts-analytics-class + 4.30.3-SNAPSHOT + + 4.0.0 + + legend-engine-xt-analytics-class-api + jar + Legend Engine - XT - Analytics - Class - API + + + + + org.finos.legend.pure + legend-pure-m3-core + + + + + + org.finos.legend.engine + legend-engine-external-shared + + + org.finos.legend.engine + legend-engine-language-pure-modelManager + + + org.finos.legend.engine + legend-engine-protocol-pure + + + org.finos.legend.engine + legend-engine-language-pure-compiler + + + org.finos.legend.engine + legend-engine-xt-analytics-class-pure + ${project.version} + + + org.finos.legend.engine + legend-engine-shared-core + + + + + + javax.ws.rs + javax.ws.rs-api + + + io.swagger + swagger-annotations + + + + + + org.pac4j.jax-rs + core + + + org.pac4j + pac4j-core + + + + + + com.fasterxml.jackson.core + jackson-annotations + + + com.fasterxml.jackson.core + jackson-databind + + + + + + org.eclipse.collections + eclipse-collections-api + + + org.eclipse.collections + eclipse-collections + + + + + + io.opentracing + opentracing-api + + + io.opentracing + opentracing-util + + + + + + log4j + log4j + test + + + + + + junit + junit + test + + + org.finos.legend.engine + legend-engine-shared-core + test-jar + test + + + org.glassfish.jersey.core + jersey-common + test + + + + diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-api/src/main/java/org.finos.legend.engine.api.analytics/ClassAnalytics.java b/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-api/src/main/java/org.finos.legend.engine.api.analytics/ClassAnalytics.java new file mode 100644 index 00000000000..be8de745a92 --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-api/src/main/java/org.finos.legend.engine.api.analytics/ClassAnalytics.java @@ -0,0 +1,104 @@ +// Copyright 2023 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 io.opentracing.Scope; +import io.opentracing.util.GlobalTracer; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.eclipse.collections.api.RichIterable; +import org.eclipse.collections.api.list.MutableList; +import org.eclipse.collections.impl.factory.Lists; +import org.finos.legend.engine.api.analytics.model.ClassModelCoverageAnalysisInput; +import org.finos.legend.engine.external.shared.format.imports.PureModelContextDataGenerator; +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.shared.core.ObjectMapperFactory; +import org.finos.legend.engine.shared.core.api.result.ManageConstantResult; +import org.finos.legend.engine.shared.core.kerberos.ProfileManagerHelper; +import org.finos.legend.engine.shared.core.operational.errorManagement.ExceptionTool; +import org.finos.legend.engine.shared.core.operational.http.InflateInterceptor; +import org.finos.legend.engine.shared.core.operational.logs.LoggingEventType; +import org.finos.legend.pure.generated.Root_meta_analytics_class_modelCoverage_ClassModelCoverageAnalysisResult; +import org.finos.legend.pure.generated.core_analytics_class_modelCoverage_analytics; +import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.extension.Profile; +import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.Class; +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.DefaultValue; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.util.Objects; + +@Api(tags = "Analytics - Model") +@Path("pure/v1/analytics/Class") +public class ClassAnalytics +{ + private static final ObjectMapper objectMapper = ObjectMapperFactory.getNewStandardObjectMapperWithPureProtocolExtensionSupports(); + + private final ModelManager modelManager; + + public ClassAnalytics(ModelManager modelManager) + { + this.modelManager = modelManager; + } + + @POST + @Path("modelCoverage") + @ApiOperation(value = "Analyze the class to identify models covered by the class") + @Consumes({MediaType.APPLICATION_JSON, InflateInterceptor.APPLICATION_ZLIB}) + @Produces(MediaType.APPLICATION_JSON) + public Response analyzeClassModelCoverage(ClassModelCoverageAnalysisInput input, + @QueryParam("includeClass") @DefaultValue("true") boolean includeClass, + @ApiParam(hidden = true) @Pac4JProfileManager ProfileManager pm) + { + 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); + Class _class = pureModel.getClass(input._class); + + try (Scope scope = GlobalTracer.get().buildSpan("Analytics: class model coverage").startActive(true)) + { + try + { + Root_meta_analytics_class_modelCoverage_ClassModelCoverageAnalysisResult result = core_analytics_class_modelCoverage_analytics.Root_meta_analytics_class_modelCoverage_getClassModelCoverage_Class_MANY__ClassModelCoverageAnalysisResult_1_(Lists.immutable.of(_class), pureModel.getExecutionSupport()); + PureModelContextData classes = PureModelContextDataGenerator.generatePureModelContextDataFromClasses(result._classes(), input.clientVersion, pureModel.getExecutionSupport()); + PureModelContextData enums = PureModelContextDataGenerator.generatePureModelContextDataFromEnumerations(result._enumerations(), input.clientVersion, pureModel.getExecutionSupport()); + PureModelContextData _profiles = PureModelContextDataGenerator.generatePureModelContextDataFromProfile((RichIterable) result._profiles(), input.clientVersion, pureModel.getExecutionSupport()); + PureModelContextData associations = PureModelContextDataGenerator.generatePureModelContextDataFromAssociations(result._associations(), input.clientVersion, pureModel.getExecutionSupport()); + PureModelContextData.Builder builder = PureModelContextData.newBuilder(); + if (includeClass) + { + builder.addElement(Objects.requireNonNull(pureModelContextData.getElements().stream().filter(el -> input._class.equals(el.getPath())).findFirst().get())); + } + return ManageConstantResult.manageResult(profiles, builder.build().combine(classes).combine(enums).combine(_profiles).combine(associations), objectMapper); + } + catch (Exception e) + { + return ExceptionTool.exceptionManager(e, LoggingEventType.ANALYTICS_ERROR, Response.Status.BAD_REQUEST, profiles); + } + } + } +} diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-api/src/main/java/org.finos.legend.engine.api.analytics/model/ClassModelCoverageAnalysisInput.java b/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-api/src/main/java/org.finos.legend.engine.api.analytics/model/ClassModelCoverageAnalysisInput.java new file mode 100644 index 00000000000..2d2658700f8 --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-api/src/main/java/org.finos.legend.engine.api.analytics/model/ClassModelCoverageAnalysisInput.java @@ -0,0 +1,41 @@ +// Copyright 2023 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.model; + +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 ClassModelCoverageAnalysisInput +{ + public String clientVersion; + + @JsonProperty(required = true) + public String _class; + + @JsonProperty(required = true) + public PureModelContext model; + + @JsonCreator + public ClassModelCoverageAnalysisInput( + @JsonProperty("clientVersion") String clientVersion, + @JsonProperty("_class") String _class, + @JsonProperty("model") PureModelContext model) + { + this.clientVersion = clientVersion; + this._class = _class; + this.model = model; + } +} \ No newline at end of file diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-api/src/test/java/org.finos.legend.engine.api.analytics.test/TestClassAnalyticsApi.java b/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-api/src/test/java/org.finos.legend.engine.api.analytics.test/TestClassAnalyticsApi.java new file mode 100644 index 00000000000..fa1a59055d3 --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-api/src/test/java/org.finos.legend.engine.api.analytics.test/TestClassAnalyticsApi.java @@ -0,0 +1,44 @@ +// Copyright 2023 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.test; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.finos.legend.engine.api.analytics.ClassAnalytics; +import org.finos.legend.engine.api.analytics.model.ClassModelCoverageAnalysisInput; +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.shared.core.ObjectMapperFactory; +import org.finos.legend.engine.shared.core.deployment.DeploymentMode; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.util.Objects; + +public class TestClassAnalyticsApi +{ + private final ClassAnalytics api = new ClassAnalytics(new ModelManager(DeploymentMode.TEST)); + private static final ObjectMapper objectMapper = ObjectMapperFactory.getNewStandardObjectMapperWithPureProtocolExtensionSupports(); + + @Test + public void testClassModelCoverageAnalysis() throws IOException + { + PureModelContextData modelContextData = objectMapper.readValue(Objects.requireNonNull(getClass().getClassLoader().getResource("classModelCoverageAnalysisTestData.json")), PureModelContextData.class); + Assert.assertEquals( + "{\"_type\":\"data\",\"elements\":[{\"_type\":\"class\",\"constraints\":[],\"name\":\"Organization\",\"originalMilestonedProperties\":[],\"package\":\"model\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"name\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"},{\"multiplicity\":{\"lowerBound\":0},\"name\":\"employees\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::Person\"},{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"type\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Person\",\"originalMilestonedProperties\":[],\"package\":\"model\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]}]}", + api.analyzeClassModelCoverage(new ClassModelCoverageAnalysisInput("vX_X_X", "model::Organization", modelContextData), true, null).getEntity().toString()); + } +} + diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-api/src/test/resources/classModelCoverageAnalysisTestData.json b/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-api/src/test/resources/classModelCoverageAnalysisTestData.json new file mode 100644 index 00000000000..a2f5e93e068 --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-api/src/test/resources/classModelCoverageAnalysisTestData.json @@ -0,0 +1,275 @@ +{ + "_type": "data", + "elements": [ + { + "_type": "Enumeration", + "name": "OrgType", + "package": "model", + "values": [ + { + "value": "CORP" + }, + { + "value": "LLC" + } + ] + }, + { + "_type": "class", + "name": "Person", + "package": "model", + "properties": [ + { + "multiplicity": { + "lowerBound": 1, + "upperBound": 1 + }, + "name": "firstName", + "type": "String" + }, + { + "multiplicity": { + "lowerBound": 1, + "upperBound": 1 + }, + "name": "lastName", + "type": "String" + } + ] + }, + { + "_type": "class", + "name": "Organization", + "package": "model", + "properties": [ + { + "multiplicity": { + "lowerBound": 1, + "upperBound": 1 + }, + "name": "name", + "type": "String" + }, + { + "multiplicity": { + "lowerBound": 0 + }, + "name": "employees", + "type": "model::Person" + }, + { + "multiplicity": { + "lowerBound": 1, + "upperBound": 1 + }, + "name": "type", + "type": "String" + } + ] + }, + { + "_type": "class", + "name": "Trader", + "package": "model", + "properties": [ + { + "multiplicity": { + "lowerBound": 1, + "upperBound": 1 + }, + "name": "fullName", + "type": "String" + } + ] + }, + { + "_type": "class", + "name": "Bank", + "package": "model", + "properties": [ + { + "multiplicity": { + "lowerBound": 1, + "upperBound": 1 + }, + "name": "entityName", + "type": "String" + }, + { + "multiplicity": { + "lowerBound": 0 + }, + "name": "employees", + "type": "model::Trader" + }, + { + "multiplicity": { + "lowerBound": 1, + "upperBound": 1 + }, + "name": "type", + "type": "model::OrgType" + } + ] + }, + { + "_type": "mapping", + "classMappings": [ + { + "_type": "pureInstance", + "class": "model::Trader", + "propertyMappings": [ + { + "_type": "purePropertyMapping", + "property": { + "class": "model::Trader", + "property": "fullName" + }, + "source": "model_Trader", + "transform": { + "_type": "lambda", + "body": [ + { + "_type": "func", + "function": "plus", + "parameters": [ + { + "_type": "collection", + "multiplicity": { + "lowerBound": 3, + "upperBound": 3 + }, + "values": [ + { + "_type": "property", + "parameters": [ + { + "_type": "var", + "name": "src" + } + ], + "property": "firstName" + }, + { + "_type": "string", + "multiplicity": { + "lowerBound": 1, + "upperBound": 1 + }, + "values": [ + " " + ] + }, + { + "_type": "property", + "parameters": [ + { + "_type": "var", + "name": "src" + } + ], + "property": "lastName" + } + ] + } + ] + } + ], + "parameters": [] + } + } + ], + "root": true, + "srcClass": "model::Person" + }, + { + "_type": "pureInstance", + "class": "model::Bank", + "propertyMappings": [ + { + "_type": "purePropertyMapping", + "property": { + "class": "model::Bank", + "property": "employees" + }, + "source": "model_Bank", + "target": "model_Trader", + "transform": { + "_type": "lambda", + "body": [ + { + "_type": "property", + "parameters": [ + { + "_type": "var", + "name": "src" + } + ], + "property": "employees" + } + ], + "parameters": [] + } + }, + { + "_type": "purePropertyMapping", + "enumMappingId": "model_OrgType", + "property": { + "class": "model::Bank", + "property": "type" + }, + "source": "model_Bank", + "transform": { + "_type": "lambda", + "body": [ + { + "_type": "property", + "parameters": [ + { + "_type": "var", + "name": "src" + } + ], + "property": "type" + } + ], + "parameters": [] + } + } + ], + "root": true, + "srcClass": "model::Organization" + } + ], + "enumerationMappings": [ + { + "enumValueMappings": [ + { + "enumValue": "CORP", + "sourceValues": [ + { + "_type": "stringSourceValue", + "value": "corporation" + } + ] + }, + { + "enumValue": "LLC", + "sourceValues": [ + { + "_type": "stringSourceValue", + "value": "limitted" + } + ] + } + ], + "enumeration": "model::OrgType" + } + ], + "includedMappings": [], + "name": "mapping", + "package": "model", + "tests": [] + } + ] +} \ No newline at end of file diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-pure/pom.xml b/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-pure/pom.xml new file mode 100644 index 00000000000..f0ca04af9a6 --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-pure/pom.xml @@ -0,0 +1,143 @@ + + + + + + org.finos.legend.engine + legend-engine-xts-analytics-class + 4.30.3-SNAPSHOT + + 4.0.0 + + legend-engine-xt-analytics-class-pure + jar + Legend Engine - XT - Analytics - Class - PAR/JAVA + + + + + org.finos.legend.pure + legend-pure-maven-generation-par + + src/main/resources + ${legend.pure.version} + + core_analytics_class + + + ${project.basedir}/src/main/resources/core_analytics_class.definition.json + + + + + generate-sources + + build-pure-jar + + + + + + org.finos.legend.pure + legend-pure-m2-dsl-diagram-grammar + ${legend.pure.version} + + + org.finos.legend.engine + legend-engine-pure-code-compiled-functions + ${project.version} + + + + + org.finos.legend.pure + legend-pure-maven-generation-java + + + compile + + build-pure-compiled-jar + + + true + true + modular + true + + core_analytics_class + + + + + + + org.finos.legend.pure + legend-pure-m2-dsl-diagram-grammar + ${legend.pure.version} + + + org.finos.legend.engine + legend-engine-pure-code-compiled-functions + ${project.version} + + + + + + + + + + org.finos.legend.pure + legend-pure-m4 + + + org.finos.legend.pure + legend-pure-m3-core + + + org.finos.legend.pure + legend-pure-runtime-java-engine-compiled + + + + + + org.finos.legend.engine + legend-engine-pure-platform-java + + + org.finos.legend.engine + legend-engine-pure-platform-functions-java + + + org.finos.legend.engine + legend-engine-pure-code-compiled-functions + ${project.version} + + + + + org.eclipse.collections + eclipse-collections + + + org.eclipse.collections + eclipse-collections-api + + + diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-pure/src/main/java/org.finos.legend.pure.code.core/CoreExternalClassAnalysisCodeRepositoryProvider.java b/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-pure/src/main/java/org.finos.legend.pure.code.core/CoreExternalClassAnalysisCodeRepositoryProvider.java new file mode 100644 index 00000000000..fe99d9e9199 --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-pure/src/main/java/org.finos.legend.pure.code.core/CoreExternalClassAnalysisCodeRepositoryProvider.java @@ -0,0 +1,28 @@ +// Copyright 2023 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.pure.code.core; + +import org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepository; +import org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepositoryProvider; +import org.finos.legend.pure.m3.serialization.filesystem.repository.GenericCodeRepository; + +public class CoreExternalClassAnalysisCodeRepositoryProvider implements CodeRepositoryProvider +{ + @Override + public CodeRepository repository() + { + return GenericCodeRepository.build("core_analytics_class.definition.json"); + } +} diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-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-class/legend-engine-xt-analytics-class-pure/src/main/resources/META-INF/services/org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepositoryProvider new file mode 100644 index 00000000000..cd37792e3cf --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-pure/src/main/resources/META-INF/services/org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepositoryProvider @@ -0,0 +1 @@ +org.finos.legend.pure.code.core.CoreExternalClassAnalysisCodeRepositoryProvider \ No newline at end of file diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-pure/src/main/resources/core_analytics_class.definition.json b/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-pure/src/main/resources/core_analytics_class.definition.json new file mode 100644 index 00000000000..8032fc0162f --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-pure/src/main/resources/core_analytics_class.definition.json @@ -0,0 +1,9 @@ +{ + "name": "core_analytics_class", + "pattern": "(meta::analytics::class)(::.*)?", + "dependencies": [ + "platform", + "platform_functions", + "core_functions" + ] +} diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-pure/src/main/resources/core_analytics_class/modelCoverage/analytics.pure b/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-pure/src/main/resources/core_analytics_class/modelCoverage/analytics.pure new file mode 100644 index 00000000000..6ab79ec2308 --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-pure/src/main/resources/core_analytics_class/modelCoverage/analytics.pure @@ -0,0 +1,128 @@ +// Copyright 2023 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. + +import meta::analytics::class::modelCoverage::utility::*; +import meta::analytics::class::modelCoverage::*; +import meta::pure::milestoning::*; + +Class meta::analytics::class::modelCoverage::ClassModelCoverageAnalysisResult +{ + classes: Class[*]; + enumerations: Enumeration[*]; + associations: Association[*]; + profiles: Profile[*]; +} + +function meta::analytics::class::modelCoverage::getClassModelCoverage(_classes: Class[*]):ClassModelCoverageAnalysisResult[1] +{ + // superTypes + let superClasses = $_classes->map(c | $c->superTypes()); + let classes = $_classes->concatenate($superClasses); + + // associations + let allPropertiesFromAssociations = $classes.propertiesFromAssociations; + let allQualifiedPropertiesFromAssociations = $classes.qualifiedPropertiesFromAssociations; + let associations = $allPropertiesFromAssociations.owner->filter(t|$t->instanceOf(Association))->cast(@Association)->removeDuplicates(); + let associationClasses = $associations.properties->map(p|$p.genericType.rawType) + ->filter(t|$t->instanceOf(Class))->cast(@Class)->removeDuplicates()->filter(c|!$classes->contains($c)); + + // properties + let allProperties = $classes.properties; + let allQualifiedProperties = $classes.qualifiedProperties; + let foundClasses = $classes->concatenate($associationClasses); + let propertyTypes = $allProperties->map(p|$p.genericType.rawType)->concatenate($allQualifiedProperties->map(p|$p.genericType.rawType)); + let propertyClasses = $propertyTypes->filter(t|$t->instanceOf(Class))->cast(@Class)->removeDuplicates()->filter(c|!$foundClasses->contains($c)); + + // enumerations + let enumerations = $propertyTypes->filter(t|$t->instanceOf(Enumeration))->cast(@Enumeration)->removeDuplicates(); + + // NOTE: following, we prune the tagged values and stereotypes from the enumerations, associations, and classes + // so we don't have to return them, if in the future, we need to return these (as this analytics require to do so) + // we should reconsider these optimization + let prunedEnumerations = $enumerations->map(e|^$e( + stereotypes = [], + taggedValues = [], + values = meta::pure::functions::meta::enumValues($e)->map(v|^$v( + stereotypes = [], + taggedValues = [] + ))->toOneMany() // this is a hack to work around a problem with validation on size of enumeration values + )); + + let prunedClasses = $classes->map(c|^$c( + properties = $c.properties->reverseMilestoningTransforms()->map(p|^$p( + stereotypes = [], + taggedValues = [] + )), + qualifiedProperties = $c.qualifiedProperties->reverseMilestoningTransforms()->cast(@QualifiedProperty)->map(p|^$p( + stereotypes = [], + taggedValues = [] + )) + )); + + // NOTE: for classes found from association and properties only, we just need to stub them + let prunedPropertyClasses = $propertyClasses->map(c|^Class( + name = $c.name, + package = $c.package + )); + let prunedAssociationClasses = $associationClasses->map(c|^Class( + name = $c.name, + package = $c.package + )); + + // Remove duplicate classes. + let prunedClassPaths = $prunedClasses->map(c | $c->elementToPath()); + let prunedStubClasses = $prunedAssociationClasses->concatenate($prunedPropertyClasses) + ->removeDuplicates()->filter(c | !$prunedClassPaths->contains($c->elementToPath())); + let coveredClasses = $prunedClasses->concatenate($prunedStubClasses); + + // NOTE: prune here so we don't have to do analytics to find the used profiles + let prunedAssociations = $associations->map(a| + let props = $a.properties->reverseMilestoningTransforms()->cast(@Property)->map(p|^$p( + stereotypes = [], + taggedValues = [] + )); + let newProps = [$props->at(0), $props->at(1)]; + ^$a( + stereotypes = [], + taggedValues = [], + properties = $newProps, + qualifiedProperties = $a.qualifiedProperties->reverseMilestoningTransforms()->cast(@QualifiedProperty)->map(p|^$p( + stereotypes = [], + taggedValues = [] + )) + ); + ); + + // profile + // NOTE: we don't support showing tagged values and stereotypes for properties at the moment + let profiles = $classes->map(class|$class.taggedValues->map(tv|$tv.tag.profile) + ->concatenate($class.stereotypes->map(st|$st.profile)) + ->cast(@Profile)->removeDuplicates()); + + // TODO?: prune profile - e.g. we can prune profile to limit to used tags and stereotypes only + let prunedProfiles = $profiles->map(p|^Profile( + name = $p.name, + package = $p.package, + p_tags = $p.p_tags, + p_stereotypes = $p.p_stereotypes + )); + + ^ClassModelCoverageAnalysisResult + ( + classes = $coveredClasses, + profiles = $prunedProfiles, + enumerations = $prunedEnumerations, + associations = $prunedAssociations + ); +} diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-pure/src/main/resources/core_analytics_class/modelCoverage/utility.pure b/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-pure/src/main/resources/core_analytics_class/modelCoverage/utility.pure new file mode 100644 index 00000000000..b85123a9cf4 --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-class/legend-engine-xt-analytics-class-pure/src/main/resources/core_analytics_class/modelCoverage/utility.pure @@ -0,0 +1,34 @@ +// Copyright 2023 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. + +import meta::analytics::class::modelCoverage::utility::*; + +function {doc.doc = 'Get the parent or super types of the provided class'} + meta::analytics::class::modelCoverage::utility::superTypes(class : Class[1], recursive:Boolean[1]) : Class[*] +{ + let types = if ($recursive, | $class->generalizations(), | $class.generalizations.general.rawType); + + $types->map(rw| + $rw->match([ + c:Class[1] | if($c != Any && $c != $class, | $c, | []), + a:Any[1] | [] + ]) + ); +} + +function {doc.doc = 'Get the parent or super types of the provided class recursively'} + meta::analytics::class::modelCoverage::utility::superTypes(class : Class[1]) : Class[*] +{ + $class->superTypes(true); +} \ No newline at end of file diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-class/pom.xml b/legend-engine-xts-analytics/legend-engine-xts-analytics-class/pom.xml new file mode 100644 index 00000000000..53377e59dd9 --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-class/pom.xml @@ -0,0 +1,33 @@ + + + + + org.finos.legend.engine + legend-engine-xts-analytics + 4.30.3-SNAPSHOT + + 4.0.0 + + legend-engine-xts-analytics-class + pom + Legend Engine - XTS - Analytics + + + legend-engine-xt-analytics-class-pure + legend-engine-xt-analytics-class-api + + \ No newline at end of file diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-api/pom.xml b/legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-api/pom.xml new file mode 100644 index 00000000000..c7459c0c20a --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-api/pom.xml @@ -0,0 +1,140 @@ + + + + + + org.finos.legend.engine + legend-engine-xts-analytics-function + 4.30.3-SNAPSHOT + + 4.0.0 + + legend-engine-xt-analytics-function-api + jar + Legend Engine - XT - Analytics - Function - API + + + + + org.finos.legend.pure + legend-pure-m3-core + + + + + + org.finos.legend.engine + legend-engine-external-shared + + + org.finos.legend.engine + legend-engine-language-pure-modelManager + + + org.finos.legend.engine + legend-engine-protocol-pure + + + org.finos.legend.engine + legend-engine-language-pure-compiler + + + org.finos.legend.engine + legend-engine-xt-analytics-function-pure + ${project.version} + + + org.finos.legend.engine + legend-engine-shared-core + + + + + + javax.ws.rs + javax.ws.rs-api + + + io.swagger + swagger-annotations + + + + + + org.pac4j.jax-rs + core + + + org.pac4j + pac4j-core + + + + + + com.fasterxml.jackson.core + jackson-annotations + + + com.fasterxml.jackson.core + jackson-databind + + + + + + org.eclipse.collections + eclipse-collections-api + + + org.eclipse.collections + eclipse-collections + + + + + + io.opentracing + opentracing-api + + + io.opentracing + opentracing-util + + + + + + junit + junit + test + + + org.finos.legend.engine + legend-engine-shared-core + test-jar + test + + + org.glassfish.jersey.core + jersey-common + test + + + + diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-api/src/main/java/org.finos.legend.engine.api.analytics/FunctionAnalytics.java b/legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-api/src/main/java/org.finos.legend.engine.api.analytics/FunctionAnalytics.java new file mode 100644 index 00000000000..46d26fd995d --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-api/src/main/java/org.finos.legend.engine.api.analytics/FunctionAnalytics.java @@ -0,0 +1,100 @@ +// Copyright 2023 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 io.opentracing.Scope; +import io.opentracing.util.GlobalTracer; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.eclipse.collections.api.list.MutableList; +import org.eclipse.collections.impl.factory.Lists; +import org.finos.legend.engine.api.analytics.model.FunctionModelCoverageAnalysisInput; +import org.finos.legend.engine.external.shared.format.imports.PureModelContextDataGenerator; +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.shared.core.ObjectMapperFactory; +import org.finos.legend.engine.shared.core.api.result.ManageConstantResult; +import org.finos.legend.engine.shared.core.kerberos.ProfileManagerHelper; +import org.finos.legend.engine.shared.core.operational.errorManagement.ExceptionTool; +import org.finos.legend.engine.shared.core.operational.http.InflateInterceptor; +import org.finos.legend.engine.shared.core.operational.logs.LoggingEventType; +import org.finos.legend.pure.generated.Root_meta_analytics_function_modelCoverage_FunctionModelCoverageAnalysisResult; +import org.finos.legend.pure.generated.core_analytics_function_modelCoverage_analytics; +import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.ConcreteFunctionDefinition; +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.DefaultValue; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.util.Objects; + +@Api(tags = "Analytics - Model") +@Path("pure/v1/analytics/function") +public class FunctionAnalytics +{ + private static final ObjectMapper objectMapper = ObjectMapperFactory.getNewStandardObjectMapperWithPureProtocolExtensionSupports(); + + private final ModelManager modelManager; + + public FunctionAnalytics(ModelManager modelManager) + { + this.modelManager = modelManager; + } + + @POST + @Path("modelCoverage") + @ApiOperation(value = "Analyze the function to identify models covered by the function") + @Consumes({MediaType.APPLICATION_JSON, InflateInterceptor.APPLICATION_ZLIB}) + @Produces(MediaType.APPLICATION_JSON) + public Response analyzeFunctionModelCoverage(FunctionModelCoverageAnalysisInput input, + @QueryParam("includeFunction") @DefaultValue("true") boolean includeFunction, + @ApiParam(hidden = true) @Pac4JProfileManager ProfileManager pm) + { + 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); + ConcreteFunctionDefinition function = pureModel.getConcreteFunctionDefinition_safe(input.function); + + try (Scope scope = GlobalTracer.get().buildSpan("Analytics: function model coverage").startActive(true)) + { + try + { + Root_meta_analytics_function_modelCoverage_FunctionModelCoverageAnalysisResult result = core_analytics_function_modelCoverage_analytics.Root_meta_analytics_function_modelCoverage_getFunctionModelCoverage_ConcreteFunctionDefinition_MANY__FunctionModelCoverageAnalysisResult_1_(Lists.immutable.of(function), pureModel.getExecutionSupport()); + PureModelContextData classes = PureModelContextDataGenerator.generatePureModelContextDataFromClasses(result._classes(), input.clientVersion, pureModel.getExecutionSupport()); + PureModelContextData enums = PureModelContextDataGenerator.generatePureModelContextDataFromEnumerations(result._enumerations(), input.clientVersion, pureModel.getExecutionSupport()); + PureModelContextData.Builder builder = PureModelContextData.newBuilder(); + if (includeFunction) + { + builder.addElement(Objects.requireNonNull(pureModelContextData.getElements().stream().filter(el -> input.function.equals(el.getPath())).findFirst().get())); + } + return ManageConstantResult.manageResult(profiles, builder.build().combine(classes).combine(enums), objectMapper); + } + catch (Exception e) + { + return ExceptionTool.exceptionManager(e, LoggingEventType.ANALYTICS_ERROR, Response.Status.BAD_REQUEST, profiles); + } + } + } +} diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-api/src/main/java/org.finos.legend.engine.api.analytics/model/FunctionModelCoverageAnalysisInput.java b/legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-api/src/main/java/org.finos.legend.engine.api.analytics/model/FunctionModelCoverageAnalysisInput.java new file mode 100644 index 00000000000..5f81dfe9eb8 --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-api/src/main/java/org.finos.legend.engine.api.analytics/model/FunctionModelCoverageAnalysisInput.java @@ -0,0 +1,41 @@ +// Copyright 2023 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.model; + +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 FunctionModelCoverageAnalysisInput +{ + public String clientVersion; + + @JsonProperty(required = true) + public String function; + + @JsonProperty(required = true) + public PureModelContext model; + + @JsonCreator + public FunctionModelCoverageAnalysisInput( + @JsonProperty("clientVersion") String clientVersion, + @JsonProperty("function") String function, + @JsonProperty("model") PureModelContext model) + { + this.clientVersion = clientVersion; + this.function = function; + this.model = model; + } +} \ No newline at end of file diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-api/src/test/java/org.finos.legend.engine.api.analytics.test/TestFunctionAnalyticsApi.java b/legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-api/src/test/java/org.finos.legend.engine.api.analytics.test/TestFunctionAnalyticsApi.java new file mode 100644 index 00000000000..bd37ad8f514 --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-api/src/test/java/org.finos.legend.engine.api.analytics.test/TestFunctionAnalyticsApi.java @@ -0,0 +1,44 @@ +// Copyright 2023 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.test; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.finos.legend.engine.api.analytics.FunctionAnalytics; +import org.finos.legend.engine.api.analytics.model.FunctionModelCoverageAnalysisInput; +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.shared.core.ObjectMapperFactory; +import org.finos.legend.engine.shared.core.deployment.DeploymentMode; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.util.Objects; + +public class TestFunctionAnalyticsApi +{ + private final FunctionAnalytics api = new FunctionAnalytics(new ModelManager(DeploymentMode.TEST)); + private static final ObjectMapper objectMapper = ObjectMapperFactory.getNewStandardObjectMapperWithPureProtocolExtensionSupports(); + + @Test + public void testFunctionModelCoverageAnalysis() throws IOException + { + PureModelContextData modelContextData = objectMapper.readValue(Objects.requireNonNull(getClass().getClassLoader().getResource("functionModelCoverageAnalysisTestData.json")), PureModelContextData.class); + Assert.assertEquals( + "{\"_type\":\"data\",\"elements\":[{\"_type\":\"class\",\"constraints\":[],\"name\":\"Person\",\"originalMilestonedProperties\":[],\"package\":\"model\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"function\",\"body\":[{\"_type\":\"func\",\"function\":\"plus\",\"parameters\":[{\"_type\":\"collection\",\"multiplicity\":{\"lowerBound\":3,\"upperBound\":3},\"values\":[{\"_type\":\"property\",\"parameters\":[{\"_type\":\"var\",\"name\":\"person\"}],\"property\":\"firstName\"},{\"_type\":\"string\",\"value\":\" \"},{\"_type\":\"property\",\"parameters\":[{\"_type\":\"var\",\"name\":\"person\"}],\"property\":\"lastName\"}]}]}],\"name\":\"personFullName_Person_1__String_1_\",\"package\":\"model\",\"parameters\":[{\"_type\":\"var\",\"class\":\"model::Person\",\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"person\"}],\"postConstraints\":[],\"preConstraints\":[],\"returnMultiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"returnType\":\"String\",\"stereotypes\":[],\"taggedValues\":[]}]}", + api.analyzeFunctionModelCoverage(new FunctionModelCoverageAnalysisInput("vX_X_X", "model::personFullName_Person_1__String_1_", modelContextData), true, null).getEntity().toString()); + } +} + diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-api/src/test/resources/functionModelCoverageAnalysisTestData.json b/legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-api/src/test/resources/functionModelCoverageAnalysisTestData.json new file mode 100644 index 00000000000..977c0b2b0dd --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-api/src/test/resources/functionModelCoverageAnalysisTestData.json @@ -0,0 +1,387 @@ +{ + "_type": "data", + "elements": [ + { + "_type": "Enumeration", + "name": "OrgType", + "package": "model", + "stereotypes": [], + "taggedValues": [], + "values": [ + { + "stereotypes": [], + "taggedValues": [], + "value": "CORP" + }, + { + "stereotypes": [], + "taggedValues": [], + "value": "LLC" + } + ] + }, + { + "_type": "class", + "constraints": [], + "name": "Person", + "originalMilestonedProperties": [], + "package": "model", + "properties": [ + { + "multiplicity": { + "lowerBound": 1, + "upperBound": 1 + }, + "name": "firstName", + "stereotypes": [], + "taggedValues": [], + "type": "String" + }, + { + "multiplicity": { + "lowerBound": 1, + "upperBound": 1 + }, + "name": "lastName", + "stereotypes": [], + "taggedValues": [], + "type": "String" + } + ], + "qualifiedProperties": [], + "stereotypes": [], + "superTypes": [], + "taggedValues": [] + }, + { + "_type": "class", + "constraints": [], + "name": "Organization", + "originalMilestonedProperties": [], + "package": "model", + "properties": [ + { + "multiplicity": { + "lowerBound": 1, + "upperBound": 1 + }, + "name": "name", + "stereotypes": [], + "taggedValues": [], + "type": "String" + }, + { + "multiplicity": { + "lowerBound": 0 + }, + "name": "employees", + "stereotypes": [], + "taggedValues": [], + "type": "model::Person" + }, + { + "multiplicity": { + "lowerBound": 1, + "upperBound": 1 + }, + "name": "type", + "stereotypes": [], + "taggedValues": [], + "type": "String" + } + ], + "qualifiedProperties": [], + "stereotypes": [], + "superTypes": [], + "taggedValues": [] + }, + { + "_type": "class", + "constraints": [], + "name": "Trader", + "originalMilestonedProperties": [], + "package": "model", + "properties": [ + { + "multiplicity": { + "lowerBound": 1, + "upperBound": 1 + }, + "name": "fullName", + "stereotypes": [], + "taggedValues": [], + "type": "String" + } + ], + "qualifiedProperties": [], + "stereotypes": [], + "superTypes": [], + "taggedValues": [] + }, + { + "_type": "class", + "constraints": [], + "name": "Bank", + "originalMilestonedProperties": [], + "package": "model", + "properties": [ + { + "multiplicity": { + "lowerBound": 1, + "upperBound": 1 + }, + "name": "entityName", + "stereotypes": [], + "taggedValues": [], + "type": "String" + }, + { + "multiplicity": { + "lowerBound": 0 + }, + "name": "employees", + "stereotypes": [], + "taggedValues": [], + "type": "model::Trader" + }, + { + "multiplicity": { + "lowerBound": 1, + "upperBound": 1 + }, + "name": "type", + "stereotypes": [], + "taggedValues": [], + "type": "model::OrgType" + } + ], + "qualifiedProperties": [], + "stereotypes": [], + "superTypes": [], + "taggedValues": [] + }, + { + "_type": "function", + "body": [ + { + "_type": "func", + "function": "plus", + "parameters": [ + { + "_type": "collection", + "multiplicity": { + "lowerBound": 3, + "upperBound": 3 + }, + "values": [ + { + "_type": "property", + "parameters": [ + { + "_type": "var", + "name": "person" + } + ], + "property": "firstName" + }, + { + "_type": "string", + "value": " " + }, + { + "_type": "property", + "parameters": [ + { + "_type": "var", + "name": "person" + } + ], + "property": "lastName" + } + ] + } + ] + } + ], + "name": "personFullName_Person_1__String_1_", + "package": "model", + "parameters": [ + { + "_type": "var", + "class": "model::Person", + "multiplicity": { + "lowerBound": 1, + "upperBound": 1 + }, + "name": "person" + } + ], + "postConstraints": [], + "preConstraints": [], + "returnMultiplicity": { + "lowerBound": 1, + "upperBound": 1 + }, + "returnType": "String", + "stereotypes": [], + "taggedValues": [] + }, + { + "_type": "mapping", + "associationMappings": [], + "classMappings": [ + { + "_type": "pureInstance", + "class": "model::Trader", + "propertyMappings": [ + { + "_type": "purePropertyMapping", + "explodeProperty": false, + "property": { + "class": "model::Trader", + "property": "fullName" + }, + "source": "", + "transform": { + "_type": "lambda", + "body": [ + { + "_type": "func", + "function": "plus", + "parameters": [ + { + "_type": "collection", + "multiplicity": { + "lowerBound": 3, + "upperBound": 3 + }, + "values": [ + { + "_type": "property", + "parameters": [ + { + "_type": "var", + "name": "src" + } + ], + "property": "firstName" + }, + { + "_type": "string", + "value": " " + }, + { + "_type": "property", + "parameters": [ + { + "_type": "var", + "name": "src" + } + ], + "property": "lastName" + } + ] + } + ] + } + ], + "parameters": [] + } + } + ], + "root": true, + "srcClass": "model::Person" + }, + { + "_type": "pureInstance", + "class": "model::Bank", + "propertyMappings": [ + { + "_type": "purePropertyMapping", + "explodeProperty": false, + "property": { + "class": "model::Bank", + "property": "employees" + }, + "source": "", + "target": "model_Trader", + "transform": { + "_type": "lambda", + "body": [ + { + "_type": "property", + "parameters": [ + { + "_type": "var", + "name": "src" + } + ], + "property": "employees" + } + ], + "parameters": [] + } + }, + { + "_type": "purePropertyMapping", + "enumMappingId": "model_OrgType", + "explodeProperty": false, + "property": { + "class": "model::Bank", + "property": "type" + }, + "source": "", + "transform": { + "_type": "lambda", + "body": [ + { + "_type": "property", + "parameters": [ + { + "_type": "var", + "name": "src" + } + ], + "property": "type" + } + ], + "parameters": [] + } + } + ], + "root": true, + "srcClass": "model::Organization" + } + ], + "enumerationMappings": [ + { + "enumValueMappings": [ + { + "enumValue": "CORP", + "sourceValues": [ + { + "_type": "stringSourceValue", + "value": "corporation" + } + ] + }, + { + "enumValue": "LLC", + "sourceValues": [ + { + "_type": "stringSourceValue", + "value": "limitted" + } + ] + } + ], + "enumeration": "model::OrgType" + } + ], + "includedMappings": [], + "name": "mapping", + "package": "model", + "tests": [] + } + ] +} \ No newline at end of file diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-pure/pom.xml b/legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-pure/pom.xml new file mode 100644 index 00000000000..e3bcaf30dc8 --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-pure/pom.xml @@ -0,0 +1,143 @@ + + + + + + org.finos.legend.engine + legend-engine-xts-analytics-function + 4.30.3-SNAPSHOT + + 4.0.0 + + legend-engine-xt-analytics-function-pure + jar + Legend Engine - XT - Analytics - Function - PAR/JAVA + + + + + org.finos.legend.pure + legend-pure-maven-generation-par + + src/main/resources + ${legend.pure.version} + + core_analytics_function + + + ${project.basedir}/src/main/resources/core_analytics_function.definition.json + + + + + generate-sources + + build-pure-jar + + + + + + org.finos.legend.pure + legend-pure-m2-dsl-diagram-grammar + ${legend.pure.version} + + + org.finos.legend.engine + legend-engine-pure-code-compiled-core + ${project.version} + + + + + org.finos.legend.pure + legend-pure-maven-generation-java + + + compile + + build-pure-compiled-jar + + + true + true + modular + true + + core_analytics_function + + + + + + + org.finos.legend.pure + legend-pure-m2-dsl-diagram-grammar + ${legend.pure.version} + + + org.finos.legend.engine + legend-engine-pure-code-compiled-core + ${project.version} + + + + + + + + + + org.finos.legend.pure + legend-pure-m4 + + + org.finos.legend.pure + legend-pure-m3-core + + + org.finos.legend.pure + legend-pure-runtime-java-engine-compiled + + + + + + org.finos.legend.engine + legend-engine-pure-platform-java + + + org.finos.legend.engine + legend-engine-pure-platform-functions-java + + + org.finos.legend.engine + legend-engine-pure-code-compiled-core + ${project.version} + + + + + org.eclipse.collections + eclipse-collections + + + org.eclipse.collections + eclipse-collections-api + + + diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-pure/src/main/java/org.finos.legend.pure.code.core/CoreExternalFunctionAnalysisCodeRepositoryProvider.java b/legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-pure/src/main/java/org.finos.legend.pure.code.core/CoreExternalFunctionAnalysisCodeRepositoryProvider.java new file mode 100644 index 00000000000..c08f150ae4b --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-pure/src/main/java/org.finos.legend.pure.code.core/CoreExternalFunctionAnalysisCodeRepositoryProvider.java @@ -0,0 +1,28 @@ +// Copyright 2023 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.pure.code.core; + +import org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepository; +import org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepositoryProvider; +import org.finos.legend.pure.m3.serialization.filesystem.repository.GenericCodeRepository; + +public class CoreExternalFunctionAnalysisCodeRepositoryProvider implements CodeRepositoryProvider +{ + @Override + public CodeRepository repository() + { + return GenericCodeRepository.build("core_analytics_function.definition.json"); + } +} diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-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-function/legend-engine-xt-analytics-function-pure/src/main/resources/META-INF/services/org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepositoryProvider new file mode 100644 index 00000000000..c5eae58b14d --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-pure/src/main/resources/META-INF/services/org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepositoryProvider @@ -0,0 +1 @@ +org.finos.legend.pure.code.core.CoreExternalFunctionAnalysisCodeRepositoryProvider \ No newline at end of file diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-pure/src/main/resources/core_analytics_function.definition.json b/legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-pure/src/main/resources/core_analytics_function.definition.json new file mode 100644 index 00000000000..35dd71f52a7 --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-pure/src/main/resources/core_analytics_function.definition.json @@ -0,0 +1,11 @@ +{ + "name": "core_analytics_function", + "pattern": "(meta::analytics::function)(::.*)?", + "dependencies": [ + "platform", + "platform_functions", + "core", + "core_functions", + "platform_functions_json" + ] +} diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-pure/src/main/resources/core_analytics_function/modelCoverage/analytics.pure b/legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-pure/src/main/resources/core_analytics_function/modelCoverage/analytics.pure new file mode 100644 index 00000000000..451bed29c5e --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-function/legend-engine-xt-analytics-function-pure/src/main/resources/core_analytics_function/modelCoverage/analytics.pure @@ -0,0 +1,57 @@ +// Copyright 2023 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. + +import meta::analytics::function::modelCoverage::*; + +Class meta::analytics::function::modelCoverage::FunctionModelCoverageAnalysisResult +{ + classes: Class[*]; + enumerations: Enumeration[*]; +} + +function meta::analytics::function::modelCoverage::getFunctionModelCoverage(functions: ConcreteFunctionDefinition[*]):FunctionModelCoverageAnalysisResult[1] +{ + let returnTypes = $functions->map(f | $f->functionReturnType().rawType->toOne()); + let coveredClasses = $returnTypes->filter(t | $t->instanceOf(Class))->cast(@Class); + let coveredEnumerations = $returnTypes->filter(t | $t->instanceOf(Enumeration))->cast(@Enumeration); + + let parameters = $functions->map(f | $f->functionType().parameters); + let parameterTypes = $parameters->map(p | $p.genericType.rawType); + + let parameterTypeClasses = $parameterTypes->filter(t | $t->instanceOf(Class))->cast(@Class); + let parameterTypeEnumerations = $parameterTypes->filter(t | $t->instanceOf(Enumeration))->cast(@Enumeration); + + let prunedClasses = $coveredClasses->concatenate($parameterTypeClasses)->removeDuplicates()->map(c|^Class( + name = $c.name, + package = $c.package + )); + + // NOTE: following, we prune the tagged values and stereotypes from the enumerations, associations, and classes + // so we don't have to return them, if in the future, we need to return these (as this analytics require to do so) + // we should reconsider these optimization + let prunedEnumerations = $coveredEnumerations->concatenate($parameterTypeEnumerations)->removeDuplicates()->map(e|^$e( + stereotypes = [], + taggedValues = [], + values = meta::pure::functions::meta::enumValues($e)->map(v|^$v( + stereotypes = [], + taggedValues = [] + ))->toOneMany() // this is a hack to work around a problem with validation on size of enumeration values + )); + + ^FunctionModelCoverageAnalysisResult + ( + classes = $prunedClasses, + enumerations = $prunedEnumerations + ); +} diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-function/pom.xml b/legend-engine-xts-analytics/legend-engine-xts-analytics-function/pom.xml new file mode 100644 index 00000000000..693e2705904 --- /dev/null +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-function/pom.xml @@ -0,0 +1,33 @@ + + + + + org.finos.legend.engine + legend-engine-xts-analytics + 4.30.3-SNAPSHOT + + 4.0.0 + + legend-engine-xts-analytics-function + pom + Legend Engine - XTS - Analytics + + + legend-engine-xt-analytics-function-pure + legend-engine-xt-analytics-function-api + + \ No newline at end of file diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-api/pom.xml b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-api/pom.xml index f722409f2e0..270109b1cd8 100644 --- a/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-api/pom.xml +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-api/pom.xml @@ -19,6 +19,10 @@ org.finos.legend.engine legend-engine-pure-code-compiled-core + + org.finos.legend.pure + legend-pure-m3-core + @@ -46,6 +50,26 @@ org.finos.legend.engine legend-engine-xt-analytics-mapping-pure + + org.finos.legend.engine + legend-engine-external-shared + + + org.finos.legend.engine + legend-engine-language-pure-grammar + + + org.finos.legend.engine + legend-engine-xt-analytics-function-pure + + + org.finos.legend.engine + legend-engine-xt-analytics-function-pure + + + org.finos.legend.engine + legend-engine-xt-analytics-binding-pure + diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-api/src/main/java/org/finos/legend/engine/api/analytics/MappingAnalytics.java b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-api/src/main/java/org/finos/legend/engine/api/analytics/MappingAnalytics.java index 4b815bc415d..750d71ac508 100644 --- a/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-api/src/main/java/org/finos/legend/engine/api/analytics/MappingAnalytics.java +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-api/src/main/java/org/finos/legend/engine/api/analytics/MappingAnalytics.java @@ -20,17 +20,22 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; +import org.eclipse.collections.api.RichIterable; import org.eclipse.collections.api.list.MutableList; import org.eclipse.collections.impl.utility.ListIterate; import org.finos.legend.engine.api.analytics.model.MappingModelCoverageAnalysisInput; import org.finos.legend.engine.api.analytics.model.MappingRuntimeCompatibilityAnalysisInput; import org.finos.legend.engine.api.analytics.model.MappingRuntimeCompatibilityAnalysisResult; +import org.finos.legend.engine.external.shared.format.imports.PureModelContextDataGenerator; import org.finos.legend.engine.language.pure.compiler.toPureGraph.HelperModelBuilder; import org.finos.legend.engine.language.pure.compiler.toPureGraph.HelperRuntimeBuilder; import org.finos.legend.engine.language.pure.compiler.toPureGraph.PureModel; +import org.finos.legend.engine.language.pure.grammar.to.HelperValueSpecificationGrammarComposer; import org.finos.legend.engine.language.pure.modelManager.ModelManager; import org.finos.legend.engine.protocol.analytics.model.MappingModelCoverageAnalysisResult; import org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContextData; +import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.domain.Function; +import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.externalFormat.Binding; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.runtime.PackageableRuntime; import org.finos.legend.engine.shared.core.ObjectMapperFactory; import org.finos.legend.engine.shared.core.api.result.ManageConstantResult; @@ -38,10 +43,20 @@ import org.finos.legend.engine.shared.core.operational.errorManagement.ExceptionTool; import org.finos.legend.engine.shared.core.operational.http.InflateInterceptor; import org.finos.legend.engine.shared.core.operational.logs.LoggingEventType; +import org.finos.legend.pure.generated.Root_meta_analytics_binding_modelCoverage_BindingModelCoverageAnalysisResult; +import org.finos.legend.pure.generated.Root_meta_analytics_function_modelCoverage_FunctionModelCoverageAnalysisResult; import org.finos.legend.pure.generated.Root_meta_analytics_mapping_modelCoverage_MappingModelCoverageAnalysisResult; +import org.finos.legend.pure.generated.Root_meta_external_format_shared_binding_Binding; +import org.finos.legend.pure.generated.core_analytics_binding_modelCoverage_analytics; +import org.finos.legend.pure.generated.core_analytics_function_modelCoverage_analytics; import org.finos.legend.pure.generated.core_analytics_mapping_modelCoverage_analytics; import org.finos.legend.pure.generated.core_analytics_mapping_modelCoverage_serializer; import org.finos.legend.pure.m3.coreinstance.meta.pure.mapping.Mapping; +import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.extension.Profile; +import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.ConcreteFunctionDefinition; +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.pac4j.core.profile.CommonProfile; import org.pac4j.core.profile.ProfileManager; import org.pac4j.jax.rs.annotations.Pac4JProfileManager; @@ -54,6 +69,9 @@ import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; @Api(tags = "Analytics - Model") @Path("pure/v1/analytics/mapping") @@ -75,17 +93,88 @@ public MappingAnalytics(ModelManager modelManager) public Response analyzeModelCoverage(MappingModelCoverageAnalysisInput input, @QueryParam("returnMappedEntityInfo") @DefaultValue("false") boolean returnMappedEntityInfo, @QueryParam("returnMappedPropertyInfo") @DefaultValue("false") boolean returnMappedPropertyInfo, + @QueryParam("returnLightGraph") @DefaultValue("false") boolean returnLightGraph, @ApiParam(hidden = true) @Pac4JProfileManager ProfileManager pm) { MutableList profiles = ProfileManagerHelper.extractProfiles(pm); PureModel pureModel = this.modelManager.loadModel(input.model, input.clientVersion, profiles, null); + PureModelContextData pureModelContextData = this.modelManager.loadData(input.model, input.clientVersion, profiles); Mapping mapping = input.mapping == null ? null : pureModel.getMapping(input.mapping); try (Scope scope = GlobalTracer.get().buildSpan("Mapping: analysis").startActive(true)) { try { - Root_meta_analytics_mapping_modelCoverage_MappingModelCoverageAnalysisResult analysisResult = core_analytics_mapping_modelCoverage_analytics.Root_meta_analytics_mapping_modelCoverage_analyze_Mapping_1__Boolean_1__Boolean_1__MappingModelCoverageAnalysisResult_1_(mapping, returnMappedEntityInfo, returnMappedPropertyInfo, pureModel.getExecutionSupport()); + Root_meta_analytics_mapping_modelCoverage_MappingModelCoverageAnalysisResult analysisResult = core_analytics_mapping_modelCoverage_analytics.Root_meta_analytics_mapping_modelCoverage_analyze_Mapping_1__Boolean_1__Boolean_1__Boolean_1__MappingModelCoverageAnalysisResult_1_(mapping, returnMappedEntityInfo, returnMappedPropertyInfo, returnLightGraph, pureModel.getExecutionSupport()); MappingModelCoverageAnalysisResult result = this.objectMapper.readValue(core_analytics_mapping_modelCoverage_serializer.Root_meta_analytics_mapping_modelCoverage_serialization_json_getSerializedMappingModelCoverageAnalysisResult_MappingModelCoverageAnalysisResult_1__String_1_(analysisResult, pureModel.getExecutionSupport()), MappingModelCoverageAnalysisResult.class); + PureModelContextData.Builder builder = PureModelContextData.newBuilder(); + if (returnLightGraph) + { + // Here we prune the bindings to have just packageableIncludes part of ModelUnit + // because we only need that as a part of analytics. + List bindingPaths = pureModelContextData.getElements().stream().filter(el -> el instanceof Binding).map(b -> + { + Binding _binding = new Binding(); + _binding.name = b.name; + _binding.contentType = ((Binding) b).contentType; + _binding._package = b._package; + _binding.modelUnit = ((Binding) b).modelUnit; + _binding.modelUnit.packageableElementExcludes = org.eclipse.collections.api.factory.Lists.mutable.empty(); + builder.addElement(_binding); + return b.getPath(); + }).collect(Collectors.toList()); + RichIterable bindings = org.eclipse.collections.api.factory.Lists.mutable.ofAll(bindingPaths.stream().map(path -> + { + Root_meta_external_format_shared_binding_Binding binding; + try + { + binding = (Root_meta_external_format_shared_binding_Binding) pureModel.getPackageableElement(path); + return binding; + } + catch (Exception ignored) + { + + } + return null; + }).filter(c -> c != null).collect(Collectors.toList())); + Root_meta_analytics_binding_modelCoverage_BindingModelCoverageAnalysisResult bindingAnalysisResult = core_analytics_binding_modelCoverage_analytics.Root_meta_analytics_binding_modelCoverage_getBindingModelCoverage_Binding_MANY__BindingModelCoverageAnalysisResult_1_(bindings, pureModel.getExecutionSupport()); + List functionPaths = pureModelContextData.getElements().stream().filter(el -> el instanceof Function).map(e -> e.getPath()).collect(Collectors.toList()); + List allExtraElements = functionPaths; + pureModelContextData.getElements().stream().filter(el -> allExtraElements.contains(el.getPath())).forEach(builder::addElement); + List elements = builder.build().getElements(); + RichIterable> functions = org.eclipse.collections.api.factory.Lists.mutable.ofAll(functionPaths.stream().map(path -> + { + ConcreteFunctionDefinition function = null; + try + { + function = pureModel.getConcreteFunctionDefinition_safe(path); + if (function == null) + { + Function _function = (Function) elements.stream().filter(e -> e.getPath().equals(path)).findFirst().get(); + function = pureModel.getConcreteFunctionDefinition_safe(path + HelperValueSpecificationGrammarComposer.getFunctionSignature(_function)); + + } + return function; + } + catch (Exception ignored) + { + + } + return null; + }).filter(c -> c != null).collect(Collectors.toList())); + Root_meta_analytics_function_modelCoverage_FunctionModelCoverageAnalysisResult functionCoverageAnalysisResult = core_analytics_function_modelCoverage_analytics.Root_meta_analytics_function_modelCoverage_getFunctionModelCoverage_ConcreteFunctionDefinition_MANY__FunctionModelCoverageAnalysisResult_1_(org.eclipse.collections.impl.factory.Lists.mutable.ofAll(functions), pureModel.getExecutionSupport()); + MutableList> coveredClasses = analysisResult._classes().toList(); + List coveredClassesPaths = coveredClasses.stream().map(c -> HelperModelBuilder.getElementFullPath(c, pureModel.getExecutionSupport())).collect(Collectors.toList()); + coveredClasses = org.eclipse.collections.impl.factory.Lists.mutable.ofAll(Stream.concat(Stream.concat(functionCoverageAnalysisResult._classes().toList().stream().filter(c -> !coveredClassesPaths.contains(HelperModelBuilder.getElementFullPath(c, pureModel.getExecutionSupport()))), + bindingAnalysisResult._classes().toList().stream().filter(c -> !coveredClassesPaths.contains(HelperModelBuilder.getElementFullPath(c, pureModel.getExecutionSupport())))).distinct(), + analysisResult._classes().toList().stream()).collect(Collectors.toList())); + MutableList> coveredEnumerations = org.eclipse.collections.impl.factory.Lists.mutable.ofAll(Stream.concat(analysisResult._enumerations().toList().stream(), functionCoverageAnalysisResult._enumerations().toList().stream()).distinct().collect(Collectors.toList())); + PureModelContextData classes = PureModelContextDataGenerator.generatePureModelContextDataFromClasses(coveredClasses, input.clientVersion, pureModel.getExecutionSupport()); + PureModelContextData enums = PureModelContextDataGenerator.generatePureModelContextDataFromEnumerations(coveredEnumerations, input.clientVersion, pureModel.getExecutionSupport()); + PureModelContextData _profiles = PureModelContextDataGenerator.generatePureModelContextDataFromProfile((RichIterable) analysisResult._profiles(), input.clientVersion, pureModel.getExecutionSupport()); + PureModelContextData associations = PureModelContextDataGenerator.generatePureModelContextDataFromAssociations(analysisResult._associations(), input.clientVersion, pureModel.getExecutionSupport()); + + result.model = builder.build().combine(classes).combine(enums).combine(_profiles).combine(associations); + } return ManageConstantResult.manageResult(profiles, result); } catch (Exception e) diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-api/src/test/java/org/finos/legend/engine/api/analytics/test/TestMappingAnalyticsApi.java b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-api/src/test/java/org/finos/legend/engine/api/analytics/test/TestMappingAnalyticsApi.java index f96098d942e..16a133f29e8 100644 --- a/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-api/src/test/java/org/finos/legend/engine/api/analytics/test/TestMappingAnalyticsApi.java +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-api/src/test/java/org/finos/legend/engine/api/analytics/test/TestMappingAnalyticsApi.java @@ -39,7 +39,7 @@ public void testMappingModelCoverageAnalysis() throws IOException PureModelContextData modelContextData = objectMapper.readValue(Objects.requireNonNull(getClass().getClassLoader().getResource("mappingModelCoverageAnalysisTestData.json")), PureModelContextData.class); Assert.assertEquals( "{\"mappedEntities\":[{\"path\":\"model::Bank\",\"properties\":[{\"_type\":\"entity\",\"entityPath\":\"model::Trader\",\"name\":\"employees\"},{\"_type\":\"enum\",\"enumPath\":\"model::OrgType\",\"name\":\"type\"}]},{\"path\":\"model::Trader\",\"properties\":[{\"_type\":\"MappedProperty\",\"name\":\"fullName\"}]}]}", - api.analyzeModelCoverage(new MappingModelCoverageAnalysisInput("vX_X_X", "model::mapping", modelContextData), false, false, null).getEntity().toString()); + api.analyzeModelCoverage(new MappingModelCoverageAnalysisInput("vX_X_X", "model::mapping", modelContextData), false, false, false, null).getEntity().toString()); } @Test @@ -47,8 +47,17 @@ public void testMappingModelCoverageAnalysisWithTypeInfoReturned() throws IOExce { PureModelContextData modelContextData = objectMapper.readValue(Objects.requireNonNull(getClass().getClassLoader().getResource("mappingModelCoverageAnalysisTestData.json")), PureModelContextData.class); Assert.assertEquals( - "{\"mappedEntities\":[{\"info\":{\"isRootEntity\":true,\"subClasses\":[]},\"path\":\"model::Bank\",\"properties\":[{\"_type\":\"entity\",\"entityPath\":\"model::Trader\",\"mappedPropertyInfo\":{\"multiplicity\":{\"lowerBound\":0},\"propertyType\":\"Entity\"},\"name\":\"employees\"},{\"_type\":\"enum\",\"enumPath\":\"model::OrgType\",\"mappedPropertyInfo\":{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"propertyType\":\"Enumeration\"},\"name\":\"type\"}]},{\"info\":{\"isRootEntity\":true,\"subClasses\":[]},\"path\":\"model::Trader\",\"properties\":[{\"_type\":\"MappedProperty\",\"mappedPropertyInfo\":{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"propertyType\":\"String\"},\"name\":\"fullName\"}]}]}", - api.analyzeModelCoverage(new MappingModelCoverageAnalysisInput("vX_X_X", "model::mapping", modelContextData), true, true, null).getEntity().toString()); + "{\"mappedEntities\":[{\"info\":{\"classPath\":\"model::Bank\",\"isRootEntity\":true,\"subClasses\":[]},\"path\":\"model::Bank\",\"properties\":[{\"_type\":\"entity\",\"entityPath\":\"model::Trader\",\"mappedPropertyInfo\":{\"multiplicity\":{\"lowerBound\":0},\"propertyType\":\"Entity\"},\"name\":\"employees\"},{\"_type\":\"enum\",\"enumPath\":\"model::OrgType\",\"mappedPropertyInfo\":{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"propertyType\":\"Enumeration\"},\"name\":\"type\"}]},{\"info\":{\"classPath\":\"model::Trader\",\"isRootEntity\":true,\"subClasses\":[]},\"path\":\"model::Trader\",\"properties\":[{\"_type\":\"MappedProperty\",\"mappedPropertyInfo\":{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"propertyType\":\"String\"},\"name\":\"fullName\"}]}]}", + api.analyzeModelCoverage(new MappingModelCoverageAnalysisInput("vX_X_X", "model::mapping", modelContextData), true, true, false, null).getEntity().toString()); + } + + @Test + public void testMappingModelCoverageAnalysisWithModelReturned() throws IOException + { + PureModelContextData modelContextData = objectMapper.readValue(Objects.requireNonNull(getClass().getClassLoader().getResource("mappingModelCoverageAnalysisTestData.json")), PureModelContextData.class); + Assert.assertEquals( + "{\"mappedEntities\":[{\"info\":{\"classPath\":\"model::Bank\",\"isRootEntity\":true,\"subClasses\":[]},\"path\":\"model::Bank\",\"properties\":[{\"_type\":\"entity\",\"entityPath\":\"model::Trader\",\"name\":\"employees\"},{\"_type\":\"enum\",\"enumPath\":\"model::OrgType\",\"name\":\"type\"}]},{\"info\":{\"classPath\":\"model::Trader\",\"isRootEntity\":true,\"subClasses\":[]},\"path\":\"model::Trader\",\"properties\":[{\"_type\":\"MappedProperty\",\"name\":\"fullName\"}]}],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"Class\",\"constraints\":[],\"name\":\"Bank\",\"originalMilestonedProperties\":[],\"package\":\"model\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"entityName\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"},{\"multiplicity\":{\"lowerBound\":0},\"name\":\"employees\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::Trader\"},{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"type\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::OrgType\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[\"meta::pure::metamodel::type::Any\"],\"taggedValues\":[]},{\"_type\":\"Enumeration\",\"name\":\"OrgType\",\"package\":\"model\",\"stereotypes\":[],\"taggedValues\":[],\"values\":[{\"stereotypes\":[],\"taggedValues\":[],\"value\":\"CORP\"},{\"stereotypes\":[],\"taggedValues\":[],\"value\":\"LLC\"}]},{\"_type\":\"Class\",\"constraints\":[],\"name\":\"Trader\",\"originalMilestonedProperties\":[],\"package\":\"model\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"fullName\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[\"meta::pure::metamodel::type::Any\"],\"taggedValues\":[]}]}}", + api.analyzeModelCoverage(new MappingModelCoverageAnalysisInput("vX_X_X", "model::mapping", modelContextData), true, false, true, null).getEntity().toString()); } @Test diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-protocol/src/main/java/org/finos/legend/engine/protocol/analytics/model/MappedEntityInfo.java b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-protocol/src/main/java/org/finos/legend/engine/protocol/analytics/model/MappedEntityInfo.java index 7e217dd5e67..634df3fc03b 100644 --- a/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-protocol/src/main/java/org/finos/legend/engine/protocol/analytics/model/MappedEntityInfo.java +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-protocol/src/main/java/org/finos/legend/engine/protocol/analytics/model/MappedEntityInfo.java @@ -19,5 +19,6 @@ public class MappedEntityInfo { public boolean isRootEntity; + public String classPath; public List subClasses; } diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-protocol/src/main/java/org/finos/legend/engine/protocol/analytics/model/MappingModelCoverageAnalysisResult.java b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-protocol/src/main/java/org/finos/legend/engine/protocol/analytics/model/MappingModelCoverageAnalysisResult.java index bd66771c80c..57415f3f570 100644 --- a/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-protocol/src/main/java/org/finos/legend/engine/protocol/analytics/model/MappingModelCoverageAnalysisResult.java +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-protocol/src/main/java/org/finos/legend/engine/protocol/analytics/model/MappingModelCoverageAnalysisResult.java @@ -14,9 +14,12 @@ package org.finos.legend.engine.protocol.analytics.model; +import org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContextData; + import java.util.List; public class MappingModelCoverageAnalysisResult { public List mappedEntities; + public PureModelContextData model; } diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/pom.xml b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/pom.xml index b7250e5f323..06f8e4cf2b9 100644 --- a/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/pom.xml +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/pom.xml @@ -68,6 +68,11 @@ legend-engine-pure-runtime-compiler ${project.version} + + org.finos.legend.engine + legend-engine-xt-analytics-class-pure + ${project.version} + org.finos.legend.engine legend-engine-pure-code-compiled-core @@ -120,6 +125,12 @@ legend-pure-m2-store-relational-grammar ${legend.pure.version} + + org.finos.legend.engine + legend-engine-xt-analytics-class-pure + ${project.version} + + org.finos.legend.engine legend-engine-pure-code-compiled-core @@ -181,6 +192,11 @@ org.finos.legend.engine legend-engine-pure-code-compiled-core + + org.finos.legend.engine + legend-engine-xt-analytics-class-pure + ${project.version} + org.finos.legend.engine legend-engine-pure-code-compiled-functions diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping.definition.json b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping.definition.json index 012c04773a2..a115eb01834 100644 --- a/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping.definition.json +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping.definition.json @@ -6,6 +6,7 @@ "platform_functions", "platform_dsl_mapping", "platform_store_relational", + "core_analytics_class", "platform_functions_json", "core_functions", "core_relational", diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/analytics.pure b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/analytics.pure index 1e885ba2453..5f7a2673d97 100644 --- a/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/analytics.pure +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/analytics.pure @@ -12,16 +12,24 @@ // See the License for the specific language governing permissions and // limitations under the License. +import meta::pure::*; import meta::analytics::mapping::modelCoverage::*; import meta::pure::mapping::*; import meta::pure::router::routing::*; import meta::analytics::mapping::modelCoverage::utility::*; +import meta::analytics::class::modelCoverage::*; +import meta::analytics::class::modelCoverage::utility::*; import meta::pure::mapping::modelToModel::*; +import meta::pure::milestoning::*; Class meta::analytics::mapping::modelCoverage::MappingModelCoverageAnalysisResult { mappedEntities : MappedEntity[*]; + classes: Class[*]; + enumerations: Enumeration[*]; + associations: Association[*]; + profiles: Profile[*]; } Enum meta::analytics::mapping::modelCoverage::MappedPropertyType @@ -42,6 +50,7 @@ Enum meta::analytics::mapping::modelCoverage::MappedPropertyType Class meta::analytics::mapping::modelCoverage::MappedEntityInfo { isRootEntity : Boolean[0..1]; + classPath: String[1]; subClasses : String[*]; } @@ -95,7 +104,8 @@ Class <> meta::analytics::mapping::modelCoverage::MultiInheritan function meta::analytics::mapping::modelCoverage::analyze( mapping: Mapping[1], returnMappedEntityInfo: Boolean[1], - returnMappedPropertyInfo: Boolean[1] + returnMappedPropertyInfo: Boolean[1], + returnLightGraph: Boolean[1] ): MappingModelCoverageAnalysisResult[1] { let config = ^AnalysisConfiguration( @@ -142,11 +152,23 @@ function meta::analytics::mapping::modelCoverage::analyze( let uniqueTypes = $subTypes->concatenate($superTypes)->removeDuplicatesBy(t | $t.class); buildInheritanceEntities($op, $op, [], $uniqueTypes, $namePrefix, $rootClassMappings, $allClasses, $allProperties, $inheritanceMap, $mappingToClassMappings, false, false, $config); )->removeDuplicatesBy(x | $x.path); - - ^MappingModelCoverageAnalysisResult( - mappedEntities = $entities->concatenate($inheritanceEntities) - ); + let mappedEntities = $entities->concatenate($inheritanceEntities); + if ($returnLightGraph == true, + | let mappedEntityPaths = $mappedEntities->map(m | $m.info->toOne().classPath)->removeDuplicates(); + let mappedClasses = $allClasses->keyValues()->map(c | $c.first)->filter(c | $mappedEntityPaths->contains($c->elementToPath())); + let classCoverageAnalysis = getClassModelCoverage($mappedClasses); + ^MappingModelCoverageAnalysisResult( + mappedEntities = $mappedEntities, + classes = $classCoverageAnalysis.classes, + enumerations = $classCoverageAnalysis.enumerations, + associations = $classCoverageAnalysis.associations, + profiles = $classCoverageAnalysis.profiles + );, + | ^MappingModelCoverageAnalysisResult( + mappedEntities = $mappedEntities, + classes = [], + enumerations = [], + associations = [], + profiles = [] + );); } - - - diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/analyticsTest.pure b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/analyticsTest.pure index ac620e1d1a8..1df60231c2b 100644 --- a/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/analyticsTest.pure +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/analyticsTest.pure @@ -17,7 +17,7 @@ import meta::pure::mapping::*; function meta::analytics::mapping::modelCoverage::test::generateModelCoverageAnalytics(mapping: Mapping[1]): MappingModelCoverageAnalysisResult[1] { - meta::analytics::mapping::modelCoverage::analyze($mapping, false, false); + meta::analytics::mapping::modelCoverage::analyze($mapping, false, false, false); } // Relational diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/mappedEntityBuilder.pure b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/mappedEntityBuilder.pure index d2a7c1766db..6531d0f599d 100644 --- a/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/mappedEntityBuilder.pure +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/mappedEntityBuilder.pure @@ -232,7 +232,7 @@ function <> meta::analytics::mapping::modelCoverage::buildEntity ^MappedEntity( path = $path, properties = $properties->removeDuplicatesBy(x | $x.name), - info = if($config.returnMappedEntityInfo == true, | ^MappedEntityInfo(isRootEntity = $isRootEntity), | []) + info = if($config.returnMappedEntityInfo == true, | ^MappedEntityInfo(isRootEntity = $isRootEntity, classPath = $class->elementToPath()), | []) ); } diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/serializer.pure b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/serializer.pure index 986b29fb68b..16e19ff7e25 100644 --- a/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/serializer.pure +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/serializer.pure @@ -58,9 +58,10 @@ function <> meta::analytics::mapping::modelCoverage::serializati newJSONObject ([ newJSONKeyValue('isRootEntity', if($info.isRootEntity->isEmpty(), - | ^JSONNull(), + | ^JSONNull(), | ^JSONBoolean(value=$info.isRootEntity->toOne()) )), + newJSONKeyValue('classPath', ^JSONString(value=$info.classPath)), newJSONKeyValue('subClasses', ^JSONArray(values=$info.subClasses->map(v | ^JSONString(value=$v)))) ]) } diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/utility.pure b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/utility.pure index 0550d83bf67..42726c46651 100644 --- a/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/utility.pure +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/utility.pure @@ -60,28 +60,6 @@ function meta::analytics::mapping::modelCoverage::utility::getFunctionPath(f:Fun $f->elementToPath()->replace($f.name->toOne(), $f.functionName->toOne()); } - -function {doc.doc = 'Get the parent or super types of the provided class'} - meta::analytics::mapping::modelCoverage::utility::superTypes(class : Class[1], recursive:Boolean[1]) : Class[*] -{ - let types = if ($recursive, | $class->generalizations(), | $class.generalizations.general.rawType); - - $types->map(rw| - $rw->match([ - c:Class[1] | if($c != Any && $c != $class, | $c, | []), - a:Any[1] | [] - ]) - ); -} - - -function {doc.doc = 'Get the parent or super types of the provided class recursively'} - meta::analytics::mapping::modelCoverage::utility::superTypes(class : Class[1]) : Class[*] -{ - $class->superTypes(true); -} - - function meta::analytics::mapping::modelCoverage::utility::qualifiedProperties(class:Class[1]):QualifiedProperty[*] { $class->generalizations()->init()->cast(@Class)->map(c | diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-search/legend-engine-xt-analytics-search-pure/src/main/resources/core_analytics_search/trans.pure b/legend-engine-xts-analytics/legend-engine-xts-analytics-search/legend-engine-xt-analytics-search-pure/src/main/resources/core_analytics_search/trans.pure index 302c10febce..ddd0a003f4d 100644 --- a/legend-engine-xts-analytics/legend-engine-xts-analytics-search/legend-engine-xt-analytics-search-pure/src/main/resources/core_analytics_search/trans.pure +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-search/legend-engine-xt-analytics-search-pure/src/main/resources/core_analytics_search/trans.pure @@ -114,7 +114,7 @@ function meta::analytics::search::transformation::dataspace::buildExecutionConte function meta::analytics::search::transformation::dataspace::buildClassDocuments(mapping: meta::pure::mapping::Mapping[1]): meta::analytics::search::metamodel::class::SimpleClassElement[*] { - let analysedMapping = meta::analytics::mapping::modelCoverage::analyze($mapping, true, true); + let analysedMapping = meta::analytics::mapping::modelCoverage::analyze($mapping, true, true, false); $analysedMapping.mappedEntities->filter(e|$e.info.isRootEntity == true)->map(e| ^meta::analytics::search::metamodel::class::SimpleClassElement( name = $e.path->split('::')->last()->toOne(), diff --git a/legend-engine-xts-analytics/pom.xml b/legend-engine-xts-analytics/pom.xml index ee319565f6b..7b7457bd1ed 100644 --- a/legend-engine-xts-analytics/pom.xml +++ b/legend-engine-xts-analytics/pom.xml @@ -31,6 +31,9 @@ legend-engine-xts-analytics-lineage legend-engine-xts-analytics-mapping + legend-engine-xts-analytics-class + legend-engine-xts-analytics-function + legend-engine-xts-analytics-binding legend-engine-xts-analytics-search legend-engine-xts-analytics-store diff --git a/legend-engine-xts-data-space/legend-engine-xt-data-space-api/src/main/java/org/finos/legend/engine/api/analytics/DataSpaceAnalytics.java b/legend-engine-xts-data-space/legend-engine-xt-data-space-api/src/main/java/org/finos/legend/engine/api/analytics/DataSpaceAnalytics.java index df0a60bf789..4f1ff451244 100644 --- a/legend-engine-xts-data-space/legend-engine-xt-data-space-api/src/main/java/org/finos/legend/engine/api/analytics/DataSpaceAnalytics.java +++ b/legend-engine-xts-data-space/legend-engine-xt-data-space-api/src/main/java/org/finos/legend/engine/api/analytics/DataSpaceAnalytics.java @@ -103,4 +103,31 @@ public Response analyzeDataSpace(DataSpaceAnalysisInput input, @ApiParam(hidden } } } + + @POST + @Path("coverage") + @ApiOperation(value = "Analyze the data space to get the model coverage") + @Consumes({MediaType.APPLICATION_JSON, InflateInterceptor.APPLICATION_ZLIB}) + @Produces(MediaType.APPLICATION_JSON) + public Response analyzeDataSpaceCoverage(DataSpaceAnalysisInput input, @ApiParam(hidden = true) @Pac4JProfileManager ProfileManager pm) + { + 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); + PackageableElement dataSpaceProtocol = pureModelContextData.getElements().stream().filter(el -> input.dataSpace.equals(el.getPath())).findFirst().orElse(null); + Assert.assertTrue(dataSpaceProtocol instanceof DataSpace, () -> "Can't find data space '" + input.dataSpace + "'"); + Root_meta_pure_metamodel_dataSpace_DataSpace dataSpace = HelperDataSpaceBuilder.getDataSpace(input.dataSpace, null, pureModel.getContext()); + + try (Scope scope = GlobalTracer.get().buildSpan("Analytics: data space model coverage").startActive(true)) + { + try + { + return ManageConstantResult.manageResult(profiles, DataSpaceAnalyticsHelper.analyzeDataSpaceCoverage(dataSpace, pureModel, (DataSpace) dataSpaceProtocol, pureModelContextData, input.clientVersion, this.generatorExtensions, this.entitlementServiceExtensions), objectMapper); + } + catch (Exception e) + { + return ExceptionTool.exceptionManager(e, LoggingEventType.ANALYTICS_ERROR, Response.Status.BAD_REQUEST, profiles); + } + } + } } diff --git a/legend-engine-xts-data-space/legend-engine-xt-data-space-api/src/test/java/org/finos/legend/engine/api/analytics/test/TestDataSpaceAnalyticsApi.java b/legend-engine-xts-data-space/legend-engine-xt-data-space-api/src/test/java/org/finos/legend/engine/api/analytics/test/TestDataSpaceAnalyticsApi.java index 03ecddf3745..56ae1cd555c 100644 --- a/legend-engine-xts-data-space/legend-engine-xt-data-space-api/src/test/java/org/finos/legend/engine/api/analytics/test/TestDataSpaceAnalyticsApi.java +++ b/legend-engine-xts-data-space/legend-engine-xt-data-space-api/src/test/java/org/finos/legend/engine/api/analytics/test/TestDataSpaceAnalyticsApi.java @@ -56,10 +56,18 @@ public void testDataSpaceAnalysisWithNotFoundDataSpace() throws IOException public void testDataSpaceAnalysis() throws IOException { PureModelContextData modelContextData = objectMapper.readValue(Objects.requireNonNull(getClass().getClassLoader().getResource("dataSpaceAnalyticsTestData.json")), PureModelContextData.class); - String expected = "{\"defaultExecutionContext\":\"dummyContext\",\"diagrams\":[],\"elementDocs\":[],\"elements\":[],\"executables\":[],\"executionContexts\":[{\"compatibleRuntimes\":[\"model::dummyRuntime\"],\"datasets\":[],\"defaultRuntime\":\"model::dummyRuntime\",\"mapping\":\"model::dummyMapping\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[]},\"name\":\"dummyContext\"}],\"model\":{\"_type\":\"data\",\"elements\":[]},\"name\":\"AnimalDS\",\"package\":\"model::animal\",\"path\":\"model::animal::AnimalDS\",\"stereotypes\":[],\"taggedValues\":[]}"; + String expected = "{\"defaultExecutionContext\":\"dummyContext\",\"diagrams\":[],\"elementDocs\":[],\"elements\":[],\"executables\":[],\"executionContexts\":[{\"compatibleRuntimes\":[\"model::dummyRuntime\"],\"datasets\":[],\"defaultRuntime\":\"model::dummyRuntime\",\"mapping\":\"model::dummyMapping\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"dataSpace\",\"defaultExecutionContext\":\"dummyContext\",\"executionContexts\":[{\"defaultRuntime\":{\"path\":\"model::dummyRuntime\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"model::dummyMapping\",\"type\":\"MAPPING\"},\"name\":\"dummyContext\"}],\"name\":\"AnimalDS\",\"package\":\"model::animal\",\"stereotypes\":[],\"taggedValues\":[]}]}},\"name\":\"dummyContext\"}],\"model\":{\"_type\":\"data\",\"elements\":[]},\"name\":\"AnimalDS\",\"package\":\"model::animal\",\"path\":\"model::animal::AnimalDS\",\"stereotypes\":[],\"taggedValues\":[]}"; testAnalyticsWithVersions(expected, modelContextData, "model::animal::AnimalDS"); } + @Test + public void testDataSpaceCoverageAnalysis() throws IOException + { + PureModelContextData modelContextData = objectMapper.readValue(Objects.requireNonNull(getClass().getClassLoader().getResource("dataSpaceAnalyticsTestData.json")), PureModelContextData.class); + String expected = "{\"defaultExecutionContext\":\"dummyContext\",\"diagrams\":[],\"elementDocs\":[],\"elements\":[],\"executables\":[],\"executionContexts\":[{\"compatibleRuntimes\":[\"model::dummyRuntime\"],\"defaultRuntime\":\"model::dummyRuntime\",\"mapping\":\"model::dummyMapping\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"dataSpace\",\"defaultExecutionContext\":\"dummyContext\",\"executionContexts\":[{\"defaultRuntime\":{\"path\":\"model::dummyRuntime\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"model::dummyMapping\",\"type\":\"MAPPING\"},\"name\":\"dummyContext\"}],\"name\":\"AnimalDS\",\"package\":\"model::animal\",\"stereotypes\":[],\"taggedValues\":[]}]}},\"name\":\"dummyContext\"}],\"name\":\"AnimalDS\",\"package\":\"model::animal\",\"path\":\"model::animal::AnimalDS\",\"stereotypes\":[],\"taggedValues\":[]}"; + testCoverageAnalyticsWithVersions(expected, modelContextData, "model::animal::AnimalDS"); + } + private void testAnalyticsWithVersions(String expected, PureModelContextData modelContextData, String dataSpace) { testVersions.forEach(pureClient -> @@ -68,5 +76,14 @@ private void testAnalyticsWithVersions(String expected, PureModelContextData mod Assert.assertEquals(expected, response.getEntity().toString()); }); } + + private void testCoverageAnalyticsWithVersions(String expected, PureModelContextData modelContextData, String dataSpace) + { + testVersions.forEach(pureClient -> + { + Response response = api.analyzeDataSpaceCoverage(new DataSpaceAnalysisInput(pureClient, dataSpace, modelContextData), null); + Assert.assertEquals(expected, response.getEntity().toString()); + }); + } } diff --git a/legend-engine-xts-data-space/legend-engine-xt-data-space-generation/pom.xml b/legend-engine-xts-data-space/legend-engine-xt-data-space-generation/pom.xml index 02c4c5502f8..7009cfe444e 100644 --- a/legend-engine-xts-data-space/legend-engine-xt-data-space-generation/pom.xml +++ b/legend-engine-xts-data-space/legend-engine-xt-data-space-generation/pom.xml @@ -123,6 +123,14 @@ org.finos.legend.engine legend-engine-xt-analytics-store-entitlement + + org.finos.legend.engine + legend-engine-xt-analytics-function-pure + + + org.finos.legend.engine + legend-engine-xt-analytics-binding-pure + diff --git a/legend-engine-xts-data-space/legend-engine-xt-data-space-generation/src/main/java/org/finos/legend/engine/generation/analytics/DataSpaceAnalyticsHelper.java b/legend-engine-xts-data-space/legend-engine-xt-data-space-generation/src/main/java/org/finos/legend/engine/generation/analytics/DataSpaceAnalyticsHelper.java index 93fb137fbeb..186fcf8719b 100644 --- a/legend-engine-xts-data-space/legend-engine-xt-data-space-generation/src/main/java/org/finos/legend/engine/generation/analytics/DataSpaceAnalyticsHelper.java +++ b/legend-engine-xts-data-space/legend-engine-xt-data-space-generation/src/main/java/org/finos/legend/engine/generation/analytics/DataSpaceAnalyticsHelper.java @@ -46,6 +46,7 @@ import org.finos.legend.engine.language.pure.compiler.toPureGraph.HelperValueSpecificationBuilder; import org.finos.legend.engine.language.pure.compiler.toPureGraph.PureModel; import org.finos.legend.engine.language.pure.grammar.to.DEPRECATED_PureGrammarComposerCore; +import org.finos.legend.engine.language.pure.grammar.to.HelperValueSpecificationGrammarComposer; import org.finos.legend.engine.plan.generation.PlanGenerator; import org.finos.legend.engine.plan.generation.extension.PlanGeneratorExtension; import org.finos.legend.engine.plan.platform.PlanPlatform; @@ -56,7 +57,9 @@ import org.finos.legend.engine.protocol.pure.v1.model.executionPlan.result.ResultType; import org.finos.legend.engine.protocol.pure.v1.model.executionPlan.result.TDSResultType; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.dataSpace.DataSpace; +import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.domain.Function; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.domain.Multiplicity; +import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.externalFormat.Binding; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.runtime.PackageableRuntime; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.runtime.RuntimePointer; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.PureMultiExecution; @@ -65,7 +68,10 @@ import org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.raw.executionContext.BaseExecutionContext; import org.finos.legend.engine.pure.code.core.PureCoreExtensionLoader; import org.finos.legend.engine.shared.core.api.grammar.RenderStyle; +import org.finos.legend.pure.generated.Root_meta_analytics_binding_modelCoverage_BindingModelCoverageAnalysisResult; +import org.finos.legend.pure.generated.Root_meta_analytics_function_modelCoverage_FunctionModelCoverageAnalysisResult; import org.finos.legend.pure.generated.Root_meta_analytics_mapping_modelCoverage_MappingModelCoverageAnalysisResult; +import org.finos.legend.pure.generated.Root_meta_external_format_shared_binding_Binding; import org.finos.legend.pure.generated.Root_meta_legend_service_metamodel_PureSingleExecution; import org.finos.legend.pure.generated.Root_meta_legend_service_metamodel_PureMultiExecution; import org.finos.legend.pure.generated.Root_meta_legend_service_metamodel_KeyedExecutionParameter; @@ -75,22 +81,30 @@ import org.finos.legend.pure.generated.Root_meta_pure_metamodel_dataSpace_analytics_DataSpaceAssociationDocumentationEntry; import org.finos.legend.pure.generated.Root_meta_pure_metamodel_dataSpace_analytics_DataSpaceBasicDocumentationEntry; import org.finos.legend.pure.generated.Root_meta_pure_metamodel_dataSpace_analytics_DataSpaceClassDocumentationEntry; +import org.finos.legend.pure.generated.Root_meta_pure_metamodel_dataSpace_analytics_DataSpaceCoverageAnalysisResult; import org.finos.legend.pure.generated.Root_meta_pure_metamodel_dataSpace_analytics_DataSpaceEnumerationDocumentationEntry; import org.finos.legend.pure.generated.Root_meta_pure_metamodel_dataSpace_analytics_DataSpaceExecutionContextAnalysisResult; import org.finos.legend.pure.generated.Root_meta_pure_metamodel_dataSpace_analytics_DataSpacePropertyDocumentationEntry; import org.finos.legend.pure.generated.Root_meta_pure_metamodel_diagram_analytics_modelCoverage_DiagramModelCoverageAnalysisResult; import org.finos.legend.pure.generated.Root_meta_pure_runtime_Runtime; +import org.finos.legend.pure.generated.core_analytics_binding_modelCoverage_analytics; +import org.finos.legend.pure.generated.core_analytics_function_modelCoverage_analytics; import org.finos.legend.pure.generated.core_analytics_mapping_modelCoverage_serializer; import org.finos.legend.pure.generated.core_data_space_analytics_analytics; import org.finos.legend.pure.m3.coreinstance.meta.pure.mapping.Mapping; import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.PackageableElement; import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.extension.Profile; +import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.ConcreteFunctionDefinition; import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.LambdaFunction; +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 java.util.ArrayList; import java.util.List; import java.util.ServiceLoader; import java.util.stream.Collectors; +import java.util.stream.Stream; import static org.finos.legend.engine.shared.core.ObjectMapperFactory.withStandardConfigurations; @@ -142,11 +156,154 @@ private static DataSpaceExecutableResult buildExecutableResult(ResultType result return null; } + private static MappingModelCoverageAnalysisResult buildMappingModelCoverageAnalysisResult(Root_meta_analytics_mapping_modelCoverage_MappingModelCoverageAnalysisResult mappingModelCoverageAnalysisResult, DataSpaceExecutionContextAnalysisResult excResult, PureModel pureModel, DataSpace dataSpaceProtocol, PureModelContextData pureModelContextData, String clientVersion, MutableList generatorExtensions, List entitlementServiceExtensions, Boolean returnDataSets) + { + try + { + MappingModelCoverageAnalysisResult mappingModelCoverageAnalysisResultProtocol = DataSpaceAnalyticsHelper.objectMapper.readValue(core_analytics_mapping_modelCoverage_serializer.Root_meta_analytics_mapping_modelCoverage_serialization_json_getSerializedMappingModelCoverageAnalysisResult_MappingModelCoverageAnalysisResult_1__String_1_(mappingModelCoverageAnalysisResult, pureModel.getExecutionSupport()), MappingModelCoverageAnalysisResult.class); + if (returnDataSets) + { + excResult.datasets = LazyIterate.flatCollect(entitlementServiceExtensions, extension -> extension.generateDatasetSpecifications(null, excResult.defaultRuntime, pureModel.getRuntime(excResult.defaultRuntime), excResult.mapping, pureModel.getMapping(excResult.mapping), pureModelContextData, pureModel)).toList(); + } + PureModelContextData.Builder builder = PureModelContextData.newBuilder(); + + // Here we prune the bindings to have just packageableIncludes part of ModelUnit + // because we only need that as a part of analytics. + List bindingPaths = pureModelContextData.getElements().stream().filter(el -> el instanceof Binding).map(b -> + { + Binding _binding = new Binding(); + _binding.name = b.name; + _binding.contentType = ((Binding) b).contentType; + _binding._package = b._package; + _binding.modelUnit = ((Binding) b).modelUnit; + _binding.modelUnit.packageableElementExcludes = org.eclipse.collections.api.factory.Lists.mutable.empty(); + builder.addElement(_binding); + return b.getPath(); + }).collect(Collectors.toList()); + RichIterable bindings = org.eclipse.collections.api.factory.Lists.mutable.ofAll(bindingPaths.stream().map(path -> + { + Root_meta_external_format_shared_binding_Binding binding; + try + { + binding = (Root_meta_external_format_shared_binding_Binding) pureModel.getPackageableElement(path); + return binding; + } + catch (Exception ignored) + { + + } + return null; + }).filter(c -> c != null).collect(Collectors.toList())); + Root_meta_analytics_binding_modelCoverage_BindingModelCoverageAnalysisResult bindingAnalysisResult = core_analytics_binding_modelCoverage_analytics.Root_meta_analytics_binding_modelCoverage_getBindingModelCoverage_Binding_MANY__BindingModelCoverageAnalysisResult_1_(bindings, pureModel.getExecutionSupport()); + List functionPaths = pureModelContextData.getElements().stream().filter(el -> el instanceof Function).map(e -> e.getPath()).collect(Collectors.toList()); + List allExtraElements = functionPaths; + allExtraElements.add(dataSpaceProtocol.getPath()); + pureModelContextData.getElements().stream().filter(el -> allExtraElements.contains(el.getPath())).forEach(builder::addElement); + List elements = builder.build().getElements(); + RichIterable> functions = org.eclipse.collections.api.factory.Lists.mutable.ofAll(functionPaths.stream().map(path -> + { + ConcreteFunctionDefinition function = null; + try + { + function = pureModel.getConcreteFunctionDefinition_safe(path); + if (function == null) + { + Function _function = (Function) elements.stream().filter(e -> e.getPath().equals(path)).findFirst().get(); + function = pureModel.getConcreteFunctionDefinition_safe(path + HelperValueSpecificationGrammarComposer.getFunctionSignature(_function)); + + } + return function; + } + catch (Exception ignored) + { + + } + return null; + }).filter(c -> c != null).collect(Collectors.toList())); + Root_meta_analytics_function_modelCoverage_FunctionModelCoverageAnalysisResult functionCoverageAnalysisResult = core_analytics_function_modelCoverage_analytics.Root_meta_analytics_function_modelCoverage_getFunctionModelCoverage_ConcreteFunctionDefinition_MANY__FunctionModelCoverageAnalysisResult_1_(org.eclipse.collections.impl.factory.Lists.mutable.ofAll(functions), pureModel.getExecutionSupport()); + MutableList> coveredClasses = mappingModelCoverageAnalysisResult._classes().toList(); + List coveredClassesPaths = coveredClasses.stream().map(c -> HelperModelBuilder.getElementFullPath(c, pureModel.getExecutionSupport())).collect(Collectors.toList()); + coveredClasses = org.eclipse.collections.impl.factory.Lists.mutable.ofAll(Stream.concat(Stream.concat(functionCoverageAnalysisResult._classes().toList().stream().filter(c -> !coveredClassesPaths.contains(HelperModelBuilder.getElementFullPath(c, pureModel.getExecutionSupport()))), + bindingAnalysisResult._classes().toList().stream().filter(c -> !coveredClassesPaths.contains(HelperModelBuilder.getElementFullPath(c, pureModel.getExecutionSupport())))).distinct(), + mappingModelCoverageAnalysisResult._classes().toList().stream()).collect(Collectors.toList())); + MutableList> coveredEnumerations = org.eclipse.collections.impl.factory.Lists.mutable.ofAll(Stream.concat(mappingModelCoverageAnalysisResult._enumerations().toList().stream(), functionCoverageAnalysisResult._enumerations().toList().stream()).distinct().collect(Collectors.toList())); + PureModelContextData classes = PureModelContextDataGenerator.generatePureModelContextDataFromClasses(coveredClasses, clientVersion, pureModel.getExecutionSupport()); + PureModelContextData enums = PureModelContextDataGenerator.generatePureModelContextDataFromEnumerations(coveredEnumerations, clientVersion, pureModel.getExecutionSupport()); + PureModelContextData _profiles = PureModelContextDataGenerator.generatePureModelContextDataFromProfile((RichIterable) mappingModelCoverageAnalysisResult._profiles(), clientVersion, pureModel.getExecutionSupport()); + PureModelContextData associations = PureModelContextDataGenerator.generatePureModelContextDataFromAssociations(mappingModelCoverageAnalysisResult._associations(), clientVersion, pureModel.getExecutionSupport()); + mappingModelCoverageAnalysisResultProtocol.model = builder.build().combine(classes).combine(enums).combine(_profiles).combine(associations); + return mappingModelCoverageAnalysisResultProtocol; + } + catch (Exception ignored) + { + } + return null; + } + public static DataSpaceAnalysisResult analyzeDataSpace(Root_meta_pure_metamodel_dataSpace_DataSpace dataSpace, PureModel pureModel, DataSpace dataSpaceProtocol, PureModelContextData pureModelContextData, String clientVersion) { return analyzeDataSpace(dataSpace, pureModel, dataSpaceProtocol, pureModelContextData, clientVersion, Lists.mutable.withAll(ServiceLoader.load(PlanGeneratorExtension.class)), EntitlementServiceExtensionLoader.extensions()); } + public static DataSpaceAnalysisResult analyzeDataSpaceCoverage(Root_meta_pure_metamodel_dataSpace_DataSpace dataSpace, PureModel pureModel, DataSpace dataSpaceProtocol, PureModelContextData pureModelContextData, String clientVersion, MutableList generatorExtensions, List entitlementServiceExtensions) + { + Root_meta_pure_metamodel_dataSpace_analytics_DataSpaceCoverageAnalysisResult analysisResult = core_data_space_analytics_analytics.Root_meta_pure_metamodel_dataSpace_analytics_analyzeDataSpaceCoverage_DataSpace_1__PackageableRuntime_MANY__DataSpaceCoverageAnalysisResult_1_( + dataSpace, + ListIterate.selectInstancesOf(pureModelContextData.getElements(), PackageableRuntime.class).collect(runtime -> pureModel.getPackageableRuntime(runtime.getPath(), runtime.sourceInformation)), + pureModel.getExecutionSupport() + ); + + DataSpaceAnalysisResult result = new DataSpaceAnalysisResult(); + result.name = dataSpaceProtocol.name; + result._package = dataSpaceProtocol._package; + result.path = dataSpaceProtocol.getPath(); + result.title = dataSpaceProtocol.title; + result.description = dataSpaceProtocol.description; + + result.taggedValues = ListIterate.collect(dataSpace._taggedValues().toList(), taggedValue -> + { + DataSpaceTaggedValueInfo info = new DataSpaceTaggedValueInfo(); + info.profile = HelperModelBuilder.getElementFullPath(taggedValue._tag()._profile(), pureModel.getExecutionSupport()); + info.tag = taggedValue._tag()._value(); + info.value = taggedValue._value(); + return info; + }); + + result.stereotypes = ListIterate.collect(dataSpace._stereotypes().toList(), stereotype -> + { + DataSpaceStereotypeInfo info = new DataSpaceStereotypeInfo(); + info.profile = HelperModelBuilder.getElementFullPath(stereotype._profile(), pureModel.getExecutionSupport()); + info.value = stereotype._value(); + return info; + }); + + result.executionContexts = dataSpace._executionContexts().toList().collect(executionContext -> + { + Root_meta_pure_metamodel_dataSpace_analytics_DataSpaceExecutionContextAnalysisResult executionContextAnalysisResult = analysisResult._executionContexts().detect(context -> context._name().equals(executionContext._name())); + DataSpaceExecutionContextAnalysisResult excResult = new DataSpaceExecutionContextAnalysisResult(); + excResult.name = executionContext._name(); + excResult.title = executionContext._title(); + excResult.description = executionContext._description(); + excResult.mapping = HelperModelBuilder.getElementFullPath(executionContext._mapping(), pureModel.getExecutionSupport()); + excResult.defaultRuntime = HelperModelBuilder.getElementFullPath(executionContext._defaultRuntime(), pureModel.getExecutionSupport()); + excResult.compatibleRuntimes = ListIterate.collect(executionContextAnalysisResult._compatibleRuntimes().toList(), runtime -> HelperModelBuilder.getElementFullPath(runtime, pureModel.getExecutionSupport())); + Root_meta_analytics_mapping_modelCoverage_MappingModelCoverageAnalysisResult mappingModelCoverageAnalysisResult = executionContextAnalysisResult._mappingCoverage(); + excResult.mappingModelCoverageAnalysisResult = buildMappingModelCoverageAnalysisResult(mappingModelCoverageAnalysisResult, excResult, pureModel, dataSpaceProtocol, pureModelContextData, clientVersion, generatorExtensions, entitlementServiceExtensions, false); + return excResult; + }); + result.defaultExecutionContext = dataSpace._defaultExecutionContext()._name(); + // elements + result.elements = dataSpace._elements() != null ? dataSpace._elements().toList().collect(el -> HelperModelBuilder.getElementFullPath(el, pureModel.getExecutionSupport())) : Lists.mutable.empty(); + // support + result.supportInfo = dataSpaceProtocol.supportInfo; + if (result.supportInfo != null) + { + result.supportInfo.sourceInformation = null; + } + + return result; + } + public static DataSpaceAnalysisResult analyzeDataSpace(Root_meta_pure_metamodel_dataSpace_DataSpace dataSpace, PureModel pureModel, DataSpace dataSpaceProtocol, PureModelContextData pureModelContextData, String clientVersion, MutableList generatorExtensions, List entitlementServiceExtensions) { Root_meta_pure_metamodel_dataSpace_analytics_DataSpaceAnalysisResult analysisResult = core_data_space_analytics_analytics.Root_meta_pure_metamodel_dataSpace_analytics_analyzeDataSpace_DataSpace_1__PackageableRuntime_MANY__DataSpaceAnalysisResult_1_( @@ -179,7 +336,6 @@ public static DataSpaceAnalysisResult analyzeDataSpace(Root_meta_pure_metamodel_ return info; }); - // execution contexts result.executionContexts = dataSpace._executionContexts().toList().collect(executionContext -> { Root_meta_pure_metamodel_dataSpace_analytics_DataSpaceExecutionContextAnalysisResult executionContextAnalysisResult = analysisResult._executionContexts().detect(context -> context._name().equals(executionContext._name())); @@ -191,14 +347,7 @@ public static DataSpaceAnalysisResult analyzeDataSpace(Root_meta_pure_metamodel_ excResult.defaultRuntime = HelperModelBuilder.getElementFullPath(executionContext._defaultRuntime(), pureModel.getExecutionSupport()); excResult.compatibleRuntimes = ListIterate.collect(executionContextAnalysisResult._compatibleRuntimes().toList(), runtime -> HelperModelBuilder.getElementFullPath(runtime, pureModel.getExecutionSupport())); Root_meta_analytics_mapping_modelCoverage_MappingModelCoverageAnalysisResult mappingModelCoverageAnalysisResult = executionContextAnalysisResult._mappingCoverage(); - try - { - excResult.mappingModelCoverageAnalysisResult = DataSpaceAnalyticsHelper.objectMapper.readValue(core_analytics_mapping_modelCoverage_serializer.Root_meta_analytics_mapping_modelCoverage_serialization_json_getSerializedMappingModelCoverageAnalysisResult_MappingModelCoverageAnalysisResult_1__String_1_(mappingModelCoverageAnalysisResult, pureModel.getExecutionSupport()), MappingModelCoverageAnalysisResult.class); - excResult.datasets = LazyIterate.flatCollect(entitlementServiceExtensions, extension -> extension.generateDatasetSpecifications(null, excResult.defaultRuntime, pureModel.getRuntime(excResult.defaultRuntime), excResult.mapping, pureModel.getMapping(excResult.mapping), pureModelContextData, pureModel)).toList(); - } - catch (Exception ignored) - { - } + excResult.mappingModelCoverageAnalysisResult = buildMappingModelCoverageAnalysisResult(mappingModelCoverageAnalysisResult, excResult, pureModel, dataSpaceProtocol, pureModelContextData, clientVersion, generatorExtensions, entitlementServiceExtensions, true); return excResult; }); result.defaultExecutionContext = dataSpace._defaultExecutionContext()._name(); diff --git a/legend-engine-xts-data-space/legend-engine-xt-data-space-generation/src/test/java/org/finos/legend/engine/generation/TestDataSpaceAnalyticsArtifactGenerationExtension.java b/legend-engine-xts-data-space/legend-engine-xt-data-space-generation/src/test/java/org/finos/legend/engine/generation/TestDataSpaceAnalyticsArtifactGenerationExtension.java index c47ecbc97c4..007a95a9377 100644 --- a/legend-engine-xts-data-space/legend-engine-xt-data-space-generation/src/test/java/org/finos/legend/engine/generation/TestDataSpaceAnalyticsArtifactGenerationExtension.java +++ b/legend-engine-xts-data-space/legend-engine-xt-data-space-generation/src/test/java/org/finos/legend/engine/generation/TestDataSpaceAnalyticsArtifactGenerationExtension.java @@ -82,50 +82,50 @@ private void testDataSpaceAnalyticsArtifactGenerationExtension(String modelFileP @Test public void testAnalyticsForBasicDataSpace() throws Exception { - testDataSpaceAnalyticsArtifactGenerationExtension("models/dataSpaceBasic.pure", "model::animal::AnimalDS_Old", "{\"defaultExecutionContext\":\"dummyContext\",\"description\":\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\",\"diagrams\":[{\"diagram\":\"model::animal::AnimalDiagram\",\"title\":\"\"},{\"diagram\":\"model::GeneralDiagram\",\"title\":\"\"}],\"elementDocs\":[],\"elements\":[],\"executables\":[],\"executionContexts\":[{\"compatibleRuntimes\":[\"model::dummyRuntime\"],\"datasets\":[],\"defaultRuntime\":\"model::dummyRuntime\",\"description\":\"An important execution context\",\"mapping\":\"model::dummyMapping\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[]},\"name\":\"dummyContext\"},{\"compatibleRuntimes\":[\"model::dummyRuntime\",\"model::dummyRuntime2\"],\"datasets\":[],\"defaultRuntime\":\"model::dummyRuntime\",\"mapping\":\"model::dummyMapping2\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[]},\"name\":\"dummyContext2\"},{\"compatibleRuntimes\":[\"model::dummyRuntime\",\"model::dummyRuntime2\"],\"datasets\":[],\"defaultRuntime\":\"model::dummyRuntime2\",\"mapping\":\"model::dummyMapping2\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[]},\"name\":\"dummyContext3\"}],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"profile\",\"name\":\"doc\",\"package\":\"meta::pure::profiles\",\"stereotypes\":[\"deprecated\"],\"tags\":[\"doc\",\"todo\"]},{\"_type\":\"diagram\",\"classViews\":[{\"class\":\"model::animal::reptile::Reptile\",\"id\":\"4cec85f9-9b66-450a-bdcb-c855aa0314e1\",\"position\":{\"x\":568.0,\"y\":404.0},\"rectangle\":{\"height\":58.0,\"width\":120.84765625}},{\"class\":\"model::animal::Animal\",\"id\":\"902bf14e-e7ff-40e7-92e4-8780f91bfa29\",\"position\":{\"x\":809.0,\"y\":187.0},\"rectangle\":{\"height\":44.0,\"width\":108.64453125}}],\"generalizationViews\":[{\"line\":{\"points\":[{\"x\":628.423828125,\"y\":433.0},{\"x\":863.322265625,\"y\":209.0}]},\"sourceView\":\"4cec85f9-9b66-450a-bdcb-c855aa0314e1\",\"targetView\":\"902bf14e-e7ff-40e7-92e4-8780f91bfa29\"}],\"name\":\"GeneralDiagram\",\"package\":\"model\",\"propertyViews\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Animal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"family\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::animal::Family\"},{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"noOfLegs\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Number\"},{\"multiplicity\":{\"lowerBound\":0},\"name\":\"children\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::animal::GenericAnimal2\"}],\"qualifiedProperties\":[{\"body\":[{\"_type\":\"func\",\"fControl\":\"greaterThan_Number_1__Number_1__Boolean_1_\",\"function\":\"greaterThan\",\"parameters\":[{\"_type\":\"property\",\"parameters\":[{\"_type\":\"var\",\"name\":\"this\"}],\"property\":\"noOfLegs\"},{\"_type\":\"integer\",\"value\":4}]}],\"name\":\"something\",\"parameters\":[],\"returnMultiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"returnType\":\"Boolean\",\"stereotypes\":[],\"taggedValues\":[]},{\"body\":[{\"_type\":\"collection\",\"multiplicity\":{\"lowerBound\":0,\"upperBound\":0},\"values\":[]}],\"name\":\"something2\",\"parameters\":[],\"returnMultiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"returnType\":\"model::animal::GenericAnimal\",\"stereotypes\":[],\"taggedValues\":[]}],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"diagram\",\"classViews\":[{\"class\":\"model::animal::mammal::Mammal\",\"id\":\"641a0336-d4b5-418c-b656-2f52461264e2\",\"position\":{\"x\":427.0,\"y\":210.0},\"rectangle\":{\"height\":44.0,\"width\":125.1123046875}},{\"class\":\"model::animal::reptile::Reptile\",\"id\":\"b92253d8-0389-4c7d-b5d2-3cdc3bb1ad98\",\"position\":{\"x\":787.0,\"y\":216.0},\"rectangle\":{\"height\":58.0,\"width\":120.84765625}},{\"class\":\"model::animal::Animal\",\"id\":\"7a992cfc-c888-4091-aa00-ab430915aced\",\"position\":{\"x\":515.423828125,\"y\":-7.5},\"rectangle\":{\"height\":100.0,\"width\":199.716796875}}],\"generalizationViews\":[{\"line\":{\"points\":[{\"x\":847.423828125,\"y\":245.0},{\"x\":615.2822265625,\"y\":42.5}]},\"sourceView\":\"b92253d8-0389-4c7d-b5d2-3cdc3bb1ad98\",\"targetView\":\"7a992cfc-c888-4091-aa00-ab430915aced\"}],\"name\":\"AnimalDiagram\",\"package\":\"model::animal\",\"propertyViews\":[]},{\"_type\":\"Enumeration\",\"name\":\"Family\",\"package\":\"model::animal\",\"stereotypes\":[],\"taggedValues\":[],\"values\":[{\"stereotypes\":[],\"taggedValues\":[],\"value\":\"UO\"},{\"stereotypes\":[],\"taggedValues\":[],\"value\":\"OP\"}]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"GenericAnimal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"GenericAnimal2\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Mammal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal::mammal\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"noOfLegs\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Reptile\",\"originalMilestonedProperties\":[],\"package\":\"model::animal::reptile\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"hasFin\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Boolean\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[\"model::animal::Animal\"],\"taggedValues\":[{\"tag\":{\"profile\":\"meta::pure::profiles::doc\",\"value\":\"doc\"},\"value\":\"\"}]}]},\"name\":\"AnimalDS_Old\",\"package\":\"model::animal\",\"path\":\"model::animal::AnimalDS_Old\",\"stereotypes\":[{\"profile\":\"meta::pure::profiles::doc\",\"value\":\"deprecated\"}],\"supportInfo\":{\"_type\":\"email\",\"address\":\"someEmail@test.org\"},\"taggedValues\":[{\"profile\":\"meta::pure::profiles::enterprise\",\"tag\":\"taxonomyNodes\",\"value\":\"abcdxyz005\"},{\"profile\":\"meta::pure::profiles::doc\",\"tag\":\"doc\",\"value\":\"Lorem ipsum\"},{\"profile\":\"meta::pure::profiles::doc\",\"tag\":\"doc\",\"value\":\"Lorem ipsum2\"},{\"profile\":\"meta::pure::metamodel::dataSpace::profiles::DataSpaceInfo\",\"tag\":\"deprecationNotice\",\"value\":\"Please use AnimalDS dataspace instead - link provided\"}]}"); - testDataSpaceAnalyticsArtifactGenerationExtension("models/dataSpaceBasic.pure", "model::animal::AnimalDS", "{\"defaultExecutionContext\":\"dummyContext\",\"description\":\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\",\"diagrams\":[{\"description\":\"Some diagram description\",\"diagram\":\"model::animal::AnimalDiagram\",\"title\":\"Diag 1\"},{\"description\":\"Some more diagram description\",\"diagram\":\"model::GeneralDiagram\",\"title\":\"Diag 2\"}],\"elementDocs\":[],\"elements\":[],\"executables\":[],\"executionContexts\":[{\"compatibleRuntimes\":[\"model::dummyRuntime\"],\"datasets\":[],\"defaultRuntime\":\"model::dummyRuntime\",\"description\":\"An important execution context\",\"mapping\":\"model::dummyMapping\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[]},\"name\":\"dummyContext\",\"title\":\"Haha Nice\"},{\"compatibleRuntimes\":[\"model::dummyRuntime\",\"model::dummyRuntime2\"],\"datasets\":[],\"defaultRuntime\":\"model::dummyRuntime\",\"mapping\":\"model::dummyMapping2\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[]},\"name\":\"dummyContext2\"},{\"compatibleRuntimes\":[\"model::dummyRuntime\",\"model::dummyRuntime2\"],\"datasets\":[],\"defaultRuntime\":\"model::dummyRuntime2\",\"mapping\":\"model::dummyMapping2\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[]},\"name\":\"dummyContext3\"}],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"profile\",\"name\":\"doc\",\"package\":\"meta::pure::profiles\",\"stereotypes\":[\"deprecated\"],\"tags\":[\"doc\",\"todo\"]},{\"_type\":\"diagram\",\"classViews\":[{\"class\":\"model::animal::reptile::Reptile\",\"id\":\"4cec85f9-9b66-450a-bdcb-c855aa0314e1\",\"position\":{\"x\":568.0,\"y\":404.0},\"rectangle\":{\"height\":58.0,\"width\":120.84765625}},{\"class\":\"model::animal::Animal\",\"id\":\"902bf14e-e7ff-40e7-92e4-8780f91bfa29\",\"position\":{\"x\":809.0,\"y\":187.0},\"rectangle\":{\"height\":44.0,\"width\":108.64453125}}],\"generalizationViews\":[{\"line\":{\"points\":[{\"x\":628.423828125,\"y\":433.0},{\"x\":863.322265625,\"y\":209.0}]},\"sourceView\":\"4cec85f9-9b66-450a-bdcb-c855aa0314e1\",\"targetView\":\"902bf14e-e7ff-40e7-92e4-8780f91bfa29\"}],\"name\":\"GeneralDiagram\",\"package\":\"model\",\"propertyViews\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Animal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"family\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::animal::Family\"},{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"noOfLegs\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Number\"},{\"multiplicity\":{\"lowerBound\":0},\"name\":\"children\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::animal::GenericAnimal2\"}],\"qualifiedProperties\":[{\"body\":[{\"_type\":\"func\",\"fControl\":\"greaterThan_Number_1__Number_1__Boolean_1_\",\"function\":\"greaterThan\",\"parameters\":[{\"_type\":\"property\",\"parameters\":[{\"_type\":\"var\",\"name\":\"this\"}],\"property\":\"noOfLegs\"},{\"_type\":\"integer\",\"value\":4}]}],\"name\":\"something\",\"parameters\":[],\"returnMultiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"returnType\":\"Boolean\",\"stereotypes\":[],\"taggedValues\":[]},{\"body\":[{\"_type\":\"collection\",\"multiplicity\":{\"lowerBound\":0,\"upperBound\":0},\"values\":[]}],\"name\":\"something2\",\"parameters\":[],\"returnMultiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"returnType\":\"model::animal::GenericAnimal\",\"stereotypes\":[],\"taggedValues\":[]}],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"diagram\",\"classViews\":[{\"class\":\"model::animal::mammal::Mammal\",\"id\":\"641a0336-d4b5-418c-b656-2f52461264e2\",\"position\":{\"x\":427.0,\"y\":210.0},\"rectangle\":{\"height\":44.0,\"width\":125.1123046875}},{\"class\":\"model::animal::reptile::Reptile\",\"id\":\"b92253d8-0389-4c7d-b5d2-3cdc3bb1ad98\",\"position\":{\"x\":787.0,\"y\":216.0},\"rectangle\":{\"height\":58.0,\"width\":120.84765625}},{\"class\":\"model::animal::Animal\",\"id\":\"7a992cfc-c888-4091-aa00-ab430915aced\",\"position\":{\"x\":515.423828125,\"y\":-7.5},\"rectangle\":{\"height\":100.0,\"width\":199.716796875}}],\"generalizationViews\":[{\"line\":{\"points\":[{\"x\":847.423828125,\"y\":245.0},{\"x\":615.2822265625,\"y\":42.5}]},\"sourceView\":\"b92253d8-0389-4c7d-b5d2-3cdc3bb1ad98\",\"targetView\":\"7a992cfc-c888-4091-aa00-ab430915aced\"}],\"name\":\"AnimalDiagram\",\"package\":\"model::animal\",\"propertyViews\":[]},{\"_type\":\"Enumeration\",\"name\":\"Family\",\"package\":\"model::animal\",\"stereotypes\":[],\"taggedValues\":[],\"values\":[{\"stereotypes\":[],\"taggedValues\":[],\"value\":\"UO\"},{\"stereotypes\":[],\"taggedValues\":[],\"value\":\"OP\"}]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"GenericAnimal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"GenericAnimal2\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Mammal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal::mammal\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"noOfLegs\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Reptile\",\"originalMilestonedProperties\":[],\"package\":\"model::animal::reptile\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"hasFin\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Boolean\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[\"model::animal::Animal\"],\"taggedValues\":[{\"tag\":{\"profile\":\"meta::pure::profiles::doc\",\"value\":\"doc\"},\"value\":\"\"}]}]},\"name\":\"AnimalDS\",\"package\":\"model::animal\",\"path\":\"model::animal::AnimalDS\",\"stereotypes\":[{\"profile\":\"meta::pure::metamodel::dataSpace::profiles::DataSpaceInfo\",\"value\":\"Verified\"}],\"supportInfo\":{\"_type\":\"email\",\"address\":\"someEmail@test.org\"},\"taggedValues\":[]}"); - testDataSpaceAnalyticsArtifactGenerationExtension("models/dataSpaceBasic.pure", "model::animal::AnimalDS2", "{\"defaultExecutionContext\":\"dummyContext\",\"description\":\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\",\"diagrams\":[{\"diagram\":\"model::animal::AnimalDiagram\",\"title\":\"\"},{\"diagram\":\"model::GeneralDiagram\",\"title\":\"\"}],\"elementDocs\":[],\"elements\":[],\"executables\":[],\"executionContexts\":[{\"compatibleRuntimes\":[\"model::dummyRuntime\"],\"datasets\":[],\"defaultRuntime\":\"model::dummyRuntime\",\"description\":\"An important execution context\",\"mapping\":\"model::dummyMapping\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[]},\"name\":\"dummyContext\"},{\"compatibleRuntimes\":[\"model::dummyRuntime\",\"model::dummyRuntime2\"],\"datasets\":[],\"defaultRuntime\":\"model::dummyRuntime\",\"mapping\":\"model::dummyMapping2\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[]},\"name\":\"dummyContext2\"},{\"compatibleRuntimes\":[\"model::dummyRuntime\",\"model::dummyRuntime2\"],\"datasets\":[],\"defaultRuntime\":\"model::dummyRuntime2\",\"mapping\":\"model::dummyMapping2\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[]},\"name\":\"dummyContext3\"}],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"profile\",\"name\":\"doc\",\"package\":\"meta::pure::profiles\",\"stereotypes\":[\"deprecated\"],\"tags\":[\"doc\",\"todo\"]},{\"_type\":\"diagram\",\"classViews\":[{\"class\":\"model::animal::reptile::Reptile\",\"id\":\"4cec85f9-9b66-450a-bdcb-c855aa0314e1\",\"position\":{\"x\":568.0,\"y\":404.0},\"rectangle\":{\"height\":58.0,\"width\":120.84765625}},{\"class\":\"model::animal::Animal\",\"id\":\"902bf14e-e7ff-40e7-92e4-8780f91bfa29\",\"position\":{\"x\":809.0,\"y\":187.0},\"rectangle\":{\"height\":44.0,\"width\":108.64453125}}],\"generalizationViews\":[{\"line\":{\"points\":[{\"x\":628.423828125,\"y\":433.0},{\"x\":863.322265625,\"y\":209.0}]},\"sourceView\":\"4cec85f9-9b66-450a-bdcb-c855aa0314e1\",\"targetView\":\"902bf14e-e7ff-40e7-92e4-8780f91bfa29\"}],\"name\":\"GeneralDiagram\",\"package\":\"model\",\"propertyViews\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Animal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"family\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::animal::Family\"},{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"noOfLegs\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Number\"},{\"multiplicity\":{\"lowerBound\":0},\"name\":\"children\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::animal::GenericAnimal2\"}],\"qualifiedProperties\":[{\"body\":[{\"_type\":\"func\",\"fControl\":\"greaterThan_Number_1__Number_1__Boolean_1_\",\"function\":\"greaterThan\",\"parameters\":[{\"_type\":\"property\",\"parameters\":[{\"_type\":\"var\",\"name\":\"this\"}],\"property\":\"noOfLegs\"},{\"_type\":\"integer\",\"value\":4}]}],\"name\":\"something\",\"parameters\":[],\"returnMultiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"returnType\":\"Boolean\",\"stereotypes\":[],\"taggedValues\":[]},{\"body\":[{\"_type\":\"collection\",\"multiplicity\":{\"lowerBound\":0,\"upperBound\":0},\"values\":[]}],\"name\":\"something2\",\"parameters\":[],\"returnMultiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"returnType\":\"model::animal::GenericAnimal\",\"stereotypes\":[],\"taggedValues\":[]}],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"diagram\",\"classViews\":[{\"class\":\"model::animal::mammal::Mammal\",\"id\":\"641a0336-d4b5-418c-b656-2f52461264e2\",\"position\":{\"x\":427.0,\"y\":210.0},\"rectangle\":{\"height\":44.0,\"width\":125.1123046875}},{\"class\":\"model::animal::reptile::Reptile\",\"id\":\"b92253d8-0389-4c7d-b5d2-3cdc3bb1ad98\",\"position\":{\"x\":787.0,\"y\":216.0},\"rectangle\":{\"height\":58.0,\"width\":120.84765625}},{\"class\":\"model::animal::Animal\",\"id\":\"7a992cfc-c888-4091-aa00-ab430915aced\",\"position\":{\"x\":515.423828125,\"y\":-7.5},\"rectangle\":{\"height\":100.0,\"width\":199.716796875}}],\"generalizationViews\":[{\"line\":{\"points\":[{\"x\":847.423828125,\"y\":245.0},{\"x\":615.2822265625,\"y\":42.5}]},\"sourceView\":\"b92253d8-0389-4c7d-b5d2-3cdc3bb1ad98\",\"targetView\":\"7a992cfc-c888-4091-aa00-ab430915aced\"}],\"name\":\"AnimalDiagram\",\"package\":\"model::animal\",\"propertyViews\":[]},{\"_type\":\"Enumeration\",\"name\":\"Family\",\"package\":\"model::animal\",\"stereotypes\":[],\"taggedValues\":[],\"values\":[{\"stereotypes\":[],\"taggedValues\":[],\"value\":\"UO\"},{\"stereotypes\":[],\"taggedValues\":[],\"value\":\"OP\"}]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"GenericAnimal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"GenericAnimal2\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Mammal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal::mammal\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"noOfLegs\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Reptile\",\"originalMilestonedProperties\":[],\"package\":\"model::animal::reptile\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"hasFin\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Boolean\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[\"model::animal::Animal\"],\"taggedValues\":[{\"tag\":{\"profile\":\"meta::pure::profiles::doc\",\"value\":\"doc\"},\"value\":\"\"}]}]},\"name\":\"AnimalDS2\",\"package\":\"model::animal\",\"path\":\"model::animal::AnimalDS2\",\"stereotypes\":[{\"profile\":\"meta::pure::metamodel::dataSpace::profiles::DataSpaceInfo\",\"value\":\"Verified\"}],\"supportInfo\":{\"_type\":\"email\",\"address\":\"someEmail@test.org\"},\"taggedValues\":[]}"); + testDataSpaceAnalyticsArtifactGenerationExtension("models/dataSpaceBasic.pure", "model::animal::AnimalDS_Old", "{\"defaultExecutionContext\":\"dummyContext\",\"description\":\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\",\"diagrams\":[{\"diagram\":\"model::animal::AnimalDiagram\",\"title\":\"\"},{\"diagram\":\"model::GeneralDiagram\",\"title\":\"\"}],\"elementDocs\":[],\"elements\":[],\"executables\":[],\"executionContexts\":[{\"compatibleRuntimes\":[\"model::dummyRuntime\"],\"datasets\":[],\"defaultRuntime\":\"model::dummyRuntime\",\"description\":\"An important execution context\",\"mapping\":\"model::dummyMapping\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"dataSpace\",\"defaultExecutionContext\":\"dummyContext\",\"description\":\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\",\"diagrams\":[{\"diagram\":{\"path\":\"model::animal::AnimalDiagram\"},\"title\":\"\"},{\"diagram\":{\"path\":\"model::GeneralDiagram\"},\"title\":\"\"}],\"executionContexts\":[{\"defaultRuntime\":{\"path\":\"model::dummyRuntime\",\"type\":\"RUNTIME\"},\"description\":\"An important execution context\",\"mapping\":{\"path\":\"model::dummyMapping\",\"type\":\"MAPPING\"},\"name\":\"dummyContext\"},{\"defaultRuntime\":{\"path\":\"model::dummyRuntime\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"model::dummyMapping2\",\"type\":\"MAPPING\"},\"name\":\"dummyContext2\"},{\"defaultRuntime\":{\"path\":\"model::dummyRuntime2\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"model::dummyMapping2\",\"type\":\"MAPPING\"},\"name\":\"dummyContext3\"}],\"name\":\"AnimalDS_Old\",\"package\":\"model::animal\",\"stereotypes\":[{\"profile\":\"doc\",\"value\":\"deprecated\"}],\"supportInfo\":{\"_type\":\"email\",\"address\":\"someEmail@test.org\"},\"taggedValues\":[{\"tag\":{\"profile\":\"meta::pure::profiles::enterprise\",\"value\":\"taxonomyNodes\"},\"value\":\"abcdxyz005\"},{\"tag\":{\"profile\":\"doc\",\"value\":\"doc\"},\"value\":\"Lorem ipsum\"},{\"tag\":{\"profile\":\"doc\",\"value\":\"doc\"},\"value\":\"Lorem ipsum2\"},{\"tag\":{\"profile\":\"meta::pure::metamodel::dataSpace::profiles::DataSpaceInfo\",\"value\":\"deprecationNotice\"},\"value\":\"Please use AnimalDS dataspace instead - link provided\"}]}]}},\"name\":\"dummyContext\"},{\"compatibleRuntimes\":[\"model::dummyRuntime\",\"model::dummyRuntime2\"],\"datasets\":[],\"defaultRuntime\":\"model::dummyRuntime\",\"mapping\":\"model::dummyMapping2\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"dataSpace\",\"defaultExecutionContext\":\"dummyContext\",\"description\":\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\",\"diagrams\":[{\"diagram\":{\"path\":\"model::animal::AnimalDiagram\"},\"title\":\"\"},{\"diagram\":{\"path\":\"model::GeneralDiagram\"},\"title\":\"\"}],\"executionContexts\":[{\"defaultRuntime\":{\"path\":\"model::dummyRuntime\",\"type\":\"RUNTIME\"},\"description\":\"An important execution context\",\"mapping\":{\"path\":\"model::dummyMapping\",\"type\":\"MAPPING\"},\"name\":\"dummyContext\"},{\"defaultRuntime\":{\"path\":\"model::dummyRuntime\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"model::dummyMapping2\",\"type\":\"MAPPING\"},\"name\":\"dummyContext2\"},{\"defaultRuntime\":{\"path\":\"model::dummyRuntime2\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"model::dummyMapping2\",\"type\":\"MAPPING\"},\"name\":\"dummyContext3\"}],\"name\":\"AnimalDS_Old\",\"package\":\"model::animal\",\"stereotypes\":[{\"profile\":\"doc\",\"value\":\"deprecated\"}],\"supportInfo\":{\"_type\":\"email\",\"address\":\"someEmail@test.org\"},\"taggedValues\":[{\"tag\":{\"profile\":\"meta::pure::profiles::enterprise\",\"value\":\"taxonomyNodes\"},\"value\":\"abcdxyz005\"},{\"tag\":{\"profile\":\"doc\",\"value\":\"doc\"},\"value\":\"Lorem ipsum\"},{\"tag\":{\"profile\":\"doc\",\"value\":\"doc\"},\"value\":\"Lorem ipsum2\"},{\"tag\":{\"profile\":\"meta::pure::metamodel::dataSpace::profiles::DataSpaceInfo\",\"value\":\"deprecationNotice\"},\"value\":\"Please use AnimalDS dataspace instead - link provided\"}]}]}},\"name\":\"dummyContext2\"},{\"compatibleRuntimes\":[\"model::dummyRuntime\",\"model::dummyRuntime2\"],\"datasets\":[],\"defaultRuntime\":\"model::dummyRuntime2\",\"mapping\":\"model::dummyMapping2\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"dataSpace\",\"defaultExecutionContext\":\"dummyContext\",\"description\":\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\",\"diagrams\":[{\"diagram\":{\"path\":\"model::animal::AnimalDiagram\"},\"title\":\"\"},{\"diagram\":{\"path\":\"model::GeneralDiagram\"},\"title\":\"\"}],\"executionContexts\":[{\"defaultRuntime\":{\"path\":\"model::dummyRuntime\",\"type\":\"RUNTIME\"},\"description\":\"An important execution context\",\"mapping\":{\"path\":\"model::dummyMapping\",\"type\":\"MAPPING\"},\"name\":\"dummyContext\"},{\"defaultRuntime\":{\"path\":\"model::dummyRuntime\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"model::dummyMapping2\",\"type\":\"MAPPING\"},\"name\":\"dummyContext2\"},{\"defaultRuntime\":{\"path\":\"model::dummyRuntime2\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"model::dummyMapping2\",\"type\":\"MAPPING\"},\"name\":\"dummyContext3\"}],\"name\":\"AnimalDS_Old\",\"package\":\"model::animal\",\"stereotypes\":[{\"profile\":\"doc\",\"value\":\"deprecated\"}],\"supportInfo\":{\"_type\":\"email\",\"address\":\"someEmail@test.org\"},\"taggedValues\":[{\"tag\":{\"profile\":\"meta::pure::profiles::enterprise\",\"value\":\"taxonomyNodes\"},\"value\":\"abcdxyz005\"},{\"tag\":{\"profile\":\"doc\",\"value\":\"doc\"},\"value\":\"Lorem ipsum\"},{\"tag\":{\"profile\":\"doc\",\"value\":\"doc\"},\"value\":\"Lorem ipsum2\"},{\"tag\":{\"profile\":\"meta::pure::metamodel::dataSpace::profiles::DataSpaceInfo\",\"value\":\"deprecationNotice\"},\"value\":\"Please use AnimalDS dataspace instead - link provided\"}]}]}},\"name\":\"dummyContext3\"}],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"profile\",\"name\":\"doc\",\"package\":\"meta::pure::profiles\",\"stereotypes\":[\"deprecated\"],\"tags\":[\"doc\",\"todo\"]},{\"_type\":\"diagram\",\"classViews\":[{\"class\":\"model::animal::reptile::Reptile\",\"id\":\"4cec85f9-9b66-450a-bdcb-c855aa0314e1\",\"position\":{\"x\":568.0,\"y\":404.0},\"rectangle\":{\"height\":58.0,\"width\":120.84765625}},{\"class\":\"model::animal::Animal\",\"id\":\"902bf14e-e7ff-40e7-92e4-8780f91bfa29\",\"position\":{\"x\":809.0,\"y\":187.0},\"rectangle\":{\"height\":44.0,\"width\":108.64453125}}],\"generalizationViews\":[{\"line\":{\"points\":[{\"x\":628.423828125,\"y\":433.0},{\"x\":863.322265625,\"y\":209.0}]},\"sourceView\":\"4cec85f9-9b66-450a-bdcb-c855aa0314e1\",\"targetView\":\"902bf14e-e7ff-40e7-92e4-8780f91bfa29\"}],\"name\":\"GeneralDiagram\",\"package\":\"model\",\"propertyViews\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Animal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"family\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::animal::Family\"},{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"noOfLegs\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Number\"},{\"multiplicity\":{\"lowerBound\":0},\"name\":\"children\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::animal::GenericAnimal2\"}],\"qualifiedProperties\":[{\"body\":[{\"_type\":\"func\",\"fControl\":\"greaterThan_Number_1__Number_1__Boolean_1_\",\"function\":\"greaterThan\",\"parameters\":[{\"_type\":\"property\",\"parameters\":[{\"_type\":\"var\",\"name\":\"this\"}],\"property\":\"noOfLegs\"},{\"_type\":\"integer\",\"value\":4}]}],\"name\":\"something\",\"parameters\":[],\"returnMultiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"returnType\":\"Boolean\",\"stereotypes\":[],\"taggedValues\":[]},{\"body\":[{\"_type\":\"collection\",\"multiplicity\":{\"lowerBound\":0,\"upperBound\":0},\"values\":[]}],\"name\":\"something2\",\"parameters\":[],\"returnMultiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"returnType\":\"model::animal::GenericAnimal\",\"stereotypes\":[],\"taggedValues\":[]}],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"diagram\",\"classViews\":[{\"class\":\"model::animal::mammal::Mammal\",\"id\":\"641a0336-d4b5-418c-b656-2f52461264e2\",\"position\":{\"x\":427.0,\"y\":210.0},\"rectangle\":{\"height\":44.0,\"width\":125.1123046875}},{\"class\":\"model::animal::reptile::Reptile\",\"id\":\"b92253d8-0389-4c7d-b5d2-3cdc3bb1ad98\",\"position\":{\"x\":787.0,\"y\":216.0},\"rectangle\":{\"height\":58.0,\"width\":120.84765625}},{\"class\":\"model::animal::Animal\",\"id\":\"7a992cfc-c888-4091-aa00-ab430915aced\",\"position\":{\"x\":515.423828125,\"y\":-7.5},\"rectangle\":{\"height\":100.0,\"width\":199.716796875}}],\"generalizationViews\":[{\"line\":{\"points\":[{\"x\":847.423828125,\"y\":245.0},{\"x\":615.2822265625,\"y\":42.5}]},\"sourceView\":\"b92253d8-0389-4c7d-b5d2-3cdc3bb1ad98\",\"targetView\":\"7a992cfc-c888-4091-aa00-ab430915aced\"}],\"name\":\"AnimalDiagram\",\"package\":\"model::animal\",\"propertyViews\":[]},{\"_type\":\"Enumeration\",\"name\":\"Family\",\"package\":\"model::animal\",\"stereotypes\":[],\"taggedValues\":[],\"values\":[{\"stereotypes\":[],\"taggedValues\":[],\"value\":\"UO\"},{\"stereotypes\":[],\"taggedValues\":[],\"value\":\"OP\"}]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"GenericAnimal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"GenericAnimal2\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Mammal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal::mammal\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"noOfLegs\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Reptile\",\"originalMilestonedProperties\":[],\"package\":\"model::animal::reptile\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"hasFin\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Boolean\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[\"model::animal::Animal\"],\"taggedValues\":[{\"tag\":{\"profile\":\"meta::pure::profiles::doc\",\"value\":\"doc\"},\"value\":\"\"}]}]},\"name\":\"AnimalDS_Old\",\"package\":\"model::animal\",\"path\":\"model::animal::AnimalDS_Old\",\"stereotypes\":[{\"profile\":\"meta::pure::profiles::doc\",\"value\":\"deprecated\"}],\"supportInfo\":{\"_type\":\"email\",\"address\":\"someEmail@test.org\"},\"taggedValues\":[{\"profile\":\"meta::pure::profiles::enterprise\",\"tag\":\"taxonomyNodes\",\"value\":\"abcdxyz005\"},{\"profile\":\"meta::pure::profiles::doc\",\"tag\":\"doc\",\"value\":\"Lorem ipsum\"},{\"profile\":\"meta::pure::profiles::doc\",\"tag\":\"doc\",\"value\":\"Lorem ipsum2\"},{\"profile\":\"meta::pure::metamodel::dataSpace::profiles::DataSpaceInfo\",\"tag\":\"deprecationNotice\",\"value\":\"Please use AnimalDS dataspace instead - link provided\"}]}"); + testDataSpaceAnalyticsArtifactGenerationExtension("models/dataSpaceBasic.pure", "model::animal::AnimalDS", "{\"defaultExecutionContext\":\"dummyContext\",\"description\":\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\",\"diagrams\":[{\"description\":\"Some diagram description\",\"diagram\":\"model::animal::AnimalDiagram\",\"title\":\"Diag 1\"},{\"description\":\"Some more diagram description\",\"diagram\":\"model::GeneralDiagram\",\"title\":\"Diag 2\"}],\"elementDocs\":[],\"elements\":[],\"executables\":[],\"executionContexts\":[{\"compatibleRuntimes\":[\"model::dummyRuntime\"],\"datasets\":[],\"defaultRuntime\":\"model::dummyRuntime\",\"description\":\"An important execution context\",\"mapping\":\"model::dummyMapping\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"dataSpace\",\"defaultExecutionContext\":\"dummyContext\",\"description\":\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\",\"diagrams\":[{\"description\":\"Some diagram description\",\"diagram\":{\"path\":\"model::animal::AnimalDiagram\"},\"title\":\"Diag 1\"},{\"description\":\"Some more diagram description\",\"diagram\":{\"path\":\"model::GeneralDiagram\"},\"title\":\"Diag 2\"}],\"executionContexts\":[{\"defaultRuntime\":{\"path\":\"model::dummyRuntime\",\"type\":\"RUNTIME\"},\"description\":\"An important execution context\",\"mapping\":{\"path\":\"model::dummyMapping\",\"type\":\"MAPPING\"},\"name\":\"dummyContext\",\"title\":\"Haha Nice\"},{\"defaultRuntime\":{\"path\":\"model::dummyRuntime\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"model::dummyMapping2\",\"type\":\"MAPPING\"},\"name\":\"dummyContext2\"},{\"defaultRuntime\":{\"path\":\"model::dummyRuntime2\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"model::dummyMapping2\",\"type\":\"MAPPING\"},\"name\":\"dummyContext3\"}],\"name\":\"AnimalDS\",\"package\":\"model::animal\",\"stereotypes\":[{\"profile\":\"meta::pure::metamodel::dataSpace::profiles::DataSpaceInfo\",\"value\":\"Verified\"}],\"supportInfo\":{\"_type\":\"email\",\"address\":\"someEmail@test.org\"},\"taggedValues\":[]}]}},\"name\":\"dummyContext\",\"title\":\"Haha Nice\"},{\"compatibleRuntimes\":[\"model::dummyRuntime\",\"model::dummyRuntime2\"],\"datasets\":[],\"defaultRuntime\":\"model::dummyRuntime\",\"mapping\":\"model::dummyMapping2\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"dataSpace\",\"defaultExecutionContext\":\"dummyContext\",\"description\":\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\",\"diagrams\":[{\"description\":\"Some diagram description\",\"diagram\":{\"path\":\"model::animal::AnimalDiagram\"},\"title\":\"Diag 1\"},{\"description\":\"Some more diagram description\",\"diagram\":{\"path\":\"model::GeneralDiagram\"},\"title\":\"Diag 2\"}],\"executionContexts\":[{\"defaultRuntime\":{\"path\":\"model::dummyRuntime\",\"type\":\"RUNTIME\"},\"description\":\"An important execution context\",\"mapping\":{\"path\":\"model::dummyMapping\",\"type\":\"MAPPING\"},\"name\":\"dummyContext\",\"title\":\"Haha Nice\"},{\"defaultRuntime\":{\"path\":\"model::dummyRuntime\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"model::dummyMapping2\",\"type\":\"MAPPING\"},\"name\":\"dummyContext2\"},{\"defaultRuntime\":{\"path\":\"model::dummyRuntime2\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"model::dummyMapping2\",\"type\":\"MAPPING\"},\"name\":\"dummyContext3\"}],\"name\":\"AnimalDS\",\"package\":\"model::animal\",\"stereotypes\":[{\"profile\":\"meta::pure::metamodel::dataSpace::profiles::DataSpaceInfo\",\"value\":\"Verified\"}],\"supportInfo\":{\"_type\":\"email\",\"address\":\"someEmail@test.org\"},\"taggedValues\":[]}]}},\"name\":\"dummyContext2\"},{\"compatibleRuntimes\":[\"model::dummyRuntime\",\"model::dummyRuntime2\"],\"datasets\":[],\"defaultRuntime\":\"model::dummyRuntime2\",\"mapping\":\"model::dummyMapping2\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"dataSpace\",\"defaultExecutionContext\":\"dummyContext\",\"description\":\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\",\"diagrams\":[{\"description\":\"Some diagram description\",\"diagram\":{\"path\":\"model::animal::AnimalDiagram\"},\"title\":\"Diag 1\"},{\"description\":\"Some more diagram description\",\"diagram\":{\"path\":\"model::GeneralDiagram\"},\"title\":\"Diag 2\"}],\"executionContexts\":[{\"defaultRuntime\":{\"path\":\"model::dummyRuntime\",\"type\":\"RUNTIME\"},\"description\":\"An important execution context\",\"mapping\":{\"path\":\"model::dummyMapping\",\"type\":\"MAPPING\"},\"name\":\"dummyContext\",\"title\":\"Haha Nice\"},{\"defaultRuntime\":{\"path\":\"model::dummyRuntime\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"model::dummyMapping2\",\"type\":\"MAPPING\"},\"name\":\"dummyContext2\"},{\"defaultRuntime\":{\"path\":\"model::dummyRuntime2\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"model::dummyMapping2\",\"type\":\"MAPPING\"},\"name\":\"dummyContext3\"}],\"name\":\"AnimalDS\",\"package\":\"model::animal\",\"stereotypes\":[{\"profile\":\"meta::pure::metamodel::dataSpace::profiles::DataSpaceInfo\",\"value\":\"Verified\"}],\"supportInfo\":{\"_type\":\"email\",\"address\":\"someEmail@test.org\"},\"taggedValues\":[]}]}},\"name\":\"dummyContext3\"}],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"profile\",\"name\":\"doc\",\"package\":\"meta::pure::profiles\",\"stereotypes\":[\"deprecated\"],\"tags\":[\"doc\",\"todo\"]},{\"_type\":\"diagram\",\"classViews\":[{\"class\":\"model::animal::reptile::Reptile\",\"id\":\"4cec85f9-9b66-450a-bdcb-c855aa0314e1\",\"position\":{\"x\":568.0,\"y\":404.0},\"rectangle\":{\"height\":58.0,\"width\":120.84765625}},{\"class\":\"model::animal::Animal\",\"id\":\"902bf14e-e7ff-40e7-92e4-8780f91bfa29\",\"position\":{\"x\":809.0,\"y\":187.0},\"rectangle\":{\"height\":44.0,\"width\":108.64453125}}],\"generalizationViews\":[{\"line\":{\"points\":[{\"x\":628.423828125,\"y\":433.0},{\"x\":863.322265625,\"y\":209.0}]},\"sourceView\":\"4cec85f9-9b66-450a-bdcb-c855aa0314e1\",\"targetView\":\"902bf14e-e7ff-40e7-92e4-8780f91bfa29\"}],\"name\":\"GeneralDiagram\",\"package\":\"model\",\"propertyViews\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Animal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"family\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::animal::Family\"},{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"noOfLegs\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Number\"},{\"multiplicity\":{\"lowerBound\":0},\"name\":\"children\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::animal::GenericAnimal2\"}],\"qualifiedProperties\":[{\"body\":[{\"_type\":\"func\",\"fControl\":\"greaterThan_Number_1__Number_1__Boolean_1_\",\"function\":\"greaterThan\",\"parameters\":[{\"_type\":\"property\",\"parameters\":[{\"_type\":\"var\",\"name\":\"this\"}],\"property\":\"noOfLegs\"},{\"_type\":\"integer\",\"value\":4}]}],\"name\":\"something\",\"parameters\":[],\"returnMultiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"returnType\":\"Boolean\",\"stereotypes\":[],\"taggedValues\":[]},{\"body\":[{\"_type\":\"collection\",\"multiplicity\":{\"lowerBound\":0,\"upperBound\":0},\"values\":[]}],\"name\":\"something2\",\"parameters\":[],\"returnMultiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"returnType\":\"model::animal::GenericAnimal\",\"stereotypes\":[],\"taggedValues\":[]}],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"diagram\",\"classViews\":[{\"class\":\"model::animal::mammal::Mammal\",\"id\":\"641a0336-d4b5-418c-b656-2f52461264e2\",\"position\":{\"x\":427.0,\"y\":210.0},\"rectangle\":{\"height\":44.0,\"width\":125.1123046875}},{\"class\":\"model::animal::reptile::Reptile\",\"id\":\"b92253d8-0389-4c7d-b5d2-3cdc3bb1ad98\",\"position\":{\"x\":787.0,\"y\":216.0},\"rectangle\":{\"height\":58.0,\"width\":120.84765625}},{\"class\":\"model::animal::Animal\",\"id\":\"7a992cfc-c888-4091-aa00-ab430915aced\",\"position\":{\"x\":515.423828125,\"y\":-7.5},\"rectangle\":{\"height\":100.0,\"width\":199.716796875}}],\"generalizationViews\":[{\"line\":{\"points\":[{\"x\":847.423828125,\"y\":245.0},{\"x\":615.2822265625,\"y\":42.5}]},\"sourceView\":\"b92253d8-0389-4c7d-b5d2-3cdc3bb1ad98\",\"targetView\":\"7a992cfc-c888-4091-aa00-ab430915aced\"}],\"name\":\"AnimalDiagram\",\"package\":\"model::animal\",\"propertyViews\":[]},{\"_type\":\"Enumeration\",\"name\":\"Family\",\"package\":\"model::animal\",\"stereotypes\":[],\"taggedValues\":[],\"values\":[{\"stereotypes\":[],\"taggedValues\":[],\"value\":\"UO\"},{\"stereotypes\":[],\"taggedValues\":[],\"value\":\"OP\"}]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"GenericAnimal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"GenericAnimal2\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Mammal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal::mammal\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"noOfLegs\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Reptile\",\"originalMilestonedProperties\":[],\"package\":\"model::animal::reptile\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"hasFin\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Boolean\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[\"model::animal::Animal\"],\"taggedValues\":[{\"tag\":{\"profile\":\"meta::pure::profiles::doc\",\"value\":\"doc\"},\"value\":\"\"}]}]},\"name\":\"AnimalDS\",\"package\":\"model::animal\",\"path\":\"model::animal::AnimalDS\",\"stereotypes\":[{\"profile\":\"meta::pure::metamodel::dataSpace::profiles::DataSpaceInfo\",\"value\":\"Verified\"}],\"supportInfo\":{\"_type\":\"email\",\"address\":\"someEmail@test.org\"},\"taggedValues\":[]}"); + testDataSpaceAnalyticsArtifactGenerationExtension("models/dataSpaceBasic.pure", "model::animal::AnimalDS2", "{\"defaultExecutionContext\":\"dummyContext\",\"description\":\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\",\"diagrams\":[{\"diagram\":\"model::animal::AnimalDiagram\",\"title\":\"\"},{\"diagram\":\"model::GeneralDiagram\",\"title\":\"\"}],\"elementDocs\":[],\"elements\":[],\"executables\":[],\"executionContexts\":[{\"compatibleRuntimes\":[\"model::dummyRuntime\"],\"datasets\":[],\"defaultRuntime\":\"model::dummyRuntime\",\"description\":\"An important execution context\",\"mapping\":\"model::dummyMapping\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"dataSpace\",\"defaultExecutionContext\":\"dummyContext\",\"description\":\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\",\"diagrams\":[{\"diagram\":{\"path\":\"model::animal::AnimalDiagram\"},\"title\":\"\"},{\"diagram\":{\"path\":\"model::GeneralDiagram\"},\"title\":\"\"}],\"executionContexts\":[{\"defaultRuntime\":{\"path\":\"model::dummyRuntime\",\"type\":\"RUNTIME\"},\"description\":\"An important execution context\",\"mapping\":{\"path\":\"model::dummyMapping\",\"type\":\"MAPPING\"},\"name\":\"dummyContext\"},{\"defaultRuntime\":{\"path\":\"model::dummyRuntime\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"model::dummyMapping2\",\"type\":\"MAPPING\"},\"name\":\"dummyContext2\"},{\"defaultRuntime\":{\"path\":\"model::dummyRuntime2\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"model::dummyMapping2\",\"type\":\"MAPPING\"},\"name\":\"dummyContext3\"}],\"name\":\"AnimalDS2\",\"package\":\"model::animal\",\"stereotypes\":[{\"profile\":\"meta::pure::metamodel::dataSpace::profiles::DataSpaceInfo\",\"value\":\"Verified\"}],\"supportInfo\":{\"_type\":\"email\",\"address\":\"someEmail@test.org\"},\"taggedValues\":[]}]}},\"name\":\"dummyContext\"},{\"compatibleRuntimes\":[\"model::dummyRuntime\",\"model::dummyRuntime2\"],\"datasets\":[],\"defaultRuntime\":\"model::dummyRuntime\",\"mapping\":\"model::dummyMapping2\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"dataSpace\",\"defaultExecutionContext\":\"dummyContext\",\"description\":\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\",\"diagrams\":[{\"diagram\":{\"path\":\"model::animal::AnimalDiagram\"},\"title\":\"\"},{\"diagram\":{\"path\":\"model::GeneralDiagram\"},\"title\":\"\"}],\"executionContexts\":[{\"defaultRuntime\":{\"path\":\"model::dummyRuntime\",\"type\":\"RUNTIME\"},\"description\":\"An important execution context\",\"mapping\":{\"path\":\"model::dummyMapping\",\"type\":\"MAPPING\"},\"name\":\"dummyContext\"},{\"defaultRuntime\":{\"path\":\"model::dummyRuntime\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"model::dummyMapping2\",\"type\":\"MAPPING\"},\"name\":\"dummyContext2\"},{\"defaultRuntime\":{\"path\":\"model::dummyRuntime2\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"model::dummyMapping2\",\"type\":\"MAPPING\"},\"name\":\"dummyContext3\"}],\"name\":\"AnimalDS2\",\"package\":\"model::animal\",\"stereotypes\":[{\"profile\":\"meta::pure::metamodel::dataSpace::profiles::DataSpaceInfo\",\"value\":\"Verified\"}],\"supportInfo\":{\"_type\":\"email\",\"address\":\"someEmail@test.org\"},\"taggedValues\":[]}]}},\"name\":\"dummyContext2\"},{\"compatibleRuntimes\":[\"model::dummyRuntime\",\"model::dummyRuntime2\"],\"datasets\":[],\"defaultRuntime\":\"model::dummyRuntime2\",\"mapping\":\"model::dummyMapping2\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"dataSpace\",\"defaultExecutionContext\":\"dummyContext\",\"description\":\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\",\"diagrams\":[{\"diagram\":{\"path\":\"model::animal::AnimalDiagram\"},\"title\":\"\"},{\"diagram\":{\"path\":\"model::GeneralDiagram\"},\"title\":\"\"}],\"executionContexts\":[{\"defaultRuntime\":{\"path\":\"model::dummyRuntime\",\"type\":\"RUNTIME\"},\"description\":\"An important execution context\",\"mapping\":{\"path\":\"model::dummyMapping\",\"type\":\"MAPPING\"},\"name\":\"dummyContext\"},{\"defaultRuntime\":{\"path\":\"model::dummyRuntime\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"model::dummyMapping2\",\"type\":\"MAPPING\"},\"name\":\"dummyContext2\"},{\"defaultRuntime\":{\"path\":\"model::dummyRuntime2\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"model::dummyMapping2\",\"type\":\"MAPPING\"},\"name\":\"dummyContext3\"}],\"name\":\"AnimalDS2\",\"package\":\"model::animal\",\"stereotypes\":[{\"profile\":\"meta::pure::metamodel::dataSpace::profiles::DataSpaceInfo\",\"value\":\"Verified\"}],\"supportInfo\":{\"_type\":\"email\",\"address\":\"someEmail@test.org\"},\"taggedValues\":[]}]}},\"name\":\"dummyContext3\"}],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"profile\",\"name\":\"doc\",\"package\":\"meta::pure::profiles\",\"stereotypes\":[\"deprecated\"],\"tags\":[\"doc\",\"todo\"]},{\"_type\":\"diagram\",\"classViews\":[{\"class\":\"model::animal::reptile::Reptile\",\"id\":\"4cec85f9-9b66-450a-bdcb-c855aa0314e1\",\"position\":{\"x\":568.0,\"y\":404.0},\"rectangle\":{\"height\":58.0,\"width\":120.84765625}},{\"class\":\"model::animal::Animal\",\"id\":\"902bf14e-e7ff-40e7-92e4-8780f91bfa29\",\"position\":{\"x\":809.0,\"y\":187.0},\"rectangle\":{\"height\":44.0,\"width\":108.64453125}}],\"generalizationViews\":[{\"line\":{\"points\":[{\"x\":628.423828125,\"y\":433.0},{\"x\":863.322265625,\"y\":209.0}]},\"sourceView\":\"4cec85f9-9b66-450a-bdcb-c855aa0314e1\",\"targetView\":\"902bf14e-e7ff-40e7-92e4-8780f91bfa29\"}],\"name\":\"GeneralDiagram\",\"package\":\"model\",\"propertyViews\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Animal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"family\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::animal::Family\"},{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"noOfLegs\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Number\"},{\"multiplicity\":{\"lowerBound\":0},\"name\":\"children\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::animal::GenericAnimal2\"}],\"qualifiedProperties\":[{\"body\":[{\"_type\":\"func\",\"fControl\":\"greaterThan_Number_1__Number_1__Boolean_1_\",\"function\":\"greaterThan\",\"parameters\":[{\"_type\":\"property\",\"parameters\":[{\"_type\":\"var\",\"name\":\"this\"}],\"property\":\"noOfLegs\"},{\"_type\":\"integer\",\"value\":4}]}],\"name\":\"something\",\"parameters\":[],\"returnMultiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"returnType\":\"Boolean\",\"stereotypes\":[],\"taggedValues\":[]},{\"body\":[{\"_type\":\"collection\",\"multiplicity\":{\"lowerBound\":0,\"upperBound\":0},\"values\":[]}],\"name\":\"something2\",\"parameters\":[],\"returnMultiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"returnType\":\"model::animal::GenericAnimal\",\"stereotypes\":[],\"taggedValues\":[]}],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"diagram\",\"classViews\":[{\"class\":\"model::animal::mammal::Mammal\",\"id\":\"641a0336-d4b5-418c-b656-2f52461264e2\",\"position\":{\"x\":427.0,\"y\":210.0},\"rectangle\":{\"height\":44.0,\"width\":125.1123046875}},{\"class\":\"model::animal::reptile::Reptile\",\"id\":\"b92253d8-0389-4c7d-b5d2-3cdc3bb1ad98\",\"position\":{\"x\":787.0,\"y\":216.0},\"rectangle\":{\"height\":58.0,\"width\":120.84765625}},{\"class\":\"model::animal::Animal\",\"id\":\"7a992cfc-c888-4091-aa00-ab430915aced\",\"position\":{\"x\":515.423828125,\"y\":-7.5},\"rectangle\":{\"height\":100.0,\"width\":199.716796875}}],\"generalizationViews\":[{\"line\":{\"points\":[{\"x\":847.423828125,\"y\":245.0},{\"x\":615.2822265625,\"y\":42.5}]},\"sourceView\":\"b92253d8-0389-4c7d-b5d2-3cdc3bb1ad98\",\"targetView\":\"7a992cfc-c888-4091-aa00-ab430915aced\"}],\"name\":\"AnimalDiagram\",\"package\":\"model::animal\",\"propertyViews\":[]},{\"_type\":\"Enumeration\",\"name\":\"Family\",\"package\":\"model::animal\",\"stereotypes\":[],\"taggedValues\":[],\"values\":[{\"stereotypes\":[],\"taggedValues\":[],\"value\":\"UO\"},{\"stereotypes\":[],\"taggedValues\":[],\"value\":\"OP\"}]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"GenericAnimal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"GenericAnimal2\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Mammal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal::mammal\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"noOfLegs\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Reptile\",\"originalMilestonedProperties\":[],\"package\":\"model::animal::reptile\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"hasFin\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Boolean\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[\"model::animal::Animal\"],\"taggedValues\":[{\"tag\":{\"profile\":\"meta::pure::profiles::doc\",\"value\":\"doc\"},\"value\":\"\"}]}]},\"name\":\"AnimalDS2\",\"package\":\"model::animal\",\"path\":\"model::animal::AnimalDS2\",\"stereotypes\":[{\"profile\":\"meta::pure::metamodel::dataSpace::profiles::DataSpaceInfo\",\"value\":\"Verified\"}],\"supportInfo\":{\"_type\":\"email\",\"address\":\"someEmail@test.org\"},\"taggedValues\":[]}"); } @Test public void testAnalyticsForDataSpaceWithAssociation() throws Exception { - testDataSpaceAnalyticsArtifactGenerationExtension("models/dataSpaceWithAssociation.pure", "domain::COVIDDatapace", "{\"defaultExecutionContext\":\"dummyContext\",\"description\":\"Not over yet?\",\"diagrams\":[{\"diagram\":\"domain::COVIDDataDiagram\",\"title\":\"\"}],\"elementDocs\":[],\"elements\":[],\"executables\":[],\"executionContexts\":[{\"compatibleRuntimes\":[\"runtime::MyRuntime\"],\"datasets\":[],\"defaultRuntime\":\"runtime::MyRuntime\",\"mapping\":\"mapping::CovidDataMapping\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[]},\"name\":\"dummyContext\"},{\"compatibleRuntimes\":[\"runtime::MyRuntime\"],\"datasets\":[],\"defaultRuntime\":\"runtime::MyRuntime\",\"mapping\":\"mapping::CovidDataMapping\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[]},\"name\":\"dummyContext2\"}],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"class\",\"constraints\":[],\"name\":\"COVIDData\",\"originalMilestonedProperties\":[],\"package\":\"domain\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"id\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Integer\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"fips\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"date\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"StrictDate\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"caseType\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"cases\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Float\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"lastReportedFlag\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Boolean\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"demographics\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"domain::Demographics\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"diagram\",\"classViews\":[{\"class\":\"domain::COVIDData\",\"id\":\"6b69f44b-f729-46aa-b244-ec5ee8164142\",\"position\":{\"x\":280.0,\"y\":159.0},\"rectangle\":{\"height\":128.0,\"width\":205.8291015625}},{\"class\":\"domain::Demographics\",\"id\":\"159e797e-ae75-437d-ba9c-253f99a48826\",\"position\":{\"x\":698.0,\"y\":238.0},\"rectangle\":{\"height\":58.0,\"width\":111.68994140625}},{\"class\":\"domain::Class1\",\"id\":\"f6bd8a50-8d18-4bd9-9a8d-7fad88d02b07\",\"position\":{\"x\":360.844970703125,\"y\":49.0},\"rectangle\":{\"height\":58.0,\"width\":137.390625}},{\"class\":\"domain::Class2\",\"id\":\"690e89d4-23e9-46e8-8543-c89c22cc9e15\",\"position\":{\"x\":696.844970703125,\"y\":95.0},\"rectangle\":{\"height\":44.0,\"width\":133.68994140625}}],\"generalizationViews\":[],\"name\":\"COVIDDataDiagram\",\"package\":\"domain\",\"propertyViews\":[{\"line\":{\"points\":[{\"x\":382.91455078125,\"y\":223.0},{\"x\":753.844970703125,\"y\":267.0}]},\"property\":{\"class\":\"domain::COVIDData\",\"property\":\"demographics\"},\"sourceView\":\"6b69f44b-f729-46aa-b244-ec5ee8164142\",\"targetView\":\"159e797e-ae75-437d-ba9c-253f99a48826\"},{\"line\":{\"points\":[{\"x\":763.68994140625,\"y\":117.0},{\"x\":429.540283203125,\"y\":78.0}]},\"property\":{\"class\":\"domain::Class2\",\"property\":\"fromClass1\"},\"sourceView\":\"690e89d4-23e9-46e8-8543-c89c22cc9e15\",\"targetView\":\"f6bd8a50-8d18-4bd9-9a8d-7fad88d02b07\"},{\"line\":{\"points\":[{\"x\":429.540283203125,\"y\":78.0},{\"x\":763.68994140625,\"y\":117.0}]},\"property\":{\"class\":\"domain::Class1\",\"property\":\"fromClass2\"},\"sourceView\":\"f6bd8a50-8d18-4bd9-9a8d-7fad88d02b07\",\"targetView\":\"690e89d4-23e9-46e8-8543-c89c22cc9e15\"}]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Class1\",\"originalMilestonedProperties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"fromClass2\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"domain::Class2\"}],\"package\":\"domain\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"propClass1\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"}],\"qualifiedProperties\":[],\"stereotypes\":[{\"profile\":\"meta::pure::profiles::temporal\",\"value\":\"businesstemporal\"}],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"association\",\"name\":\"Class12Assoc\",\"originalMilestonedProperties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"fromClass1\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"domain::Class1\"},{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"fromClass2\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"domain::Class2\"}],\"package\":\"domain\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"fromClass1\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"domain::Class1\"},{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"fromClass2\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"domain::Class2\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Class2\",\"originalMilestonedProperties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"fromClass1\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"domain::Class1\"}],\"package\":\"domain\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"propClass2\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"}],\"qualifiedProperties\":[],\"stereotypes\":[{\"profile\":\"meta::pure::profiles::temporal\",\"value\":\"processingtemporal\"}],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Demographics\",\"originalMilestonedProperties\":[],\"package\":\"domain\",\"properties\":[{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"fips\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"state\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"BusinessDateMilestoning\",\"originalMilestonedProperties\":[],\"package\":\"meta::pure::milestoning\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"ProcessingDateMilestoning\",\"originalMilestonedProperties\":[],\"package\":\"meta::pure::milestoning\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"profile\",\"name\":\"temporal\",\"package\":\"meta::pure::profiles\",\"stereotypes\":[\"bitemporal\",\"businesstemporal\",\"processingtemporal\"],\"tags\":[]}]},\"name\":\"COVIDDatapace\",\"package\":\"domain\",\"path\":\"domain::COVIDDatapace\",\"stereotypes\":[],\"taggedValues\":[],\"title\":\"COVID Sample Data\"}"); + testDataSpaceAnalyticsArtifactGenerationExtension("models/dataSpaceWithAssociation.pure", "domain::COVIDDatapace", "{\"defaultExecutionContext\":\"dummyContext\",\"description\":\"Not over yet?\",\"diagrams\":[{\"diagram\":\"domain::COVIDDataDiagram\",\"title\":\"\"}],\"elementDocs\":[],\"elements\":[],\"executables\":[],\"executionContexts\":[{\"compatibleRuntimes\":[\"runtime::MyRuntime\"],\"datasets\":[],\"defaultRuntime\":\"runtime::MyRuntime\",\"mapping\":\"mapping::CovidDataMapping\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"dataSpace\",\"defaultExecutionContext\":\"dummyContext\",\"description\":\"Not over yet?\",\"diagrams\":[{\"diagram\":{\"path\":\"domain::COVIDDataDiagram\"},\"title\":\"\"}],\"executionContexts\":[{\"defaultRuntime\":{\"path\":\"runtime::MyRuntime\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"mapping::CovidDataMapping\",\"type\":\"MAPPING\"},\"name\":\"dummyContext\"},{\"defaultRuntime\":{\"path\":\"runtime::MyRuntime\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"mapping::CovidDataMapping\",\"type\":\"MAPPING\"},\"name\":\"dummyContext2\"}],\"name\":\"COVIDDatapace\",\"package\":\"domain\",\"stereotypes\":[],\"taggedValues\":[],\"title\":\"COVID Sample Data\"}]}},\"name\":\"dummyContext\"},{\"compatibleRuntimes\":[\"runtime::MyRuntime\"],\"datasets\":[],\"defaultRuntime\":\"runtime::MyRuntime\",\"mapping\":\"mapping::CovidDataMapping\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"dataSpace\",\"defaultExecutionContext\":\"dummyContext\",\"description\":\"Not over yet?\",\"diagrams\":[{\"diagram\":{\"path\":\"domain::COVIDDataDiagram\"},\"title\":\"\"}],\"executionContexts\":[{\"defaultRuntime\":{\"path\":\"runtime::MyRuntime\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"mapping::CovidDataMapping\",\"type\":\"MAPPING\"},\"name\":\"dummyContext\"},{\"defaultRuntime\":{\"path\":\"runtime::MyRuntime\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"mapping::CovidDataMapping\",\"type\":\"MAPPING\"},\"name\":\"dummyContext2\"}],\"name\":\"COVIDDatapace\",\"package\":\"domain\",\"stereotypes\":[],\"taggedValues\":[],\"title\":\"COVID Sample Data\"}]}},\"name\":\"dummyContext2\"}],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"class\",\"constraints\":[],\"name\":\"COVIDData\",\"originalMilestonedProperties\":[],\"package\":\"domain\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"id\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Integer\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"fips\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"date\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"StrictDate\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"caseType\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"cases\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Float\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"lastReportedFlag\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Boolean\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"demographics\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"domain::Demographics\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"diagram\",\"classViews\":[{\"class\":\"domain::COVIDData\",\"id\":\"6b69f44b-f729-46aa-b244-ec5ee8164142\",\"position\":{\"x\":280.0,\"y\":159.0},\"rectangle\":{\"height\":128.0,\"width\":205.8291015625}},{\"class\":\"domain::Demographics\",\"id\":\"159e797e-ae75-437d-ba9c-253f99a48826\",\"position\":{\"x\":698.0,\"y\":238.0},\"rectangle\":{\"height\":58.0,\"width\":111.68994140625}},{\"class\":\"domain::Class1\",\"id\":\"f6bd8a50-8d18-4bd9-9a8d-7fad88d02b07\",\"position\":{\"x\":360.844970703125,\"y\":49.0},\"rectangle\":{\"height\":58.0,\"width\":137.390625}},{\"class\":\"domain::Class2\",\"id\":\"690e89d4-23e9-46e8-8543-c89c22cc9e15\",\"position\":{\"x\":696.844970703125,\"y\":95.0},\"rectangle\":{\"height\":44.0,\"width\":133.68994140625}}],\"generalizationViews\":[],\"name\":\"COVIDDataDiagram\",\"package\":\"domain\",\"propertyViews\":[{\"line\":{\"points\":[{\"x\":382.91455078125,\"y\":223.0},{\"x\":753.844970703125,\"y\":267.0}]},\"property\":{\"class\":\"domain::COVIDData\",\"property\":\"demographics\"},\"sourceView\":\"6b69f44b-f729-46aa-b244-ec5ee8164142\",\"targetView\":\"159e797e-ae75-437d-ba9c-253f99a48826\"},{\"line\":{\"points\":[{\"x\":763.68994140625,\"y\":117.0},{\"x\":429.540283203125,\"y\":78.0}]},\"property\":{\"class\":\"domain::Class2\",\"property\":\"fromClass1\"},\"sourceView\":\"690e89d4-23e9-46e8-8543-c89c22cc9e15\",\"targetView\":\"f6bd8a50-8d18-4bd9-9a8d-7fad88d02b07\"},{\"line\":{\"points\":[{\"x\":429.540283203125,\"y\":78.0},{\"x\":763.68994140625,\"y\":117.0}]},\"property\":{\"class\":\"domain::Class1\",\"property\":\"fromClass2\"},\"sourceView\":\"f6bd8a50-8d18-4bd9-9a8d-7fad88d02b07\",\"targetView\":\"690e89d4-23e9-46e8-8543-c89c22cc9e15\"}]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Class1\",\"originalMilestonedProperties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"fromClass2\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"domain::Class2\"}],\"package\":\"domain\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"propClass1\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"}],\"qualifiedProperties\":[],\"stereotypes\":[{\"profile\":\"meta::pure::profiles::temporal\",\"value\":\"businesstemporal\"}],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"association\",\"name\":\"Class12Assoc\",\"originalMilestonedProperties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"fromClass1\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"domain::Class1\"},{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"fromClass2\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"domain::Class2\"}],\"package\":\"domain\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"fromClass1\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"domain::Class1\"},{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"fromClass2\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"domain::Class2\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Class2\",\"originalMilestonedProperties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"fromClass1\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"domain::Class1\"}],\"package\":\"domain\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"propClass2\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"}],\"qualifiedProperties\":[],\"stereotypes\":[{\"profile\":\"meta::pure::profiles::temporal\",\"value\":\"processingtemporal\"}],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Demographics\",\"originalMilestonedProperties\":[],\"package\":\"domain\",\"properties\":[{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"fips\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"state\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"BusinessDateMilestoning\",\"originalMilestonedProperties\":[],\"package\":\"meta::pure::milestoning\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"ProcessingDateMilestoning\",\"originalMilestonedProperties\":[],\"package\":\"meta::pure::milestoning\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"profile\",\"name\":\"temporal\",\"package\":\"meta::pure::profiles\",\"stereotypes\":[\"bitemporal\",\"businesstemporal\",\"processingtemporal\"],\"tags\":[]}]},\"name\":\"COVIDDatapace\",\"package\":\"domain\",\"path\":\"domain::COVIDDatapace\",\"stereotypes\":[],\"taggedValues\":[],\"title\":\"COVID Sample Data\"}"); } @Test public void testAnalyticsForDataSpaceWithSubstantialMapping() throws Exception { - testDataSpaceAnalyticsArtifactGenerationExtension("models/dataSpaceWithSubstantialMapping.pure", "model::animal::AnimalDS", "{\"defaultExecutionContext\":\"dummyContext\",\"description\":\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\",\"diagrams\":[{\"diagram\":\"model::animal::AnimalDiagram\",\"title\":\"\"},{\"diagram\":\"model::GeneralDiagram\",\"title\":\"\"}],\"elementDocs\":[],\"elements\":[],\"executables\":[],\"executionContexts\":[{\"compatibleRuntimes\":[\"model::dummyRuntime\"],\"datasets\":[],\"defaultRuntime\":\"model::dummyRuntime\",\"description\":\"An important execution context\",\"mapping\":\"model::dummyMapping\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[{\"path\":\"model::animal::Animal\",\"properties\":[{\"_type\":\"MappedProperty\",\"name\":\"noOfLegs\"},{\"_type\":\"MappedProperty\",\"name\":\"something\"},{\"_type\":\"entity\",\"entityPath\":\"model::animal::GenericAnimal\",\"name\":\"something2\"}]},{\"path\":\"model::animal::Animal2\",\"properties\":[{\"_type\":\"MappedProperty\",\"name\":\"name\"},{\"_type\":\"MappedProperty\",\"name\":\"name2\"}]},{\"path\":\"model::animal::GenericAnimal\",\"properties\":[]},{\"path\":\"model::animal::GenericAnimal2\",\"properties\":[]}]},\"name\":\"dummyContext\"},{\"compatibleRuntimes\":[\"model::dummyRuntime\",\"model::dummyRuntime2\"],\"datasets\":[],\"defaultRuntime\":\"model::dummyRuntime\",\"mapping\":\"model::dummyMapping2\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[{\"path\":\"model::animal::mammal::Mammal\",\"properties\":[{\"_type\":\"MappedProperty\",\"name\":\"noOfLegs\"}]},{\"path\":\"model::animal::reptile::Reptile\",\"properties\":[{\"_type\":\"enum\",\"enumPath\":\"model::animal::Family\",\"name\":\"family\"},{\"_type\":\"MappedProperty\",\"name\":\"name2\"},{\"_type\":\"MappedProperty\",\"name\":\"something\"},{\"_type\":\"MappedProperty\",\"name\":\"hasFin\"}]}]},\"name\":\"dummyContext2\"},{\"compatibleRuntimes\":[\"model::dummyRuntime\",\"model::dummyRuntime2\"],\"datasets\":[],\"defaultRuntime\":\"model::dummyRuntime2\",\"mapping\":\"model::dummyMapping2\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[{\"path\":\"model::animal::mammal::Mammal\",\"properties\":[{\"_type\":\"MappedProperty\",\"name\":\"noOfLegs\"}]},{\"path\":\"model::animal::reptile::Reptile\",\"properties\":[{\"_type\":\"enum\",\"enumPath\":\"model::animal::Family\",\"name\":\"family\"},{\"_type\":\"MappedProperty\",\"name\":\"name2\"},{\"_type\":\"MappedProperty\",\"name\":\"something\"},{\"_type\":\"MappedProperty\",\"name\":\"hasFin\"}]}]},\"name\":\"dummyContext3\"}],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"profile\",\"name\":\"doc\",\"package\":\"meta::pure::profiles\",\"stereotypes\":[\"deprecated\"],\"tags\":[\"doc\",\"todo\"]},{\"_type\":\"diagram\",\"classViews\":[{\"class\":\"model::animal::reptile::Reptile\",\"id\":\"4cec85f9-9b66-450a-bdcb-c855aa0314e1\",\"position\":{\"x\":568.0,\"y\":404.0},\"rectangle\":{\"height\":58.0,\"width\":120.84765625}},{\"class\":\"model::animal::Animal\",\"id\":\"902bf14e-e7ff-40e7-92e4-8780f91bfa29\",\"position\":{\"x\":809.0,\"y\":187.0},\"rectangle\":{\"height\":44.0,\"width\":108.64453125}}],\"generalizationViews\":[{\"line\":{\"points\":[{\"x\":628.423828125,\"y\":433.0},{\"x\":863.322265625,\"y\":209.0}]},\"sourceView\":\"4cec85f9-9b66-450a-bdcb-c855aa0314e1\",\"targetView\":\"902bf14e-e7ff-40e7-92e4-8780f91bfa29\"}],\"name\":\"GeneralDiagram\",\"package\":\"model\",\"propertyViews\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Animal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"family\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::animal::Family\"},{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"noOfLegs\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Number\"},{\"multiplicity\":{\"lowerBound\":0},\"name\":\"children\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::animal::GenericAnimal2\"}],\"qualifiedProperties\":[{\"body\":[{\"_type\":\"func\",\"fControl\":\"greaterThan_Number_1__Number_1__Boolean_1_\",\"function\":\"greaterThan\",\"parameters\":[{\"_type\":\"property\",\"parameters\":[{\"_type\":\"var\",\"name\":\"this\"}],\"property\":\"noOfLegs\"},{\"_type\":\"integer\",\"value\":4}]}],\"name\":\"something\",\"parameters\":[],\"returnMultiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"returnType\":\"Boolean\",\"stereotypes\":[],\"taggedValues\":[]},{\"body\":[{\"_type\":\"collection\",\"multiplicity\":{\"lowerBound\":0,\"upperBound\":0},\"values\":[]}],\"name\":\"something2\",\"parameters\":[],\"returnMultiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"returnType\":\"model::animal::GenericAnimal\",\"stereotypes\":[],\"taggedValues\":[]}],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"diagram\",\"classViews\":[{\"class\":\"model::animal::mammal::Mammal\",\"id\":\"641a0336-d4b5-418c-b656-2f52461264e2\",\"position\":{\"x\":427.0,\"y\":210.0},\"rectangle\":{\"height\":44.0,\"width\":125.1123046875}},{\"class\":\"model::animal::reptile::Reptile\",\"id\":\"b92253d8-0389-4c7d-b5d2-3cdc3bb1ad98\",\"position\":{\"x\":787.0,\"y\":216.0},\"rectangle\":{\"height\":58.0,\"width\":120.84765625}},{\"class\":\"model::animal::Animal\",\"id\":\"7a992cfc-c888-4091-aa00-ab430915aced\",\"position\":{\"x\":515.423828125,\"y\":-7.5},\"rectangle\":{\"height\":100.0,\"width\":199.716796875}}],\"generalizationViews\":[{\"line\":{\"points\":[{\"x\":847.423828125,\"y\":245.0},{\"x\":615.2822265625,\"y\":42.5}]},\"sourceView\":\"b92253d8-0389-4c7d-b5d2-3cdc3bb1ad98\",\"targetView\":\"7a992cfc-c888-4091-aa00-ab430915aced\"}],\"name\":\"AnimalDiagram\",\"package\":\"model::animal\",\"propertyViews\":[]},{\"_type\":\"Enumeration\",\"name\":\"Family\",\"package\":\"model::animal\",\"stereotypes\":[],\"taggedValues\":[],\"values\":[{\"stereotypes\":[],\"taggedValues\":[],\"value\":\"UO\"},{\"stereotypes\":[],\"taggedValues\":[],\"value\":\"OP\"}]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"GenericAnimal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"GenericAnimal2\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Mammal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal::mammal\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"noOfLegs\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Reptile\",\"originalMilestonedProperties\":[],\"package\":\"model::animal::reptile\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"hasFin\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Boolean\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[\"model::animal::Animal\"],\"taggedValues\":[{\"tag\":{\"profile\":\"meta::pure::profiles::doc\",\"value\":\"doc\"},\"value\":\"\"}]}]},\"name\":\"AnimalDS\",\"package\":\"model::animal\",\"path\":\"model::animal::AnimalDS\",\"stereotypes\":[{\"profile\":\"meta::pure::profiles::doc\",\"value\":\"deprecated\"}],\"supportInfo\":{\"_type\":\"email\",\"address\":\"someEmail@test.org\"},\"taggedValues\":[{\"profile\":\"meta::pure::profiles::enterprise\",\"tag\":\"taxonomyNodes\",\"value\":\"abcdxyz005\"},{\"profile\":\"meta::pure::profiles::doc\",\"tag\":\"doc\",\"value\":\"Lorem ipsum\"},{\"profile\":\"meta::pure::profiles::doc\",\"tag\":\"doc\",\"value\":\"Lorem ipsum2\"}]}"); + testDataSpaceAnalyticsArtifactGenerationExtension("models/dataSpaceWithSubstantialMapping.pure", "model::animal::AnimalDS", "{\"defaultExecutionContext\":\"dummyContext\",\"description\":\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\",\"diagrams\":[{\"diagram\":\"model::animal::AnimalDiagram\",\"title\":\"\"},{\"diagram\":\"model::GeneralDiagram\",\"title\":\"\"}],\"elementDocs\":[],\"elements\":[],\"executables\":[],\"executionContexts\":[{\"compatibleRuntimes\":[\"model::dummyRuntime\"],\"datasets\":[],\"defaultRuntime\":\"model::dummyRuntime\",\"description\":\"An important execution context\",\"mapping\":\"model::dummyMapping\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[{\"info\":{\"classPath\":\"model::animal::Animal\",\"isRootEntity\":true,\"subClasses\":[]},\"path\":\"model::animal::Animal\",\"properties\":[{\"_type\":\"MappedProperty\",\"name\":\"noOfLegs\"},{\"_type\":\"MappedProperty\",\"name\":\"something\"},{\"_type\":\"entity\",\"entityPath\":\"model::animal::GenericAnimal\",\"name\":\"something2\"}]},{\"info\":{\"classPath\":\"model::animal::Animal2\",\"isRootEntity\":true,\"subClasses\":[]},\"path\":\"model::animal::Animal2\",\"properties\":[{\"_type\":\"MappedProperty\",\"name\":\"name\"},{\"_type\":\"MappedProperty\",\"name\":\"name2\"}]},{\"info\":{\"classPath\":\"model::animal::GenericAnimal\",\"isRootEntity\":true,\"subClasses\":[]},\"path\":\"model::animal::GenericAnimal\",\"properties\":[]},{\"info\":{\"classPath\":\"model::animal::GenericAnimal2\",\"isRootEntity\":true,\"subClasses\":[]},\"path\":\"model::animal::GenericAnimal2\",\"properties\":[]}],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"class\",\"constraints\":[],\"name\":\"Animal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"family\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::animal::Family\"},{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"noOfLegs\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Number\"},{\"multiplicity\":{\"lowerBound\":0},\"name\":\"children\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::animal::GenericAnimal2\"}],\"qualifiedProperties\":[{\"body\":[{\"_type\":\"func\",\"fControl\":\"greaterThan_Number_1__Number_1__Boolean_1_\",\"function\":\"greaterThan\",\"parameters\":[{\"_type\":\"property\",\"parameters\":[{\"_type\":\"var\",\"name\":\"this\"}],\"property\":\"noOfLegs\"},{\"_type\":\"integer\",\"value\":4}]}],\"name\":\"something\",\"parameters\":[],\"returnMultiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"returnType\":\"Boolean\",\"stereotypes\":[],\"taggedValues\":[]},{\"body\":[{\"_type\":\"collection\",\"multiplicity\":{\"lowerBound\":0,\"upperBound\":0},\"values\":[]}],\"name\":\"something2\",\"parameters\":[],\"returnMultiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"returnType\":\"model::animal::GenericAnimal\",\"stereotypes\":[],\"taggedValues\":[]}],\"stereotypes\":[],\"superTypes\":[\"meta::pure::metamodel::type::Any\"],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Animal2\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"name\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"}],\"qualifiedProperties\":[{\"body\":[{\"_type\":\"string\",\"value\":\"\"}],\"name\":\"name2\",\"parameters\":[],\"returnMultiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"returnType\":\"String\",\"stereotypes\":[],\"taggedValues\":[]}],\"stereotypes\":[],\"superTypes\":[\"meta::pure::metamodel::type::Any\"],\"taggedValues\":[]},{\"_type\":\"dataSpace\",\"defaultExecutionContext\":\"dummyContext\",\"description\":\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\",\"diagrams\":[{\"diagram\":{\"path\":\"model::animal::AnimalDiagram\"},\"title\":\"\"},{\"diagram\":{\"path\":\"model::GeneralDiagram\"},\"title\":\"\"}],\"executionContexts\":[{\"defaultRuntime\":{\"path\":\"model::dummyRuntime\",\"type\":\"RUNTIME\"},\"description\":\"An important execution context\",\"mapping\":{\"path\":\"model::dummyMapping\",\"type\":\"MAPPING\"},\"name\":\"dummyContext\"},{\"defaultRuntime\":{\"path\":\"model::dummyRuntime\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"model::dummyMapping2\",\"type\":\"MAPPING\"},\"name\":\"dummyContext2\"},{\"defaultRuntime\":{\"path\":\"model::dummyRuntime2\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"model::dummyMapping2\",\"type\":\"MAPPING\"},\"name\":\"dummyContext3\"}],\"name\":\"AnimalDS\",\"package\":\"model::animal\",\"stereotypes\":[{\"profile\":\"doc\",\"value\":\"deprecated\"}],\"supportInfo\":{\"_type\":\"email\",\"address\":\"someEmail@test.org\"},\"taggedValues\":[{\"tag\":{\"profile\":\"meta::pure::profiles::enterprise\",\"value\":\"taxonomyNodes\"},\"value\":\"abcdxyz005\"},{\"tag\":{\"profile\":\"doc\",\"value\":\"doc\"},\"value\":\"Lorem ipsum\"},{\"tag\":{\"profile\":\"doc\",\"value\":\"doc\"},\"value\":\"Lorem ipsum2\"}]},{\"_type\":\"Enumeration\",\"name\":\"Family\",\"package\":\"model::animal\",\"stereotypes\":[],\"taggedValues\":[],\"values\":[{\"stereotypes\":[],\"taggedValues\":[],\"value\":\"UO\"},{\"stereotypes\":[],\"taggedValues\":[],\"value\":\"OP\"}]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"GenericAnimal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[\"meta::pure::metamodel::type::Any\"],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"GenericAnimal2\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[\"meta::pure::metamodel::type::Any\"],\"taggedValues\":[]}]}},\"name\":\"dummyContext\"},{\"compatibleRuntimes\":[\"model::dummyRuntime\",\"model::dummyRuntime2\"],\"datasets\":[],\"defaultRuntime\":\"model::dummyRuntime\",\"mapping\":\"model::dummyMapping2\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[{\"info\":{\"classPath\":\"model::animal::mammal::Mammal\",\"isRootEntity\":true,\"subClasses\":[]},\"path\":\"model::animal::mammal::Mammal\",\"properties\":[{\"_type\":\"MappedProperty\",\"name\":\"noOfLegs\"}]},{\"info\":{\"classPath\":\"model::animal::reptile::Reptile\",\"isRootEntity\":true,\"subClasses\":[]},\"path\":\"model::animal::reptile::Reptile\",\"properties\":[{\"_type\":\"enum\",\"enumPath\":\"model::animal::Family\",\"name\":\"family\"},{\"_type\":\"MappedProperty\",\"name\":\"name2\"},{\"_type\":\"MappedProperty\",\"name\":\"something\"},{\"_type\":\"MappedProperty\",\"name\":\"hasFin\"}]}],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"profile\",\"name\":\"doc\",\"package\":\"meta::pure::profiles\",\"stereotypes\":[\"deprecated\"],\"tags\":[\"doc\",\"todo\"]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Animal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"family\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::animal::Family\"},{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"noOfLegs\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Number\"},{\"multiplicity\":{\"lowerBound\":0},\"name\":\"children\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::animal::GenericAnimal2\"}],\"qualifiedProperties\":[{\"body\":[{\"_type\":\"func\",\"fControl\":\"greaterThan_Number_1__Number_1__Boolean_1_\",\"function\":\"greaterThan\",\"parameters\":[{\"_type\":\"property\",\"parameters\":[{\"_type\":\"var\",\"name\":\"this\"}],\"property\":\"noOfLegs\"},{\"_type\":\"integer\",\"value\":4}]}],\"name\":\"something\",\"parameters\":[],\"returnMultiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"returnType\":\"Boolean\",\"stereotypes\":[],\"taggedValues\":[]},{\"body\":[{\"_type\":\"collection\",\"multiplicity\":{\"lowerBound\":0,\"upperBound\":0},\"values\":[]}],\"name\":\"something2\",\"parameters\":[],\"returnMultiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"returnType\":\"model::animal::GenericAnimal\",\"stereotypes\":[],\"taggedValues\":[]}],\"stereotypes\":[],\"superTypes\":[\"meta::pure::metamodel::type::Any\"],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Animal2\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"name\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"}],\"qualifiedProperties\":[{\"body\":[{\"_type\":\"string\",\"value\":\"\"}],\"name\":\"name2\",\"parameters\":[],\"returnMultiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"returnType\":\"String\",\"stereotypes\":[],\"taggedValues\":[]}],\"stereotypes\":[],\"superTypes\":[\"meta::pure::metamodel::type::Any\"],\"taggedValues\":[]},{\"_type\":\"dataSpace\",\"defaultExecutionContext\":\"dummyContext\",\"description\":\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\",\"diagrams\":[{\"diagram\":{\"path\":\"model::animal::AnimalDiagram\"},\"title\":\"\"},{\"diagram\":{\"path\":\"model::GeneralDiagram\"},\"title\":\"\"}],\"executionContexts\":[{\"defaultRuntime\":{\"path\":\"model::dummyRuntime\",\"type\":\"RUNTIME\"},\"description\":\"An important execution context\",\"mapping\":{\"path\":\"model::dummyMapping\",\"type\":\"MAPPING\"},\"name\":\"dummyContext\"},{\"defaultRuntime\":{\"path\":\"model::dummyRuntime\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"model::dummyMapping2\",\"type\":\"MAPPING\"},\"name\":\"dummyContext2\"},{\"defaultRuntime\":{\"path\":\"model::dummyRuntime2\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"model::dummyMapping2\",\"type\":\"MAPPING\"},\"name\":\"dummyContext3\"}],\"name\":\"AnimalDS\",\"package\":\"model::animal\",\"stereotypes\":[{\"profile\":\"doc\",\"value\":\"deprecated\"}],\"supportInfo\":{\"_type\":\"email\",\"address\":\"someEmail@test.org\"},\"taggedValues\":[{\"tag\":{\"profile\":\"meta::pure::profiles::enterprise\",\"value\":\"taxonomyNodes\"},\"value\":\"abcdxyz005\"},{\"tag\":{\"profile\":\"doc\",\"value\":\"doc\"},\"value\":\"Lorem ipsum\"},{\"tag\":{\"profile\":\"doc\",\"value\":\"doc\"},\"value\":\"Lorem ipsum2\"}]},{\"_type\":\"Enumeration\",\"name\":\"Family\",\"package\":\"model::animal\",\"stereotypes\":[],\"taggedValues\":[],\"values\":[{\"stereotypes\":[],\"taggedValues\":[],\"value\":\"UO\"},{\"stereotypes\":[],\"taggedValues\":[],\"value\":\"OP\"}]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"GenericAnimal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"GenericAnimal2\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Mammal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal::mammal\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"noOfLegs\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[\"meta::pure::metamodel::type::Any\"],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Reptile\",\"originalMilestonedProperties\":[],\"package\":\"model::animal::reptile\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"hasFin\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Boolean\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[\"model::animal::Animal2\",\"model::animal::Animal\"],\"taggedValues\":[{\"tag\":{\"profile\":\"meta::pure::profiles::doc\",\"value\":\"doc\"},\"value\":\"\"}]}]}},\"name\":\"dummyContext2\"},{\"compatibleRuntimes\":[\"model::dummyRuntime\",\"model::dummyRuntime2\"],\"datasets\":[],\"defaultRuntime\":\"model::dummyRuntime2\",\"mapping\":\"model::dummyMapping2\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[{\"info\":{\"classPath\":\"model::animal::mammal::Mammal\",\"isRootEntity\":true,\"subClasses\":[]},\"path\":\"model::animal::mammal::Mammal\",\"properties\":[{\"_type\":\"MappedProperty\",\"name\":\"noOfLegs\"}]},{\"info\":{\"classPath\":\"model::animal::reptile::Reptile\",\"isRootEntity\":true,\"subClasses\":[]},\"path\":\"model::animal::reptile::Reptile\",\"properties\":[{\"_type\":\"enum\",\"enumPath\":\"model::animal::Family\",\"name\":\"family\"},{\"_type\":\"MappedProperty\",\"name\":\"name2\"},{\"_type\":\"MappedProperty\",\"name\":\"something\"},{\"_type\":\"MappedProperty\",\"name\":\"hasFin\"}]}],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"profile\",\"name\":\"doc\",\"package\":\"meta::pure::profiles\",\"stereotypes\":[\"deprecated\"],\"tags\":[\"doc\",\"todo\"]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Animal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"family\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::animal::Family\"},{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"noOfLegs\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Number\"},{\"multiplicity\":{\"lowerBound\":0},\"name\":\"children\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::animal::GenericAnimal2\"}],\"qualifiedProperties\":[{\"body\":[{\"_type\":\"func\",\"fControl\":\"greaterThan_Number_1__Number_1__Boolean_1_\",\"function\":\"greaterThan\",\"parameters\":[{\"_type\":\"property\",\"parameters\":[{\"_type\":\"var\",\"name\":\"this\"}],\"property\":\"noOfLegs\"},{\"_type\":\"integer\",\"value\":4}]}],\"name\":\"something\",\"parameters\":[],\"returnMultiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"returnType\":\"Boolean\",\"stereotypes\":[],\"taggedValues\":[]},{\"body\":[{\"_type\":\"collection\",\"multiplicity\":{\"lowerBound\":0,\"upperBound\":0},\"values\":[]}],\"name\":\"something2\",\"parameters\":[],\"returnMultiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"returnType\":\"model::animal::GenericAnimal\",\"stereotypes\":[],\"taggedValues\":[]}],\"stereotypes\":[],\"superTypes\":[\"meta::pure::metamodel::type::Any\"],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Animal2\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"name\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"}],\"qualifiedProperties\":[{\"body\":[{\"_type\":\"string\",\"value\":\"\"}],\"name\":\"name2\",\"parameters\":[],\"returnMultiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"returnType\":\"String\",\"stereotypes\":[],\"taggedValues\":[]}],\"stereotypes\":[],\"superTypes\":[\"meta::pure::metamodel::type::Any\"],\"taggedValues\":[]},{\"_type\":\"dataSpace\",\"defaultExecutionContext\":\"dummyContext\",\"description\":\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\",\"diagrams\":[{\"diagram\":{\"path\":\"model::animal::AnimalDiagram\"},\"title\":\"\"},{\"diagram\":{\"path\":\"model::GeneralDiagram\"},\"title\":\"\"}],\"executionContexts\":[{\"defaultRuntime\":{\"path\":\"model::dummyRuntime\",\"type\":\"RUNTIME\"},\"description\":\"An important execution context\",\"mapping\":{\"path\":\"model::dummyMapping\",\"type\":\"MAPPING\"},\"name\":\"dummyContext\"},{\"defaultRuntime\":{\"path\":\"model::dummyRuntime\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"model::dummyMapping2\",\"type\":\"MAPPING\"},\"name\":\"dummyContext2\"},{\"defaultRuntime\":{\"path\":\"model::dummyRuntime2\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"model::dummyMapping2\",\"type\":\"MAPPING\"},\"name\":\"dummyContext3\"}],\"name\":\"AnimalDS\",\"package\":\"model::animal\",\"stereotypes\":[{\"profile\":\"doc\",\"value\":\"deprecated\"}],\"supportInfo\":{\"_type\":\"email\",\"address\":\"someEmail@test.org\"},\"taggedValues\":[{\"tag\":{\"profile\":\"meta::pure::profiles::enterprise\",\"value\":\"taxonomyNodes\"},\"value\":\"abcdxyz005\"},{\"tag\":{\"profile\":\"doc\",\"value\":\"doc\"},\"value\":\"Lorem ipsum\"},{\"tag\":{\"profile\":\"doc\",\"value\":\"doc\"},\"value\":\"Lorem ipsum2\"}]},{\"_type\":\"Enumeration\",\"name\":\"Family\",\"package\":\"model::animal\",\"stereotypes\":[],\"taggedValues\":[],\"values\":[{\"stereotypes\":[],\"taggedValues\":[],\"value\":\"UO\"},{\"stereotypes\":[],\"taggedValues\":[],\"value\":\"OP\"}]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"GenericAnimal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"GenericAnimal2\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Mammal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal::mammal\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"noOfLegs\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[\"meta::pure::metamodel::type::Any\"],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Reptile\",\"originalMilestonedProperties\":[],\"package\":\"model::animal::reptile\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"hasFin\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Boolean\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[\"model::animal::Animal2\",\"model::animal::Animal\"],\"taggedValues\":[{\"tag\":{\"profile\":\"meta::pure::profiles::doc\",\"value\":\"doc\"},\"value\":\"\"}]}]}},\"name\":\"dummyContext3\"}],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"profile\",\"name\":\"doc\",\"package\":\"meta::pure::profiles\",\"stereotypes\":[\"deprecated\"],\"tags\":[\"doc\",\"todo\"]},{\"_type\":\"diagram\",\"classViews\":[{\"class\":\"model::animal::reptile::Reptile\",\"id\":\"4cec85f9-9b66-450a-bdcb-c855aa0314e1\",\"position\":{\"x\":568.0,\"y\":404.0},\"rectangle\":{\"height\":58.0,\"width\":120.84765625}},{\"class\":\"model::animal::Animal\",\"id\":\"902bf14e-e7ff-40e7-92e4-8780f91bfa29\",\"position\":{\"x\":809.0,\"y\":187.0},\"rectangle\":{\"height\":44.0,\"width\":108.64453125}}],\"generalizationViews\":[{\"line\":{\"points\":[{\"x\":628.423828125,\"y\":433.0},{\"x\":863.322265625,\"y\":209.0}]},\"sourceView\":\"4cec85f9-9b66-450a-bdcb-c855aa0314e1\",\"targetView\":\"902bf14e-e7ff-40e7-92e4-8780f91bfa29\"}],\"name\":\"GeneralDiagram\",\"package\":\"model\",\"propertyViews\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Animal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"family\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::animal::Family\"},{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"noOfLegs\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Number\"},{\"multiplicity\":{\"lowerBound\":0},\"name\":\"children\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::animal::GenericAnimal2\"}],\"qualifiedProperties\":[{\"body\":[{\"_type\":\"func\",\"fControl\":\"greaterThan_Number_1__Number_1__Boolean_1_\",\"function\":\"greaterThan\",\"parameters\":[{\"_type\":\"property\",\"parameters\":[{\"_type\":\"var\",\"name\":\"this\"}],\"property\":\"noOfLegs\"},{\"_type\":\"integer\",\"value\":4}]}],\"name\":\"something\",\"parameters\":[],\"returnMultiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"returnType\":\"Boolean\",\"stereotypes\":[],\"taggedValues\":[]},{\"body\":[{\"_type\":\"collection\",\"multiplicity\":{\"lowerBound\":0,\"upperBound\":0},\"values\":[]}],\"name\":\"something2\",\"parameters\":[],\"returnMultiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"returnType\":\"model::animal::GenericAnimal\",\"stereotypes\":[],\"taggedValues\":[]}],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"diagram\",\"classViews\":[{\"class\":\"model::animal::mammal::Mammal\",\"id\":\"641a0336-d4b5-418c-b656-2f52461264e2\",\"position\":{\"x\":427.0,\"y\":210.0},\"rectangle\":{\"height\":44.0,\"width\":125.1123046875}},{\"class\":\"model::animal::reptile::Reptile\",\"id\":\"b92253d8-0389-4c7d-b5d2-3cdc3bb1ad98\",\"position\":{\"x\":787.0,\"y\":216.0},\"rectangle\":{\"height\":58.0,\"width\":120.84765625}},{\"class\":\"model::animal::Animal\",\"id\":\"7a992cfc-c888-4091-aa00-ab430915aced\",\"position\":{\"x\":515.423828125,\"y\":-7.5},\"rectangle\":{\"height\":100.0,\"width\":199.716796875}}],\"generalizationViews\":[{\"line\":{\"points\":[{\"x\":847.423828125,\"y\":245.0},{\"x\":615.2822265625,\"y\":42.5}]},\"sourceView\":\"b92253d8-0389-4c7d-b5d2-3cdc3bb1ad98\",\"targetView\":\"7a992cfc-c888-4091-aa00-ab430915aced\"}],\"name\":\"AnimalDiagram\",\"package\":\"model::animal\",\"propertyViews\":[]},{\"_type\":\"Enumeration\",\"name\":\"Family\",\"package\":\"model::animal\",\"stereotypes\":[],\"taggedValues\":[],\"values\":[{\"stereotypes\":[],\"taggedValues\":[],\"value\":\"UO\"},{\"stereotypes\":[],\"taggedValues\":[],\"value\":\"OP\"}]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"GenericAnimal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"GenericAnimal2\",\"originalMilestonedProperties\":[],\"package\":\"model::animal\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Mammal\",\"originalMilestonedProperties\":[],\"package\":\"model::animal::mammal\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"noOfLegs\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Reptile\",\"originalMilestonedProperties\":[],\"package\":\"model::animal::reptile\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"hasFin\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Boolean\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[\"model::animal::Animal\"],\"taggedValues\":[{\"tag\":{\"profile\":\"meta::pure::profiles::doc\",\"value\":\"doc\"},\"value\":\"\"}]}]},\"name\":\"AnimalDS\",\"package\":\"model::animal\",\"path\":\"model::animal::AnimalDS\",\"stereotypes\":[{\"profile\":\"meta::pure::profiles::doc\",\"value\":\"deprecated\"}],\"supportInfo\":{\"_type\":\"email\",\"address\":\"someEmail@test.org\"},\"taggedValues\":[{\"profile\":\"meta::pure::profiles::enterprise\",\"tag\":\"taxonomyNodes\",\"value\":\"abcdxyz005\"},{\"profile\":\"meta::pure::profiles::doc\",\"tag\":\"doc\",\"value\":\"Lorem ipsum\"},{\"profile\":\"meta::pure::profiles::doc\",\"tag\":\"doc\",\"value\":\"Lorem ipsum2\"}]}"); } @Test public void testAnalyticsForDataSpaceWithElements() throws Exception { - testDataSpaceAnalyticsArtifactGenerationExtension("models/dataSpaceWithElements.pure", "dataSpace::_FirmDataSpace", "{\"defaultExecutionContext\":\"dummyContext\",\"diagrams\":[],\"elementDocs\":[{\"_type\":\"class\",\"docs\":[\"Animal class\"],\"name\":\"Animal\",\"path\":\"model::Animal\",\"properties\":[{\"docs\":[\"age\"],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"age\",\"type\":\"Integer\"}]},{\"_type\":\"class\",\"docs\":[\"The Firm concept\"],\"name\":\"Firm\",\"path\":\"model::Firm\",\"properties\":[{\"docs\":[\"type of firm: e.g. CORP, LTD\"],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"type\",\"type\":\"String\"},{\"docs\":[\"some doc for employees\"],\"multiplicity\":{\"lowerBound\":1},\"name\":\"employees\",\"type\":\"model::Person\"}]},{\"_type\":\"association\",\"docs\":[],\"name\":\"Firm_Person\",\"path\":\"model::Firm_Person\",\"properties\":[{\"docs\":[],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"firm\",\"type\":\"model::Firm\"},{\"docs\":[\"some doc for employees\"],\"multiplicity\":{\"lowerBound\":1},\"name\":\"employees\",\"type\":\"model::Person\"}]},{\"_type\":\"class\",\"docs\":[],\"name\":\"LegalEntity\",\"path\":\"model::LegalEntity\",\"properties\":[{\"docs\":[\"name of the entity\"],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"legalName\",\"type\":\"String\"}]},{\"_type\":\"class\",\"docs\":[\"Homo Sapien\"],\"name\":\"Person\",\"path\":\"model::Person\",\"properties\":[{\"docs\":[],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"firstName\",\"type\":\"String\"},{\"docs\":[],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"lastName\",\"type\":\"String\"},{\"docs\":[],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"firm\",\"type\":\"model::Firm\"}]},{\"_type\":\"enumeration\",\"docs\":[\"Types of company\"],\"enumValues\":[{\"docs\":[\"Limited\"],\"name\":\"LLC\"},{\"docs\":[],\"name\":\"CORP\"}],\"name\":\"IncType\",\"path\":\"model::target::IncType\"},{\"_type\":\"class\",\"docs\":[],\"name\":\"_Person\",\"path\":\"model::target::_Person\",\"properties\":[{\"docs\":[],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"fullName\",\"type\":\"String\"}]}],\"elements\":[\"model::Animal\",\"model::Firm\",\"model::Firm_Person\",\"model::LegalEntity\",\"model::Person\",\"model::target::IncType\",\"model::target::_Person\"],\"executables\":[],\"executionContexts\":[{\"compatibleRuntimes\":[\"mapping::ModelToModelRuntime\"],\"datasets\":[],\"defaultRuntime\":\"mapping::ModelToModelRuntime\",\"mapping\":\"mapping::ModelToModelMapping\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[{\"path\":\"model::target::_Firm\",\"properties\":[{\"_type\":\"entity\",\"entityPath\":\"model::target::_Person\",\"name\":\"employees\"},{\"_type\":\"MappedProperty\",\"name\":\"name\"},{\"_type\":\"enum\",\"enumPath\":\"model::target::IncType\",\"name\":\"type\"}]},{\"path\":\"model::target::_Person\",\"properties\":[{\"_type\":\"MappedProperty\",\"name\":\"fullName\"}]}]},\"name\":\"dummyContext\"}],\"model\":{\"_type\":\"data\",\"elements\":[]},\"name\":\"_FirmDataSpace\",\"package\":\"dataSpace\",\"path\":\"dataSpace::_FirmDataSpace\",\"stereotypes\":[],\"taggedValues\":[],\"title\":\"Firm Dataspace\"}"); + testDataSpaceAnalyticsArtifactGenerationExtension("models/dataSpaceWithElements.pure", "dataSpace::_FirmDataSpace", "{\"defaultExecutionContext\":\"dummyContext\",\"diagrams\":[],\"elementDocs\":[{\"_type\":\"class\",\"docs\":[\"Animal class\"],\"name\":\"Animal\",\"path\":\"model::Animal\",\"properties\":[{\"docs\":[\"age\"],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"age\",\"type\":\"Integer\"}]},{\"_type\":\"class\",\"docs\":[\"The Firm concept\"],\"name\":\"Firm\",\"path\":\"model::Firm\",\"properties\":[{\"docs\":[\"type of firm: e.g. CORP, LTD\"],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"type\",\"type\":\"String\"},{\"docs\":[\"some doc for employees\"],\"multiplicity\":{\"lowerBound\":1},\"name\":\"employees\",\"type\":\"model::Person\"}]},{\"_type\":\"association\",\"docs\":[],\"name\":\"Firm_Person\",\"path\":\"model::Firm_Person\",\"properties\":[{\"docs\":[],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"firm\",\"type\":\"model::Firm\"},{\"docs\":[\"some doc for employees\"],\"multiplicity\":{\"lowerBound\":1},\"name\":\"employees\",\"type\":\"model::Person\"}]},{\"_type\":\"class\",\"docs\":[],\"name\":\"LegalEntity\",\"path\":\"model::LegalEntity\",\"properties\":[{\"docs\":[\"name of the entity\"],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"legalName\",\"type\":\"String\"}]},{\"_type\":\"class\",\"docs\":[\"Homo Sapien\"],\"name\":\"Person\",\"path\":\"model::Person\",\"properties\":[{\"docs\":[],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"firstName\",\"type\":\"String\"},{\"docs\":[],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"lastName\",\"type\":\"String\"},{\"docs\":[],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"firm\",\"type\":\"model::Firm\"}]},{\"_type\":\"enumeration\",\"docs\":[\"Types of company\"],\"enumValues\":[{\"docs\":[\"Limited\"],\"name\":\"LLC\"},{\"docs\":[],\"name\":\"CORP\"}],\"name\":\"IncType\",\"path\":\"model::target::IncType\"},{\"_type\":\"class\",\"docs\":[],\"name\":\"_Person\",\"path\":\"model::target::_Person\",\"properties\":[{\"docs\":[],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"fullName\",\"type\":\"String\"}]}],\"elements\":[\"model::Animal\",\"model::Firm\",\"model::Firm_Person\",\"model::LegalEntity\",\"model::Person\",\"model::target::IncType\",\"model::target::_Person\"],\"executables\":[],\"executionContexts\":[{\"compatibleRuntimes\":[\"mapping::ModelToModelRuntime\"],\"datasets\":[],\"defaultRuntime\":\"mapping::ModelToModelRuntime\",\"mapping\":\"mapping::ModelToModelMapping\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[{\"info\":{\"classPath\":\"model::target::_Firm\",\"isRootEntity\":true,\"subClasses\":[]},\"path\":\"model::target::_Firm\",\"properties\":[{\"_type\":\"entity\",\"entityPath\":\"model::target::_Person\",\"name\":\"employees\"},{\"_type\":\"MappedProperty\",\"name\":\"name\"},{\"_type\":\"enum\",\"enumPath\":\"model::target::IncType\",\"name\":\"type\"}]},{\"info\":{\"classPath\":\"model::target::_Person\",\"isRootEntity\":true,\"subClasses\":[]},\"path\":\"model::target::_Person\",\"properties\":[{\"_type\":\"MappedProperty\",\"name\":\"fullName\"}]}],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"dataSpace\",\"defaultExecutionContext\":\"dummyContext\",\"elements\":[{\"path\":\"model\"},{\"exclude\":true,\"path\":\"model::experiment\"},{\"exclude\":true,\"path\":\"model::target::_Firm\"},{\"exclude\":true,\"path\":\"model::NotRelevant\"}],\"executionContexts\":[{\"defaultRuntime\":{\"path\":\"mapping::ModelToModelRuntime\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"mapping::ModelToModelMapping\",\"type\":\"MAPPING\"},\"name\":\"dummyContext\"}],\"name\":\"_FirmDataSpace\",\"package\":\"dataSpace\",\"stereotypes\":[],\"taggedValues\":[],\"title\":\"Firm Dataspace\"},{\"_type\":\"Enumeration\",\"name\":\"IncType\",\"package\":\"model::target\",\"stereotypes\":[],\"taggedValues\":[],\"values\":[{\"stereotypes\":[],\"taggedValues\":[],\"value\":\"LLC\"},{\"stereotypes\":[],\"taggedValues\":[],\"value\":\"CORP\"}]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"_Firm\",\"originalMilestonedProperties\":[],\"package\":\"model::target\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1},\"name\":\"employees\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::target::_Person\"},{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"type\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::target::IncType\"},{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"name\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[\"meta::pure::metamodel::type::Any\"],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"_Person\",\"originalMilestonedProperties\":[],\"package\":\"model::target\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"fullName\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[\"meta::pure::metamodel::type::Any\"],\"taggedValues\":[]}]}},\"name\":\"dummyContext\"}],\"model\":{\"_type\":\"data\",\"elements\":[]},\"name\":\"_FirmDataSpace\",\"package\":\"dataSpace\",\"path\":\"dataSpace::_FirmDataSpace\",\"stereotypes\":[],\"taggedValues\":[],\"title\":\"Firm Dataspace\"}"); } @Test public void testAnalyticsForDataSpaceWithMilestoningElements() throws Exception { - testDataSpaceAnalyticsArtifactGenerationExtension("models/dataSpaceWithMilestoningElements.pure", "dataSpace::_FirmDataSpace", "{\"defaultExecutionContext\":\"dummyContext\",\"diagrams\":[],\"elementDocs\":[{\"_type\":\"class\",\"docs\":[\"Animal class\"],\"name\":\"Animal\",\"path\":\"model::Animal\",\"properties\":[{\"docs\":[\"age\"],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"age\",\"type\":\"Integer\"}]},{\"_type\":\"class\",\"docs\":[\"The Firm concept\"],\"milestoning\":\"processingtemporal\",\"name\":\"Firm\",\"path\":\"model::Firm\",\"properties\":[{\"docs\":[\"type of firm: e.g. CORP, LTD\"],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"type\",\"type\":\"String\"},{\"docs\":[\"some doc for employees\"],\"multiplicity\":{\"lowerBound\":1},\"name\":\"employees\",\"type\":\"model::Person\"}]},{\"_type\":\"association\",\"docs\":[],\"name\":\"Firm_Person\",\"path\":\"model::Firm_Person\",\"properties\":[{\"docs\":[\"some doc for employees\"],\"multiplicity\":{\"lowerBound\":1},\"name\":\"employees\",\"type\":\"model::Person\"},{\"docs\":[],\"milestoning\":\"processingtemporal\",\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"firm\",\"type\":\"model::Firm\"}]},{\"_type\":\"class\",\"docs\":[],\"name\":\"LegalEntity\",\"path\":\"model::LegalEntity\",\"properties\":[{\"docs\":[\"name of the entity\"],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"legalName\",\"type\":\"String\"}]},{\"_type\":\"class\",\"docs\":[],\"name\":\"NotRelevant\",\"path\":\"model::NotRelevant\",\"properties\":[]},{\"_type\":\"class\",\"docs\":[\"Homo Sapien\"],\"name\":\"Person\",\"path\":\"model::Person\",\"properties\":[{\"docs\":[],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"firstName\",\"type\":\"String\"},{\"docs\":[],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"lastName\",\"type\":\"String\"},{\"docs\":[],\"milestoning\":\"processingtemporal\",\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"firm\",\"type\":\"model::Firm\"}]},{\"_type\":\"class\",\"docs\":[],\"milestoning\":\"businesstemporal\",\"name\":\"Animal\",\"path\":\"model::experiment::Animal\",\"properties\":[]},{\"_type\":\"class\",\"docs\":[],\"milestoning\":\"businesstemporal\",\"name\":\"Human\",\"path\":\"model::experiment::Human\",\"properties\":[]},{\"_type\":\"enumeration\",\"docs\":[\"Types of company\"],\"enumValues\":[{\"docs\":[\"Limited\"],\"name\":\"LLC\"},{\"docs\":[],\"name\":\"CORP\"}],\"name\":\"IncType\",\"path\":\"model::target::IncType\"},{\"_type\":\"class\",\"docs\":[],\"name\":\"_Firm\",\"path\":\"model::target::_Firm\",\"properties\":[{\"docs\":[],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"type\",\"type\":\"model::target::IncType\"},{\"docs\":[],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"name\",\"type\":\"String\"},{\"docs\":[],\"milestoning\":\"bitemporal\",\"multiplicity\":{\"lowerBound\":1},\"name\":\"employees\",\"type\":\"model::target::_Person\"}]},{\"_type\":\"class\",\"docs\":[],\"milestoning\":\"bitemporal\",\"name\":\"_Person\",\"path\":\"model::target::_Person\",\"properties\":[{\"docs\":[],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"fullName\",\"type\":\"String\"}]}],\"elements\":[\"model::Animal\",\"model::Firm\",\"model::Firm_Person\",\"model::LegalEntity\",\"model::NotRelevant\",\"model::Person\",\"model::experiment::Animal\",\"model::experiment::Human\",\"model::target::IncType\",\"model::target::_Firm\",\"model::target::_Person\"],\"executables\":[],\"executionContexts\":[{\"compatibleRuntimes\":[\"mapping::ModelToModelRuntime\"],\"datasets\":[],\"defaultRuntime\":\"mapping::ModelToModelRuntime\",\"mapping\":\"mapping::ModelToModelMapping\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[{\"path\":\"model::target::_Firm\",\"properties\":[{\"_type\":\"entity\",\"entityPath\":\"model::target::_Person\",\"name\":\"employees\"},{\"_type\":\"MappedProperty\",\"name\":\"name\"},{\"_type\":\"enum\",\"enumPath\":\"model::target::IncType\",\"name\":\"type\"}]},{\"path\":\"model::target::_Person\",\"properties\":[{\"_type\":\"MappedProperty\",\"name\":\"fullName\"}]}]},\"name\":\"dummyContext\"}],\"model\":{\"_type\":\"data\",\"elements\":[]},\"name\":\"_FirmDataSpace\",\"package\":\"dataSpace\",\"path\":\"dataSpace::_FirmDataSpace\",\"stereotypes\":[],\"taggedValues\":[],\"title\":\"Firm Dataspace\"}"); + testDataSpaceAnalyticsArtifactGenerationExtension("models/dataSpaceWithMilestoningElements.pure", "dataSpace::_FirmDataSpace", "{\"defaultExecutionContext\":\"dummyContext\",\"diagrams\":[],\"elementDocs\":[{\"_type\":\"class\",\"docs\":[\"Animal class\"],\"name\":\"Animal\",\"path\":\"model::Animal\",\"properties\":[{\"docs\":[\"age\"],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"age\",\"type\":\"Integer\"}]},{\"_type\":\"class\",\"docs\":[\"The Firm concept\"],\"milestoning\":\"processingtemporal\",\"name\":\"Firm\",\"path\":\"model::Firm\",\"properties\":[{\"docs\":[\"type of firm: e.g. CORP, LTD\"],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"type\",\"type\":\"String\"},{\"docs\":[\"some doc for employees\"],\"multiplicity\":{\"lowerBound\":1},\"name\":\"employees\",\"type\":\"model::Person\"}]},{\"_type\":\"association\",\"docs\":[],\"name\":\"Firm_Person\",\"path\":\"model::Firm_Person\",\"properties\":[{\"docs\":[\"some doc for employees\"],\"multiplicity\":{\"lowerBound\":1},\"name\":\"employees\",\"type\":\"model::Person\"},{\"docs\":[],\"milestoning\":\"processingtemporal\",\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"firm\",\"type\":\"model::Firm\"}]},{\"_type\":\"class\",\"docs\":[],\"name\":\"LegalEntity\",\"path\":\"model::LegalEntity\",\"properties\":[{\"docs\":[\"name of the entity\"],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"legalName\",\"type\":\"String\"}]},{\"_type\":\"class\",\"docs\":[],\"name\":\"NotRelevant\",\"path\":\"model::NotRelevant\",\"properties\":[]},{\"_type\":\"class\",\"docs\":[\"Homo Sapien\"],\"name\":\"Person\",\"path\":\"model::Person\",\"properties\":[{\"docs\":[],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"firstName\",\"type\":\"String\"},{\"docs\":[],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"lastName\",\"type\":\"String\"},{\"docs\":[],\"milestoning\":\"processingtemporal\",\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"firm\",\"type\":\"model::Firm\"}]},{\"_type\":\"class\",\"docs\":[],\"milestoning\":\"businesstemporal\",\"name\":\"Animal\",\"path\":\"model::experiment::Animal\",\"properties\":[]},{\"_type\":\"class\",\"docs\":[],\"milestoning\":\"businesstemporal\",\"name\":\"Human\",\"path\":\"model::experiment::Human\",\"properties\":[]},{\"_type\":\"enumeration\",\"docs\":[\"Types of company\"],\"enumValues\":[{\"docs\":[\"Limited\"],\"name\":\"LLC\"},{\"docs\":[],\"name\":\"CORP\"}],\"name\":\"IncType\",\"path\":\"model::target::IncType\"},{\"_type\":\"class\",\"docs\":[],\"name\":\"_Firm\",\"path\":\"model::target::_Firm\",\"properties\":[{\"docs\":[],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"type\",\"type\":\"model::target::IncType\"},{\"docs\":[],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"name\",\"type\":\"String\"},{\"docs\":[],\"milestoning\":\"bitemporal\",\"multiplicity\":{\"lowerBound\":1},\"name\":\"employees\",\"type\":\"model::target::_Person\"}]},{\"_type\":\"class\",\"docs\":[],\"milestoning\":\"bitemporal\",\"name\":\"_Person\",\"path\":\"model::target::_Person\",\"properties\":[{\"docs\":[],\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"fullName\",\"type\":\"String\"}]}],\"elements\":[\"model::Animal\",\"model::Firm\",\"model::Firm_Person\",\"model::LegalEntity\",\"model::NotRelevant\",\"model::Person\",\"model::experiment::Animal\",\"model::experiment::Human\",\"model::target::IncType\",\"model::target::_Firm\",\"model::target::_Person\"],\"executables\":[],\"executionContexts\":[{\"compatibleRuntimes\":[\"mapping::ModelToModelRuntime\"],\"datasets\":[],\"defaultRuntime\":\"mapping::ModelToModelRuntime\",\"mapping\":\"mapping::ModelToModelMapping\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[{\"info\":{\"classPath\":\"model::target::_Firm\",\"isRootEntity\":true,\"subClasses\":[]},\"path\":\"model::target::_Firm\",\"properties\":[{\"_type\":\"entity\",\"entityPath\":\"model::target::_Person\",\"name\":\"employees\"},{\"_type\":\"MappedProperty\",\"name\":\"name\"},{\"_type\":\"enum\",\"enumPath\":\"model::target::IncType\",\"name\":\"type\"}]},{\"info\":{\"classPath\":\"model::target::_Person\",\"isRootEntity\":true,\"subClasses\":[]},\"path\":\"model::target::_Person\",\"properties\":[{\"_type\":\"MappedProperty\",\"name\":\"fullName\"}]}],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"dataSpace\",\"defaultExecutionContext\":\"dummyContext\",\"elements\":[{\"path\":\"model\"}],\"executionContexts\":[{\"defaultRuntime\":{\"path\":\"mapping::ModelToModelRuntime\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"mapping::ModelToModelMapping\",\"type\":\"MAPPING\"},\"name\":\"dummyContext\"}],\"name\":\"_FirmDataSpace\",\"package\":\"dataSpace\",\"stereotypes\":[],\"taggedValues\":[],\"title\":\"Firm Dataspace\"},{\"_type\":\"class\",\"constraints\":[],\"name\":\"BiTemporalMilestoning\",\"originalMilestonedProperties\":[],\"package\":\"meta::pure::milestoning\",\"properties\":[],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[],\"taggedValues\":[]},{\"_type\":\"profile\",\"name\":\"temporal\",\"package\":\"meta::pure::profiles\",\"stereotypes\":[\"bitemporal\",\"businesstemporal\",\"processingtemporal\"],\"tags\":[]},{\"_type\":\"Enumeration\",\"name\":\"IncType\",\"package\":\"model::target\",\"stereotypes\":[],\"taggedValues\":[],\"values\":[{\"stereotypes\":[],\"taggedValues\":[],\"value\":\"LLC\"},{\"stereotypes\":[],\"taggedValues\":[],\"value\":\"CORP\"}]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"_Firm\",\"originalMilestonedProperties\":[{\"multiplicity\":{\"lowerBound\":1},\"name\":\"employees\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::target::_Person\"}],\"package\":\"model::target\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"type\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::target::IncType\"},{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"name\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"},{\"multiplicity\":{\"lowerBound\":1},\"name\":\"employees\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"model::target::_Person\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[\"meta::pure::metamodel::type::Any\"],\"taggedValues\":[]},{\"_type\":\"class\",\"constraints\":[],\"name\":\"_Person\",\"originalMilestonedProperties\":[],\"package\":\"model::target\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"fullName\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"}],\"qualifiedProperties\":[],\"stereotypes\":[{\"profile\":\"meta::pure::profiles::temporal\",\"value\":\"bitemporal\"}],\"superTypes\":[\"meta::pure::metamodel::type::Any\"],\"taggedValues\":[]}]}},\"name\":\"dummyContext\"}],\"model\":{\"_type\":\"data\",\"elements\":[]},\"name\":\"_FirmDataSpace\",\"package\":\"dataSpace\",\"path\":\"dataSpace::_FirmDataSpace\",\"stereotypes\":[],\"taggedValues\":[],\"title\":\"Firm Dataspace\"}"); } @Test public void testAnalyticsForDataSpaceWithExecutables() throws Exception { - testDataSpaceAnalyticsArtifactGenerationExtension("models/dataSpaceWithExecutables.pure", "domain::COVIDDataspace", "{\"defaultExecutionContext\":\"dummyContext\",\"description\":\"# Peleus rupit\\n\\n## Sum super gerens paterque\\n\\nLorem markdownum presso, et tamen cogitis, Taenarius lactantia fluxerunt\\nterrita, vota. Tempore flumina ferrumque bella.\\n\\n- Per dixit\\n- Truces tellusque indignata ducem\\n- Cervice venitis cavernis minus\\n\\n## Tum ausus fovebam incursus magis dici extemplo\\n\\nPiscator degenerat desertaque quid scelus tyranni feror ipsa mortis nec silva\\nsparsus neci cum? Est patulas meam decorem, dat demit corpora exuritque Ulixes,\\ngenitore. Captare certa amore pressos, Diamque\\n[traxit](http://istecondar.net/ministropudoris) devorat duritia ecce, capillos\\nfuerint progenitore curva relictas. Iubae pectus et quateret, non vires tibi\\ncacumina figuram Antigonen rursus verti.\\n\\n## Dicta nec Thestiadae tristi exempla sed suoque\\n\\nFlumina quae loricaeque meruique defensae *me terram* tamen attollere totum\\nneque nullos. Quem plus, stratum.\\n\\n## Quaeque si reddite summoque vultu Teleboasque vincere\\n\\nIsmariae me munus umbram. Usum pedem multis quotiensque mirantum Cephenum et\\namori Procne locutum auctor Volturnus pavent virgineas.\\n\\n if (edi + sidebarTooltip < aiffDisk) {\\n drive_key_firewire += bank(searchHardBoot(bus, packet_click));\\n }\\n var adRow = dlc_rootkit(rdramMegabit) - hertzBanner * 2 +\\n memory_adc.horizontal(class_box_rte, disk, lte_grep);\\n if (grayscale) {\\n spool_windows_metal.zif_firewire *= 3;\\n emoticon_mp = user.thunderboltIcqBus.installer_remote(4, searchCable) *\\n kibibyteYoutubeRaster.simm(-3, nosqlCharacter, sip);\\n }\\n var blob = -2;\\n\\n## Est magis interdum in luctus\\n\\nPrimus illa sub bis infregit saepe agrestem Cyllare lumen cultrosque **Cnosia**.\\nSuis est fero durisque satis.\\n\\n- Nos quas est maesta aliquis se unum\\n- Tu ossa Cupido sagitta hanc inflati profuso\\n- Modo est proles pavor\\n- Stillabant pallada invitaque et tantum dictaque in\\n- Generum coegi tum edaci\\n\\nSuo nec cerae me omnem Famemque, passi si auditque ullo, praebita. Gravi annos\\npudore formidabilis erat pectora perpetuo qua oscula cum ad sed Nabataeus\\nRomethiumque deum Erectheus? O Victoria rostro utque terras vitisque classe.\\nTibi [miserrima hirta](http://decentia-qui.net/docta-petentem), eratis saepius\\ntuus.\",\"diagrams\":[],\"elementDocs\":[],\"elements\":[],\"executables\":[{\"description\":\"Some exec description\",\"executable\":\"service::CovidDataMulti\",\"result\":{\"_type\":\"tds\",\"columns\":[{\"name\":\"Cases\",\"relationalType\":\"INTEGER\",\"type\":\"Float\"}]},\"title\":\"Exec 1\"},{\"description\":\"Some more exec description\",\"executable\":\"service::CovidDataSingle\",\"info\":{\"_type\":\"service\",\"datasets\":[{\"_type\":\"relationalDatabaseTable\",\"database\":\"CovidDataStore\",\"name\":\"default.DEMOGRAPHICS\",\"schema\":\"default\",\"table\":\"DEMOGRAPHICS\",\"type\":\"H2\"},{\"_type\":\"relationalDatabaseTable\",\"database\":\"CovidDataStore\",\"name\":\"default.COVID_DATA\",\"schema\":\"default\",\"table\":\"COVID_DATA\",\"type\":\"H2\"}],\"mapping\":\"mapping::CovidDataMapping\",\"pattern\":\"/9566f101-2108-408f-863f-6d7e154dc17b\",\"query\":\"|domain::COVIDData.all()->project(\\n [\\n x: domain::COVIDData[1]|$x.cases\\n ],\\n ['Cases']\\n)\",\"runtime\":\"runtime::H2Runtime\"},\"result\":{\"_type\":\"tds\",\"columns\":[{\"name\":\"Cases\",\"relationalType\":\"INTEGER\",\"type\":\"Float\"}]},\"title\":\"Exec 2\"}],\"executionContexts\":[{\"compatibleRuntimes\":[\"runtime::H2Runtime\"],\"datasets\":[{\"_type\":\"relationalDatabaseTable\",\"database\":\"CovidDataStore\",\"name\":\"default.DEMOGRAPHICS\",\"schema\":\"default\",\"table\":\"DEMOGRAPHICS\",\"type\":\"H2\"},{\"_type\":\"relationalDatabaseTable\",\"database\":\"CovidDataStore\",\"name\":\"default.COVID_DATA\",\"schema\":\"default\",\"table\":\"COVID_DATA\",\"type\":\"H2\"}],\"defaultRuntime\":\"runtime::H2Runtime\",\"mapping\":\"mapping::CovidDataMapping\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[{\"path\":\"domain::COVIDData\",\"properties\":[{\"_type\":\"MappedProperty\",\"name\":\"caseType\"},{\"_type\":\"MappedProperty\",\"name\":\"cases\"},{\"_type\":\"MappedProperty\",\"name\":\"date\"},{\"_type\":\"entity\",\"entityPath\":\"domain::Demographics\",\"name\":\"demographics\"},{\"_type\":\"MappedProperty\",\"name\":\"fips\"},{\"_type\":\"MappedProperty\",\"name\":\"id\"},{\"_type\":\"MappedProperty\",\"name\":\"lastReportedFlag\"}]},{\"path\":\"domain::Demographics\",\"properties\":[{\"_type\":\"MappedProperty\",\"name\":\"fips\"},{\"_type\":\"MappedProperty\",\"name\":\"state\"}]}]},\"name\":\"dummyContext\"}],\"model\":{\"_type\":\"data\",\"elements\":[]},\"name\":\"COVIDDataspace\",\"package\":\"domain\",\"path\":\"domain::COVIDDataspace\",\"stereotypes\":[],\"taggedValues\":[],\"title\":\"COVID Sample Data\"}"); + testDataSpaceAnalyticsArtifactGenerationExtension("models/dataSpaceWithExecutables.pure", "domain::COVIDDataspace", "{\"defaultExecutionContext\":\"dummyContext\",\"description\":\"# Peleus rupit\\n\\n## Sum super gerens paterque\\n\\nLorem markdownum presso, et tamen cogitis, Taenarius lactantia fluxerunt\\nterrita, vota. Tempore flumina ferrumque bella.\\n\\n- Per dixit\\n- Truces tellusque indignata ducem\\n- Cervice venitis cavernis minus\\n\\n## Tum ausus fovebam incursus magis dici extemplo\\n\\nPiscator degenerat desertaque quid scelus tyranni feror ipsa mortis nec silva\\nsparsus neci cum? Est patulas meam decorem, dat demit corpora exuritque Ulixes,\\ngenitore. Captare certa amore pressos, Diamque\\n[traxit](http://istecondar.net/ministropudoris) devorat duritia ecce, capillos\\nfuerint progenitore curva relictas. Iubae pectus et quateret, non vires tibi\\ncacumina figuram Antigonen rursus verti.\\n\\n## Dicta nec Thestiadae tristi exempla sed suoque\\n\\nFlumina quae loricaeque meruique defensae *me terram* tamen attollere totum\\nneque nullos. Quem plus, stratum.\\n\\n## Quaeque si reddite summoque vultu Teleboasque vincere\\n\\nIsmariae me munus umbram. Usum pedem multis quotiensque mirantum Cephenum et\\namori Procne locutum auctor Volturnus pavent virgineas.\\n\\n if (edi + sidebarTooltip < aiffDisk) {\\n drive_key_firewire += bank(searchHardBoot(bus, packet_click));\\n }\\n var adRow = dlc_rootkit(rdramMegabit) - hertzBanner * 2 +\\n memory_adc.horizontal(class_box_rte, disk, lte_grep);\\n if (grayscale) {\\n spool_windows_metal.zif_firewire *= 3;\\n emoticon_mp = user.thunderboltIcqBus.installer_remote(4, searchCable) *\\n kibibyteYoutubeRaster.simm(-3, nosqlCharacter, sip);\\n }\\n var blob = -2;\\n\\n## Est magis interdum in luctus\\n\\nPrimus illa sub bis infregit saepe agrestem Cyllare lumen cultrosque **Cnosia**.\\nSuis est fero durisque satis.\\n\\n- Nos quas est maesta aliquis se unum\\n- Tu ossa Cupido sagitta hanc inflati profuso\\n- Modo est proles pavor\\n- Stillabant pallada invitaque et tantum dictaque in\\n- Generum coegi tum edaci\\n\\nSuo nec cerae me omnem Famemque, passi si auditque ullo, praebita. Gravi annos\\npudore formidabilis erat pectora perpetuo qua oscula cum ad sed Nabataeus\\nRomethiumque deum Erectheus? O Victoria rostro utque terras vitisque classe.\\nTibi [miserrima hirta](http://decentia-qui.net/docta-petentem), eratis saepius\\ntuus.\",\"diagrams\":[],\"elementDocs\":[],\"elements\":[],\"executables\":[{\"description\":\"Some exec description\",\"executable\":\"service::CovidDataMulti\",\"result\":{\"_type\":\"tds\",\"columns\":[{\"name\":\"Cases\",\"relationalType\":\"INTEGER\",\"type\":\"Float\"}]},\"title\":\"Exec 1\"},{\"description\":\"Some more exec description\",\"executable\":\"service::CovidDataSingle\",\"info\":{\"_type\":\"service\",\"datasets\":[{\"_type\":\"relationalDatabaseTable\",\"database\":\"CovidDataStore\",\"name\":\"default.DEMOGRAPHICS\",\"schema\":\"default\",\"table\":\"DEMOGRAPHICS\",\"type\":\"H2\"},{\"_type\":\"relationalDatabaseTable\",\"database\":\"CovidDataStore\",\"name\":\"default.COVID_DATA\",\"schema\":\"default\",\"table\":\"COVID_DATA\",\"type\":\"H2\"}],\"mapping\":\"mapping::CovidDataMapping\",\"pattern\":\"/9566f101-2108-408f-863f-6d7e154dc17b\",\"query\":\"|domain::COVIDData.all()->project(\\n [\\n x: domain::COVIDData[1]|$x.cases\\n ],\\n ['Cases']\\n)\",\"runtime\":\"runtime::H2Runtime\"},\"result\":{\"_type\":\"tds\",\"columns\":[{\"name\":\"Cases\",\"relationalType\":\"INTEGER\",\"type\":\"Float\"}]},\"title\":\"Exec 2\"}],\"executionContexts\":[{\"compatibleRuntimes\":[\"runtime::H2Runtime\"],\"datasets\":[{\"_type\":\"relationalDatabaseTable\",\"database\":\"CovidDataStore\",\"name\":\"default.DEMOGRAPHICS\",\"schema\":\"default\",\"table\":\"DEMOGRAPHICS\",\"type\":\"H2\"},{\"_type\":\"relationalDatabaseTable\",\"database\":\"CovidDataStore\",\"name\":\"default.COVID_DATA\",\"schema\":\"default\",\"table\":\"COVID_DATA\",\"type\":\"H2\"}],\"defaultRuntime\":\"runtime::H2Runtime\",\"mapping\":\"mapping::CovidDataMapping\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[{\"info\":{\"classPath\":\"domain::COVIDData\",\"isRootEntity\":true,\"subClasses\":[]},\"path\":\"domain::COVIDData\",\"properties\":[{\"_type\":\"MappedProperty\",\"name\":\"caseType\"},{\"_type\":\"MappedProperty\",\"name\":\"cases\"},{\"_type\":\"MappedProperty\",\"name\":\"date\"},{\"_type\":\"entity\",\"entityPath\":\"domain::Demographics\",\"name\":\"demographics\"},{\"_type\":\"MappedProperty\",\"name\":\"fips\"},{\"_type\":\"MappedProperty\",\"name\":\"id\"},{\"_type\":\"MappedProperty\",\"name\":\"lastReportedFlag\"}]},{\"info\":{\"classPath\":\"domain::Demographics\",\"isRootEntity\":true,\"subClasses\":[]},\"path\":\"domain::Demographics\",\"properties\":[{\"_type\":\"MappedProperty\",\"name\":\"fips\"},{\"_type\":\"MappedProperty\",\"name\":\"state\"}]}],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"class\",\"constraints\":[],\"name\":\"COVIDData\",\"originalMilestonedProperties\":[],\"package\":\"domain\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"id\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Integer\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"fips\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"date\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"StrictDate\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"caseType\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"cases\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Float\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"lastReportedFlag\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Boolean\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"demographics\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"domain::Demographics\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[\"meta::pure::metamodel::type::Any\"],\"taggedValues\":[{\"tag\":{\"profile\":\"meta::pure::profiles::doc\",\"value\":\"doc\"},\"value\":\"COVID-19 data report consisting of case statistics details and basic information on demographics\"}]},{\"_type\":\"dataSpace\",\"defaultExecutionContext\":\"dummyContext\",\"description\":\"# Peleus rupit\\n\\n## Sum super gerens paterque\\n\\nLorem markdownum presso, et tamen cogitis, Taenarius lactantia fluxerunt\\nterrita, vota. Tempore flumina ferrumque bella.\\n\\n- Per dixit\\n- Truces tellusque indignata ducem\\n- Cervice venitis cavernis minus\\n\\n## Tum ausus fovebam incursus magis dici extemplo\\n\\nPiscator degenerat desertaque quid scelus tyranni feror ipsa mortis nec silva\\nsparsus neci cum? Est patulas meam decorem, dat demit corpora exuritque Ulixes,\\ngenitore. Captare certa amore pressos, Diamque\\n[traxit](http://istecondar.net/ministropudoris) devorat duritia ecce, capillos\\nfuerint progenitore curva relictas. Iubae pectus et quateret, non vires tibi\\ncacumina figuram Antigonen rursus verti.\\n\\n## Dicta nec Thestiadae tristi exempla sed suoque\\n\\nFlumina quae loricaeque meruique defensae *me terram* tamen attollere totum\\nneque nullos. Quem plus, stratum.\\n\\n## Quaeque si reddite summoque vultu Teleboasque vincere\\n\\nIsmariae me munus umbram. Usum pedem multis quotiensque mirantum Cephenum et\\namori Procne locutum auctor Volturnus pavent virgineas.\\n\\n if (edi + sidebarTooltip < aiffDisk) {\\n drive_key_firewire += bank(searchHardBoot(bus, packet_click));\\n }\\n var adRow = dlc_rootkit(rdramMegabit) - hertzBanner * 2 +\\n memory_adc.horizontal(class_box_rte, disk, lte_grep);\\n if (grayscale) {\\n spool_windows_metal.zif_firewire *= 3;\\n emoticon_mp = user.thunderboltIcqBus.installer_remote(4, searchCable) *\\n kibibyteYoutubeRaster.simm(-3, nosqlCharacter, sip);\\n }\\n var blob = -2;\\n\\n## Est magis interdum in luctus\\n\\nPrimus illa sub bis infregit saepe agrestem Cyllare lumen cultrosque **Cnosia**.\\nSuis est fero durisque satis.\\n\\n- Nos quas est maesta aliquis se unum\\n- Tu ossa Cupido sagitta hanc inflati profuso\\n- Modo est proles pavor\\n- Stillabant pallada invitaque et tantum dictaque in\\n- Generum coegi tum edaci\\n\\nSuo nec cerae me omnem Famemque, passi si auditque ullo, praebita. Gravi annos\\npudore formidabilis erat pectora perpetuo qua oscula cum ad sed Nabataeus\\nRomethiumque deum Erectheus? O Victoria rostro utque terras vitisque classe.\\nTibi [miserrima hirta](http://decentia-qui.net/docta-petentem), eratis saepius\\ntuus.\",\"executables\":[{\"description\":\"Some exec description\",\"executable\":{\"path\":\"service::CovidDataMulti\"},\"title\":\"Exec 1\"},{\"description\":\"Some more exec description\",\"executable\":{\"path\":\"service::CovidDataSingle\"},\"title\":\"Exec 2\"}],\"executionContexts\":[{\"defaultRuntime\":{\"path\":\"runtime::H2Runtime\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"mapping::CovidDataMapping\",\"type\":\"MAPPING\"},\"name\":\"dummyContext\"}],\"name\":\"COVIDDataspace\",\"package\":\"domain\",\"stereotypes\":[],\"taggedValues\":[],\"title\":\"COVID Sample Data\"},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Demographics\",\"originalMilestonedProperties\":[],\"package\":\"domain\",\"properties\":[{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"fips\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"state\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[\"meta::pure::metamodel::type::Any\"],\"taggedValues\":[{\"tag\":{\"profile\":\"meta::pure::profiles::doc\",\"value\":\"doc\"},\"value\":\"COVID-19 data demographics consisting of geolocation information\"}]},{\"_type\":\"profile\",\"name\":\"doc\",\"package\":\"meta::pure::profiles\",\"stereotypes\":[\"deprecated\"],\"tags\":[\"doc\",\"todo\"]}]}},\"name\":\"dummyContext\"}],\"model\":{\"_type\":\"data\",\"elements\":[]},\"name\":\"COVIDDataspace\",\"package\":\"domain\",\"path\":\"domain::COVIDDataspace\",\"stereotypes\":[],\"taggedValues\":[],\"title\":\"COVID Sample Data\"}"); } @Test public void testAnalyticsForDataSpaceWithAccessEntitlementsToH2() throws Exception { - testDataSpaceAnalyticsArtifactGenerationExtension("models/dataspaceAccessAnalytics.pure", "domain::COVIDDataspace", "{\"defaultExecutionContext\":\"dummyContext\",\"description\":\"# Peleus rupit\\n\\n## Sum super gerens paterque\\n\\nLorem markdownum presso, et tamen cogitis, Taenarius lactantia fluxerunt\\nterrita, vota. Tempore flumina ferrumque bella.\\n\\n- Per dixit\\n- Truces tellusque indignata ducem\\n- Cervice venitis cavernis minus\\n\\n## Tum ausus fovebam incursus magis dici extemplo\\n\\nPiscator degenerat desertaque quid scelus tyranni feror ipsa mortis nec silva\\nsparsus neci cum? Est patulas meam decorem, dat demit corpora exuritque Ulixes,\\ngenitore. Captare certa amore pressos, Diamque\\n[traxit](http://istecondar.net/ministropudoris) devorat duritia ecce, capillos\\nfuerint progenitore curva relictas. Iubae pectus et quateret, non vires tibi\\ncacumina figuram Antigonen rursus verti.\\n\\n## Dicta nec Thestiadae tristi exempla sed suoque\\n\\nFlumina quae loricaeque meruique defensae *me terram* tamen attollere totum\\nneque nullos. Quem plus, stratum.\\n\\n## Quaeque si reddite summoque vultu Teleboasque vincere\\n\\nIsmariae me munus umbram. Usum pedem multis quotiensque mirantum Cephenum et\\namori Procne locutum auctor Volturnus pavent virgineas.\\n\\n if (edi + sidebarTooltip < aiffDisk) {\\n drive_key_firewire += bank(searchHardBoot(bus, packet_click));\\n }\\n var adRow = dlc_rootkit(rdramMegabit) - hertzBanner * 2 +\\n memory_adc.horizontal(class_box_rte, disk, lte_grep);\\n if (grayscale) {\\n spool_windows_metal.zif_firewire *= 3;\\n emoticon_mp = user.thunderboltIcqBus.installer_remote(4, searchCable) *\\n kibibyteYoutubeRaster.simm(-3, nosqlCharacter, sip);\\n }\\n var blob = -2;\\n\\n## Est magis interdum in luctus\\n\\nPrimus illa sub bis infregit saepe agrestem Cyllare lumen cultrosque **Cnosia**.\\nSuis est fero durisque satis.\\n\\n- Nos quas est maesta aliquis se unum\\n- Tu ossa Cupido sagitta hanc inflati profuso\\n- Modo est proles pavor\\n- Stillabant pallada invitaque et tantum dictaque in\\n- Generum coegi tum edaci\\n\\nSuo nec cerae me omnem Famemque, passi si auditque ullo, praebita. Gravi annos\\npudore formidabilis erat pectora perpetuo qua oscula cum ad sed Nabataeus\\nRomethiumque deum Erectheus? O Victoria rostro utque terras vitisque classe.\\nTibi [miserrima hirta](http://decentia-qui.net/docta-petentem), eratis saepius\\ntuus.\",\"diagrams\":[],\"elementDocs\":[],\"elements\":[],\"executables\":[{\"description\":\"Some exec description\",\"executable\":\"service::CovidDataMulti\",\"result\":{\"_type\":\"tds\",\"columns\":[{\"name\":\"Cases\",\"relationalType\":\"INTEGER\",\"type\":\"Float\"}]},\"title\":\"Exec 1\"},{\"description\":\"Some more exec description\",\"executable\":\"service::CovidDataSingle\",\"info\":{\"_type\":\"service\",\"datasets\":[{\"_type\":\"relationalDatabaseTable\",\"database\":\"CovidDataStore\",\"name\":\"default.DEMOGRAPHICS\",\"schema\":\"default\",\"table\":\"DEMOGRAPHICS\",\"type\":\"H2\"},{\"_type\":\"relationalDatabaseTable\",\"database\":\"CovidDataStore\",\"name\":\"default.COVID_DATA\",\"schema\":\"default\",\"table\":\"COVID_DATA\",\"type\":\"H2\"}],\"mapping\":\"mapping::CovidDataMapping\",\"pattern\":\"/9566f101-2108-408f-863f-6d7e154dc17b\",\"query\":\"|domain::COVIDData.all()->project(\\n [\\n x: domain::COVIDData[1]|$x.cases\\n ],\\n ['Cases']\\n)\",\"runtime\":\"runtime::H2Runtime\"},\"result\":{\"_type\":\"tds\",\"columns\":[{\"name\":\"Cases\",\"relationalType\":\"INTEGER\",\"type\":\"Float\"}]},\"title\":\"Exec 2\"}],\"executionContexts\":[{\"compatibleRuntimes\":[\"runtime::H2Runtime\",\"runtime::SnowflakeRuntime\"],\"datasets\":[{\"_type\":\"relationalDatabaseTable\",\"database\":\"CovidDataStore\",\"name\":\"default.DEMOGRAPHICS\",\"schema\":\"default\",\"table\":\"DEMOGRAPHICS\",\"type\":\"H2\"},{\"_type\":\"relationalDatabaseTable\",\"database\":\"CovidDataStore\",\"name\":\"default.COVID_DATA\",\"schema\":\"default\",\"table\":\"COVID_DATA\",\"type\":\"H2\"}],\"defaultRuntime\":\"runtime::H2Runtime\",\"mapping\":\"mapping::CovidDataMapping\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[{\"path\":\"domain::COVIDData\",\"properties\":[{\"_type\":\"MappedProperty\",\"name\":\"caseType\"},{\"_type\":\"MappedProperty\",\"name\":\"cases\"},{\"_type\":\"MappedProperty\",\"name\":\"date\"},{\"_type\":\"entity\",\"entityPath\":\"domain::Demographics\",\"name\":\"demographics\"},{\"_type\":\"MappedProperty\",\"name\":\"fips\"},{\"_type\":\"MappedProperty\",\"name\":\"id\"},{\"_type\":\"MappedProperty\",\"name\":\"lastReportedFlag\"}]},{\"path\":\"domain::Demographics\",\"properties\":[{\"_type\":\"MappedProperty\",\"name\":\"fips\"},{\"_type\":\"MappedProperty\",\"name\":\"state\"}]}]},\"name\":\"dummyContext\"}],\"model\":{\"_type\":\"data\",\"elements\":[]},\"name\":\"COVIDDataspace\",\"package\":\"domain\",\"path\":\"domain::COVIDDataspace\",\"stereotypes\":[],\"taggedValues\":[],\"title\":\"COVID Sample Data\"}"); + testDataSpaceAnalyticsArtifactGenerationExtension("models/dataspaceAccessAnalytics.pure", "domain::COVIDDataspace", "{\"defaultExecutionContext\":\"dummyContext\",\"description\":\"# Peleus rupit\\n\\n## Sum super gerens paterque\\n\\nLorem markdownum presso, et tamen cogitis, Taenarius lactantia fluxerunt\\nterrita, vota. Tempore flumina ferrumque bella.\\n\\n- Per dixit\\n- Truces tellusque indignata ducem\\n- Cervice venitis cavernis minus\\n\\n## Tum ausus fovebam incursus magis dici extemplo\\n\\nPiscator degenerat desertaque quid scelus tyranni feror ipsa mortis nec silva\\nsparsus neci cum? Est patulas meam decorem, dat demit corpora exuritque Ulixes,\\ngenitore. Captare certa amore pressos, Diamque\\n[traxit](http://istecondar.net/ministropudoris) devorat duritia ecce, capillos\\nfuerint progenitore curva relictas. Iubae pectus et quateret, non vires tibi\\ncacumina figuram Antigonen rursus verti.\\n\\n## Dicta nec Thestiadae tristi exempla sed suoque\\n\\nFlumina quae loricaeque meruique defensae *me terram* tamen attollere totum\\nneque nullos. Quem plus, stratum.\\n\\n## Quaeque si reddite summoque vultu Teleboasque vincere\\n\\nIsmariae me munus umbram. Usum pedem multis quotiensque mirantum Cephenum et\\namori Procne locutum auctor Volturnus pavent virgineas.\\n\\n if (edi + sidebarTooltip < aiffDisk) {\\n drive_key_firewire += bank(searchHardBoot(bus, packet_click));\\n }\\n var adRow = dlc_rootkit(rdramMegabit) - hertzBanner * 2 +\\n memory_adc.horizontal(class_box_rte, disk, lte_grep);\\n if (grayscale) {\\n spool_windows_metal.zif_firewire *= 3;\\n emoticon_mp = user.thunderboltIcqBus.installer_remote(4, searchCable) *\\n kibibyteYoutubeRaster.simm(-3, nosqlCharacter, sip);\\n }\\n var blob = -2;\\n\\n## Est magis interdum in luctus\\n\\nPrimus illa sub bis infregit saepe agrestem Cyllare lumen cultrosque **Cnosia**.\\nSuis est fero durisque satis.\\n\\n- Nos quas est maesta aliquis se unum\\n- Tu ossa Cupido sagitta hanc inflati profuso\\n- Modo est proles pavor\\n- Stillabant pallada invitaque et tantum dictaque in\\n- Generum coegi tum edaci\\n\\nSuo nec cerae me omnem Famemque, passi si auditque ullo, praebita. Gravi annos\\npudore formidabilis erat pectora perpetuo qua oscula cum ad sed Nabataeus\\nRomethiumque deum Erectheus? O Victoria rostro utque terras vitisque classe.\\nTibi [miserrima hirta](http://decentia-qui.net/docta-petentem), eratis saepius\\ntuus.\",\"diagrams\":[],\"elementDocs\":[],\"elements\":[],\"executables\":[{\"description\":\"Some exec description\",\"executable\":\"service::CovidDataMulti\",\"result\":{\"_type\":\"tds\",\"columns\":[{\"name\":\"Cases\",\"relationalType\":\"INTEGER\",\"type\":\"Float\"}]},\"title\":\"Exec 1\"},{\"description\":\"Some more exec description\",\"executable\":\"service::CovidDataSingle\",\"info\":{\"_type\":\"service\",\"datasets\":[{\"_type\":\"relationalDatabaseTable\",\"database\":\"CovidDataStore\",\"name\":\"default.DEMOGRAPHICS\",\"schema\":\"default\",\"table\":\"DEMOGRAPHICS\",\"type\":\"H2\"},{\"_type\":\"relationalDatabaseTable\",\"database\":\"CovidDataStore\",\"name\":\"default.COVID_DATA\",\"schema\":\"default\",\"table\":\"COVID_DATA\",\"type\":\"H2\"}],\"mapping\":\"mapping::CovidDataMapping\",\"pattern\":\"/9566f101-2108-408f-863f-6d7e154dc17b\",\"query\":\"|domain::COVIDData.all()->project(\\n [\\n x: domain::COVIDData[1]|$x.cases\\n ],\\n ['Cases']\\n)\",\"runtime\":\"runtime::H2Runtime\"},\"result\":{\"_type\":\"tds\",\"columns\":[{\"name\":\"Cases\",\"relationalType\":\"INTEGER\",\"type\":\"Float\"}]},\"title\":\"Exec 2\"}],\"executionContexts\":[{\"compatibleRuntimes\":[\"runtime::H2Runtime\",\"runtime::SnowflakeRuntime\"],\"datasets\":[{\"_type\":\"relationalDatabaseTable\",\"database\":\"CovidDataStore\",\"name\":\"default.DEMOGRAPHICS\",\"schema\":\"default\",\"table\":\"DEMOGRAPHICS\",\"type\":\"H2\"},{\"_type\":\"relationalDatabaseTable\",\"database\":\"CovidDataStore\",\"name\":\"default.COVID_DATA\",\"schema\":\"default\",\"table\":\"COVID_DATA\",\"type\":\"H2\"}],\"defaultRuntime\":\"runtime::H2Runtime\",\"mapping\":\"mapping::CovidDataMapping\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[{\"info\":{\"classPath\":\"domain::COVIDData\",\"isRootEntity\":true,\"subClasses\":[]},\"path\":\"domain::COVIDData\",\"properties\":[{\"_type\":\"MappedProperty\",\"name\":\"caseType\"},{\"_type\":\"MappedProperty\",\"name\":\"cases\"},{\"_type\":\"MappedProperty\",\"name\":\"date\"},{\"_type\":\"entity\",\"entityPath\":\"domain::Demographics\",\"name\":\"demographics\"},{\"_type\":\"MappedProperty\",\"name\":\"fips\"},{\"_type\":\"MappedProperty\",\"name\":\"id\"},{\"_type\":\"MappedProperty\",\"name\":\"lastReportedFlag\"}]},{\"info\":{\"classPath\":\"domain::Demographics\",\"isRootEntity\":true,\"subClasses\":[]},\"path\":\"domain::Demographics\",\"properties\":[{\"_type\":\"MappedProperty\",\"name\":\"fips\"},{\"_type\":\"MappedProperty\",\"name\":\"state\"}]}],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"class\",\"constraints\":[],\"name\":\"COVIDData\",\"originalMilestonedProperties\":[],\"package\":\"domain\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"id\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Integer\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"fips\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"date\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"StrictDate\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"caseType\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"cases\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Float\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"lastReportedFlag\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Boolean\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"demographics\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"domain::Demographics\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[\"meta::pure::metamodel::type::Any\"],\"taggedValues\":[{\"tag\":{\"profile\":\"meta::pure::profiles::doc\",\"value\":\"doc\"},\"value\":\"COVID-19 data report consisting of case statistics details and basic information on demographics\"}]},{\"_type\":\"dataSpace\",\"defaultExecutionContext\":\"dummyContext\",\"description\":\"# Peleus rupit\\n\\n## Sum super gerens paterque\\n\\nLorem markdownum presso, et tamen cogitis, Taenarius lactantia fluxerunt\\nterrita, vota. Tempore flumina ferrumque bella.\\n\\n- Per dixit\\n- Truces tellusque indignata ducem\\n- Cervice venitis cavernis minus\\n\\n## Tum ausus fovebam incursus magis dici extemplo\\n\\nPiscator degenerat desertaque quid scelus tyranni feror ipsa mortis nec silva\\nsparsus neci cum? Est patulas meam decorem, dat demit corpora exuritque Ulixes,\\ngenitore. Captare certa amore pressos, Diamque\\n[traxit](http://istecondar.net/ministropudoris) devorat duritia ecce, capillos\\nfuerint progenitore curva relictas. Iubae pectus et quateret, non vires tibi\\ncacumina figuram Antigonen rursus verti.\\n\\n## Dicta nec Thestiadae tristi exempla sed suoque\\n\\nFlumina quae loricaeque meruique defensae *me terram* tamen attollere totum\\nneque nullos. Quem plus, stratum.\\n\\n## Quaeque si reddite summoque vultu Teleboasque vincere\\n\\nIsmariae me munus umbram. Usum pedem multis quotiensque mirantum Cephenum et\\namori Procne locutum auctor Volturnus pavent virgineas.\\n\\n if (edi + sidebarTooltip < aiffDisk) {\\n drive_key_firewire += bank(searchHardBoot(bus, packet_click));\\n }\\n var adRow = dlc_rootkit(rdramMegabit) - hertzBanner * 2 +\\n memory_adc.horizontal(class_box_rte, disk, lte_grep);\\n if (grayscale) {\\n spool_windows_metal.zif_firewire *= 3;\\n emoticon_mp = user.thunderboltIcqBus.installer_remote(4, searchCable) *\\n kibibyteYoutubeRaster.simm(-3, nosqlCharacter, sip);\\n }\\n var blob = -2;\\n\\n## Est magis interdum in luctus\\n\\nPrimus illa sub bis infregit saepe agrestem Cyllare lumen cultrosque **Cnosia**.\\nSuis est fero durisque satis.\\n\\n- Nos quas est maesta aliquis se unum\\n- Tu ossa Cupido sagitta hanc inflati profuso\\n- Modo est proles pavor\\n- Stillabant pallada invitaque et tantum dictaque in\\n- Generum coegi tum edaci\\n\\nSuo nec cerae me omnem Famemque, passi si auditque ullo, praebita. Gravi annos\\npudore formidabilis erat pectora perpetuo qua oscula cum ad sed Nabataeus\\nRomethiumque deum Erectheus? O Victoria rostro utque terras vitisque classe.\\nTibi [miserrima hirta](http://decentia-qui.net/docta-petentem), eratis saepius\\ntuus.\",\"executables\":[{\"description\":\"Some exec description\",\"executable\":{\"path\":\"service::CovidDataMulti\"},\"title\":\"Exec 1\"},{\"description\":\"Some more exec description\",\"executable\":{\"path\":\"service::CovidDataSingle\"},\"title\":\"Exec 2\"}],\"executionContexts\":[{\"defaultRuntime\":{\"path\":\"runtime::H2Runtime\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"mapping::CovidDataMapping\",\"type\":\"MAPPING\"},\"name\":\"dummyContext\"}],\"name\":\"COVIDDataspace\",\"package\":\"domain\",\"stereotypes\":[],\"taggedValues\":[],\"title\":\"COVID Sample Data\"},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Demographics\",\"originalMilestonedProperties\":[],\"package\":\"domain\",\"properties\":[{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"fips\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"state\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[\"meta::pure::metamodel::type::Any\"],\"taggedValues\":[{\"tag\":{\"profile\":\"meta::pure::profiles::doc\",\"value\":\"doc\"},\"value\":\"COVID-19 data demographics consisting of geolocation information\"}]},{\"_type\":\"profile\",\"name\":\"doc\",\"package\":\"meta::pure::profiles\",\"stereotypes\":[\"deprecated\"],\"tags\":[\"doc\",\"todo\"]}]}},\"name\":\"dummyContext\"}],\"model\":{\"_type\":\"data\",\"elements\":[]},\"name\":\"COVIDDataspace\",\"package\":\"domain\",\"path\":\"domain::COVIDDataspace\",\"stereotypes\":[],\"taggedValues\":[],\"title\":\"COVID Sample Data\"}"); } @Test public void testAnalyticsForDataSpaceWithAccessEntitlementsToSnowflake() throws Exception { - testDataSpaceAnalyticsArtifactGenerationExtension("models/dataspaceAccessAnalytics.pure", "domain::COVIDDataspaceSnowflake", "{\"defaultExecutionContext\":\"dummyContext\",\"description\":\"# Peleus rupit\\n\\n## Sum super gerens paterque\\n\\nLorem markdownum presso, et tamen cogitis, Taenarius lactantia fluxerunt\\nterrita, vota. Tempore flumina ferrumque bella.\\n\\n- Per dixit\\n- Truces tellusque indignata ducem\\n- Cervice venitis cavernis minus\\n\\n## Tum ausus fovebam incursus magis dici extemplo\\n\\nPiscator degenerat desertaque quid scelus tyranni feror ipsa mortis nec silva\\nsparsus neci cum? Est patulas meam decorem, dat demit corpora exuritque Ulixes,\\ngenitore. Captare certa amore pressos, Diamque\\n[traxit](http://istecondar.net/ministropudoris) devorat duritia ecce, capillos\\nfuerint progenitore curva relictas. Iubae pectus et quateret, non vires tibi\\ncacumina figuram Antigonen rursus verti.\\n\\n## Dicta nec Thestiadae tristi exempla sed suoque\\n\\nFlumina quae loricaeque meruique defensae *me terram* tamen attollere totum\\nneque nullos. Quem plus, stratum.\\n\\n## Quaeque si reddite summoque vultu Teleboasque vincere\\n\\nIsmariae me munus umbram. Usum pedem multis quotiensque mirantum Cephenum et\\namori Procne locutum auctor Volturnus pavent virgineas.\\n\\n if (edi + sidebarTooltip < aiffDisk) {\\n drive_key_firewire += bank(searchHardBoot(bus, packet_click));\\n }\\n var adRow = dlc_rootkit(rdramMegabit) - hertzBanner * 2 +\\n memory_adc.horizontal(class_box_rte, disk, lte_grep);\\n if (grayscale) {\\n spool_windows_metal.zif_firewire *= 3;\\n emoticon_mp = user.thunderboltIcqBus.installer_remote(4, searchCable) *\\n kibibyteYoutubeRaster.simm(-3, nosqlCharacter, sip);\\n }\\n var blob = -2;\\n\\n## Est magis interdum in luctus\\n\\nPrimus illa sub bis infregit saepe agrestem Cyllare lumen cultrosque **Cnosia**.\\nSuis est fero durisque satis.\\n\\n- Nos quas est maesta aliquis se unum\\n- Tu ossa Cupido sagitta hanc inflati profuso\\n- Modo est proles pavor\\n- Stillabant pallada invitaque et tantum dictaque in\\n- Generum coegi tum edaci\\n\\nSuo nec cerae me omnem Famemque, passi si auditque ullo, praebita. Gravi annos\\npudore formidabilis erat pectora perpetuo qua oscula cum ad sed Nabataeus\\nRomethiumque deum Erectheus? O Victoria rostro utque terras vitisque classe.\\nTibi [miserrima hirta](http://decentia-qui.net/docta-petentem), eratis saepius\\ntuus.\",\"diagrams\":[],\"elementDocs\":[],\"elements\":[],\"executables\":[{\"description\":\"Some exec description\",\"executable\":\"service::CovidDataMulti\",\"result\":{\"_type\":\"tds\",\"columns\":[{\"name\":\"Cases\",\"relationalType\":\"INTEGER\",\"type\":\"Float\"}]},\"title\":\"Exec 1\"},{\"description\":\"Some more exec description\",\"executable\":\"service::CovidDataSingle\",\"info\":{\"_type\":\"service\",\"datasets\":[{\"_type\":\"relationalDatabaseTable\",\"database\":\"CovidDataStore\",\"name\":\"default.DEMOGRAPHICS\",\"schema\":\"default\",\"table\":\"DEMOGRAPHICS\",\"type\":\"H2\"},{\"_type\":\"relationalDatabaseTable\",\"database\":\"CovidDataStore\",\"name\":\"default.COVID_DATA\",\"schema\":\"default\",\"table\":\"COVID_DATA\",\"type\":\"H2\"}],\"mapping\":\"mapping::CovidDataMapping\",\"pattern\":\"/9566f101-2108-408f-863f-6d7e154dc17b\",\"query\":\"|domain::COVIDData.all()->project(\\n [\\n x: domain::COVIDData[1]|$x.cases\\n ],\\n ['Cases']\\n)\",\"runtime\":\"runtime::H2Runtime\"},\"result\":{\"_type\":\"tds\",\"columns\":[{\"name\":\"Cases\",\"relationalType\":\"INTEGER\",\"type\":\"Float\"}]},\"title\":\"Exec 2\"}],\"executionContexts\":[{\"compatibleRuntimes\":[\"runtime::H2Runtime\",\"runtime::SnowflakeRuntime\"],\"datasets\":[{\"_type\":\"relationalDatabaseTable\",\"database\":\"CovidDataStore\",\"name\":\"default.DEMOGRAPHICS\",\"schema\":\"default\",\"table\":\"DEMOGRAPHICS\",\"type\":\"Snowflake\"},{\"_type\":\"relationalDatabaseTable\",\"database\":\"CovidDataStore\",\"name\":\"default.COVID_DATA\",\"schema\":\"default\",\"table\":\"COVID_DATA\",\"type\":\"Snowflake\"}],\"defaultRuntime\":\"runtime::SnowflakeRuntime\",\"mapping\":\"mapping::CovidDataMapping\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[{\"path\":\"domain::COVIDData\",\"properties\":[{\"_type\":\"MappedProperty\",\"name\":\"caseType\"},{\"_type\":\"MappedProperty\",\"name\":\"cases\"},{\"_type\":\"MappedProperty\",\"name\":\"date\"},{\"_type\":\"entity\",\"entityPath\":\"domain::Demographics\",\"name\":\"demographics\"},{\"_type\":\"MappedProperty\",\"name\":\"fips\"},{\"_type\":\"MappedProperty\",\"name\":\"id\"},{\"_type\":\"MappedProperty\",\"name\":\"lastReportedFlag\"}]},{\"path\":\"domain::Demographics\",\"properties\":[{\"_type\":\"MappedProperty\",\"name\":\"fips\"},{\"_type\":\"MappedProperty\",\"name\":\"state\"}]}]},\"name\":\"dummyContext\"}],\"model\":{\"_type\":\"data\",\"elements\":[]},\"name\":\"COVIDDataspaceSnowflake\",\"package\":\"domain\",\"path\":\"domain::COVIDDataspaceSnowflake\",\"stereotypes\":[],\"taggedValues\":[],\"title\":\"COVID Sample Data\"}"); + testDataSpaceAnalyticsArtifactGenerationExtension("models/dataspaceAccessAnalytics.pure", "domain::COVIDDataspaceSnowflake", "{\"defaultExecutionContext\":\"dummyContext\",\"description\":\"# Peleus rupit\\n\\n## Sum super gerens paterque\\n\\nLorem markdownum presso, et tamen cogitis, Taenarius lactantia fluxerunt\\nterrita, vota. Tempore flumina ferrumque bella.\\n\\n- Per dixit\\n- Truces tellusque indignata ducem\\n- Cervice venitis cavernis minus\\n\\n## Tum ausus fovebam incursus magis dici extemplo\\n\\nPiscator degenerat desertaque quid scelus tyranni feror ipsa mortis nec silva\\nsparsus neci cum? Est patulas meam decorem, dat demit corpora exuritque Ulixes,\\ngenitore. Captare certa amore pressos, Diamque\\n[traxit](http://istecondar.net/ministropudoris) devorat duritia ecce, capillos\\nfuerint progenitore curva relictas. Iubae pectus et quateret, non vires tibi\\ncacumina figuram Antigonen rursus verti.\\n\\n## Dicta nec Thestiadae tristi exempla sed suoque\\n\\nFlumina quae loricaeque meruique defensae *me terram* tamen attollere totum\\nneque nullos. Quem plus, stratum.\\n\\n## Quaeque si reddite summoque vultu Teleboasque vincere\\n\\nIsmariae me munus umbram. Usum pedem multis quotiensque mirantum Cephenum et\\namori Procne locutum auctor Volturnus pavent virgineas.\\n\\n if (edi + sidebarTooltip < aiffDisk) {\\n drive_key_firewire += bank(searchHardBoot(bus, packet_click));\\n }\\n var adRow = dlc_rootkit(rdramMegabit) - hertzBanner * 2 +\\n memory_adc.horizontal(class_box_rte, disk, lte_grep);\\n if (grayscale) {\\n spool_windows_metal.zif_firewire *= 3;\\n emoticon_mp = user.thunderboltIcqBus.installer_remote(4, searchCable) *\\n kibibyteYoutubeRaster.simm(-3, nosqlCharacter, sip);\\n }\\n var blob = -2;\\n\\n## Est magis interdum in luctus\\n\\nPrimus illa sub bis infregit saepe agrestem Cyllare lumen cultrosque **Cnosia**.\\nSuis est fero durisque satis.\\n\\n- Nos quas est maesta aliquis se unum\\n- Tu ossa Cupido sagitta hanc inflati profuso\\n- Modo est proles pavor\\n- Stillabant pallada invitaque et tantum dictaque in\\n- Generum coegi tum edaci\\n\\nSuo nec cerae me omnem Famemque, passi si auditque ullo, praebita. Gravi annos\\npudore formidabilis erat pectora perpetuo qua oscula cum ad sed Nabataeus\\nRomethiumque deum Erectheus? O Victoria rostro utque terras vitisque classe.\\nTibi [miserrima hirta](http://decentia-qui.net/docta-petentem), eratis saepius\\ntuus.\",\"diagrams\":[],\"elementDocs\":[],\"elements\":[],\"executables\":[{\"description\":\"Some exec description\",\"executable\":\"service::CovidDataMulti\",\"result\":{\"_type\":\"tds\",\"columns\":[{\"name\":\"Cases\",\"relationalType\":\"INTEGER\",\"type\":\"Float\"}]},\"title\":\"Exec 1\"},{\"description\":\"Some more exec description\",\"executable\":\"service::CovidDataSingle\",\"info\":{\"_type\":\"service\",\"datasets\":[{\"_type\":\"relationalDatabaseTable\",\"database\":\"CovidDataStore\",\"name\":\"default.DEMOGRAPHICS\",\"schema\":\"default\",\"table\":\"DEMOGRAPHICS\",\"type\":\"H2\"},{\"_type\":\"relationalDatabaseTable\",\"database\":\"CovidDataStore\",\"name\":\"default.COVID_DATA\",\"schema\":\"default\",\"table\":\"COVID_DATA\",\"type\":\"H2\"}],\"mapping\":\"mapping::CovidDataMapping\",\"pattern\":\"/9566f101-2108-408f-863f-6d7e154dc17b\",\"query\":\"|domain::COVIDData.all()->project(\\n [\\n x: domain::COVIDData[1]|$x.cases\\n ],\\n ['Cases']\\n)\",\"runtime\":\"runtime::H2Runtime\"},\"result\":{\"_type\":\"tds\",\"columns\":[{\"name\":\"Cases\",\"relationalType\":\"INTEGER\",\"type\":\"Float\"}]},\"title\":\"Exec 2\"}],\"executionContexts\":[{\"compatibleRuntimes\":[\"runtime::H2Runtime\",\"runtime::SnowflakeRuntime\"],\"datasets\":[{\"_type\":\"relationalDatabaseTable\",\"database\":\"CovidDataStore\",\"name\":\"default.DEMOGRAPHICS\",\"schema\":\"default\",\"table\":\"DEMOGRAPHICS\",\"type\":\"Snowflake\"},{\"_type\":\"relationalDatabaseTable\",\"database\":\"CovidDataStore\",\"name\":\"default.COVID_DATA\",\"schema\":\"default\",\"table\":\"COVID_DATA\",\"type\":\"Snowflake\"}],\"defaultRuntime\":\"runtime::SnowflakeRuntime\",\"mapping\":\"mapping::CovidDataMapping\",\"mappingModelCoverageAnalysisResult\":{\"mappedEntities\":[{\"info\":{\"classPath\":\"domain::COVIDData\",\"isRootEntity\":true,\"subClasses\":[]},\"path\":\"domain::COVIDData\",\"properties\":[{\"_type\":\"MappedProperty\",\"name\":\"caseType\"},{\"_type\":\"MappedProperty\",\"name\":\"cases\"},{\"_type\":\"MappedProperty\",\"name\":\"date\"},{\"_type\":\"entity\",\"entityPath\":\"domain::Demographics\",\"name\":\"demographics\"},{\"_type\":\"MappedProperty\",\"name\":\"fips\"},{\"_type\":\"MappedProperty\",\"name\":\"id\"},{\"_type\":\"MappedProperty\",\"name\":\"lastReportedFlag\"}]},{\"info\":{\"classPath\":\"domain::Demographics\",\"isRootEntity\":true,\"subClasses\":[]},\"path\":\"domain::Demographics\",\"properties\":[{\"_type\":\"MappedProperty\",\"name\":\"fips\"},{\"_type\":\"MappedProperty\",\"name\":\"state\"}]}],\"model\":{\"_type\":\"data\",\"elements\":[{\"_type\":\"class\",\"constraints\":[],\"name\":\"COVIDData\",\"originalMilestonedProperties\":[],\"package\":\"domain\",\"properties\":[{\"multiplicity\":{\"lowerBound\":1,\"upperBound\":1},\"name\":\"id\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Integer\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"fips\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"date\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"StrictDate\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"caseType\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"cases\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Float\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"lastReportedFlag\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"Boolean\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"demographics\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"domain::Demographics\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[\"meta::pure::metamodel::type::Any\"],\"taggedValues\":[{\"tag\":{\"profile\":\"meta::pure::profiles::doc\",\"value\":\"doc\"},\"value\":\"COVID-19 data report consisting of case statistics details and basic information on demographics\"}]},{\"_type\":\"dataSpace\",\"defaultExecutionContext\":\"dummyContext\",\"description\":\"# Peleus rupit\\n\\n## Sum super gerens paterque\\n\\nLorem markdownum presso, et tamen cogitis, Taenarius lactantia fluxerunt\\nterrita, vota. Tempore flumina ferrumque bella.\\n\\n- Per dixit\\n- Truces tellusque indignata ducem\\n- Cervice venitis cavernis minus\\n\\n## Tum ausus fovebam incursus magis dici extemplo\\n\\nPiscator degenerat desertaque quid scelus tyranni feror ipsa mortis nec silva\\nsparsus neci cum? Est patulas meam decorem, dat demit corpora exuritque Ulixes,\\ngenitore. Captare certa amore pressos, Diamque\\n[traxit](http://istecondar.net/ministropudoris) devorat duritia ecce, capillos\\nfuerint progenitore curva relictas. Iubae pectus et quateret, non vires tibi\\ncacumina figuram Antigonen rursus verti.\\n\\n## Dicta nec Thestiadae tristi exempla sed suoque\\n\\nFlumina quae loricaeque meruique defensae *me terram* tamen attollere totum\\nneque nullos. Quem plus, stratum.\\n\\n## Quaeque si reddite summoque vultu Teleboasque vincere\\n\\nIsmariae me munus umbram. Usum pedem multis quotiensque mirantum Cephenum et\\namori Procne locutum auctor Volturnus pavent virgineas.\\n\\n if (edi + sidebarTooltip < aiffDisk) {\\n drive_key_firewire += bank(searchHardBoot(bus, packet_click));\\n }\\n var adRow = dlc_rootkit(rdramMegabit) - hertzBanner * 2 +\\n memory_adc.horizontal(class_box_rte, disk, lte_grep);\\n if (grayscale) {\\n spool_windows_metal.zif_firewire *= 3;\\n emoticon_mp = user.thunderboltIcqBus.installer_remote(4, searchCable) *\\n kibibyteYoutubeRaster.simm(-3, nosqlCharacter, sip);\\n }\\n var blob = -2;\\n\\n## Est magis interdum in luctus\\n\\nPrimus illa sub bis infregit saepe agrestem Cyllare lumen cultrosque **Cnosia**.\\nSuis est fero durisque satis.\\n\\n- Nos quas est maesta aliquis se unum\\n- Tu ossa Cupido sagitta hanc inflati profuso\\n- Modo est proles pavor\\n- Stillabant pallada invitaque et tantum dictaque in\\n- Generum coegi tum edaci\\n\\nSuo nec cerae me omnem Famemque, passi si auditque ullo, praebita. Gravi annos\\npudore formidabilis erat pectora perpetuo qua oscula cum ad sed Nabataeus\\nRomethiumque deum Erectheus? O Victoria rostro utque terras vitisque classe.\\nTibi [miserrima hirta](http://decentia-qui.net/docta-petentem), eratis saepius\\ntuus.\",\"executables\":[{\"description\":\"Some exec description\",\"executable\":{\"path\":\"service::CovidDataMulti\"},\"title\":\"Exec 1\"},{\"description\":\"Some more exec description\",\"executable\":{\"path\":\"service::CovidDataSingle\"},\"title\":\"Exec 2\"}],\"executionContexts\":[{\"defaultRuntime\":{\"path\":\"runtime::SnowflakeRuntime\",\"type\":\"RUNTIME\"},\"mapping\":{\"path\":\"mapping::CovidDataMapping\",\"type\":\"MAPPING\"},\"name\":\"dummyContext\"}],\"name\":\"COVIDDataspaceSnowflake\",\"package\":\"domain\",\"stereotypes\":[],\"taggedValues\":[],\"title\":\"COVID Sample Data\"},{\"_type\":\"class\",\"constraints\":[],\"name\":\"Demographics\",\"originalMilestonedProperties\":[],\"package\":\"domain\",\"properties\":[{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"fips\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"},{\"multiplicity\":{\"lowerBound\":0,\"upperBound\":1},\"name\":\"state\",\"stereotypes\":[],\"taggedValues\":[],\"type\":\"String\"}],\"qualifiedProperties\":[],\"stereotypes\":[],\"superTypes\":[\"meta::pure::metamodel::type::Any\"],\"taggedValues\":[{\"tag\":{\"profile\":\"meta::pure::profiles::doc\",\"value\":\"doc\"},\"value\":\"COVID-19 data demographics consisting of geolocation information\"}]},{\"_type\":\"profile\",\"name\":\"doc\",\"package\":\"meta::pure::profiles\",\"stereotypes\":[\"deprecated\"],\"tags\":[\"doc\",\"todo\"]}]}},\"name\":\"dummyContext\"}],\"model\":{\"_type\":\"data\",\"elements\":[]},\"name\":\"COVIDDataspaceSnowflake\",\"package\":\"domain\",\"path\":\"domain::COVIDDataspaceSnowflake\",\"stereotypes\":[],\"taggedValues\":[],\"title\":\"COVID Sample Data\"}"); } } diff --git a/legend-engine-xts-data-space/legend-engine-xt-data-space-pure/src/main/resources/core_data_space/analytics/analytics.pure b/legend-engine-xts-data-space/legend-engine-xt-data-space-pure/src/main/resources/core_data_space/analytics/analytics.pure index 7919d07bdb4..b51e37d9a22 100644 --- a/legend-engine-xts-data-space/legend-engine-xt-data-space-pure/src/main/resources/core_data_space/analytics/analytics.pure +++ b/legend-engine-xts-data-space/legend-engine-xt-data-space-pure/src/main/resources/core_data_space/analytics/analytics.pure @@ -26,6 +26,11 @@ Class meta::pure::metamodel::dataSpace::analytics::DataSpaceAnalysisResult elementDocs: DataSpaceModelDocumentationEntry[*]; } +Class meta::pure::metamodel::dataSpace::analytics::DataSpaceCoverageAnalysisResult +{ + executionContexts: DataSpaceExecutionContextAnalysisResult[*]; +} + function meta::pure::metamodel::dataSpace::analytics::analyzeDataSpace(dataSpace: DataSpace[1], allAvailableRuntimes: PackageableRuntime[*]): DataSpaceAnalysisResult[1] { ^DataSpaceAnalysisResult @@ -36,6 +41,14 @@ function meta::pure::metamodel::dataSpace::analytics::analyzeDataSpace(dataSpace ); } +function meta::pure::metamodel::dataSpace::analytics::analyzeDataSpaceCoverage(dataSpace: DataSpace[1], allAvailableRuntimes: PackageableRuntime[*]): DataSpaceCoverageAnalysisResult[1] +{ + ^DataSpaceCoverageAnalysisResult + ( + executionContexts = analyzeDataSpaceExecutionContexts($dataSpace, $allAvailableRuntimes) + ); +} + // ------------------------- Execution Context ---------------------------- @@ -51,7 +64,7 @@ function <> meta::pure::metamodel::dataSpace::analytics::analyze $dataSpace.executionContexts->map(context|^DataSpaceExecutionContextAnalysisResult( name = $context.name, compatibleRuntimes = getMappingCompatibleRuntimes($context.mapping, $allAvailableRuntimes), - mappingCoverage = meta::analytics::mapping::modelCoverage::analyze($context.mapping, false, false) + mappingCoverage = meta::analytics::mapping::modelCoverage::analyze($context.mapping, true, false, true) )); } diff --git a/pom.xml b/pom.xml index eabe0d5ae12..7214f1ea1e2 100644 --- a/pom.xml +++ b/pom.xml @@ -1481,6 +1481,39 @@ ${project.version} + + org.finos.legend.engine + legend-engine-xt-analytics-class-api + ${project.version} + + + org.finos.legend.engine + legend-engine-xt-analytics-class-pure + ${project.version} + + + + org.finos.legend.engine + legend-engine-xt-analytics-function-api + ${project.version} + + + org.finos.legend.engine + legend-engine-xt-analytics-function-pure + ${project.version} + + + + org.finos.legend.engine + legend-engine-xt-analytics-binding-api + ${project.version} + + + org.finos.legend.engine + legend-engine-xt-analytics-binding-pure + ${project.version} + + org.finos.legend.engine legend-engine-xt-analytics-search-pure