#!/usr/bin/env bash set -euo pipefail CONTEXT_FILE="" WORK_DIR="" while [[ $# -gt 0 ]]; do case "$1" in --context-file) CONTEXT_FILE="${2:-}" shift 2 ;; --work-dir) WORK_DIR="${2:-}" shift 2 ;; *) echo "[ERROR] unsupported argument: $1" >&2 exit 1 ;; esac done if [[ -z "${CONTEXT_FILE}" || ! -f "${CONTEXT_FILE}" ]]; then echo "[ERROR] --context-file is required" >&2 exit 1 fi WORK_DIR="${WORK_DIR:-$(dirname "${CONTEXT_FILE}")}" mkdir -p "${WORK_DIR}" LOG_FILE="${WORK_DIR}/mq-replay.log" touch "${LOG_FILE}" log() { printf '[%s] %s\n' "$(date '+%F %T')" "$1" >> "${LOG_FILE}" } json_text() { local key="$1" sed -nE 's/.*"'"${key}"'"[[:space:]]*:[[:space:]]*"([^"]*)".*/\1/p' "${CONTEXT_FILE}" | head -n 1 } split_command() { local value="$1" # shellcheck disable=SC2206 CTL_COMMAND=(${value}) } find_ctl() { local configured="${RABBITMQ_CTL_COMMAND:-}" if [[ -n "${configured}" ]]; then split_command "${configured}" return 0 fi if [[ -x "/usr/local/sbin/tms-rabbitmqctl" ]] && command -v sudo >/dev/null 2>&1; then CTL_COMMAND=(sudo -n /usr/local/sbin/tms-rabbitmqctl) return 0 fi for candidate in rabbitmqctl /usr/local/rabbitmq/sbin/rabbitmqctl /usr/local/rabbitmq-server/sbin/rabbitmqctl /usr/sbin/rabbitmqctl /usr/lib/rabbitmq/bin/rabbitmqctl; do if command -v "${candidate}" >/dev/null 2>&1; then CTL_COMMAND=("$(command -v "${candidate}")") return 0 fi if [[ -x "${candidate}" ]]; then CTL_COMMAND=("${candidate}") return 0 fi done return 1 } run_ctl() { local timeout_seconds="${RABBITMQ_CTL_TIMEOUT_SECONDS:-30}" if command -v timeout >/dev/null 2>&1; then timeout "${timeout_seconds}" "${CTL_COMMAND[@]}" "$@" else "${CTL_COMMAND[@]}" "$@" fi } if [[ -n "${MQ_REPLAY_COMMAND:-}" ]]; then log "delegating mq replay to configured command" "${MQ_REPLAY_COMMAND}" --context-file "${CONTEXT_FILE}" --work-dir "${WORK_DIR}" >> "${LOG_FILE}" 2>&1 exit 0 fi MQ_TYPE="$(json_text mqType)" USER_NAME="$(json_text channelUsername)" USER_PASS="$(json_text channelPassword)" ORG_CODE="$(json_text orgCode)" VHOST="${RABBIT_VHOST:-/RQ}" case "${MQ_TYPE}" in RABBITMQ|RABBITMQ_TLQ|RABBITMQ_CFMQ) ;; *) log "mq replay skipped for mqType=${MQ_TYPE}" exit 0 ;; esac if [[ -z "${USER_NAME}" || -z "${USER_PASS}" ]]; then echo "[ERROR] mq replay context missing channel account" >&2 exit 1 fi CTL_COMMAND=() find_ctl || { echo "[ERROR] rabbitmqctl not found" >&2 exit 1 } run_ctl status >> "${LOG_FILE}" 2>&1 || log "rabbitmqctl status failed, continue replay" run_ctl add_vhost "${VHOST}" >> "${LOG_FILE}" 2>&1 || true run_ctl add_user "${USER_NAME}" "${USER_PASS}" >> "${LOG_FILE}" 2>&1 || run_ctl change_password "${USER_NAME}" "${USER_PASS}" >> "${LOG_FILE}" 2>&1 run_ctl set_permissions -p "${VHOST}" "${USER_NAME}" ".*" ".*" ".*" >> "${LOG_FILE}" 2>&1 log "rabbitmq user and permissions replayed" if [[ -n "${RABBIT_QUEUE_REPLAY_SCRIPT_PATH:-}" && -x "${RABBIT_QUEUE_REPLAY_SCRIPT_PATH}" ]]; then STAGED_QUEUE_SCRIPT="${WORK_DIR}/$(basename "${RABBIT_QUEUE_REPLAY_SCRIPT_PATH}")" cp -f "${RABBIT_QUEUE_REPLAY_SCRIPT_PATH}" "${STAGED_QUEUE_SCRIPT}" if [[ -n "${ORG_CODE}" ]]; then sed -i.bak "s/AAAABBBBXXX/${ORG_CODE}/g" "${STAGED_QUEUE_SCRIPT}" || true fi bash "${STAGED_QUEUE_SCRIPT}" >> "${LOG_FILE}" 2>&1 log "rabbitmq queue script replayed" fi