Skip to content

Commit

Permalink
docs: add details about deployment of .gama files #3646 (#3653)
Browse files Browse the repository at this point in the history
  • Loading branch information
jgomer2001 committed Jan 20, 2023
1 parent 0d9a2a7 commit 2a8377e
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 5 deletions.
174 changes: 174 additions & 0 deletions docs/admin/developer/agama/gama-deployment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
# `.gama` files deployment

Flows management often incurs several tasks such as manual upload of UI templates and web assets plus java source files, and interaction with a REST API for the CRUD of flows themselves. Here, an alternative mechanism for deployment is described where several flows can be supplied alongside their assets and metadata in a single bundle for bulk processing at the server.

This mechanism may facilitate developers' work when multiple flows need to be manipulated. Also it can be used in the development of tools that may serve as IDEs for Agama.

## What's in an `.gama` file?

A `.gama` file is an atomic deployment unit. It is an archive containing the several flows to deploy on the server plus related files and some metadata. This archive has to be "presented" to an [API endpoint](#api-endpoints) which takes charge of its processing.

The below shows the structure of an extracted `.gama` file (recall it has to originally follow the ZIP format):

```
├── code/
├── lib/
├── web/
├── project.json
├── LICENSE
└── README.md
```

- `code` directory holds Agama code. Every flow has to reside in a separate file with extension `flow` and with file name matching the qualified name of the flow in question
- `lib` can contain Java/Groovy source files and `jar` files. These are used to agument the classpath as explained [here](./java-classpath.md)
- `web` is expected to hold all UI templates plus required web assets (stylesheets, images, etc.) of all flows in this bundle
- `project.json` file contains metadata about this bundle, like display name, description, etc. More on this later
- `README.md` file may contain extra documentation in markdown format

**Notes**:

- Except for `code` and `web` directories, all elements in the archive structure are optional
- A `flow` file in `code` may reside at the top level or at any level in a directory structure
- `jar` files in `lib` are expected to be at top level only. Note these files are ignored in Cloud Native installations
- `java` and `groovy` files in `lib` are expected to be placed in a directory hierarchy according to the Java packages they belong to
- files in `web` must follow a directory structure that is consistent with respect to `Basepath` and `RRF` directives found in the included flows. Note except for templates, all files placed here will be publicly accessible via HTTP once the archive is deployed
- The file extension `gama` is not mandatory, just a mere convention

## Metadata

`project.json` file is expected to contain metadata about the contents of the archive in JSON format. While these details don't have direct influence in the deployment process, data is saved for reference and can be later retrieved by the API for deployment listing purposes. This is an example:

```
{
"projectName": "A name that will be associated to this deployment",
"author": "A user handle that identifies you",
"description": "Other relevant data can go here"
}
```

## Sample file

As an example assume you want to deploy these two flows:

```
Flow test
Basepath "hello"
in = { name: "John" }
RRF "templates/index.ftlh" in
Log "Done!"
Finish "john_doe"
```

```
Flow com.foods.sweet
Basepath "recipes/desserts"
...
choice = RRF "selection.ftl"
list = Call com.foods.RecipeUtils#retrieveIngredients choice.meal
...
```

Here is how the archive might look like:

```
├── code/
│ └── test.flow
│ └── com.foods.sweet.flow
├── web/
│ ├── hello/
| | └── templates/
│ | └── index.ftlh
│ | └── js/
│ | └── font-awesome.js
| └── recipes/
│ └── desserts/
│ └── selection.ftl
│ └── logo.png
├── lib/
│ └── com/
│ └── foods/
│ └── RecipeUtils.java
└── project.json
```

## API endpoints

Once a `.gama` file is built the deployment process follows. Here is a typical workflow:

1. Send (POST) the archive contents to the deployment endpoint. Normally a 202 response should be obtained meaning a task has been queued for processing
2. Poll (via GET) the status of the deployment. When the archive has been effectively deployed a status of 200 should be obtained. It may take up to 30 seconds for the process to complete once the archive is sent
3. Test the deployed flows and adjust the archive for any changes required
4. Go to point 1 if needed
5. If desired, a request can be sent to undeploy the flows (via DELETE)

The following tables summarize the available endpoints. All URLs are relative to `/jans-config-api/api/v1`. An OpenAPI document is also available [here](https://github.com/JanssenProject/jans/blob/main/jans-config-api/docs/jans-config-api-swagger-auto.yaml#L-110-L254).


|Endpoint -> |`/ads-deployment/list`|
|-|-|
|Purpose|Retrieve a list of deployments in the server. This is not a search, just a paged listing|
|Method|GET|
|Query params|`start` and `count` helps paginating results. `start` is 0-index based. Both params optional|
|Output|Existing deployments (regardless they are thoroughly processed or still being deployed). They are listed and sorted by deployment date|
|Sample output|`{"start":...,"totalEntriesCount":...,"entriesCount":...,"entries":[ ... ]}`|
|Status|200 (OK)|


|Endpoint -> |`/ads-deployment`|
|-|-|
|Purpose|Retrieve details of a single deployment by name|
|Method|GET|
|Query params|`name` - mandatory|
|Sample output|The structure of a deployment is explained below|
|Status|200 (deployment task is finished), 204 (task still in course), 404 (project unknown), 400 (a param is missing)|


|Deployment structure|Notes|Example|
|-|-|-|
|dn|Distinguished name|`jansId=123,ou=deployments,ou=agama,o=jans`|
|id|Identifier of deployment (generated automatically)|`115276`|
|createdAt|Datetime (in UTC) of the instant the deployment task was created (POSTed)|`2022-12-07T21:47:42`|
|taskActive|Boolean value indicating if the deployment task is being currently processed, ie. the .agama file is being scanned, flows analysed, etc.|`false`|
|finishedAt|Datetime (in UTC) representing the instant when the deployment task was finished, or `null` if it hasn't ended|`2022-12-07T21:48:42`|
|details|Extra details, see below|


|Deployment details structure|Notes|Example|
|-|-|-|
|projectMetadata|Includes author, type, description, and project's name - as supplied when the deployment task was created||
|error|A general description of the error (if presented) when processing the task, otherwise `null`|`Archive missing web and/or code subdirectories`|
|flowsError|A mapping of the errors obtained per flow found in the archive. The keys correspond to qualified names. A `null` value indicates the flow was successfully added|`{ "co.acme.example": "Syntax error on line 4", "io.jans.test": null }`|


|Endpoint -> |`/ads-deployment`|
|-|-|
|Purpose|Add or replace an ADS project to the server|
|Method|POST|
|Query params|`name` (the project's name) - mandatory|
|Body|The binary contents of a `.gama` file. See example below. Ensure to use header `Content-Type: application/zip`|
|Output|Textual explanation, e.g. `A deployment task for project XXX has been queued. Use the GET endpoint to poll status`|
|Status|202 (the task was created and scheduled for deployment), 409 (there is a task already for this project and it hasn't finished yet), 400 (a param is missing)|


|Endpoint -> |`/ads-deployment`|
|-|-|
|Purpose|Undeploy an ADS project from the server. Entails removing flows and assets initally supplied|
|Method|DELETE|
|Query params|`name` (the project's name) - mandatory|
|Status|204 (scheduled for removal), 409 (the project is being deployed currently), 404 (unknown project), 400 (a param is missing)|

### Endpoints access

API operations are protected by Oauth2 scopes this way:

- GET: `https://jans.io/oauth/config/agama.readonly`
- Others: `https://jans.io/oauth/config/agama.write`

## Internals of deployment

TODO

9 changes: 7 additions & 2 deletions docs/admin/developer/agama/lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ As usual, several iterations will take place until you get it right.

!!! Note
Throughout this document it is assumed you have a standard single-VM Janssen installation

## Design and code

It is up to developers how to design. This will normally require identifying the several "steps" that make up a flow and the conditions upon which "branching" takes place. Also it is important to check already existing flows in the server that may be reused for the purpose.
Expand All @@ -34,7 +34,7 @@ Currently there are no IDE/editor plugins for coding in Agama available. We hope

As a flow executes things can go wrong for reasons that developers cannot foresee. A database may have crashed, a connection to an external system may have failed, the flow engine may have some bug, etc. When an abnormal situation is presented, a flow simply crashes.

If a flow crashes, its parent flows (or flow) if they exist, crash as well. Trying to handle crashes involves a lot of planning and work which is too costly and will unlikely account for the so many things that might fail in a real setting. Thus, coding defensively is not recommended. While in Agama is possible to deal with Java exceptions, that feature should be used sparingly.
If a flow crashes, its parent flows (or flow) if they exist, crash as well. Trying to handle crashes involves a lot of planning and work which is too costly and will unlikely account for the so many things that might fail in a real setting. Thus, coding defensively is not recommended. While in Agama is possible to deal with Java exceptions, that feature should be used sparingly.

## Creating a flow

Expand Down Expand Up @@ -263,3 +263,8 @@ By design Agama is a [transpiled language](./dsl.md#language-compiler) and trans
- Otherwise, no error is shown and the flow will behave as if no changes had been applied to the flow's code. This helps preserve the last known "healthy" state of your flow so end-users are not impacted

In any case, the cause of the error can be inspected by [retrieving](#flow-retrieval-and-removal) the flow's data and checking the property `codeError`.


## `.gama` files: an alternative for deployment

There is an alternative way to manage flows and is via deployment of `.gama` files. This is a more elaborate technique that allows bundling several flows and their required assets and classes for bulk deployment. Learn more about it [here](#gama-deployment.md).
8 changes: 5 additions & 3 deletions docs/admin/developer/agama/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,16 +178,16 @@ curl -k -i -H 'Authorization: Bearer <token>'

Note the source code is not part of the response by default. Append `?includeSource=true` to the URL for the source to be included.


!!! Important
!!! Important
There are different, more detailed ways to retrieve, create and update flows but they are regarded in the [Development lifecycle](./lifecycle.md) doc page.


Finally the flow assets must be uploaded. You can SFTP/SCP or use other means to do so. In our example, only two steps are required:

- Create a directory `hello` under `/opt/jans/jetty/jans-auth/agama/ftl`
- Upload the [template](https://github.com/JanssenProject/jans/raw/main/docs/admin/developer/agama/index.ftlh) there

There is an alternative way to manage flows and is via deployment of `.gama` files. This is a more elaborate technique that allows bundling several flows and their required assets and classes for bulk deployment. Learn more about it [here](#gama-deployment.md).

### Craft an authentication request

This section assumes your [client application](#client-application) is ready, or at least you have made the configurations required so that you can trigger an (OpendId Connect) authentication request.
Expand Down Expand Up @@ -231,6 +231,8 @@ We have barely scratched the surface so far. There is lots more to learn in orde

- [Flows lifecycle](./flows-lifecycle.md)

- [`.gama` files deployment](#gama-deployment.md)

- [Engine configuration](./engine-config.md)

- [Sample flows](./samples.md)
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,7 @@ nav:
- 'DSL Reference': 'admin/developer/agama/dsl-full.md'
- 'Java Classpath': 'admin/developer/agama/java-classpath.md'
- 'A closer look to the engine': 'admin/developer/agama/hello-world-closer.md'
- '.gama files deployment': 'admin/developer/agama/gama-deployment.md'
- 'FAQ': 'admin/developer/agama/faq.md'
- 'Interception Script Overview': 'admin/developer/interception-scripts.md'
- 'Script Debugging': 'admin/developer/interception-scripts-debug.md'
Expand Down

0 comments on commit 2a8377e

Please sign in to comment.