Files
query-orchestration/test/create.client.sh
T

280 lines
7.6 KiB
Bash
Raw Normal View History

#!/bin/bash
# =============================================================================
# create.client.sh
# =============================================================================
#
# DESCRIPTION:
# Creates a new client in the Query Orchestration API using a JWT token
# from a file for authentication. After creation, verifies the client exists.
#
# USAGE:
# ./create.client.sh <base_url> <token_file> <client_name>
#
# ARGUMENTS:
# base_url - The URL of the Query Orchestration API (e.g., http://localhost:8080)
# token_file - Path to a file containing the JWT auth token
# client_name - The name to assign to the new client
#
# EXAMPLES:
# ./create.client.sh http://localhost:8080 ./token.txt "My Client"
# ./create.client.sh http://localhost:8080 test/token.txt "Demo Client"
#
# EXIT CODES:
# 0 - Client created successfully
# 1 - Missing dependencies or invalid arguments
# 2 - API call failed
# 3 - Authentication failed
#
# =============================================================================
set -e
# =============================================================================
# CONFIGURATION
# =============================================================================
# Colors for output (disable if not a terminal)
if [[ -t 1 ]]; then
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
else
RED=''
GREEN=''
YELLOW=''
BLUE=''
NC=''
fi
# Generate unique external ID for this client
TIMESTAMP=$(date +%s)
CLIENT_EXTERNAL_ID="client-${TIMESTAMP}"
# Variables set by api_call
HTTP_CODE=""
RESPONSE_BODY=""
# =============================================================================
# HELPER FUNCTIONS
# =============================================================================
# print_success - Prints a success message
# Parameters:
# $1 - Message
print_success() {
echo -e "${GREEN} OK: $1${NC}"
}
# print_error - Prints an error message and exits
# Parameters:
# $1 - Message
print_error() {
echo -e "${RED} ERROR: $1${NC}"
exit 2
}
# print_info - Prints an informational message
# Parameters:
# $1 - Message
print_info() {
echo -e " $1"
}
# check_response - Checks if the HTTP response code indicates success
# Parameters:
# $1 - Expected HTTP status code(s) (comma-separated, e.g., "200,201")
# $2 - Actual HTTP status code
# $3 - Response body (for error messages)
# $4 - Endpoint description
check_response() {
local expected="$1"
local actual="$2"
local body="$3"
local desc="$4"
IFS=',' read -ra CODES <<< "$expected"
for code in "${CODES[@]}"; do
if [[ "$actual" == "$code" ]]; then
return 0
fi
done
if [[ "$actual" == "401" ]]; then
echo -e "${RED} AUTHENTICATION FAILED: $desc${NC}"
echo " Token may be expired or invalid"
echo " Response: $body"
exit 3
fi
if [[ "$actual" == "403" ]]; then
echo -e "${RED} AUTHORIZATION FAILED: $desc${NC}"
echo " User does not have permission for this operation"
echo " Response: $body"
exit 3
fi
echo -e "${RED} FAILED: $desc${NC}"
echo " Expected: $expected, Got: $actual"
echo " Response: $body"
exit 2
}
# api_call - Makes an authenticated API call and captures response
# Parameters:
# $1 - HTTP method (GET, POST, PATCH, DELETE)
# $2 - Endpoint path (e.g., "/client")
# $3 - Request body (optional, empty string for none)
# $4 - Content-Type header (optional, defaults to application/json)
# Sets globals: HTTP_CODE, RESPONSE_BODY
api_call() {
local method="$1"
local endpoint="$2"
local body="$3"
local content_type="${4:-application/json}"
local url="${BASE_URL}${endpoint}"
local curl_opts=(-s -k -w "\n%{http_code}")
curl_opts+=(-X "$method")
if [[ -n "$AUTH_TOKEN" ]]; then
curl_opts+=(-H "Authorization: Bearer ${AUTH_TOKEN}")
fi
if [[ -n "$body" ]]; then
curl_opts+=(-H "Content-Type: $content_type")
curl_opts+=(-d "$body")
fi
local response
local retries=3
local delay=1
for ((i=1; i<=retries; i++)); do
if ! response=$(curl --connect-timeout 5 --max-time 30 "${curl_opts[@]}" "$url" 2>&1); then
echo -e "${RED} CONNECTION FAILED: Could not reach ${url}${NC}"
echo " curl error: $response"
exit 2
fi
HTTP_CODE=$(echo "$response" | tail -n1)
RESPONSE_BODY=$(echo "$response" | sed '$d')
if [[ "$HTTP_CODE" != "429" ]]; then
break
fi
if [[ $i -lt $retries ]]; then
print_info "Rate limited (429), waiting ${delay}s before retry $((i+1))/$retries..."
sleep "$delay"
delay=$((delay * 2))
fi
done
sleep 0.1
}
# =============================================================================
# ARGUMENT VALIDATION
# =============================================================================
if [[ $# -lt 3 ]]; then
echo "Usage: $0 <base_url> <token_file> <client_name>"
echo ""
echo "Arguments:"
echo " base_url - The URL of the Query Orchestration API"
echo " token_file - Path to a file containing the JWT auth token"
echo " client_name - The name to assign to the new client"
echo ""
echo "Examples:"
echo " $0 http://localhost:8080 ./token.txt \"My Client\""
echo " $0 http://localhost:8080 test/token.txt \"Demo Client\""
exit 1
fi
# Check dependencies
for cmd in curl jq; do
if ! command -v "$cmd" &> /dev/null; then
echo -e "${RED}ERROR: Required command '$cmd' not found${NC}"
exit 1
fi
done
BASE_URL="${1%/}"
TOKEN_FILE="$2"
CLIENT_NAME="$3"
if [[ ! -f "$TOKEN_FILE" ]]; then
echo -e "${RED}ERROR: Token file not found: $TOKEN_FILE${NC}"
exit 1
fi
AUTH_TOKEN=$(cat "$TOKEN_FILE" | tr -d '[:space:]')
if [[ -z "$AUTH_TOKEN" ]]; then
echo -e "${RED}ERROR: Token file is empty: $TOKEN_FILE${NC}"
exit 1
fi
# =============================================================================
# MAIN
# =============================================================================
echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE}Create Client${NC}"
echo -e "${BLUE}========================================${NC}"
echo ""
echo "Base URL: ${BASE_URL}"
echo "Token File: ${TOKEN_FILE}"
echo "Client Name: ${CLIENT_NAME}"
echo "External ID: ${CLIENT_EXTERNAL_ID}"
echo ""
# Step 1: Create client via POST /client
echo -e "${BLUE}--- Creating client ---${NC}"
body=$(cat << EOF
{
"id": "${CLIENT_EXTERNAL_ID}",
"name": "${CLIENT_NAME}"
}
EOF
)
print_info "Request: POST /client"
print_info "Body: $body"
api_call "POST" "/client" "$body"
check_response "201" "$HTTP_CODE" "$RESPONSE_BODY" "Create client"
CLIENT_ID=$(echo "$RESPONSE_BODY" | jq -r '.id')
print_success "Client created successfully"
print_info "Client ID: $CLIENT_ID"
# Step 2: Verify client via GET /client/{id}
echo ""
echo -e "${BLUE}--- Verifying client ---${NC}"
print_info "Request: GET /client/${CLIENT_ID}"
api_call "GET" "/client/${CLIENT_ID}" ""
check_response "200" "$HTTP_CODE" "$RESPONSE_BODY" "Get client"
name=$(echo "$RESPONSE_BODY" | jq -r '.name')
can_sync=$(echo "$RESPONSE_BODY" | jq -r '.can_sync')
print_success "Client verified"
print_info "Name: $name"
print_info "Can Sync: $can_sync"
# Summary
echo ""
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}Client created and verified${NC}"
echo -e "${GREEN}========================================${NC}"
echo " ID: $CLIENT_ID"
echo " External ID: $CLIENT_EXTERNAL_ID"
echo " Name: $CLIENT_NAME"