Skip to content

Commit d9c9a70

Browse files
authored
Feature/improve open api generation (#81)
* Improve generation with Crud functionality from sdk * Update ame.postman_collection.json * Add unit tests for generation of crud operation in open api * Update pom.xml * Update GenerateController.java * Update ame.postman_collection.json * Fix unit tests * Update ame.postman_collection.json
1 parent 535ae35 commit d9c9a70

File tree

5 files changed

+450
-74
lines changed

5 files changed

+450
-74
lines changed

aspect-model-editor-runtime/postman/ame.postman_collection.json

+172-18
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"info": {
3-
"_postman_id": "26a275be-9ff5-4002-a3c8-9cdd4bcf4f29",
3+
"_postman_id": "c1d51dcb-56f1-4bbd-968f-43220329eada",
44
"name": "AME.POSTMAN.RESOURCES",
55
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
66
"_exporter_id": "30151852"
@@ -26,13 +26,11 @@
2626
"header": [
2727
{
2828
"key": "NAMESPACE",
29-
"value": "org.eclipse.examples:1.0.0",
30-
"type": "default"
29+
"value": "org.eclipse.examples:1.0.0"
3130
},
3231
{
3332
"key": "FILE-NAME",
34-
"value": "Movement.ttl",
35-
"type": "default"
33+
"value": "Movement.ttl"
3634
}
3735
],
3836
"body": {
@@ -76,8 +74,7 @@
7674
"header": [
7775
{
7876
"key": "FILE-NAME",
79-
"value": "latest.ttl",
80-
"type": "text"
77+
"value": "latest.ttl"
8178
}
8279
],
8380
"body": {
@@ -122,13 +119,11 @@
122119
"header": [
123120
{
124121
"key": "NAMESPACE",
125-
"value": "org.eclipse.examples:1.0.0",
126-
"type": "text"
122+
"value": "org.eclipse.examples:1.0.0"
127123
},
128124
{
129125
"key": "FILE-NAME",
130-
"value": "Movement.ttl",
131-
"type": "default"
126+
"value": "Movement.ttl"
132127
}
133128
],
134129
"url": {
@@ -168,8 +163,7 @@
168163
"header": [
169164
{
170165
"key": "FILE-NAME",
171-
"value": "latest.ttl",
172-
"type": "text"
166+
"value": "latest.ttl"
173167
}
174168
],
175169
"url": {
@@ -413,13 +407,11 @@
413407
"header": [
414408
{
415409
"key": "NAMESPACE",
416-
"value": "org.eclipse.examples:1.0.0",
417-
"type": "text"
410+
"value": "org.eclipse.examples:1.0.0"
418411
},
419412
{
420413
"key": "FILE-NAME",
421-
"value": "Movement.ttl",
422-
"type": "default"
414+
"value": "Movement.ttl"
423415
}
424416
],
425417
"url": {
@@ -511,7 +503,6 @@
511503
{
512504
"key": "language",
513505
"value": "\"en\"",
514-
"type": "text",
515506
"disabled": true
516507
}
517508
],
@@ -1279,6 +1270,169 @@
12791270
},
12801271
"response": []
12811272
},
1273+
{
1274+
"name": "GenerateYamlOpenApiSpecCrud",
1275+
"event": [
1276+
{
1277+
"listen": "test",
1278+
"script": {
1279+
"exec": [
1280+
"pm.test(\"Status code is 200\", function () {\r",
1281+
" pm.response.to.have.status(200);\r",
1282+
"});\r",
1283+
"pm.test(\"Response body is valid\", function () {\r",
1284+
" const jsonData = pm.response.text();\r",
1285+
" pm.expect(jsonData).to.include(\"openapi: 3.0.3\");\r",
1286+
" pm.expect(jsonData).to.include(\"title: movement\");\r",
1287+
" pm.expect(jsonData).to.include(\"version: v1\");\r",
1288+
" pm.expect(jsonData).to.include(\"url: http://www.test.com/api/v1\");\r",
1289+
"\r",
1290+
" pm.expect(jsonData).to.include(\"get:\");\r",
1291+
" pm.expect(jsonData).to.include(\"post:\");\r",
1292+
" pm.expect(jsonData).to.include(\"put:\");\r",
1293+
" pm.expect(jsonData).to.include(\"patch:\");\r",
1294+
"});"
1295+
],
1296+
"type": "text/javascript",
1297+
"packages": {}
1298+
}
1299+
},
1300+
{
1301+
"listen": "prerequest",
1302+
"script": {
1303+
"packages": {},
1304+
"type": "text/javascript"
1305+
}
1306+
}
1307+
],
1308+
"request": {
1309+
"method": "POST",
1310+
"header": [],
1311+
"body": {
1312+
"mode": "raw",
1313+
"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:org.eclipse.examples:1.0.0#> .\r\n\r\n:Movement a samm:Aspect ;\r\n samm:preferredName \"movement\"@en ;\r\n samm:description \"Aspect for movement information\"@en ;\r\n samm:properties ( :isMoving :position :speed :speedLimitWarning ) ;\r\n samm:operations ( ) ;\r\n samm:events ( ) .\r\n\r\n:isMoving a samm:Property ;\r\n samm:preferredName \"is moving\"@en ;\r\n samm:description \"Flag indicating whether the asset is currently moving\"@en ;\r\n samm:characteristic samm-c:Boolean .\r\n\r\n:position a samm:Property ;\r\n samm:preferredName \"position\"@en ;\r\n samm:description \"Indicates a position\"@en ;\r\n samm:characteristic :SpatialPositionCharacteristic .\r\n\r\n:speed a samm:Property ;\r\n samm:preferredName \"speed\"@en ;\r\n samm:description \"speed of vehicle\"@en ;\r\n samm:characteristic :Speed .\r\n\r\n:speedLimitWarning a samm:Property ;\r\n samm:preferredName \"speed limit warning\"@en ;\r\n samm:description \"Indicates if the speed limit is adhered to.\"@en ;\r\n samm:characteristic :TrafficLight .\r\n\r\n:SpatialPositionCharacteristic a samm-c:SingleEntity ;\r\n samm:preferredName \"spatial position characteristic\"@en ;\r\n samm:description \"Represents a single position in space with optional z coordinate.\"@en ;\r\n samm:dataType :SpatialPosition .\r\n\r\n:Speed a samm-c:Measurement ;\r\n samm:preferredName \"speed\"@en ;\r\n samm:description \"Scalar representation of speed of an object in kilometers per hour.\"@en ;\r\n samm:dataType xsd:float ;\r\n samm-c:unit unit:kilometrePerHour .\r\n\r\n:TrafficLight a samm-c:Enumeration ;\r\n samm:preferredName \"warning level\"@en ;\r\n samm:description \"Represents if speed of position change is within specification (green), within tolerance (yellow), or outside specification (red).\"@en ;\r\n samm:dataType xsd:string ;\r\n samm-c:values ( \"green\" \"yellow\" \"red\" ) .\r\n\r\n:SpatialPosition a samm:Entity ;\r\n samm:preferredName \"spatial position\"@en ;\r\n samm:description \"Represents latitude, longitude and altitude information in the WGS84 geodetic reference datum\"@en ;\r\n samm:see <https://www.w3.org/2003/01/geo/> ;\r\n samm:properties ( :latitude :longitude [ samm:property :altitude; samm:optional true ] ) .\r\n\r\n:latitude a samm:Property ;\r\n samm:preferredName \"latitude\"@en ;\r\n samm:description \"latitude coordinate in space (WGS84)\"@en ;\r\n samm:see <http://www.w3.org/2003/01/geo/wgs84_pos#lat> ;\r\n samm:characteristic :Coordinate ;\r\n samm:exampleValue \"9.1781\"^^xsd:decimal .\r\n\r\n:longitude a samm:Property ;\r\n samm:preferredName \"longitude\"@en ;\r\n samm:description \"longitude coordinate in space (WGS84)\"@en ;\r\n samm:see <http://www.w3.org/2003/01/geo/wgs84_pos#long> ;\r\n samm:characteristic :Coordinate ;\r\n samm:exampleValue \"48.80835\"^^xsd:decimal .\r\n\r\n:altitude a samm:Property ;\r\n samm:preferredName \"altitude\"@en ;\r\n samm:description \"Elevation above sea level zero\"@en ;\r\n samm:see <http://www.w3.org/2003/01/geo/wgs84_pos#alt> ;\r\n samm:characteristic :MetresAboveMeanSeaLevel ;\r\n samm:exampleValue \"153\"^^xsd:float .\r\n\r\n:Coordinate a samm-c:Measurement ;\r\n samm:preferredName \"coordinate\"@en ;\r\n samm:description \"Representing the geographical coordinate\"@en ;\r\n samm:dataType xsd:decimal ;\r\n samm-c:unit unit:degreeUnitOfAngle .\r\n\r\n:MetresAboveMeanSeaLevel a samm-c:Measurement ;\r\n samm:preferredName \"metres above mean sea level\"@en ;\r\n samm:description \"Signifies the vertical distance in reference to a historic mean sea level as a vertical datum\"@en ;\r\n samm:see <https://en.wikipedia.org/wiki/Height_above_sea_level> ;\r\n samm:dataType xsd:float ;\r\n samm-c:unit unit:metre .\r\n"
1314+
},
1315+
"url": {
1316+
"raw": "http://localhost:{{port}}/ame/api/generate/open-api-spec?output=yaml&baseUrl=http://www.test.com&includeQueryApi=true&useSemanticVersion=true&pagingOption=NO_PAGING&includeCrud=true",
1317+
"protocol": "http",
1318+
"host": [
1319+
"localhost"
1320+
],
1321+
"port": "{{port}}",
1322+
"path": [
1323+
"ame",
1324+
"api",
1325+
"generate",
1326+
"open-api-spec"
1327+
],
1328+
"query": [
1329+
{
1330+
"key": "output",
1331+
"value": "yaml"
1332+
},
1333+
{
1334+
"key": "baseUrl",
1335+
"value": "http://www.test.com"
1336+
},
1337+
{
1338+
"key": "includeQueryApi",
1339+
"value": "true"
1340+
},
1341+
{
1342+
"key": "useSemanticVersion",
1343+
"value": "true"
1344+
},
1345+
{
1346+
"key": "pagingOption",
1347+
"value": "NO_PAGING"
1348+
},
1349+
{
1350+
"key": "includeCrud",
1351+
"value": "true"
1352+
}
1353+
]
1354+
}
1355+
},
1356+
"response": []
1357+
},
1358+
{
1359+
"name": "GenerateJsonOpenApiSpecCrud",
1360+
"event": [
1361+
{
1362+
"listen": "test",
1363+
"script": {
1364+
"exec": [
1365+
"pm.test(\"Status code is 200\", function () {\r",
1366+
" pm.response.to.have.status(200);\r",
1367+
"});\r",
1368+
"pm.test(\"Response body is valid\", function () {\r",
1369+
" const jsonData = pm.response.text();\r",
1370+
" pm.expect(jsonData).to.include(\"\\\"openapi\\\" : \\\"3.0.3\\\"\");\r",
1371+
" pm.expect(jsonData).to.include(\"\\\"title\\\" : \\\"movement\\\"\");\r",
1372+
" pm.expect(jsonData).to.include(\"\\\"version\\\" : \\\"v1.0.0\\\"\");\r",
1373+
" pm.expect(jsonData).to.include(\"\\\"url\\\" : \\\"http://www.test.com/api/v1.0.0\\\"\");\r",
1374+
"\r",
1375+
" pm.expect(jsonData).to.include(\"\\\"get\\\" :\");\r",
1376+
" pm.expect(jsonData).to.include(\"\\\"post\\\" :\");\r",
1377+
" pm.expect(jsonData).to.include(\"\\\"put\\\" :\");\r",
1378+
" pm.expect(jsonData).to.include(\"\\\"patch\\\" :\");\r",
1379+
"});"
1380+
],
1381+
"type": "text/javascript",
1382+
"packages": {}
1383+
}
1384+
}
1385+
],
1386+
"request": {
1387+
"method": "POST",
1388+
"header": [],
1389+
"body": {
1390+
"mode": "raw",
1391+
"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:org.eclipse.examples:1.0.0#> .\r\n\r\n:Movement a samm:Aspect ;\r\n samm:preferredName \"movement\"@en ;\r\n samm:description \"Aspect for movement information\"@en ;\r\n samm:properties ( :isMoving :position :speed :speedLimitWarning ) ;\r\n samm:operations ( ) ;\r\n samm:events ( ) .\r\n\r\n:isMoving a samm:Property ;\r\n samm:preferredName \"is moving\"@en ;\r\n samm:description \"Flag indicating whether the asset is currently moving\"@en ;\r\n samm:characteristic samm-c:Boolean .\r\n\r\n:position a samm:Property ;\r\n samm:preferredName \"position\"@en ;\r\n samm:description \"Indicates a position\"@en ;\r\n samm:characteristic :SpatialPositionCharacteristic .\r\n\r\n:speed a samm:Property ;\r\n samm:preferredName \"speed\"@en ;\r\n samm:description \"speed of vehicle\"@en ;\r\n samm:characteristic :Speed .\r\n\r\n:speedLimitWarning a samm:Property ;\r\n samm:preferredName \"speed limit warning\"@en ;\r\n samm:description \"Indicates if the speed limit is adhered to.\"@en ;\r\n samm:characteristic :TrafficLight .\r\n\r\n:SpatialPositionCharacteristic a samm-c:SingleEntity ;\r\n samm:preferredName \"spatial position characteristic\"@en ;\r\n samm:description \"Represents a single position in space with optional z coordinate.\"@en ;\r\n samm:dataType :SpatialPosition .\r\n\r\n:Speed a samm-c:Measurement ;\r\n samm:preferredName \"speed\"@en ;\r\n samm:description \"Scalar representation of speed of an object in kilometers per hour.\"@en ;\r\n samm:dataType xsd:float ;\r\n samm-c:unit unit:kilometrePerHour .\r\n\r\n:TrafficLight a samm-c:Enumeration ;\r\n samm:preferredName \"warning level\"@en ;\r\n samm:description \"Represents if speed of position change is within specification (green), within tolerance (yellow), or outside specification (red).\"@en ;\r\n samm:dataType xsd:string ;\r\n samm-c:values ( \"green\" \"yellow\" \"red\" ) .\r\n\r\n:SpatialPosition a samm:Entity ;\r\n samm:preferredName \"spatial position\"@en ;\r\n samm:description \"Represents latitude, longitude and altitude information in the WGS84 geodetic reference datum\"@en ;\r\n samm:see <https://www.w3.org/2003/01/geo/> ;\r\n samm:properties ( :latitude :longitude [ samm:property :altitude; samm:optional true ] ) .\r\n\r\n:latitude a samm:Property ;\r\n samm:preferredName \"latitude\"@en ;\r\n samm:description \"latitude coordinate in space (WGS84)\"@en ;\r\n samm:see <http://www.w3.org/2003/01/geo/wgs84_pos#lat> ;\r\n samm:characteristic :Coordinate ;\r\n samm:exampleValue \"9.1781\"^^xsd:decimal .\r\n\r\n:longitude a samm:Property ;\r\n samm:preferredName \"longitude\"@en ;\r\n samm:description \"longitude coordinate in space (WGS84)\"@en ;\r\n samm:see <http://www.w3.org/2003/01/geo/wgs84_pos#long> ;\r\n samm:characteristic :Coordinate ;\r\n samm:exampleValue \"48.80835\"^^xsd:decimal .\r\n\r\n:altitude a samm:Property ;\r\n samm:preferredName \"altitude\"@en ;\r\n samm:description \"Elevation above sea level zero\"@en ;\r\n samm:see <http://www.w3.org/2003/01/geo/wgs84_pos#alt> ;\r\n samm:characteristic :MetresAboveMeanSeaLevel ;\r\n samm:exampleValue \"153\"^^xsd:float .\r\n\r\n:Coordinate a samm-c:Measurement ;\r\n samm:preferredName \"coordinate\"@en ;\r\n samm:description \"Representing the geographical coordinate\"@en ;\r\n samm:dataType xsd:decimal ;\r\n samm-c:unit unit:degreeUnitOfAngle .\r\n\r\n:MetresAboveMeanSeaLevel a samm-c:Measurement ;\r\n samm:preferredName \"metres above mean sea level\"@en ;\r\n samm:description \"Signifies the vertical distance in reference to a historic mean sea level as a vertical datum\"@en ;\r\n samm:see <https://en.wikipedia.org/wiki/Height_above_sea_level> ;\r\n samm:dataType xsd:float ;\r\n samm-c:unit unit:metre .\r\n"
1392+
},
1393+
"url": {
1394+
"raw": "http://localhost:{{port}}/ame/api/generate/open-api-spec?output=json&baseUrl=http://www.test.com&includeQueryApi=true&useSemanticVersion=true&pagingOption=NO_PAGING&includeCrud=true",
1395+
"protocol": "http",
1396+
"host": [
1397+
"localhost"
1398+
],
1399+
"port": "{{port}}",
1400+
"path": [
1401+
"ame",
1402+
"api",
1403+
"generate",
1404+
"open-api-spec"
1405+
],
1406+
"query": [
1407+
{
1408+
"key": "output",
1409+
"value": "json"
1410+
},
1411+
{
1412+
"key": "baseUrl",
1413+
"value": "http://www.test.com"
1414+
},
1415+
{
1416+
"key": "includeQueryApi",
1417+
"value": "true"
1418+
},
1419+
{
1420+
"key": "useSemanticVersion",
1421+
"value": "true"
1422+
},
1423+
{
1424+
"key": "pagingOption",
1425+
"value": "NO_PAGING"
1426+
},
1427+
{
1428+
"key": "includeCrud",
1429+
"value": "true"
1430+
}
1431+
]
1432+
}
1433+
},
1434+
"response": []
1435+
},
12821436
{
12831437
"name": "GenerateAASX",
12841438
"event": [

aspect-model-editor-service/src/main/java/org/eclipse/esmf/ame/services/GenerateService.java

+8-14
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import java.util.HashMap;
2121
import java.util.Locale;
2222
import java.util.Map;
23-
import java.util.Optional;
2423

2524
import org.apache.commons.lang3.LocaleUtils;
2625
import org.eclipse.esmf.ame.exceptions.FileHandlingException;
@@ -40,7 +39,7 @@
4039
import org.eclipse.esmf.aspectmodel.generator.json.AspectModelJsonPayloadGenerator;
4140
import org.eclipse.esmf.aspectmodel.generator.jsonschema.AspectModelJsonSchemaGenerator;
4241
import org.eclipse.esmf.aspectmodel.generator.openapi.AspectModelOpenApiGenerator;
43-
import org.eclipse.esmf.aspectmodel.generator.openapi.PagingOption;
42+
import org.eclipse.esmf.aspectmodel.generator.openapi.OpenApiSchemaGenerationConfig;
4443
import org.eclipse.esmf.aspectmodel.resolver.services.DataType;
4544
import org.eclipse.esmf.aspectmodel.resolver.services.VersionedModel;
4645
import org.eclipse.esmf.metamodel.Aspect;
@@ -153,12 +152,10 @@ private AspectContext generateAspectContext( final String aspectModel ) {
153152
return ModelUtils.getAspectContext( context );
154153
}
155154

156-
public String generateYamlOpenApiSpec( final String language, final String aspectModel, final String baseUrl,
157-
final boolean includeQueryApi, final boolean useSemanticVersion, final Optional<PagingOption> pagingOption,
158-
final Optional<String> resourcePath, final Optional<String> yamlProperties ) {
159-
final String ymlOutput = new AspectModelOpenApiGenerator().applyForYaml(
160-
ResolverUtils.resolveAspectFromModel( aspectModel ), useSemanticVersion, baseUrl, resourcePath,
161-
yamlProperties, includeQueryApi, pagingOption, Locale.forLanguageTag( language ) );
155+
public String generateYamlOpenApiSpec( final String aspectModel, final OpenApiSchemaGenerationConfig config ) {
156+
157+
final String ymlOutput = new AspectModelOpenApiGenerator().apply(
158+
ResolverUtils.resolveAspectFromModel( aspectModel ), config ).getContentAsYaml();
162159

163160
if ( ymlOutput.equals( "--- {}\n" ) ) {
164161
throw new GenerationException( WRONG_RESOURCE_PATH_ID );
@@ -167,13 +164,10 @@ public String generateYamlOpenApiSpec( final String language, final String aspec
167164
return ymlOutput;
168165
}
169166

170-
public String generateJsonOpenApiSpec( final String language, final String aspectModel, final String baseUrl,
171-
final boolean includeQueryApi, final boolean useSemanticVersion, final Optional<PagingOption> pagingOption,
172-
final Optional<String> resourcePath, final Optional<JsonNode> jsonProperties ) {
167+
public String generateJsonOpenApiSpec( final String aspectModel, final OpenApiSchemaGenerationConfig config ) {
173168
try {
174-
final JsonNode json = new AspectModelOpenApiGenerator().applyForJson(
175-
ResolverUtils.resolveAspectFromModel( aspectModel ), useSemanticVersion, baseUrl, resourcePath,
176-
jsonProperties, includeQueryApi, pagingOption, LocaleUtils.toLocale( language ) );
169+
final JsonNode json = new AspectModelOpenApiGenerator()
170+
.apply( ResolverUtils.resolveAspectFromModel( aspectModel ), config ).getContent();
177171

178172
final ByteArrayOutputStream out = new ByteArrayOutputStream();
179173
final ObjectMapper objectMapper = new ObjectMapper();

0 commit comments

Comments
 (0)