diff --git a/README.md b/README.md index 61e1d3e3af12547d52a3a5fc7583b694a6b53407..d249e0e11de6ce18ad1c55b4b1f028ebb1c8cbae 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ - [Build and run the app with Docker](#build-and-run-the-app-with-docker) - [Collecting Metrics](#collecting-and-displaying-metrics) - [Grafana](#grafana-setup) +- [Runnable scenario](#runnable-scenario) ## About Project @@ -89,13 +90,6 @@ cd core mvn ``` -or alternatively: - -```bash -cd core -mvn spring-boot:run -``` - To see the running REST api's in action, use CURL or swagger UI: http://localhost:8090/swagger-ui/index.html @@ -173,7 +167,8 @@ docker-compose down To collect the metrics in an automated way we use Prometheus, Grafana is used for displaying the most useful metrics. -Both services are running in docker container together with modules.<br> +Both services are running automatically in docker container together with other modules, + when you run the docker-compose.<br> You can check prometheus UI at http://localhost:9090.<br> You can see grafana at http://localhost:3000 @@ -183,4 +178,98 @@ Credentials to log into Grafana are: - user `admin` - password `admin` -Two dashboards are imported automatically, but feel free to experiment and see different metrics. \ No newline at end of file +Two dashboards are imported automatically, but feel free to experiment and see different metrics. + +## Runnable scenario + +To showcase our system, we defined two scenarios:<br> +- Engineer, manager and their everyday business +- Applications module load test + +### Engineer, manager and their everyday business +Our system is a management system for a formula 1 team. It is designed to help engineers and manager +to keep track of drivers, car components and current state of the cars. Naturally, this system will +not experience any high loads, so (in the core module) there is no reason to simulate user behaviour +with any kind of script. The best way to test the system is to manually try it. + +#### 1. Become a manager of our F1 team (optional) +Navigate to ``/core/src/main/resources/application.properties`` file and add your e-mail address to the +``notification.receivers`` field. You can either delete the address that's already there, or add your own +separated with a comma(,). This means that you will get e-mail notifications same as the manager would. + +#### 2. Run all modules +```bash +docker-compose up --build +``` +Now, all the modules, including prometheus and grafana should be available through your web browser. +Feel free to play around with every module's swagger UI. Ports of all modules are listed above.<br> +Also feel free to monitor the system through grafana during all the following steps. + +#### 3. Log in as an engineer and create a new component +- Visit swagger UI of core module at http://localhost:8090/swagger-ui/index.html. +- Check, that without logging in, you are unable to perform any operations, except the /seed and /clear. +- Log in with the authorize button and select the engineer scope (test_1). +- Now, you are able to perform only the operations at the ``/carComponent`` endpoint. +- Create a new component that you just made with your team of engineers at your lab. +- Log out from the engineer scope. + +If you followed step 1, you (as a manager) should also get an e-mail notification about +new component being created. + +*Note: It is possible to time-out our team's e-mail address if you make too many new notifications (for example during the second scenario - load test). +So if the Notifications module is not working, try to wait a few minutes, maybe another reviewer +was doing a load test at the same time. In real system we would not use a regular Gmail address for such job - there would be no timeouts.* + +#### 4. Log in as an manager and create a visualization of a car +- Log in using a manager scope (test_5), same way as before. +- Now, you can perform all operations, except POST at /carComponent (only engineers can do that). +- Check, that the new component created by the engineer is really in the system. +- Play around with the other endpoints, for example try to change the driver in one of the cars. +(If you cleared the database before, seed it so you don't have to create everything manually) +- Now call the GET operation on a certain car, this operation returns the car as a JSON directly in the response, +but also calls the Visualization module with that car. +- Check ``/visualization/output-data`` and you should be able to see a PDF visualization of the car you chose. +- Hopefully you chose the right components and drivers for your cars. Good luck in the next race. + +This scenario showcased the functionality of the Core module and it's communication with Notification and Visualization modules. + +### Applications module load test: +This scenario showcases a situation, where lots of people are sending applications to this F1 team.<br> +At the same time, some admin (someone from HR for example) is randomly accepting/rejecting these applications.<br> + +Before running this scenario make sure you have installed ``python`` and ``locust`` module, which can be installed with<br> +``pip install locust`` + +#### 1. Run all modules + +```bash +docker-compose up +``` + +#### 2. Run script + +```bash +cd scenario-locust +locust -f scenario.py --host http://localhost:8081 --users 2 +``` +*Note: Script can be run without arguments, but then you have them fill up in the next step.* + +#### 3. Open in web browser + +```bash +http://localhost:8089/ +``` +Adjust ``Number of users`` and ``Spawn rate`` to test different scenarios. +<br>*Note: At least 2 users are required to simulate ``Admin`` and ``User`` simultaneously* +<br>*Note: !Do not change Host!* + +#### 4. Collecting and displaying Metrics +After started swarming in web browser, locust provides several pages to display various data. +Feel free to explore them, but two main pages are ``Statistics`` and ``Charts`` + +If you want to display more complex metrics, do not hesitate to use: +- ``Grafana`` http://localhost:9090 +- ``Prometheus`` http://localhost:3000 + +#### 5. Clear Data - optional +Don't forget to clear your Application DB via ``/clear`` end point. \ No newline at end of file diff --git a/notification/openapi.yaml b/notification/openapi.yaml index 975d5f7cbfac27de5761ce59eb5ce89611b680fb..b212e96299d64ab3f266e3b086f2f6fa8611ef5e 100644 --- a/notification/openapi.yaml +++ b/notification/openapi.yaml @@ -82,10 +82,10 @@ components: type: string description: Type of a component enum: - - chassis - - engine - - frontWing - - suspension + - CHASSIS + - ENGINE + - FRONTWING + - SUSPENSION CarComponentDto: type: object title: Component diff --git a/scenario-locust/scenario.py b/scenario-locust/scenario.py new file mode 100644 index 0000000000000000000000000000000000000000..abbeff262096946c59db8351db6675065f728afc --- /dev/null +++ b/scenario-locust/scenario.py @@ -0,0 +1,35 @@ +from locust import HttpUser, task +import random + +class Admin(HttpUser): + fixed_count = 1 + + @task + def update_random_application_status(self): + response = self.client.get("/application") + + if len(response.json()) == 0: + return + + applicationNumber = random.choice([i for i in range(1, len(response.json()))]) + status = random.choice(["accepted", "rejected"]) + self.client.put(f"/application/status?id={applicationNumber}&applicationStatus={status}") + + @task + def get_application(self): + self.client.get("/application?id=1") + + @task + def get_all_application(self): + self.client.get("/application") + + +class User(HttpUser): + @task + def create_application(self): + self.client.post("/application", json={ + "name": "Jozko", + "surname": "Example", + "birthday": "2000-05-06", + "email": "john@example.com" + })