Skip to content

Commit

Permalink
Add AASX and AAS-XML generation to backend
Browse files Browse the repository at this point in the history
  • Loading branch information
michelu89 committed Nov 2, 2023
1 parent 512cdde commit 5b32ccd
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 8 deletions.
13 changes: 12 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,14 @@
<main.class>org.eclipse.esmf.ame.Application</main.class>

<!-- Internal esmf dependencies -->
<esmf-sdk-version>2.3.2</esmf-sdk-version>
<esmf-sdk-version>2.4.1</esmf-sdk-version>

<!-- Versions of third party dependencies -->
<spring-boot-version>3.0.0</spring-boot-version>
<lombok-version>1.18.24</lombok-version>
<commons-io-version>2.13.0</commons-io-version>
<commons-validator-version>1.7</commons-validator-version>
<commons-code-version>1.15</commons-code-version>
<port-allocator-version>1.2</port-allocator-version>
<process-exec-version>0.9</process-exec-version>
<mockito-inline-version>5.1.1</mockito-inline-version>
Expand Down Expand Up @@ -138,6 +139,11 @@
<artifactId>esmf-aspect-meta-model-java</artifactId>
<version>${esmf-sdk-version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.esmf</groupId>
<artifactId>esmf-aspect-model-aas-generator</artifactId>
<version>${esmf-sdk-version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.esmf</groupId>
<artifactId>esmf-aspect-model-document-generators</artifactId>
Expand Down Expand Up @@ -249,6 +255,11 @@
<artifactId>memoryfilesystem</artifactId>
<version>${memoryfilesystem-version}</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>${commons-code-version}</version>
</dependency>

<!-- Third party dependencies for testing -->
<dependency>
Expand Down
93 changes: 91 additions & 2 deletions postman/ame.postman_collection.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{
"info": {
"_postman_id": "60a84c95-6f04-4bea-86ee-17e70d30b603",
"_postman_id": "556ca409-a79a-4d08-a85e-eb1482a8a672",
"name": "AME.POSTMAN.RESOURCES",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
"_exporter_id": "30151852"
},
"item": [
{
Expand Down Expand Up @@ -902,6 +903,94 @@
}
},
"response": []
},
{
"name": "GenerateAASX",
"event": [
{
"listen": "test",
"script": {
"exec": [
"pm.test(\"Status code is 200\", function () {\r",
" pm.response.to.have.status(200);\r",
"});\r",
"pm.test(\"Response body is valid\", function () {\r",
" const jsonData = pm.response.text();\r",
" pm.expect(jsonData).to.include(\"aasx\");\r",
"});"
],
"type": "text/javascript"
}
}
],
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "raw",
"raw": "@prefix samm: <urn:samm:org.eclipse.esmf.samm:meta-model:2.1.0#> .\r\n@prefix samm-c: <urn:samm:org.eclipse.esmf.samm:characteristic:2.1.0#> .\r\n@prefix samm-e: <urn:samm:org.eclipse.esmf.samm:entity:2.1.0#> .\r\n@prefix unit: <urn:samm:org.eclipse.esmf.samm:unit:2.1.0#> .\r\n@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\r\n@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\r\n@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .\r\n@prefix : <urn:samm:io.aspectmodel:1.0.0#> .\r\n\r\n:AspectDefault a samm:Aspect ;\r\n samm:properties (:property1) ;\r\n samm:operations () .\r\n\r\n:property1 a samm:Property;\r\n samm:characteristic :Characteristic1 .\r\n\r\n:Characteristic1 a samm:Characteristic ;\r\n samm:dataType xsd:string .\r\n"
},
"url": {
"raw": "http://localhost:{{port}}/ame/api/generate/aasx",
"protocol": "http",
"host": [
"localhost"
],
"port": "{{port}}",
"path": [
"ame",
"api",
"generate",
"aasx"
]
}
},
"response": []
},
{
"name": "GenerateAASXML",
"event": [
{
"listen": "test",
"script": {
"exec": [
"pm.test(\"Status code is 200\", function () {\r",
" pm.response.to.have.status(200);\r",
"});\r",
"pm.test(\"Response body is valid\", function () {\r",
" const jsonData = pm.response.text();\r",
" pm.expect(jsonData).to.include(\"<?xml version='1.0' encoding='UTF-8'?>\");\r",
" pm.expect(jsonData).to.include(\"https://admin-shell.io/aas/3/0\");\r",
"\r",
"});"
],
"type": "text/javascript"
}
}
],
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "raw",
"raw": "@prefix samm: <urn:samm:org.eclipse.esmf.samm:meta-model:2.1.0#> .\r\n@prefix samm-c: <urn:samm:org.eclipse.esmf.samm:characteristic:2.1.0#> .\r\n@prefix samm-e: <urn:samm:org.eclipse.esmf.samm:entity:2.1.0#> .\r\n@prefix unit: <urn:samm:org.eclipse.esmf.samm:unit:2.1.0#> .\r\n@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\r\n@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\r\n@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .\r\n@prefix : <urn:samm:io.aspectmodel:1.0.0#> .\r\n\r\n:AspectDefault a samm:Aspect ;\r\n samm:properties (:property1) ;\r\n samm:operations () .\r\n\r\n:property1 a samm:Property;\r\n samm:characteristic :Characteristic1 .\r\n\r\n:Characteristic1 a samm:Characteristic ;\r\n samm:dataType xsd:string .\r\n"
},
"url": {
"raw": "http://localhost:{{port}}/ame/api/generate/aas-xml",
"protocol": "http",
"host": [
"localhost"
],
"port": "{{port}}",
"path": [
"ame",
"api",
"generate",
"aas-xml"
]
}
},
"response": []
}
],
"event": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,12 @@

package org.eclipse.esmf.ame.exceptions.model;

import javax.validation.constraints.NotEmpty;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;

import jakarta.validation.constraints.NotEmpty;
import lombok.AllArgsConstructor;
import lombok.Data;

Expand Down
38 changes: 36 additions & 2 deletions src/main/java/org/eclipse/esmf/ame/services/GenerateService.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Locale;
import java.util.Optional;

import org.apache.commons.lang3.LocaleUtils;
import org.eclipse.esmf.ame.exceptions.InvalidAspectModelException;
import org.eclipse.esmf.ame.resolver.strategy.FileSystemStrategy;
import org.eclipse.esmf.ame.services.utils.ModelUtils;
import org.eclipse.esmf.aspectmodel.aas.AspectModelAASGenerator;
import org.eclipse.esmf.aspectmodel.generator.docu.AspectModelDocumentationGenerator;
import org.eclipse.esmf.aspectmodel.generator.json.AspectModelJsonPayloadGenerator;
import org.eclipse.esmf.aspectmodel.generator.jsonschema.AspectModelJsonSchemaGenerator;
Expand Down Expand Up @@ -77,7 +79,7 @@ public String jsonSchema( final String aspectModel, final String language ) {

return out.toString();
} catch ( final IOException e ) {
LOG.error( "Aspect Model could not be loaded correctly." );
LOG.error( COULD_NOT_LOAD_ASPECT_MODEL );
throw new InvalidAspectModelException( COULD_NOT_LOAD_ASPECT, e );
}
}
Expand All @@ -87,11 +89,43 @@ public String sampleJSONPayload( final String aspectModel ) {
return new AspectModelJsonPayloadGenerator(
generateAspectContext( aspectModel ) ).generateJson();
} catch ( final IOException e ) {
LOG.error( "Aspect Model could not be loaded correctly." );
LOG.error( COULD_NOT_LOAD_ASPECT_MODEL );
throw new InvalidAspectModelException( COULD_NOT_LOAD_ASPECT, e );
}
}

public String generateAASXFile( String aspectModel ) {
final AspectModelAASGenerator generator = new AspectModelAASGenerator();
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

AspectContext aspectContext = generateAspectContext( aspectModel );

try {
generator.generateAASXFile( aspectContext.aspect(), name -> outputStream );
} catch ( IOException e ) {
LOG.error( COULD_NOT_LOAD_ASPECT_MODEL );
throw new InvalidAspectModelException( COULD_NOT_LOAD_ASPECT, e );
}

return outputStream.toString( StandardCharsets.UTF_8 );
}

public String generateAasXmlFile( String aspectModel ) {
final AspectModelAASGenerator generator = new AspectModelAASGenerator();
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

AspectContext aspectContext = generateAspectContext( aspectModel );

try {
generator.generateAasXmlFile( aspectContext.aspect(), name -> outputStream );
} catch ( IOException e ) {
LOG.error( COULD_NOT_LOAD_ASPECT_MODEL );
throw new InvalidAspectModelException( COULD_NOT_LOAD_ASPECT, e );
}

return outputStream.toString( StandardCharsets.UTF_8 );
}

private AspectContext generateAspectContext( final String aspectModel ) {
final FileSystemStrategy fileSystemStrategy = new FileSystemStrategy( aspectModel );
final Try<VersionedModel> versionedModels = ModelUtils.fetchVersionModel( fileSystemStrategy );
Expand Down
22 changes: 22 additions & 0 deletions src/main/java/org/eclipse/esmf/ame/web/GenerateResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,28 @@ public ResponseEntity<String> jsonSchema( @RequestBody final String aspectModel,
return ResponseEntity.ok( generateService.jsonSchema( aspectModel, language ) );
}

/**
* Handles the request to generate an AASX file based on the given aspect model.
*
* @param aspectModel The model provided in the request body used to generate the AASX file.
* @return A {@link ResponseEntity} containing the result of the AASX file generation.
*/
@PostMapping( "aasx" )
public ResponseEntity<String> assx( @RequestBody final String aspectModel ) {
return ResponseEntity.ok( generateService.generateAASXFile( aspectModel ) );
}

/**
* Handles the request to generate an AAS XML file based on the provided aspect model.
*
* @param aspectModel The model provided in the request body used to generate the AAS XML file.
* @return A {@link ResponseEntity} containing the result of the AAS XML file generation.
*/
@PostMapping( "aas-xml" )
public ResponseEntity<String> assXml( @RequestBody final String aspectModel ) {
return ResponseEntity.ok( generateService.generateAasXmlFile( aspectModel ) );
}

/**
* This method is used to generate an OpenAPI specification of the Aspect Model
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ void testAspectModelJsonSchema() throws IOException {
@Test
void testAspectModelJsonOpenApiSpec() throws IOException {
final Path storagePath = Path.of( eclipseTestPath.toString(), model );

final String testModel = Files.readString( storagePath, StandardCharsets.UTF_8 );

final String payload = generateService.generateJsonOpenApiSpec( "en", testModel, "https://test.com", false, false,
Expand All @@ -90,4 +89,25 @@ void testAspectModelYamlOpenApiSpec() throws IOException {
assertTrue( payload.contains( "version: v1" ) );
assertTrue( payload.contains( "url: https://test.com/api/v1" ) );
}

@Test
void testAspectModelAASX() throws IOException {
final Path storagePath = Path.of( eclipseTestPath.toString(), model );
final String testModel = Files.readString( storagePath, StandardCharsets.UTF_8 );

final String payload = generateService.generateAASXFile( testModel );

assertTrue( payload.contains( "aasx" ) );
}

@Test
void testAspectModelAASXML() throws IOException {
final Path storagePath = Path.of( eclipseTestPath.toString(), model );
final String testModel = Files.readString( storagePath, StandardCharsets.UTF_8 );

final String payload = generateService.generateAasXmlFile( testModel );

assertTrue( payload.contains( "<?xml version='1.0' encoding='UTF-8'?>" ) );
assertTrue( payload.contains( "https://admin-shell.io/aas/3/0" ) );
}
}

0 comments on commit 5b32ccd

Please sign in to comment.