Skip to content

Commit a497cbc

Browse files
HarshCasperwhummerremotesynth
authored
add initial version of WireMock extension (#118)
--------- Co-authored-by: Waldemar Hummer <waldemar.hummer@gmail.com> Co-authored-by: Brian Rinaldi <brian.rinaldi@gmail.com>
1 parent f4b4626 commit a497cbc

28 files changed

+8208
-2
lines changed

.github/workflows/wiremock.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
name: LocalStack WireMock Extension Tests
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
paths:
8+
- 'wiremock/**'
9+
push:
10+
branches:
11+
- main
12+
paths:
13+
- 'wiremock/**'
14+
workflow_dispatch:
15+
16+
env:
17+
LOCALSTACK_DISABLE_EVENTS: "1"
18+
LOCALSTACK_AUTH_TOKEN: ${{ secrets.LOCALSTACK_AUTH_TOKEN }}
19+
20+
jobs:
21+
integration-tests:
22+
name: Run WireMock Extension Tests
23+
runs-on: ubuntu-latest
24+
timeout-minutes: 10
25+
steps:
26+
- name: Checkout
27+
uses: actions/checkout@v4
28+
29+
- name: Set up Terraform
30+
uses: hashicorp/setup-terraform@v3
31+
32+
- name: Set up LocalStack and extension
33+
run: |
34+
cd wiremock
35+
36+
docker pull localstack/localstack-pro &
37+
docker pull wiremock/wiremock &
38+
docker pull public.ecr.aws/lambda/python:3.9 &
39+
pip install localstack terraform-local awscli-local[ver1]
40+
41+
make install
42+
make dist
43+
localstack extensions -v install file://$(ls ./dist/localstack_wiremock-*.tar.gz)
44+
45+
DEBUG=1 localstack start -d
46+
localstack wait
47+
48+
- name: Run sample app test
49+
run: |
50+
cd wiremock
51+
make sample-oss
52+
53+
- name: Print logs
54+
if: always()
55+
run: |
56+
localstack logs
57+
localstack stop

.gitignore

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ dist/
1414
downloads/
1515
eggs/
1616
.eggs/
17-
lib/
1817
lib64/
1918
parts/
2019
sdist/
@@ -133,4 +132,6 @@ dmypy.json
133132
.vscode
134133

135134
node_modules/
136-
.DS_Store
135+
.DS_Store
136+
137+
.wiremock

wiremock/.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.venv
2+
dist
3+
build
4+
**/*.egg-info
5+
.eggs
6+
.terraform*
7+
terraform.tfstate*
8+
*.zip
9+
.wiremock

wiremock/Makefile

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
VENV_BIN = python3 -m venv
2+
VENV_DIR ?= .venv
3+
VENV_ACTIVATE = $(VENV_DIR)/bin/activate
4+
VENV_RUN = . $(VENV_ACTIVATE)
5+
6+
usage: ## Shows usage for this Makefile
7+
@cat Makefile | grep -E '^[a-zA-Z_-]+:.*?## .*$$' | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-15s\033[0m %s\n", $$1, $$2}'
8+
9+
venv: $(VENV_ACTIVATE)
10+
11+
$(VENV_ACTIVATE): pyproject.toml
12+
test -d .venv || $(VENV_BIN) .venv
13+
$(VENV_RUN); pip install --upgrade pip setuptools plux
14+
$(VENV_RUN); pip install -e .[dev]
15+
touch $(VENV_DIR)/bin/activate
16+
17+
clean:
18+
rm -rf .venv/
19+
rm -rf build/
20+
rm -rf .eggs/
21+
rm -rf *.egg-info/
22+
23+
install: venv ## Install dependencies
24+
$(VENV_RUN); python -m plux entrypoints
25+
26+
dist: venv ## Create distribution
27+
$(VENV_RUN); python -m build
28+
29+
publish: clean-dist venv dist ## Publish extension to pypi
30+
$(VENV_RUN); pip install --upgrade twine; twine upload dist/*
31+
32+
entrypoints: venv # Generate plugin entrypoints for Python package
33+
$(VENV_RUN); python -m plux entrypoints
34+
35+
format: ## Run ruff to format the whole codebase
36+
$(VENV_RUN); python -m ruff format .; python -m ruff check --output-format=full --fix .
37+
sample-oss: ## Deploy sample app (OSS mode)
38+
echo "Creating stubs in WireMock ..."
39+
bin/create-stubs.sh
40+
echo "Deploying sample app into LocalStack via Terraform ..."
41+
(cd sample-app-oss; tflocal init; tflocal apply -auto-approve)
42+
apiId=$$(awslocal apigateway get-rest-apis | jq -r '.items[0].id'); \
43+
endpoint=https://$$apiId.execute-api.us-east-1.localhost.localstack.cloud/dev/time-off; \
44+
echo "Invoking local API Gateway endpoint: $$endpoint"; \
45+
curl -k -v $$endpoint | grep time_off_date
46+
47+
sample-runner-setup: ## Set up the mock APIs for WireMock Cloud (Runner mode)
48+
echo "Creating stubs in WireMock ..."
49+
bin/setup-wiremock-runner.sh
50+
51+
sample-runner: ## Deploy sample app (Runner mode)
52+
echo "Deploying sample app into LocalStack via CDK ..."
53+
(cd sample-app-runner; npm install; cdklocal bootstrap; cdklocal deploy)
54+
apiId=$$(awslocal apigateway get-rest-apis | jq -r '.items[0].id'); \
55+
endpoint=https://$$apiId.execute-api.us-east-1.localhost.localstack.cloud/dev/models; \
56+
echo "Invoking local API Gateway endpoint: $$endpoint"; \
57+
curl -k -v $$endpoint
58+
59+
clean-dist: clean
60+
rm -rf dist/
61+
62+
.PHONY: clean clean-dist dist install publish usage venv format test

wiremock/README.md

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# WireMock on LocalStack
2+
3+
This repo contains a [LocalStack Extension](https://github.com/localstack/localstack-extensions) that facilitates developing [WireMock](https://wiremock.org)-based applications locally.
4+
5+
The extension supports two modes:
6+
7+
- **OSS WireMock**: Uses the open-source `wiremock/wiremock` image (default)
8+
- **WireMock Runner**: Uses `wiremock/wiremock-runner` with WireMock Cloud integration (requires API token)
9+
10+
## Prerequisites
11+
12+
- Docker
13+
- LocalStack Pro (free trial available)
14+
- `localstack` CLI
15+
- `make`
16+
- [WireMock CLI](https://docs.wiremock.io/cli/overview) (for WireMock Runner mode)
17+
18+
## Install from GitHub repository
19+
20+
This extension can be installed directly from this Github repo via:
21+
22+
```bash
23+
localstack extensions install "git+https://github.com/localstack/localstack-extensions.git#egg=localstack-wiremock&subdirectory=wiremock"
24+
```
25+
26+
## Install local development version
27+
28+
To install the extension into LocalStack in developer mode, you will need Python 3.11, and create a virtual environment in the extensions project.
29+
30+
In the newly generated project, simply run
31+
32+
```bash
33+
make install
34+
```
35+
36+
Then, to enable the extension for LocalStack, run
37+
38+
```bash
39+
localstack extensions dev enable .
40+
```
41+
42+
You can then start LocalStack with `EXTENSION_DEV_MODE=1` to load all enabled extensions:
43+
44+
```bash
45+
EXTENSION_DEV_MODE=1 localstack start
46+
```
47+
48+
## Usage
49+
50+
### OSS WireMock Mode (Default)
51+
52+
Start LocalStack without any special configuration:
53+
54+
```bash
55+
localstack start
56+
```
57+
58+
The WireMock server will be available at `http://wiremock.localhost.localstack.cloud:4566`.
59+
60+
You can import stubs using the WireMock Admin API (assuming a `stubs.json` exists in the local working directory):
61+
62+
```bash
63+
curl -X POST -H "Content-Type: application/json" \
64+
--data-binary "@stubs.json" \
65+
"http://wiremock.localhost.localstack.cloud:4566/__admin/mappings/import"
66+
```
67+
68+
### WireMock Runner Mode (Cloud Integration)
69+
70+
To use WireMock Runner with WireMock Cloud, you need:
71+
72+
1. A WireMock Cloud API token
73+
2. A `.wiremock` directory with your mock API configuration
74+
75+
#### Step 1: Get your WireMock Cloud API Token
76+
77+
1. Sign up at [WireMock Cloud](https://app.wiremock.cloud)
78+
2. Go to Settings → API Tokens
79+
3. Create a new token
80+
81+
#### Step 2: Create your Mock API configuration
82+
83+
First, create a Mock API in WireMock Cloud, then pull the configuration locally:
84+
85+
```bash
86+
# Install WireMock CLI if not already installed
87+
npm install -g @wiremock/cli
88+
89+
# Login with your API token
90+
wiremock login
91+
92+
# Pull your Mock API configuration
93+
# Find your Mock API ID from the WireMock Cloud URL (e.g., https://app.wiremock.cloud/mock-apis/zwg1l/...)
94+
wiremock pull mock-api <mock-api-id>
95+
```
96+
97+
This creates a `.wiremock` directory with your `wiremock.yaml` configuration.
98+
99+
#### Step 3: Start LocalStack with WireMock Runner
100+
101+
```bash
102+
LOCALSTACK_WIREMOCK_API_TOKEN="your-api-token" \
103+
LOCALSTACK_WIREMOCK_CONFIG_DIR="/path/to/your/project" \
104+
localstack start
105+
```
106+
107+
**Environment Variables:**
108+
109+
- `WIREMOCK_API_TOKEN`: Your WireMock Cloud API token (required for runner mode)
110+
- `WIREMOCK_CONFIG_DIR`: Path to the directory containing your `.wiremock` folder (required for runner mode)
111+
112+
Note: When using the LocalStack CLI, prefix environment variables with `LOCALSTACK_` to forward them to the container.
113+
114+
## Sample Application
115+
116+
See the `sample-app-runner/` directory for a complete example using Terraform that demonstrates:
117+
118+
- Creating an API Gateway
119+
- Lambda function that calls WireMock stubs
120+
- Integration testing with mocked external APIs

wiremock/bin/create-stubs.sh

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/bin/bash
2+
3+
# Import stubs into OSS WireMock (for WireMock Runner, use setup-wiremock-runner.sh)
4+
5+
STUBS_URL="${STUBS_URL:-https://library.wiremock.org/catalog/api/p/personio.de/personio-de-personnel/personio.de-personnel-stubs.json}"
6+
TMP_STUBS_FILE="/tmp/personio-stubs.json"
7+
WIREMOCK_URL="${WIREMOCK_URL:-http://wiremock.localhost.localstack.cloud:4566}"
8+
9+
echo "Downloading stubs from ${STUBS_URL}..."
10+
curl -s -o "$TMP_STUBS_FILE" "$STUBS_URL"
11+
12+
echo "Importing stubs into WireMock at ${WIREMOCK_URL}..."
13+
curl -v -X POST -H "Content-Type: application/json" --data-binary "@$TMP_STUBS_FILE" "${WIREMOCK_URL}/__admin/mappings/import"
14+
15+
echo ""
16+
echo "Verify stubs at: ${WIREMOCK_URL}/__admin/mappings"
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#!/bin/bash
2+
3+
# Setup WireMock Runner for LocalStack
4+
5+
set -e
6+
7+
MOCK_API_NAME="${MOCK_API_NAME:-wiremock}"
8+
MOCK_API_PORT="${MOCK_API_PORT:-8080}"
9+
WIREMOCK_DIR="${WIREMOCK_DIR:-.wiremock}"
10+
STUBS_URL="${STUBS_URL:-https://library.wiremock.org/catalog/api/p/personio.de/personio-de-personnel/personio.de-personnel-stubs.json}"
11+
12+
echo "=== WireMock Runner Setup ==="
13+
14+
# Check prerequisites
15+
if ! command -v wiremock &> /dev/null; then
16+
echo "Error: WireMock CLI not installed. Run: npm install -g @wiremock/cli"
17+
exit 1
18+
fi
19+
20+
if ! wiremock mock-apis list &> /dev/null; then
21+
echo "Error: Not logged in. Run: wiremock login"
22+
exit 1
23+
fi
24+
25+
echo "✓ CLI authenticated"
26+
27+
# Create Mock API
28+
echo "Creating Mock API '${MOCK_API_NAME}'..."
29+
wiremock mock-apis create "${MOCK_API_NAME}" 2>&1 || echo "Note: May already exist"
30+
31+
wiremock mock-apis list
32+
echo ""
33+
echo "Enter Mock API ID:"
34+
read -r MOCK_API_ID
35+
36+
[ -z "$MOCK_API_ID" ] && { echo "Error: Mock API ID required"; exit 1; }
37+
38+
# Create config
39+
mkdir -p "${WIREMOCK_DIR}/stubs/${MOCK_API_NAME}/mappings"
40+
41+
cat > "${WIREMOCK_DIR}/wiremock.yaml" << EOF
42+
services:
43+
${MOCK_API_NAME}:
44+
type: 'REST'
45+
name: '${MOCK_API_NAME}'
46+
port: ${MOCK_API_PORT}
47+
path: '/'
48+
cloud_id: '${MOCK_API_ID}'
49+
EOF
50+
51+
echo "✓ Created ${WIREMOCK_DIR}/wiremock.yaml"
52+
53+
# Download stubs
54+
TMP_STUBS_FILE="/tmp/wiremock-stubs.json"
55+
curl -s -o "$TMP_STUBS_FILE" "$STUBS_URL"
56+
57+
if [ -f "$TMP_STUBS_FILE" ] && command -v jq &> /dev/null; then
58+
MAPPING_COUNT=$(jq '.mappings | length' "$TMP_STUBS_FILE" 2>/dev/null || jq 'length' "$TMP_STUBS_FILE" 2>/dev/null || echo "0")
59+
if [ "$MAPPING_COUNT" != "0" ] && [ "$MAPPING_COUNT" != "null" ]; then
60+
for i in $(seq 0 $((MAPPING_COUNT - 1))); do
61+
jq ".mappings[$i] // .[$i]" "$TMP_STUBS_FILE" > "${WIREMOCK_DIR}/stubs/${MOCK_API_NAME}/mappings/mapping-$i.json" 2>/dev/null
62+
done
63+
echo "✓ Extracted ${MAPPING_COUNT} stubs"
64+
fi
65+
fi
66+
67+
echo ""
68+
echo "=== Setup Complete ==="
69+
echo ""
70+
echo "Start LocalStack with:"
71+
echo " LOCALSTACK_WIREMOCK_API_TOKEN=\"your-token\" \\"
72+
echo " LOCALSTACK_WIREMOCK_CONFIG_DIR=\"$(pwd)\" \\"
73+
echo " localstack start"
74+
echo ""
75+
echo "WireMock available at: http://wiremock.localhost.localstack.cloud:4566"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
name = "localstack_wiremock"

0 commit comments

Comments
 (0)