first commit
This commit is contained in:
145
files/rabbit-consumer.sh
Normal file
145
files/rabbit-consumer.sh
Normal file
@@ -0,0 +1,145 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# --- Config (override via env or flags) ---
|
||||
RMQ_USER="${RMQ_USER:-admin}"
|
||||
RMQ_PASS="${RMQ_PASS:-change_me}"
|
||||
RMQ_HOST="${RMQ_HOST:-localhost}"
|
||||
RMQ_PORT="${RMQ_PORT:-15672}"
|
||||
VHOST="${VHOST:-app}"
|
||||
|
||||
# Mode A: read from a queue (default)
|
||||
QUEUE="${QUEUE:-queue1}"
|
||||
|
||||
# Mode B: bind temp queue to an exchange + routing key and consume from it
|
||||
EXCHANGE="${EXCHANGE:-}" # e.g. "amq.topic" or "my-exchange". Leave empty to skip binding mode.
|
||||
ROUTING_KEY="${ROUTING_KEY:-#}" # pattern for topic/direct, default is catch-all "#"
|
||||
|
||||
# Polling interval when no messages
|
||||
SLEEP_SECS="${SLEEP_SECS:-1}"
|
||||
|
||||
# Pretty-print with jq if available
|
||||
USE_JQ="${USE_JQ:-auto}" # auto|yes|no
|
||||
USE_COLOR="${USE_COLOR:-yes}" # yes|no -> 'yes' forces color with jq -C
|
||||
|
||||
# --- Helpers ---
|
||||
api() {
|
||||
local method="$1"; shift
|
||||
local path="$1"; shift
|
||||
local data="${1:-}"
|
||||
if [[ -n "$data" ]]; then
|
||||
curl -sS -u "$RMQ_USER:$RMQ_PASS" -H "content-type:application/json" -X "$method" "http://$RMQ_HOST:$RMQ_PORT$path" -d "$data"
|
||||
else
|
||||
curl -sS -u "$RMQ_USER:$RMQ_PASS" -H "content-type:application/json" -X "$method" "http://$RMQ_HOST:$RMQ_PORT$path"
|
||||
fi
|
||||
}
|
||||
|
||||
has_jq() { command -v jq >/dev/null 2>&1; }
|
||||
|
||||
# pretty(): colorized JSON when jq is present. We **force** color with -C so it survives pipes/subshells.
|
||||
pretty() {
|
||||
if [[ "$USE_JQ" == "yes" ]] || { [[ "$USE_JQ" == "auto" ]] && has_jq; }; then
|
||||
if [[ "$USE_COLOR" == "yes" ]]; then
|
||||
jq -C .
|
||||
else
|
||||
jq .
|
||||
fi
|
||||
else
|
||||
cat
|
||||
fi
|
||||
}
|
||||
|
||||
urlenc() {
|
||||
# vhost is simple ("app"), so we skip full encoding, but keep function for completeness
|
||||
printf '%s' "$1" | sed -e 's, ,%20,g' -e 's,/,%2F,g'
|
||||
}
|
||||
|
||||
cleanup_queue=""
|
||||
cleanup() {
|
||||
if [[ -n "$cleanup_queue" ]]; then
|
||||
echo "Cleaning up temp queue: $cleanup_queue"
|
||||
api DELETE "/api/queues/$(urlenc "$VHOST")/$cleanup_queue" >/dev/null || true
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
# --- Setup: decide queue source ---
|
||||
if [[ -n "$EXCHANGE" ]]; then
|
||||
# Create a temp, exclusive, auto-delete queue and bind to exchange
|
||||
cleanup_queue="tmp.$(hostname -s).$$.$(date +%s)"
|
||||
echo "Declaring temp queue: $cleanup_queue (exclusive, auto-delete)"
|
||||
api PUT "/api/queues/$(urlenc "$VHOST")/$cleanup_queue" '{
|
||||
"auto_delete": true,
|
||||
"durable": false,
|
||||
"arguments": {},
|
||||
"exclusive": true
|
||||
}' >/dev/null
|
||||
|
||||
echo "Binding temp queue to exchange '$EXCHANGE' with routing key '$ROUTING_KEY'"
|
||||
api POST "/api/bindings/$(urlenc "$VHOST")/e/$EXCHANGE/q/$cleanup_queue" "{
|
||||
\"routing_key\": \"$ROUTING_KEY\",
|
||||
\"arguments\": {}
|
||||
}" >/dev/null
|
||||
|
||||
QUEUE="$cleanup_queue"
|
||||
echo "Consuming from bound temp queue: $QUEUE"
|
||||
else
|
||||
echo "Consuming directly from queue: $QUEUE (vhost: $VHOST)"
|
||||
fi
|
||||
|
||||
echo "Press Ctrl+C to stop."
|
||||
|
||||
# --- Consume loop ---
|
||||
while :; do
|
||||
RESP="$(api POST "/api/queues/$(urlenc "$VHOST")/$QUEUE/get" '{
|
||||
"count": 1,
|
||||
"ackmode": "ack_requeue_false",
|
||||
"encoding": "auto",
|
||||
"truncate": 1000000
|
||||
}')"
|
||||
|
||||
# Empty array => no messages
|
||||
if [[ "$RESP" == "[]" ]] || [[ -z "$RESP" ]]; then
|
||||
sleep "$SLEEP_SECS"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Print one-by-one (the API returns an array)
|
||||
if has_jq && { [[ "$USE_JQ" == "yes" ]] || [[ "$USE_JQ" == "auto" ]]; }; then
|
||||
echo "$RESP" | jq -c '.[]' | while read -r item; do
|
||||
# Extract fields (raw to avoid extra quotes)
|
||||
payload=$(printf '%s' "$item" | jq -r '.payload')
|
||||
rk=$(printf '%s' "$item" | jq -r '.routing_key')
|
||||
ex=$(printf '%s' "$item" | jq -r '.exchange')
|
||||
|
||||
echo "-----"
|
||||
echo "exchange: ${ex:-\"\"}"
|
||||
echo "routing_key: $rk"
|
||||
echo "payload:"
|
||||
|
||||
# Smart payload handling:
|
||||
# 1) If payload parses as JSON:
|
||||
# - If it's a JSON string, decode once; if decoded text is JSON, pretty-print it; else print plain text.
|
||||
# - If it's object/array/etc, pretty-print directly.
|
||||
# 2) If payload isn't JSON at all, print as-is.
|
||||
if jq -e . >/dev/null 2>&1 <<<"$payload"; then
|
||||
ptype="$(printf '%s' "$payload" | jq -r 'type')"
|
||||
if [[ "$ptype" == "string" ]]; then
|
||||
decoded="$(printf '%s' "$payload" | jq -r .)"
|
||||
if jq -e . >/dev/null 2>&1 <<<"$decoded"; then
|
||||
printf '%s' "$decoded" | pretty
|
||||
else
|
||||
printf '%s\n' "$decoded"
|
||||
fi
|
||||
else
|
||||
printf '%s' "$payload" | pretty
|
||||
fi
|
||||
else
|
||||
printf '%s\n' "$payload"
|
||||
fi
|
||||
done
|
||||
else
|
||||
# Minimal parsing without jq
|
||||
echo "$RESP"
|
||||
fi
|
||||
done
|
||||
Reference in New Issue
Block a user