CI / build (pull_request) Successful in 1m9s
CI / lint (pull_request) Successful in 1m22s
CI / unit (pull_request) Successful in 1m27s
CI / frontend (pull_request) Successful in 3m9s
CI / mutation (pull_request) Successful in 6m7s
CI / verify-stack (pull_request) Failing after 9m56s
The projection check now opens its zaak through the ACL, which puts it in the same bind
run-domain-check.sh already handles:
400 {"name":"zaaktype","code":"bad-url","reason":"Voer een geldige URL in."}
OpenZaak reflects the request Host into the zaaktype `url` it returns and then rejects that
same URL on zaak-create when the host is single-label. The stack's ACL is configured with
`http://openzaak:8000/`, so it has to be recreated with ACL_OPENZAAK_BASEURL pointed at
OpenZaak's container IP first — the mechanism compose already documents on that variable.
Same class of constraint as the objecten.local alias (ADR-0029), and the third module now
known to reflect a request Host into data another module validates.
101 lines
5.7 KiB
Bash
Executable File
101 lines
5.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Verify the end-to-end read-projection path (S-06, re-sourced by S-19b-2) against an ALREADY-RUNNING
|
|
# full stack: ACL → Objecten → NRC → Event Subscriber → projection → projection-api. Seeds a
|
|
# published BIG zaaktype (idempotent), registers an abonnement on the `objecten` kanaal pointing at
|
|
# the real Event Subscriber's /notifications callback (with the bearer it enforces), opens a zaak
|
|
# *through the ACL*, and asserts projection-api serves a row for it with status INGEDIEND.
|
|
#
|
|
# The zaak is opened through the ACL, not straight against OpenZaak: since ADR-0030 the projection is
|
|
# derived from the RegisterRecord in Objecten, and the ACL is what writes that record (INGEDIEND on
|
|
# submit). A zaak created behind the ACL's back produces no register write and so no projection row —
|
|
# which is the point of the re-source.
|
|
#
|
|
# All in-network, reaching services by container IP — single-label hosts aren't URL-valid and
|
|
# the runner can't reach published ports (gitea-actions-gotchas.md §5/§6). Does not own the stack
|
|
# lifecycle (the caller brings it up and tears it down), but does recreate the `acl` service to
|
|
# repoint it — see below, and run-domain-check.sh, which does the same. Plain docker primitives only.
|
|
# See ADR-0007/0008/0030.
|
|
set -euo pipefail
|
|
|
|
here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
root="$(cd "$here/.." && pwd)"
|
|
compose="$root/infra/docker-compose.yml"
|
|
WEBHOOK_AUTH="${NOTIFICATION_WEBHOOK_TOKEN:-Bearer big-reference-notifications}"
|
|
|
|
cleanup() { docker rm -f rr-pverify rr-pquery >/dev/null 2>&1 || true; }
|
|
trap cleanup EXIT
|
|
|
|
ip() { docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$1"; }
|
|
|
|
oz="$(docker ps -q --filter 'name=[-_]openzaak[-_]' | head -1)"
|
|
nrc="$(docker ps -q --filter 'name=nrc-web' | head -1)"
|
|
es="$(docker ps -q --filter 'name=event-subscriber' | head -1)"
|
|
proj="$(docker ps -q --filter 'name=projection-api' | head -1)"
|
|
acl="$(docker ps -q --filter 'name=[-_]acl[-_]' | head -1)"
|
|
[ -n "$oz" ] && [ -n "$nrc" ] || { echo "ERROR: OpenZaak and/or NRC not running — bring the stack up first" >&2; exit 1; }
|
|
[ -n "$es" ] && [ -n "$proj" ] || { echo "ERROR: event-subscriber and/or projection-api not running — bring the stack up first" >&2; exit 1; }
|
|
[ -n "$acl" ] || { echo "ERROR: acl not running — bring the stack up first" >&2; exit 1; }
|
|
net="$(docker inspect -f '{{range $k,$_ := .NetworkSettings.Networks}}{{$k}}{{"\n"}}{{end}}' "$oz" | head -1)"
|
|
oz_ip="$(ip "$oz")"; nrc_ip="$(ip "$nrc")"; es_ip="$(ip "$es")"; proj_ip="$(ip "$proj")"; acl_ip="$(ip "$acl")"
|
|
echo ">> network=$net openzaak=$oz_ip nrc=$nrc_ip event-subscriber=$es_ip projection-api=$proj_ip acl=$acl_ip"
|
|
|
|
echo ">> seeding a published BIG zaaktype (idempotent)"
|
|
sid="$(docker create --network "$net" -e "OZ_BASE=http://$oz_ip:8000" -e OZ_PUBLISH=1 \
|
|
python:3-slim python /seed.py)"
|
|
docker cp "$here/openzaak/seed_catalogus.py" "$sid:/seed.py" >/dev/null
|
|
docker start -a "$sid"
|
|
docker rm -f "$sid" >/dev/null
|
|
|
|
echo ">> registering the event-subscriber abonnement on the objecten kanaal"
|
|
docker rm -f rr-pverify >/dev/null 2>&1 || true
|
|
# The same script the local stack uses (ADR-0020), so both paths register the identical abonnement.
|
|
drv="$(docker create --network "$net" --name rr-pverify \
|
|
-e "NRC_BASE=http://$nrc_ip:8000" \
|
|
-e "SINK_HOST=$es_ip" -e "SINK_PORT=8080" -e "SINK_AUTH=$WEBHOOK_AUTH" \
|
|
python:3-slim python /subscribe.py)"
|
|
docker cp "$here/local/register-abonnement.py" "$drv:/subscribe.py" >/dev/null
|
|
docker start -a "$drv"
|
|
docker rm -f rr-pverify >/dev/null
|
|
|
|
# OpenZaak reflects the request Host into the zaaktype `url` it returns, and then rejects that same
|
|
# URL on zaak-create when the host is single-label ("Voer een geldige URL in."). The stack's ACL is
|
|
# configured with `http://openzaak:8000/`, so it must be repointed at OpenZaak's container IP before
|
|
# it can open a zaak — exactly what run-domain-check.sh does, and the same class of constraint as the
|
|
# `objecten.local` alias (ADR-0029). The ACL resolves the zaaktype itself (S-27, ADR-0021), so the
|
|
# base URL is the only thing to inject.
|
|
echo ">> recreating the acl service pointed at OpenZaak's IP"
|
|
ACL_OPENZAAK_BASEURL="http://$oz_ip:8000/" docker compose -f "$compose" up -d acl
|
|
WAIT_TIMEOUT="${WAIT_TIMEOUT:-120}" bash "$here/wait-healthy.sh" acl
|
|
# The container is replaced, so its IP may have changed.
|
|
acl="$(docker ps -q --filter 'name=[-_]acl[-_]' | head -1)"
|
|
acl_ip="$(ip "$acl")"
|
|
|
|
echo ">> opening a zaak through the ACL (which writes the INGEDIEND register record)"
|
|
reference="PROJ-$(date +%s)"
|
|
zaak_url="$(docker run --rm --network "$net" curlimages/curl:latest \
|
|
-fsS -X POST "http://$acl_ip:8080/zaken" -H 'Content-Type: application/json' \
|
|
-d "{\"bsn\":\"123456782\",\"reference\":\"$reference\"}" \
|
|
| sed -n 's/.*"zaakUrl":"\([^"]*\)".*/\1/p')"
|
|
[ -n "$zaak_url" ] || { echo "ERROR: the ACL did not open a zaak" >&2; exit 1; }
|
|
zaak_uuid="${zaak_url##*/}"
|
|
echo ">> zaak created: $zaak_url (reference $reference)"
|
|
|
|
echo ">> polling projection-api for the projected row (status INGEDIEND)"
|
|
for _ in $(seq 1 30); do
|
|
body="$(docker run --rm --network "$net" curlimages/curl:latest \
|
|
-fsS "http://$proj_ip:8080/register/$zaak_uuid" 2>/dev/null || true)"
|
|
if echo "$body" | grep -q '"INGEDIEND"'; then
|
|
echo "OK — projection-api serves zaak $zaak_uuid with status INGEDIEND"
|
|
echo "$body" | cut -c1-300
|
|
exit 0
|
|
fi
|
|
sleep 2
|
|
done
|
|
echo "FAIL — projection-api never served an INGEDIEND row for zaak $zaak_uuid" >&2
|
|
echo " The chain is ACL → Objecten → NRC → event-subscriber → projection (ADR-0030)." >&2
|
|
echo "--- event-subscriber log ---" >&2; docker logs "$es" 2>&1 | tail -10 >&2
|
|
echo "--- projection-api log ---" >&2; docker logs "$proj" 2>&1 | tail -10 >&2
|
|
echo "--- acl log ---" >&2; docker logs "$acl" 2>&1 | tail -10 >&2
|
|
exit 1
|