diff --git a/README.md b/README.md index 0771bd9..d4c388b 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ start! After you have tried out application simulator with the quick start, you can learn using it with the step by step tutorial: -1. [Two java services](./docs/tutorial/1-two-java-services.md) +1. [Two services](./docs/tutorial/1-two-services.md) 2. [A database and more services](./docs/tutorial/2-a-database-and-more-services.md) 3. [Errors and randomness](./docs/tutorial/3-errors-and-randomness.md) 4. [Observability with OpenTelemetry](./docs/tutorial/4-observability-with-opentelemetry.md) diff --git a/docs/quick-start/kubernetes.md b/docs/quick-start/kubernetes.md index ad4101e..a9a698c 100644 --- a/docs/quick-start/kubernetes.md +++ b/docs/quick-start/kubernetes.md @@ -3,6 +3,8 @@ You can turn an [app sim config](../specification/README.md) into kubernetes manifest files using the [k8s generator](../../scripts/generators/k8s/). +## Generate k8s manifest files + The generator is available as docker image and you can retrieve it by running ```shell @@ -16,7 +18,7 @@ in a new folder: services: frontend: type: java - port: 3000 + exposedPort: 3000 endpoints: http: /upload: @@ -56,8 +58,10 @@ To generate manifest files for kubernetes from this file run docker run --rm -t -i -v ${PWD}/deployments:/app/deployments -v ${PWD}:/mnt ghcr.io/cisco-open/app-simulator-generators-k8s:latest --config /mnt/config.yaml ``` -This will create a set of YAML files in the `deployments` folder of your current -working directory. +## Run application simulation + +The last step has created a set of YAML files in the `deployments` folder of +your current working directory. To deploy the simulation into your cluster run @@ -66,4 +70,17 @@ kubectl apply -f deployments/ ``` This will bring up the three services (`frontend`, `processing` and -`virus-scanner`) and a loader (`user-1`). +`virus-scanner`) and a loader (`user-1`). Run `kubectl get pods` to verify that +all services are up and running. + +The loader will continuously load from the `/upload` endpoint. You can also +reach that endpoint yourself, either by opening +in the browser or by running the following: + +```shell +curl http://localhost:3000/upload +``` + +The files in `deployments/` that were generated now work independent of the +generator. You can use them wherever you want and you can modify them to your +needs. diff --git a/docs/specification/README.md b/docs/specification/README.md index 3951ff5..60854a7 100644 --- a/docs/specification/README.md +++ b/docs/specification/README.md @@ -1,43 +1,54 @@ # Application Simulator Configuration Specification -The following document outlines the technical specification for the configuration -files used by different components of [cisco-open/app-simulator](https://github.com/cisco-open/app-simulator). +The following document outlines the technical specification for the +configuration files used by different components of +[cisco-open/app-simulator](https://github.com/cisco-open/app-simulator). ## Components There are two groups of components: -- **generators** are convenience functions that translate an application simulator - configuration file for multiple containers into the format recognized by popular - container orchestration engines, like Kubernetes or docker compose. An application - simulator configuration file is for the most part independent of the orchestration engine, such that - it is possible to reuse a configuration with different orchestration engines. -- **containers** are the building blocks of application simulator. They encapsulate - **services**, **databases** and **loaders** which can be combined to represent a - complex microservice architecture. Containers share some of their configuration, - but they also have some domain-specific settings. - -Component configurations MAY contain elements that are specific to one orchestration engine. -They are grouped in under a key that identified the engine, i.e. `k8s` for Kubernetes and -`dockerCompose` for docker compose. +- **generators** are convenience functions that translate an application + simulator configuration file for multiple containers into the format + recognized by popular container orchestration engines, like Kubernetes or + docker compose. An application simulator configuration file is for the most + part independent of the orchestration engine, such that it is possible to + reuse a configuration with different orchestration engines. +- **containers** are the building blocks of application simulator. They + encapsulate **services**, **databases** and **loaders** which can be combined + to represent a complex microservice architecture. Containers share some of + their configuration, but they also have some domain-specific settings. + +Component configurations MAY contain elements that are specific to one +orchestration engine. They are grouped in under a key that identified the +engine, i.e. `k8s` for Kubernetes and `dockerCompose` for docker compose. ## Generator configuration -The configuration file that can be read by a generator is called "application simulator configuration file" (or short "app sim config"), since it -represents the top-level structure of a simulated microservice application. +The configuration file that can be read by a generator is called "application +simulator configuration file" (or short "app sim config"), since it represents +the top-level structure of a simulated microservice application. -A generator MUST support reading an app sim config in YAML format. A generator MAY support other formats like JSON, TOML, etc. +A generator MUST support reading an app sim config in YAML format. A generator +MAY support other formats like JSON, TOML, etc. -The top level element of an app sim config file MUST be [mapping](https://yaml.org/spec/1.2.2/#mapping) and MAY contain -sections represented by the following keys: +The top level element of an app sim config file MUST be +[mapping](https://yaml.org/spec/1.2.2/#mapping) and MAY contain sections +represented by the following keys: -- **global**: the value node MUST either be empty, or a mapping that contains configurations that are either relevant for the generation process or applied to all **containers**. -- **services**: the value node MUST either be empty, or a mapping of **services** by their name. -- **databases**: the value node MUST either be empty, or a mapping of **databases** be their name. -- **loaders**: the value node MUST either be empty, or a mapping of **loaders** by their name. +- **global**: the value node MUST either be empty, or a mapping that contains + configurations that are either relevant for the generation process or applied + to all **containers**. +- **services**: the value node MUST either be empty, or a mapping of + **services** by their name. +- **databases**: the value node MUST either be empty, or a mapping of + **databases** be their name. +- **loaders**: the value node MUST either be empty, or a mapping of **loaders** + by their name. -The structure of the mappings for the different **container** components (**services**, **databases**, **loaders**) are described -below in the chatper [Container configuration](#container-configuration). +The structure of the mappings for the different **container** components +(**services**, **databases**, **loaders**) are described below in the chatper +[Container configuration](#container-configuration). The **global** configuration MAY have the following child nodes: @@ -53,7 +64,7 @@ All **container** configurations share the following settings: - **type** (required) - **name** -- **port** +- **exposedPort** - **aliases** - **enabled** diff --git a/docs/tutorial/1-two-java-services.md b/docs/tutorial/1-two-java-services.md deleted file mode 100644 index 931d21a..0000000 --- a/docs/tutorial/1-two-java-services.md +++ /dev/null @@ -1 +0,0 @@ -# Tutorial 1: Two java services diff --git a/docs/tutorial/1-two-services.md b/docs/tutorial/1-two-services.md new file mode 100644 index 0000000..6d0c1be --- /dev/null +++ b/docs/tutorial/1-two-services.md @@ -0,0 +1,68 @@ +# Tutorial 1: Two services + +> [!NOTE] +> +> This tutorial is work in progress. + +Make sure that you have either completed the +[docker compose](../quick-start/docker-compose/README.md) or +[kubernetes](../quick-start/kubernetes.md) quick start. + +In this tutorial you will learn more about the structure of an application +simulation configuration (app sim config) and how you can influence the behavior +of your services. + +Create a new empty directory, in this directory, create a `config.yaml` file +with the following content: + +```yaml +services: + frontend: + type: java + endpoints: + http: + /list: + - http://backend/list/items + backend: + type: java + endpoints: + http: + /list/items: + - slow,1024 +loaders: + user1: + type: curl + wait: 5 + sleep: 1 + urls: + - http://frontend/list +``` + +This configuration file defines two services and one loader: + +1. The service `frontend` is a Java-based application, that provides an HTTP + endpoint called `/list`. When this endpoint gets called, it will send a HTTP + request to the URL `http://backend/list/items` +2. The service `backend` is also a Java-based application that provides an HTTP + endpoint, called `/list/items`. When this endpoind gets called, it will some + "slow" code for ~1024 milliseconds. +3. The loader `user1` is a [curl](https://curl.se/)-based load generator. It + will wait 5 seconds after start up and then call the URL + `http://frontend/list` repeatedly. It will wait 1 second between each call. + +Use your preferred [generator](../../scripts/generators/) to deploy this +simulation: + +- For docker compose run + + ```shell + docker run --rm -t -i -v ${PWD}:/mnt cisco-open/app-simulator-generators-docker-compose --config /mnt/config.yaml --output /mnt/docker-compose.yaml + docker compose up + ``` + +- For kubernetes run + + ```shell + docker run --rm -t -i -v ${PWD}/deployments:/app/deployments -v ${PWD}:/mnt ghcr.io/cisco-open/app-simulator-generators-k8s:latest --config /mnt/config.yaml + kubectl apply -f deployments/ + ``` diff --git a/docs/tutorial/2-a-database-and-more-services.md b/docs/tutorial/2-a-database-and-more-services.md index 2676f0a..e26c447 100644 --- a/docs/tutorial/2-a-database-and-more-services.md +++ b/docs/tutorial/2-a-database-and-more-services.md @@ -1 +1,45 @@ # Tutorial 2: A database and more services + +> [!NOTE] +> +> This tutorial is work in progress. + +In this tutorial we will take the simulation with +[two services from tutorial 1](./1-two-services.md) and add a database and some +additional services. + +If you continue from tutorial 1, open `config.yaml`, otherwise create a file +with that name in an empty directory. Fill the file with the following content: + +```yaml +services: + frontend: + type: java + endpoints: + http: + /list: + - http://backend/list/items + backend: + type: java + endpoints: + http: + /list/items: + - slow,1024 + - sql://backend-db/mydb?query=SELECT id, name FROM items + /insert/item: + - sql://backend-db/mydb?query=INSERT INTO items(id,name) VALUES(123, + 'test') +databases: + backend-db: + type: mysql + databases: + mydb: + items: [id, name] +loaders: + user1: + type: curl + wait: 5 + sleep: 1 + urls: + - http://frontend/list +``` diff --git a/docs/tutorial/3-errors-and-randmoness.md b/docs/tutorial/3-errors-and-randmoness.md index 2dcf308..673900f 100644 --- a/docs/tutorial/3-errors-and-randmoness.md +++ b/docs/tutorial/3-errors-and-randmoness.md @@ -1,3 +1,16 @@ # Tutorial 3: Errors and randomness -to be done +> [!NOTE] +> +> This tutorial is work in progress. + +In this tutorial we will take the simulation +[from tutorial 2](./2-a-database-and-more-services.md) and introduce errors and +randomness into the behavior of the services + +If you continue from tutorial 2, open `config.yaml`, otherwise create a file +with that name in an empty directory. Fill the file with the following content: + +```yaml + +```