Skip to content

Commit

Permalink
minor updates to ArtifactGenerationExtension (#900)
Browse files Browse the repository at this point in the history
  • Loading branch information
MauricioUyaguari authored Sep 10, 2022
1 parent 0e0200c commit 07d20ce
Show file tree
Hide file tree
Showing 7 changed files with 313 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

package org.finos.legend.engine.extensions.collection.generation;

import java.util.Set;
import org.eclipse.collections.api.factory.Lists;
import org.eclipse.collections.api.factory.Sets;
import org.eclipse.collections.api.list.MutableList;
Expand All @@ -25,6 +26,7 @@
import org.finos.legend.engine.language.pure.compiler.toPureGraph.PureModel;
import org.finos.legend.engine.language.pure.compiler.toPureGraph.extension.CompilerExtension;
import org.finos.legend.engine.language.pure.dsl.generation.extension.ArtifactGenerationExtension;
import org.finos.legend.engine.language.pure.dsl.generation.extension.ArtifactGenerationExtensionLoader;
import org.finos.legend.engine.language.pure.grammar.from.DataSpaceParserExtension;
import org.finos.legend.engine.language.pure.grammar.from.DiagramParserExtension;
import org.finos.legend.engine.language.pure.grammar.from.TextParserExtension;
Expand Down Expand Up @@ -93,7 +95,7 @@ public void testExpectedExternalFormatExtensionsArePresent()
@Test
public void testExpectedArtifactGenerationExtensionsArePresent()
{
assertHasExtensions(getExpectedArtifactGenerationExtensions(), ArtifactGenerationExtension.class);
assertHasExtensions(ArtifactGenerationExtensionLoader.extensions(), getExpectedArtifactGenerationExtensions(), ArtifactGenerationExtension.class);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,24 +25,19 @@
*/
public interface ArtifactGenerationExtension
{


/**
* Determines whether the extension can generate artifacts based on the element.
* Gives the key for the extension
*
* @return boolean flag indicating if the extension can generate artifacts
* @return string
*/
boolean canGenerate(PackageableElement element);

String getKey();

/**
* Gets root path where all artifacts will be stored
* Determines whether a packageable element can generate artifacts
*
* @return root path
* @return boolean flag indicating if the extension can generate artifacts
*/

String getArtifactsRootPath();

boolean canGenerate(PackageableElement element);

/**
* Generates artifacts given a packageable element. Methods assumes element can generate
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright 2022 Goldman Sachs
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package org.finos.legend.engine.language.pure.dsl.generation.extension;

import java.util.List;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.stream.Collectors;
import org.eclipse.collections.api.factory.Lists;
import org.eclipse.collections.api.factory.Sets;
import org.eclipse.collections.impl.utility.ListIterate;
import org.finos.legend.engine.shared.core.operational.errorManagement.EngineException;

public class ArtifactGenerationExtensionLoader
{
public static final String EXTENSION_KEY_REGEX = "^[a-zA-Z_\\-]+$";

public static List<ArtifactGenerationExtension> extensions()
{
List<ArtifactGenerationExtension> extensions = Lists.mutable.withAll(ServiceLoader.load(ArtifactGenerationExtension.class));
Set<String> extensionKeys = Sets.mutable.empty();
for (ArtifactGenerationExtension extension : extensions)
{
if (!extensionKeys.add(extension.getKey()))
{
String extensionsWithSameKey = ListIterate.collect(extensions.stream().filter(e -> e.getKey().equals(extension.getKey())).collect(Collectors.toList()), e -> e.getClass().getName())
.makeString(",");
throw new EngineException("Artifact extension keys must be unique. Found duplicate key: '" + extension.getKey() + "' on extensions: " + extensionsWithSameKey);
}
if (!extension.getKey().matches(EXTENSION_KEY_REGEX))
{
throw new EngineException("Artifact extension keys can't have spaces or special characters. Found invalid key: '" + extension.getKey() + "'.");
}
}
return extensions;
}

}
38 changes: 35 additions & 3 deletions legend-engine-xt-data-space-generation/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,14 @@
<name>Legend Engine - XT - Data Space - Generation</name>

<dependencies>
<!-- PURE -->
<!-- ECLIPSE COLLECTIONS -->
<dependency>
<groupId>org.finos.legend.pure</groupId>
<artifactId>legend-pure-runtime-java-engine-compiled</artifactId>
<groupId>org.eclipse.collections</groupId>
<artifactId>eclipse-collections-api</artifactId>
</dependency>
<!-- ECLIPSE COLLECTIONS -->

<!-- PURE -->
<dependency>
<groupId>org.finos.legend.pure</groupId>
<artifactId>legend-pure-m3-core</artifactId>
Expand Down Expand Up @@ -76,5 +79,34 @@
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- JACKSON -->

<!-- TEST -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.finos.legend.engine</groupId>
<artifactId>legend-engine-xt-diagram-grammar</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.finos.legend.engine</groupId>
<artifactId>legend-engine-xt-data-space-grammar</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.finos.legend.engine</groupId>
<artifactId>legend-engine-language-pure-grammar</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.finos.legend.engine</groupId>
<artifactId>legend-engine-language-pure-compiler</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<!-- TEST -->
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@

package org.finos.legend.engine.generation;

import static org.finos.legend.engine.language.pure.compiler.toPureGraph.HelperModelBuilder.getElementFullPath;

import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Collections;
import java.util.List;
import org.finos.legend.engine.analytics.DataSpaceAnalyticsHelper;
import org.finos.legend.engine.analytics.model.DataSpaceAnalysisResult;
import org.finos.legend.engine.language.pure.compiler.toPureGraph.PureModel;
Expand All @@ -24,36 +28,32 @@
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.dataSpace.DataSpace;
import org.finos.legend.engine.shared.core.ObjectMapperFactory;
import org.finos.legend.engine.shared.core.operational.Assert;
import org.finos.legend.engine.shared.core.operational.errorManagement.EngineException;
import org.finos.legend.pure.generated.Root_meta_pure_metamodel_dataSpace_DataSpace;
import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.PackageableElement;

import java.util.Collections;
import java.util.List;

import static org.finos.legend.engine.language.pure.compiler.toPureGraph.HelperModelBuilder.getElementFullPath;
import static org.finos.legend.pure.generated.platform_pure_corefunctions_meta.Root_meta_pure_functions_meta_elementToPath_PackageableElement_1__String_1__String_1_;

public class DataSpaceAnalyticsArtifactGenerationExtension implements ArtifactGenerationExtension
{
public final String ROOT_PATH = "dataSpace-analytics";

public final String ROOT_PATH = "data-space-analytics";
public static ObjectMapper objectMapper = ObjectMapperFactory.getNewStandardObjectMapperWithPureProtocolExtensionSupports();

@Override
public boolean canGenerate(PackageableElement element)
public String getKey()
{
return element instanceof Root_meta_pure_metamodel_dataSpace_DataSpace;
return ROOT_PATH;
}

@Override
public String getArtifactsRootPath()
public boolean canGenerate(PackageableElement element)
{
return ROOT_PATH;
return element instanceof Root_meta_pure_metamodel_dataSpace_DataSpace;
}

@Override
public List<Artifact> generate(PackageableElement element, PureModel pureModel, PureModelContextData data, String clientVersion)
{
String fileName = "AnalyticsResult.json";
String dataSpacePath = getElementFullPath(element, pureModel.getExecutionSupport());
Assert.assertTrue(this.canGenerate(element), () -> "DataSpace analytics only supports dataSpace elements");
Root_meta_pure_metamodel_dataSpace_DataSpace dataSpace = (Root_meta_pure_metamodel_dataSpace_DataSpace) element;
Expand All @@ -63,15 +63,12 @@ public List<Artifact> generate(PackageableElement element, PureModel pureModel,
try
{
String stringResult = objectMapper.writeValueAsString(result);
String filePath = Root_meta_pure_functions_meta_elementToPath_PackageableElement_1__String_1__String_1_(element, "/", pureModel.getExecutionSupport()) + ".json";
Artifact output = new Artifact(stringResult, filePath, "json");
Artifact output = new Artifact(stringResult, fileName, "json");
return Collections.singletonList(output);

}
catch (Exception ignored)
catch (Exception exception)
{
// ignore
throw new EngineException("Can't serialize data space analysis result", exception);
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright 2022 Goldman Sachs
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package org.finos.legend.engine.generation;

import java.net.URL;
import java.util.List;
import java.util.Map;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.eclipse.collections.api.factory.Maps;
import org.finos.legend.engine.analytics.model.DataSpaceAnalysisResult;
import org.finos.legend.engine.language.pure.compiler.Compiler;
import org.finos.legend.engine.language.pure.compiler.toPureGraph.PureModel;
import org.finos.legend.engine.language.pure.dsl.generation.extension.Artifact;
import org.finos.legend.engine.language.pure.grammar.from.PureGrammarParser;
import org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContextData;
import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.dataSpace.DataSpace;
import org.finos.legend.engine.shared.core.ObjectMapperFactory;
import org.finos.legend.engine.shared.core.deployment.DeploymentMode;
import org.finos.legend.engine.shared.core.deployment.DeploymentStateAndVersions;
import org.finos.legend.pure.generated.Root_meta_pure_metamodel_dataSpace_DataSpace;
import org.junit.Assert;
import org.junit.Test;


public class TestDataSpaceAnalyticsArtifactGenerationExtension
{
private static final ObjectMapper objectMapper = ObjectMapperFactory.getNewStandardObjectMapperWithPureProtocolExtensionSupports();

private String getResourceAsString(String path)
{
try
{
URL infoURL = DeploymentStateAndVersions.class.getClassLoader().getResource(path);
if (infoURL != null)
{
java.util.Scanner scanner = new java.util.Scanner(infoURL.openStream()).useDelimiter("\\A");
return scanner.hasNext() ? scanner.next() : null;
}
return null;
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}

@Test
public void testDataSpaceAnalyticsArtifactGenerationExtension() throws Exception
{
String pureModelString = getResourceAsString("models/DataspaceModel.pure");
PureModelContextData pureModelContextData = PureGrammarParser.newInstance().parseModel(pureModelString);
PureModel pureModel = Compiler.compile(pureModelContextData, DeploymentMode.TEST, null);
Map<DataSpace, List<Artifact>> results = Maps.mutable.empty();
DataSpaceAnalyticsArtifactGenerationExtension extension = new DataSpaceAnalyticsArtifactGenerationExtension();
org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.PackageableElement packageableElement = pureModel.getPackageableElement("dataSpace::_FirmDataSpace");
Assert.assertTrue(packageableElement instanceof Root_meta_pure_metamodel_dataSpace_DataSpace);
Root_meta_pure_metamodel_dataSpace_DataSpace metamodelDatasapce = (Root_meta_pure_metamodel_dataSpace_DataSpace) packageableElement;
Assert.assertTrue(extension.canGenerate(metamodelDatasapce));
List<Artifact> outputs = extension.generate(packageableElement, pureModel, pureModelContextData, "vX_X_X");
Assert.assertEquals(1, outputs.size());
Artifact dataSpaceAnalyticsResult = outputs.get(0);
Assert.assertEquals(dataSpaceAnalyticsResult.format, "json");
Assert.assertEquals(dataSpaceAnalyticsResult.path, "AnalyticsResult.json");
Assert.assertNotNull(dataSpaceAnalyticsResult.content);
// assert the result is JSON of data space analysis result
objectMapper.readValue(dataSpaceAnalyticsResult.content, DataSpaceAnalysisResult.class);
}
}
Loading

0 comments on commit 07d20ce

Please sign in to comment.