#!/bin/bash # Given the base URLs of two SAP Sailing servers, obtains their /sailingserver/api/v1/leaderboardgroups # service output, sorts it, compares them, and if equal, obtains all corresponding leaderboardgroups/* # documents and compares those in turn. # # When used with -a (use REST API) then optionally -b can be used to provide a bearer token to # authenticate a subject. Furthermore, in -a mode the exit status, if not 0 for OK will be the # API's HTTP response status code modulo 256, e.g., 153 in case the response status cod ewas 409. # See https://www.sapsailing.com/sailingserver/webservices/api/v1/compareServers.html for details # about possible API response codes. # # The -c ("continue"), -e ("exit on error"), and -l ("list") options will be ignored when # the -a option ("use REST API") is used. options='ab:cevl' while getopts $options option do case $option in a) useRestApi="1";; b) BEARER_TOKEN="${OPTARG}";; c) continue="1";; e) exitOnError="1";; v) verbose="1";; l) list="1";; \?) echo "Invalid option" exit 4;; esac done shift $((OPTIND-1)) if [ "$verbose" = "1" ]; then WGET_ERR=/dev/stderr WGET_QUIET="" else WGET_ERR=/dev/null WGET_QUIET="--quiet" fi OLDSERVER=$1 NEWSERVER=$2 OLDGROUPS=leaderboardgroups.old.sed NEWGROUPS=leaderboardgroups.new.sed OLDGROUPS_FOR_CONTINUE=${OLDGROUPS}.continue NEWGROUPS_FOR_CONTINUE=${NEWGROUPS}.continue # Check old and new server for healthy status; no point in preparing for a switch if any # of them is unhealthy if ! curl --fail --silent "${OLDSERVER}/gwt/status" >/dev/null; then echo "${OLDSERVER} unhealthy. Aborting." exit 1 fi if ! curl --fail --silent "${NEWSERVER}/gwt/status" >/dev/null; then echo "${NEWSERVER} unhealthy. Aborting." exit 1 fi if [ "${useRestApi}" = "1" ]; then if [ -n "${BEARER_TOKEN}" ]; then AUTH="-H \"Authorization: Bearer ${BEARER_TOKEN}\"" else AUTH="" fi HEADERS=$( mktemp ) LEADERBOARD_GROUPS="" while [ -n "$3" ]; do LEADERBOARD_GROUPS="${LEADERBOARD_GROUPS} -d leaderboardgroupUUID[]=$3" shift done CURL_OUTPUT=$( curl -sL --dump-header "${HEADERS}" -H 'Content-Type: multipart/form-data' "${NEWSERVER}/sailingserver/api/v1/compareservers" -d "server2=${OLDSERVER}" ${AUTH} ${LEADERBOARD_GROUPS} 2>${WGET_ERR} ) echo "${CURL_OUTPUT}" HTTP_STATUS=$( cat "${HEADERS}" | grep "^HTTP\/[0-9.]* [0-9]\{3\}" | tail -1 | sed -e 's/^HTTP\/[0-9.]* \([0-9]\{3\}\).*$/\1/' ) rm -f "${HEADERS}" MESSAGE_SUFFIX=". HTTP_STATUS was ${HTTP_STATUS}." if [[ "${HTTP_STATUS}" =~ 2.. ]]; then echo "Success${MESSAGE_SUFFIX}" >&2 exit 0 else echo "Failed${MESSAGE_SUFFIX}" >&2 exit ${HTTP_STATUS} fi else # If we continue, don't download again if [ "$continue" != "1" ]; then wget --no-cache $WGET_QUIET -O - ${OLDSERVER}/sailingserver/api/v1/leaderboardgroups | jq -r '.[]' | sed -e 's/\//%2F/g' | sort >$OLDGROUPS wget --no-cache $WGET_QUIET -O - ${NEWSERVER}/sailingserver/api/v1/leaderboardgroups | jq -r '.[]' | sed -e 's/\//%2F/g' | sort >$NEWGROUPS fi download_and_fix_boatclasses () { wget --no-cache $WGET_QUIET -O - "$1/sailingserver/api/v1/leaderboardgroups/`echo $OLD_LB | sed -e 's/ /%20/g'`" | jq 'del(.leaderboards[].series[].fleets[].races[].raceViewerUrls)' | jq 'del(.displayName)' | grep -v "\"id\": \"[^\"]*\"" | grep -v "\"timepoint\": \"[^\"]*\"" | grep -v "\"timepoint-ms\":" >"$2" 2>$WGET_ERR #wget --no-cache $WGET_QUIET -O - "$1/sailingserver/api/v1/leaderboardgroups/`echo $OLD_LB | sed -e 's/ /%20/g'`" | python -m json.tool | grep -v "\"id\": \"[^\"]*\"" | grep -v "\"timepoint\": \"[^\"]*\"" >"$2" 2>$WGET_ERR } diff leaderboardgroups.old.sed leaderboardgroups.new.sed if [ "$?" = "0" ]; then cp "$OLDGROUPS" "$OLDGROUPS_FOR_CONTINUE" cp "$NEWGROUPS" "$NEWGROUPS_FOR_CONTINUE" exec 3<> $OLDGROUPS exec 4<> $NEWGROUPS read OLD_LB <&3 read NEW_LB <&4 while [ "$OLD_LB" != "" ]; do if [ "$list" = "1" ]; then echo " * $OLD_LB" fi download_and_fix_boatclasses "${OLDSERVER}" "${OLD_LB}.old.json" download_and_fix_boatclasses "${NEWSERVER}" "${NEW_LB}.new.json" diff -b -i -B "${OLD_LB}.old.json" "${NEW_LB}.new.json" DIFFRESULT=$? if [ "$DIFFRESULT" != "0" ]; then echo "Difference detected in leaderboard group $OLD_LB vs. $NEW_LB" if [ "$exitOnError" = "1" ]; then cp "$OLDGROUPS_FOR_CONTINUE" "$OLDGROUPS" cp "$NEWGROUPS_FOR_CONTINUE" "$NEWGROUPS" echo "Exiting..." exit $DIFFRESULT fi else # no diff; remove the leaderboards successfully compared from both leaderboardgroups lists in case a later -c invocation occurs sed -i -e '1d' $OLDGROUPS_FOR_CONTINUE sed -i -e '1d' $NEWGROUPS_FOR_CONTINUE fi read OLD_LB <&3 read NEW_LB <&4 done cp "$OLDGROUPS_FOR_CONTINUE" "$OLDGROUPS" cp "$NEWGROUPS_FOR_CONTINUE" "$NEWGROUPS" else # pass on diff result to caller exit $? fi fi