Files
spring-boot-demo/pdf-invoice/scripts/run-all.sh
T

81 lines
4.5 KiB
Bash
Executable File

#!/usr/bin/env bash
# Regenerates everything under output/. Needs JDK 25, Maven, curl, poppler (pdftoppm, pdftotext, pdffonts),
# python3 with Pillow built with libraqm. Network is needed once for Maven and for 00-versions-and-licences.txt.
set -euo pipefail
cd "$(dirname "$0")/.."
mkdir -p output/pdf output/png
JAR=target/pdf-invoice-1.0.0.jar
HOST="$(java -version 2>&1 | grep -v JAVA_TOOL | head -1) | $(nproc) vCPU | $(awk '/MemTotal/ {printf "%d MB RAM", $2/1024}' /proc/meminfo)"
scripts/licences.sh > output/00-versions-and-licences.txt || echo "licence check skipped (offline?)"
mvn -q -B test # writes output/01, 04, 05
mvn -q -B -DskipTests package
serve() { # serve <port> : start the packaged jar, wait until it answers
setsid nohup java -jar "$JAR" --server.port="$1" > "target/app-$1.log" 2>&1 < /dev/null &
echo $! > "target/app-$1.pid"
for _ in $(seq 1 60); do curl -s -o /dev/null "localhost:$1/invoices/openpdf.pdf" && return 0; sleep 1; done
echo "app did not start" >&2; return 1
}
stop() { kill "$(cat "target/app-$1.pid")" 2>/dev/null || true; }
P=$((20000 + RANDOM % 10000))
serve "$P"
ENGINES="openpdf itext flyingsaucer openpdf-jdk openpdf-jdk-actualtext flyingsaucer-shaped"
for e in $ENGINES; do
curl -s -o "output/pdf/$e.pdf" "localhost:$P/invoices/$e.pdf"
curl -s -o "output/pdf/probe-$e.pdf" "localhost:$P/invoices/$e.pdf?probe=true"
done
{
echo "# HTTP: status and headers per engine (curl -D -), then streaming vs buffered, then a failure after rendering"
echo "# $HOST"
for e in $ENGINES; do
echo "--- GET /invoices/$e.pdf"
curl -s -D - -o /dev/null "localhost:$P/invoices/$e.pdf" | tr -d '\r' | grep -i -E '^HTTP|^content-type|^content-disposition|^content-length|^transfer-encoding'
done
echo "--- GET /invoices/openpdf.pdf?mode=buffered"
curl -s -D - -o /dev/null "localhost:$P/invoices/openpdf.pdf?mode=buffered" | tr -d '\r' | grep -i -E '^HTTP|^content-length|^transfer-encoding'
echo "--- GET /invoices/openpdf.pdf?disposition=inline"
curl -s -D - -o /dev/null "localhost:$P/invoices/openpdf.pdf?disposition=inline" | tr -d '\r' | grep -i -E '^HTTP|^content-disposition'
echo "--- GET /invoices/nope.pdf"
curl -s -D - -o /dev/null "localhost:$P/invoices/nope.pdf" | tr -d '\r' | grep -i -E '^HTTP'
echo "--- GET /invoices/openpdf.pdf?failAtEnd=true (streamed: headers are already gone when the failure happens)"
curl -s -D - -o target/fail-stream.pdf -w "curl exit=%{exitcode} bytes_received=%{size_download}\n" "localhost:$P/invoices/openpdf.pdf?failAtEnd=true" 2>&1 | tr -d '\r' | grep -i -E '^HTTP|^content-length|^transfer-encoding|curl exit' || true
echo "--- GET /invoices/openpdf.pdf?failAtEnd=true&mode=buffered (rendered into memory first)"
curl -s -D - -o target/fail-buffered.bin -w "curl exit=%{exitcode} bytes_received=%{size_download}\n" "localhost:$P/invoices/openpdf.pdf?failAtEnd=true&mode=buffered" 2>&1 | tr -d '\r' | grep -i -E '^HTTP|^content-length|curl exit' || true
} > output/02-endpoints.txt
{
echo "# pdffonts per engine (poppler): name, type, embedded, subset"
for e in $ENGINES; do echo "--- $e ($(stat -c %s "output/pdf/$e.pdf") bytes)"; pdffonts "output/pdf/$e.pdf"; done
echo; echo "# Producer/Creator lines the libraries write into the PDF (pdfinfo)"
for e in openpdf itext flyingsaucer; do echo "--- $e"; pdfinfo "output/pdf/$e.pdf" | grep -E '^(Title|Creator|Producer)'; done
} > output/03-pdffonts-and-producer.txt
stop "$P"
# the FOP variant needs Apache FOP (121 jars with Batik) on the classpath: Maven profile fop
mvn -q -B -Pfop -DskipTests package
P2=$((20000 + RANDOM % 10000))
serve "$P2"
curl -s -o output/pdf/openpdf-fop.pdf "localhost:$P2/invoices/openpdf-fop.pdf"
curl -s -o output/pdf/probe-openpdf-fop.pdf "localhost:$P2/invoices/openpdf-fop.pdf?probe=true"
stop "$P2"
mvn -q -B -DskipTests package # back to the default jar
for e in openpdf itext flyingsaucer openpdf-jdk-actualtext flyingsaucer-shaped openpdf-fop; do
pdftoppm -r 110 -png -singlefile -H 800 "output/pdf/$e.pdf" "output/png/invoice-$e"
done
python3 scripts/compare.py output/pdf output/png src/main/resources/fonts/NotoSansDevanagari-Regular.ttf
{
echo "# in-process timing, $HOST"
echo "# indicative: shared sandbox, one JVM, one run per line"
java -jar "$JAR" --spring.profiles.active=bench --spring.main.web-application-type=none \
--bench.n="${BENCH_N:-500}" --bench.engines=openpdf,itext,flyingsaucer,openpdf-jdk-actualtext,flyingsaucer-shaped 2>/dev/null | grep -E '^#|^[a-z]'
} > output/06-bench.txt
echo done