Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create Aspect Models from AAS submodel template #517

Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
ea8be68
Create Aspect Models from AAS submodel template
Yauhenikapl Jan 29, 2024
b4b6d96
Extend static meta model generation with property accessors
andreas-schilling Jan 25, 2024
3c715f1
Fix import issues
andreas-schilling Jan 26, 2024
2489866
Adjust formatting, imports, usage of final
atextor Jan 29, 2024
56c336b
Move MODEL_WITH_CYCLES to invalid aspect models enum
atextor Jan 24, 2024
3bf6a99
Copy jar files so they are available for Temurin test
atextor Jan 24, 2024
39d2876
Explicitly mark AAS model and impl classes for reflection
atextor Jan 24, 2024
79f9697
Run AAS gen tests for all models in native exec integration test
atextor Jan 24, 2024
3335f7a
Mark reflection configuration feature as hosted only
atextor Jan 24, 2024
7d2a5ec
Silence chatty unhelpful logger
atextor Jan 25, 2024
31c3016
Refactor native-image.properties into features
atextor Jan 25, 2024
e0b371e
Merge branch 'main' into 468-create-aspect-models-from-AAS-submodel-t…
Yauhenikapl Jan 29, 2024
acf1eab
Create Aspect Models from AAS submodel template
Yauhenikapl Feb 5, 2024
9a111a6
Merge branch 'main' into 468-create-aspect-models-from-AAS-submodel-t…
Yauhenikapl Feb 5, 2024
733aba3
Create Aspect Models from AAS submodel template
Yauhenikapl Feb 5, 2024
422865a
Fix tests.
Yauhenikapl Feb 5, 2024
f9d837e
Update description
Yauhenikapl Feb 6, 2024
edc466d
Update docs
Yauhenikapl Feb 6, 2024
453b839
Refactoring
Yauhenikapl Feb 8, 2024
1112a71
Fix build
Yauhenikapl Feb 8, 2024
927fb35
Formatting
Yauhenikapl Feb 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.eclipse.digitaltwin.aas4j.v3.model.Referable;
import org.eclipse.esmf.aspectmodel.VersionNumber;
import org.eclipse.esmf.aspectmodel.urn.AspectModelUrn;
import org.eclipse.esmf.aspectmodel.vocabulary.SAMMC;
Expand Down Expand Up @@ -165,6 +166,14 @@ public List<Aspect> generateAspects() {
.toList();
}

public List<String> getSubmodelNames() {
return aasEnvironment.getSubmodels()
.stream()
.filter( submodel -> submodel.getKind().equals( ModellingKind.TEMPLATE ) )
.map( Referable::getIdShort )
.collect( Collectors.toList());
}

protected String escapeUrnNamespacePart( final String namespacePart ) {
if ( namespacePart.matches( AspectModelUrn.NAMESPACE_REGEX ) ) {
return namespacePart;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,14 @@ The available options and their meaning can also be seen in the help text of the
| _--format, -f_ : output file format (xml, json, or aasx, default: xml) |
| _--custom-resolver_ : use an external resolver for the resolution of the model elements |
| _--aspect-data, -a_ : path to a JSON file containing aspect data corresponding to the Aspect Model |
.2+| aas <aas file> to aspect | Translate Asset Administration Shell (AAS) Submodel Templates to Aspect Models | `samm aas AssetAdminShell.aasx to aspect`
.3+| aas <aas file> to aspect | Translate Asset Administration Shell (AAS) Submodel Templates to Aspect Models | `samm aas AssetAdminShell.aasx to aspect`
| _--output-directory, -d_ : output directory to write files to (default:
current directory) |
| _--submodel-template, -s_ : selected submodel for generating. For getting these options
run `aas <aas file> list` command. | `samm aas AssetAdminShell.aasx to aspect -s 1 -s 2`
Yauhenikapl marked this conversation as resolved.
Show resolved Hide resolved
.1+| aas <aas file> list | Retrieve a list of submodel templates contained within the provided
Asset Administration Shell (AAS) file. | `samm ass AssetAdminShell.aasx list`

|===

=== Custom model resolver
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
subcommands = {
CommandLine.HelpCommand.class,
AasToCommand.class,
AasListSubmodelsCommand.class
},
headerHeading = "@|bold Usage|@:%n%n",
descriptionHeading = "%n@|bold Description|@:%n%n",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.eclipse.esmf.aas;

import java.io.File;
import java.util.List;

import org.apache.commons.io.FilenameUtils;
import org.eclipse.esmf.AbstractCommand;
import org.eclipse.esmf.LoggingMixin;
import org.eclipse.esmf.aspectmodel.aas.AasToAspectModelGenerator;
import org.eclipse.esmf.exception.CommandException;

import picocli.CommandLine;

@CommandLine.Command( name = AasListSubmodelsCommand.COMMAND_NAME, description = "Get list submodel templates of AAS input.",
Yauhenikapl marked this conversation as resolved.
Show resolved Hide resolved
descriptionHeading = "%n@|bold Description|@:%n%n",
parameterListHeading = "%n@|bold Parameters|@:%n",
optionListHeading = "%n@|bold Options|@:%n",
mixinStandardHelpOptions = true
)
public class AasListSubmodelsCommand extends AbstractCommand {
public static final String COMMAND_NAME = "list";

@CommandLine.Mixin
private LoggingMixin loggingMixin;

@CommandLine.ParentCommand
private AasCommand parentCommand;

@Override
public void run() {
final String path = parentCommand.getInput();
final String extension = FilenameUtils.getExtension( path );
if ( !extension.equals( "xml" ) && !extension.equals( "json" ) && !extension.equals( "aasx" ) ) {
Yauhenikapl marked this conversation as resolved.
Show resolved Hide resolved
throw new CommandException( "Input file name must be an .xml, .aasx or .json file" );
Yauhenikapl marked this conversation as resolved.
Show resolved Hide resolved
}

List<String> submodelNames = AasToAspectModelGenerator.fromFile( new File( path ) ).getSubmodelNames();
Yauhenikapl marked this conversation as resolved.
Show resolved Hide resolved

for ( String submodelName : submodelNames ) {
int count = submodelNames.indexOf( submodelName );
if ( count < 10 ) {
System.out.printf( " %s: %s%n", count + 1, submodelName );
} else {
System.out.printf( "%s: %s%n", count + 1, submodelName );
}
}
Yauhenikapl marked this conversation as resolved.
Show resolved Hide resolved
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,21 @@
import java.io.IOException;
import java.io.Writer;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.io.FilenameUtils;
import org.eclipse.esmf.AbstractCommand;
import org.eclipse.esmf.LoggingMixin;
import org.eclipse.esmf.aas.AasToCommand;
import org.eclipse.esmf.aspectmodel.aas.AasToAspectModelGenerator;
import org.eclipse.esmf.aspectmodel.resolver.fs.StructuredModelsRoot;
import org.eclipse.esmf.aspectmodel.serializer.AspectSerializer;
import org.eclipse.esmf.exception.CommandException;
import org.eclipse.esmf.metamodel.Aspect;

import org.eclipse.esmf.aspectmodel.resolver.fs.StructuredModelsRoot;
import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import picocli.CommandLine;

@CommandLine.Command(
Expand All @@ -38,6 +40,10 @@ public class AasToAspectCommand extends AbstractCommand {
@CommandLine.Option( names = { "--output-directory", "-d" }, description = "Output directory to write files to" )
private String outputPath = ".";

@CommandLine.Option( names = { "--submodel-template", "-s" },
description = "Select one or a few options for generation an Aspect Model from AAS. Before run 'list' command for getting possible options." )
Yauhenikapl marked this conversation as resolved.
Show resolved Hide resolved
private List<Integer> selectedOptions = new ArrayList<>();

@CommandLine.Mixin
private LoggingMixin loggingMixin;

Expand All @@ -53,7 +59,16 @@ public void run() {

private void generateAspects( final AasToAspectModelGenerator generator ) {
final StructuredModelsRoot modelsRoot = new StructuredModelsRoot( Path.of( outputPath ) );
for ( final Aspect aspect : generator.generateAspects() ) {
final List<Aspect> generatedAspects = generator.generateAspects();

List<Aspect> filteredAspects = generatedAspects;
if ( !this.selectedOptions.isEmpty() ) {
filteredAspects = this.selectedOptions.stream()
.map( index -> generatedAspects.get( index - 1 ) )
.toList();
}
Yauhenikapl marked this conversation as resolved.
Show resolved Hide resolved

for ( final Aspect aspect : filteredAspects ) {
final String aspectString = AspectSerializer.INSTANCE.apply( aspect );
final File targetFile = modelsRoot.determineAspectModelFile( aspect.getAspectModelUrn().get() );
LOG.info( "Writing {}", targetFile.getAbsolutePath() );
Expand Down
49 changes: 44 additions & 5 deletions tools/samm-cli/src/test/java/org/eclipse/esmf/SammCliTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
import java.util.Optional;
import java.util.stream.Stream;

import org.apache.tika.config.TikaConfig;
import org.apache.tika.exception.TikaException;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.mime.MediaType;
import org.eclipse.esmf.ProcessLauncher.ExecutionResult;
import org.eclipse.esmf.aspect.AspectValidateCommand;
import org.eclipse.esmf.aspectmodel.shacl.violation.InvalidSyntaxViolation;
Expand All @@ -39,11 +43,6 @@
import org.eclipse.esmf.test.MetaModelVersions;
import org.eclipse.esmf.test.TestAspect;
import org.eclipse.esmf.test.TestModel;

import org.apache.tika.config.TikaConfig;
import org.apache.tika.exception.TikaException;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.mime.MediaType;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -381,6 +380,46 @@ public void testAasToAspectModel() {
assertThat( sourceFile ).content().contains( ":" + testModel.getName() + " a samm:Aspect" );
}

@Test
public void testAasListSubmodels() {
final File aasXmlFile = outputFile( "output.xml" );
final ExecutionResult generateAasXmlResult = sammCli.runAndExpectSuccess( "--disable-color", "aspect", defaultInputFile, "to", "aas",
"--format", "xml", "-o", aasXmlFile.getAbsolutePath() );
assertThat( generateAasXmlResult.stdout() ).isEmpty();
assertThat( generateAasXmlResult.stderr() ).isEmpty();

final ExecutionResult result = sammCli.runAndExpectSuccess( "--disable-color", "aas", aasXmlFile.getAbsolutePath(), "list" );
assertThat( result.stdout() ).isNotEmpty();
assertThat( result.stderr() ).isEmpty();
}

@Test
public void testAasToAspectModelWithSelectedSubmodels() {
// First create the AAS XML file we want to read
final File aasXmlFile = outputFile( "output.xml" );
final ExecutionResult generateAasXmlResult = sammCli.runAndExpectSuccess( "--disable-color", "aspect", defaultInputFile, "to", "aas",
"--format", "xml", "-o", aasXmlFile.getAbsolutePath() );
assertThat( generateAasXmlResult.stdout() ).isEmpty();
assertThat( generateAasXmlResult.stderr() ).isEmpty();

// Now the actual test, convert it to an Aspect Model
final File outputDir = outputDirectory.toFile();
final ExecutionResult result = sammCli.runAndExpectSuccess( "--disable-color", "aas", aasXmlFile.getAbsolutePath(), "to", "aspect",
"--output-directory", outputDir.getAbsolutePath(), "-s", "1" );
assertThat( result.stdout() ).isEmpty();
assertThat( result.stderr() ).isEmpty();

final File directory = outputDirectory.resolve( testModel.getUrn().getNamespace() )
.resolve( testModel.getUrn().getVersion() )
.toFile();
assertThat( directory ).exists();
final String expectedAspectModelFileName = testModel.getName() + ".ttl";
assertThat( directory ).isDirectoryContaining( file -> file.getName().equals( expectedAspectModelFileName ) );

final File sourceFile = directory.toPath().resolve( expectedAspectModelFileName ).toFile();
assertThat( sourceFile ).content().contains( ":" + testModel.getName() + " a samm:Aspect" );
}

@Test
public void testAspectToHtmlWithDefaultLanguageToFile() {
final File targetFile = outputFile( "output.html" );
Expand Down
Loading