OAS Specifications Generation and Import - Xyna-Factory/xyna GitHub Wiki
This page provides an overview of the process of generating applications from OAS conform specifications and importing them into Xyna.
Below you can find an overview of the import process of a specification file. The specification must either be a YAML or JSON file. In the first step the generator reads the specification file and generates one or multiple applications, which are imported into Xyna automatically. Once all applications have been generated and imported into Xyna, several steps have to be performed manually to implement business logic and to expose the api.
In this tutorial we use a minimalist Xyna Ping Service api for clarity:
xyna_ping_v1.2.yaml
openapi: 3.0.3
info:
title: Xyna Ping Service
description: |
Services for testing the availability of the system
version: "1.2"
tags:
- name: XynaPing
servers:
- url: https://serverRoot/pingservice/
paths:
/ping:
get:
tags:
- XynaPing
summary: Ping Service
parameters:
- name: input
in: query
description: Optional Input
required: false
schema:
type: string
responses:
'200':
description: Created
content:
application/json:
schema:
$ref: '#/components/schemas/ResultObject'
'404':
description: Not Found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
post:
tags:
- XynaPing
summary: Ping Service
requestBody:
description: The specification to be imported with control parameters
content:
application/json:
schema:
$ref: '#/components/schemas/PingBody'
required: true
responses:
'200':
description: Created
content:
application/json:
schema:
$ref: '#/components/schemas/ResultObject'
'404':
description: Not Found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
components:
schemas:
PingBody:
type: object
properties:
inputStr:
type: string
description: Just an input body that is used as return value
ResultObject:
type: object
properties:
outputStr:
type: string
description: output object
Error:
required:
- code
type: object
properties:
code:
type: string
description: HTTP Error Code
reason:
type: string
description: Explanation of the reason for the error which can be shown to a client user.
message:
type: string
description: More details and corrective actions related to the error which can be shown to a client user.
The generator is contained in the application "OAS_Base". This application has to be imported into Xyna first. If you already have the application file, you can import it via the tab "Applications" in the Xyna Factory Manager GUI, using the button "Import Application...". Alternatively, the OAS_Base application is also included in the xyna-factory delivery bundle. You can find instructions to install the application on the installation page.
The figure below shows the import mask for OAS/TMF specification files.
The generation and import process can be started by navigating to the tab "OAS Import" on the left-hand side in the Xyna Factory Manager GUI. To start the import process click the button "Generate and Import OAS Applications" in the top right-hand corner, which opens an import dialog window. Here you can upload your specification file. Keep the default options for the other settings and click "Start generation and Import" to start the import process. Once the process has started you can safely close the dialog window.
Check the table if the import was successful. You might need to refresh the table via the button in the top right-hand corner. After the import process has completed successfully, three applications are available in Xyna:
-
Data Model Application: contains Xyna datatypes for every object defined in the specifications schema section
-
Provider Application: contains the "OAS Filter" instance, the api path instance datatypes, the response/request data types and the endpoint workflows
-
Client Application: contains request/response data types and request workflows for the case Xyna acts as a client
As you saw in the previous step, the generated content is imported into applications by default. Applications in Xyna are readonly. With our generator we follow the approach to keep the generated content strictly separated form the implemented business logic. Therefore, the next step is to create a workspace that will be used for your implementation workflows. Inside the "Factory Manager" GUI click on the tab "Workspaces", which can be found on the left hand side. Now click on the plus button in the top right corner to create a new workspace, see image below.
Give it a descriptive name related to your application. In this example we want to implement the provider application workflows, so the name of the workspace could be "Xyna Ping Service Provider Impl". The newly created workspace contains nothing and has no dependencies except for the "Processing" application. To be able to use the Objects from the generated Applications in your workspace, you have to add the correct dependency manually, in this case the generated provider application "Xyna_Ping_Service_Provider". Click the name of the workspace and then "Manage..." and add the application as dependency.
The result should look like in the image below:
The import process generates abstract api data types which contain the methods your api will expose. These methods correspond to the defined methods and paths within your specification file (e.g. GET /ping) and are grouped according to the names given under the keyword "tags". For every tag defined in your specification file, one api datatype is created inside Xyna. These abstract data types are needed to dispatch incoming requests at runtime to the implemented business logic.
- Switch to the Process Modeller inside the Xyna GUI.
First, change the active Workspace to the one you created in step 2 via the button in the top right-hand corner.
Click the search button on the right (magnifier) and search for "XynaPing Api" and open the data type with a double click.
This is the generated api data type.
You have to create a derived data type that you can modify.
Copy the fully qualified name (FQN), see image below.
- Then, click on the "new file" symbol in the top left corner to create a new object and choose "Data Type". Paste the FQN into the field "Base Type".
- Fill in the field "Label" using the same label that is used for the abstract datatype and append "Impl". This is of course not strictly necessary, but it is good practice have to a clear naming convention to keep track of the data types.
- Fill in the field "path", e.g. with "oas.impl". Again, use a naming scheme that helps you to organize implemented data types and workflows.
- Hit the top cog symbol in the upper left corner to deploy the data type.
The result should look like this:
The services of the derived data types must be overridden by your manual implementation. Let's implement the endpoint "GET /ping" as an example.
-
Click on the path instance service under "Inherited Services" and hit the button "Override". The service is now listed under "Overridden Services".
-
Switch to the "Implementation" tab and set the "Implementation Type" to "Reference". A Plus symbol should appear:
-
Clicking on the plus symbol "Open new workflow with matching signature" opens a new blank workflow with the correct signature (inputs/outpus) for the manual implementation workflow. Leave the derived datatype open in the background.
-
Implement the method. An example implementation may look as follows:
The image shows a simple example implementation that checks if the query parameter of this endpoint is present in the request and copies the value to the output string of the response. If no value was given, the message "ping successful" is returned instead. An implementation workflow must return one of the generated response data types for this endpoint. In the implementation above, only "GET /ping Response 200 OK" is used.
Please note: In more complex workflows, like database operations, file input/output, or connections to other devices, a workflow may throw different types of exceptions on errors. It is important to ensure that each implementation workflow handles all exception types, except for "Exception" and "Server Exception" to preserve the correct signature of the overridden service.
-
When the workflow is finished click on the cog symbol to save and deploy the workflow. Enter a descriptive name and path for the workflow.
-
Switch back to the derived datatype and click in the field "Reference". Select the workflow you just deployed.
-
Deploy the derived datatype and repeat steps (1) to (6) for all the services you want to implement.
Finally, we need to expose the api and make Xyna listen to incoming requests. Xyna can react to external signals or requests via triggers and filters. A Trigger implements an interface and can listen on a server socket for incoming requests. For each request an event is created. The trigger then calls the filters connected to it. Filters take over the handling and dispatching of the events, usually by calling a Xyna-workflow. (For more information, please have a look at the wiki pages Trigger and Filter).
Generated provider applications contain an OAS filter that calls the workflows labelled "Endpoint". As an example, the following image shows the endpoint workflow for the request "GET /ping". The generated endpoint workflow contains pre- and post-processing steps as well as decode and encode steps for parsing and validation of the request and the response. Your implementation workflow is called in the third step.
Deploy new trigger and filter instances:
-
Navigate to the Factory Manager and click on the tab "Trigger". You should see the Http trigger, which is part of the Http application. Click the plus button to deploy a new trigger instance.
-
In the dialog window set a trigger instance name and set the workspace that contains your implementation as runtime context. You can optionally add a description. Click the plus button to add a new start parameter. Select the parameter "port" and set a port for the trigger, e.g. 4246. Use the image below to verify whether your settings are correct and hit "Deploy Trigger".
Check that the trigger instance is enabled, which is indicated by a "play" symbol next to the name. -
Open the tab "Filter". There should be an OAS Filter which is part of the generated provider application, in this case "Xyna_Ping_Service_Provider". Click the plus button to deploy a new filter instance.
-
Enter a name for the filter instance and set the workspace with your implementation as runtime context. Select the name of the trigger instance you just deployed to register this filter instance with the trigger instance. You can add a description which is optional. Compare your settings with those in the image below and click "Deploy Filter".
As before, check that the filter instance is enabled.
If you followed the steps in this tutorial, you should now be able to send requests to the api implemented in Xyna. This can be tested with a simple curl request. If you are on the same machine on which Xyna is running on, just execute:
$ curl localhost:4246/pingservice/ping
Use the correct port of your trigger instance. With the implementation provided above, the return message looks like this:
{
"outputStr" : "ping successful"
}
If the query parameter for this endpoint is specified, the value is passed through to the output:
$ curl localhost:4246/pingservice/ping?input="Hello"
{
"outputStr" : "Hello"
}
You can also see in the Process Monitor that the endpoint workflow xmcp.oas.provider.xynaPing.wf.GETPingEndpoint is executed for each request.
- Validation, pre- and post-processing
- TMF import (WIP)