diff --git a/README.md b/README.md index 33963e8..a890d3a 100644 --- a/README.md +++ b/README.md @@ -2,25 +2,26 @@ This is a mock API playground used for developing robust API wrappers and other HTTP-related code. +The API is created and served using [Mockoon](https://mockoon.com). Latency, +timeouts, and outages are introduced at random with +[Toxiproxy](https://github.com/Shopify/toxiproxy). + ## Requirements -Requires either [Mockoon Desktop](https://mockcoon.com/download) or -[Mockoon CLI](https://hub.docker.com/r/mockoon/cli). +- Docker Compose ## Features - JSON responses - Randomized HTTP responses +- Randomized timeouts, latency, and outages ## Usage -Import the environment file [mockoon-env.json](mockoon-env.json) into Mockcoon Desktop and click "Start Server". - - -For a more simple deployment, use Docker Compose: ```shell docker compose up ``` -Requests will be served at http://localhost:3000 unless another port is specified -in the Mockcoon environment settings or the [docker-compose.yml](docker-compose.yml) file. +Requests with random faults will be served at http://localhost:18080. The API +is accessible without Toxiproxy at http://localhost:3000, but will stil throw +some bad response codes at random. ## Routes diff --git a/docker-compose.yml b/docker-compose.yml index 9a6060d..1f7c9d3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,5 +5,17 @@ services: ports: - 3000:3000 volumes: - - ./mockoon-env.json:/data:ro + - ./mockoon/mockoon-env.json:/data:ro command: ["--data", "data"] + toxiproxy: + image: ghcr.io/shopify/toxiproxy:2.6.0 + ports: + - 8474:8474 + - 18080:18080 + depends_on: + - mockoon + toxifier: + build: + context: ./toxiproxy + depends_on: + - toxiproxy diff --git a/mockoon-env.json b/mockoon/mockoon-env.json similarity index 99% rename from mockoon-env.json rename to mockoon/mockoon-env.json index a5c33ba..1272720 100644 --- a/mockoon-env.json +++ b/mockoon/mockoon-env.json @@ -4,7 +4,7 @@ "name": "API Playground", "endpointPrefix": "", "latency": 0, - "port": 3002, + "port": 3000, "hostname": "", "folders": [ { diff --git a/toxiproxy/Dockerfile b/toxiproxy/Dockerfile new file mode 100644 index 0000000..31ca355 --- /dev/null +++ b/toxiproxy/Dockerfile @@ -0,0 +1,10 @@ +FROM alpine:latest + +RUN apk update +RUN apk upgrade +RUN apk add curl bash + +WORKDIR /tmp +COPY toxify.sh /tmp/toxify.sh + +CMD ["/bin/bash", "toxify.sh"] \ No newline at end of file diff --git a/toxiproxy/toxify.sh b/toxiproxy/toxify.sh new file mode 100644 index 0000000..2822f06 --- /dev/null +++ b/toxiproxy/toxify.sh @@ -0,0 +1,106 @@ +#!/bin/bash + +SERVICE_NAME=mockapi_dev + +TIMEOUT_ENABLED=0 +LATENCY_ENABLED=0 +OUTAGE_ENABLED=0 + +# Toxic functions +enable_timeout() { + if (( TIMEOUT_ENABLED == 0 )); then + echo "enabling timeouts..." + curl -s -X POST http://toxiproxy:8474/proxies/$SERVICE_NAME/toxics -d'{ + "type": "timeout", + "name": "timeouts", + "attributes": {"timeout": 7000} + }' > /dev/null + TIMEOUT_ENABLED=1 + fi +} + +disable_timeout() { + if (( TIMEOUT_ENABLED == 1 )); then + echo "disabling timeouts..." + curl -s -X DELETE http://toxiproxy:8474/proxies/$SERVICE_NAME/toxics/timeouts > /dev/null + TIMEOUT_ENABLED=0 + fi +} + +enable_latency() { + if (( LATENCY_ENABLED == 0 )); then + echo "enabling latency..." + curl -s -X POST http://toxiproxy:8474/proxies/$SERVICE_NAME/toxics -d'{ + "type": "latency", + "name": "lag", + "attributes": {"latency": 3000, "jitter": 2000} + }' > /dev/null + LATENCY_ENABLED=1 + fi +} + +disable_latency() { + if (( LATENCY_ENABLED == 1 )); then + echo "disabling latency..." + curl -s -X DELETE http://toxiproxy:8474/proxies/$SERVICE_NAME/toxics/lag > /dev/null + LATENCY_ENABLED=0 + fi +} + +enable_outage() { + if (( OUTAGE_ENABLED == 0 )); then + echo "enabling outage..." + curl -s -X POST http://toxiproxy:8474/proxies/$SERVICE_NAME -d'{ + "enabled": false + }' > /dev/null + OUTAGE_ENABLED=1 + fi +} + +disable_outage() { + if (( OUTAGE_ENABLED == 1 )); then + echo "disabling outage..." + curl -s -X POST http://toxiproxy:8474/proxies/$SERVICE_NAME -d'{ + "enabled": true + }' > /dev/null + OUTAGE_ENABLED=0 + fi +} + + +# Sleep to allow toxiproxy to start listening +sleep 5 + +# Add upstream +curl -s -X POST -d "{\"name\": \"$SERVICE_NAME\", \"listen\": \"toxiproxy:18080\", \"upstream\": \"mockoon:3000\"}" http://toxiproxy:8474/proxies > /dev/null + +# infinite loop +while true +do + # Disable all toxics from previous iteration + disable_timeout + disable_latency + disable_outage + + # Randomly choose a new toxic or as per your request, do nothing (50% chance) + case $(( RANDOM % 6 )) in + 0) + enable_timeout + ;; + 1) + enable_latency + ;; + 2) + enable_outage + ;; + 3) # Do nothing + ;; + 4) # Do nothing + ;; + 5) # Do nothing + ;; + esac + + # Sleep for 30 seconds before the next iteration. + sleep 30 +done \ No newline at end of file