#!/bin/bash # ROA2WEB Testing Starter Script # Starts SSH tunnel, backend, and frontend services set -e # Exit on any error # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Function to print colored messages print_message() { echo -e "${BLUE}[ROA2WEB]${NC} $1" } print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" } # Function to check if port is in use check_port() { local port=$1 if lsof -Pi :$port -sTCP:LISTEN -t >/dev/null 2>&1; then return 0 else return 1 fi } # Function to check if requirements.txt has changed check_requirements_changed() { local requirements_file=$1 local checksum_file="${requirements_file}.checksum" if [ ! -f "$requirements_file" ]; then return 1 # Requirements file doesn't exist fi # Calculate current checksum current_checksum=$(md5sum "$requirements_file" | cut -d' ' -f1) # Check if checksum file exists and compare if [ -f "$checksum_file" ]; then stored_checksum=$(cat "$checksum_file") if [ "$current_checksum" = "$stored_checksum" ]; then return 1 # No change fi fi return 0 # Changed or first time } # Function to save requirements checksum save_requirements_checksum() { local requirements_file=$1 local checksum_file="${requirements_file}.checksum" if [ -f "$requirements_file" ]; then md5sum "$requirements_file" | cut -d' ' -f1 > "$checksum_file" fi } # Function to install or update Python dependencies install_python_dependencies() { local project_name=$1 local venv_path=$2 local requirements_file=$3 # Check if venv exists if [ ! -d "$venv_path" ]; then print_message "Creating Python virtual environment for $project_name..." python3 -m venv "$venv_path" fi # Activate virtual environment source "$venv_path/bin/activate" # Check if requirements have changed or dependencies are missing local should_install=false if check_requirements_changed "$requirements_file"; then print_message "Requirements changed for $project_name - updating dependencies..." should_install=true elif ! python -c "import sys; import importlib; [importlib.import_module(line.split('>=')[0].split('==')[0]) for line in open('$requirements_file').read().splitlines() if line and not line.startswith('#')]" 2>/dev/null; then print_message "Missing dependencies detected for $project_name - installing..." should_install=true fi if [ "$should_install" = true ]; then print_message "Installing/updating $project_name dependencies..." pip install --upgrade pip > /dev/null 2>&1 pip install -r "$requirements_file" save_requirements_checksum "$requirements_file" print_success "$project_name dependencies installed/updated successfully" else print_message "$project_name dependencies are up to date" fi } # Function to cleanup processes on exit cleanup() { print_message "Stopping services..." # Kill background processes if [[ -n $BACKEND_PID ]]; then kill $BACKEND_PID 2>/dev/null || true fi if [[ -n $FRONTEND_PID ]]; then kill $FRONTEND_PID 2>/dev/null || true fi if [[ -n $TELEGRAM_BOT_PID ]]; then kill $TELEGRAM_BOT_PID 2>/dev/null || true fi # Stop SSH tunnel - try the same paths as in stop_services SSH_TUNNEL_PATHS=( "/mnt/d/PROIECTE/roa-flask/roa2web/ssh-tunnel-test.sh" "/mnt/e/proiecte/roa2web/roa2web/ssh-tunnel-test.sh" "./ssh-tunnel-test.sh" ) for tunnel_path in "${SSH_TUNNEL_PATHS[@]}"; do if [[ -f "$tunnel_path" ]]; then $tunnel_path stop break fi done print_success "All services stopped." exit 0 } # Function to stop all services stop_services() { print_message "Stopping all ROA2WEB services..." # Stop processes running on specific ports print_message "Checking for backend processes on port 8001..." if check_port 8001; then BACKEND_PIDS=$(lsof -ti:8001) if [[ -n $BACKEND_PIDS ]]; then echo $BACKEND_PIDS | xargs kill -TERM 2>/dev/null || true sleep 2 echo $BACKEND_PIDS | xargs kill -KILL 2>/dev/null || true print_success "Backend processes stopped" fi else print_message "No backend processes found on port 8001" fi print_message "Checking for frontend processes on common ports..." FRONTEND_STOPPED=false for port in 3000 3001 3002 3003 3004 3005; do if check_port $port; then FRONTEND_PIDS=$(lsof -ti:$port) if [[ -n $FRONTEND_PIDS ]]; then # Kill the main process listening on port echo $FRONTEND_PIDS | xargs kill -TERM 2>/dev/null || true sleep 2 echo $FRONTEND_PIDS | xargs kill -KILL 2>/dev/null || true # Also kill parent npm processes that might have spawned vite for pid in $FRONTEND_PIDS; do PARENT_PID=$(ps -o ppid= -p $pid 2>/dev/null | tr -d ' ') if [[ -n $PARENT_PID ]] && [[ $PARENT_PID != "1" ]]; then PARENT_CMD=$(ps -o comm= -p $PARENT_PID 2>/dev/null) if [[ $PARENT_CMD == "npm" ]] || [[ $PARENT_CMD == "node" ]]; then kill -TERM $PARENT_PID 2>/dev/null || true sleep 1 kill -KILL $PARENT_PID 2>/dev/null || true fi fi done print_success "Frontend processes stopped on port $port" FRONTEND_STOPPED=true fi fi done if [[ $FRONTEND_STOPPED == false ]]; then print_message "No frontend processes found on common ports" fi # Stop Telegram Bot print_message "Checking for Telegram bot processes on port 8002..." if check_port 8002; then TELEGRAM_BOT_PIDS=$(lsof -ti:8002) if [[ -n $TELEGRAM_BOT_PIDS ]]; then echo $TELEGRAM_BOT_PIDS | xargs kill -TERM 2>/dev/null || true sleep 2 echo $TELEGRAM_BOT_PIDS | xargs kill -KILL 2>/dev/null || true print_success "Telegram bot processes stopped" fi else print_message "No Telegram bot processes found on port 8002" fi # Stop SSH tunnel print_message "Stopping SSH tunnel..." # Try both possible paths for SSH tunnel SSH_TUNNEL_PATHS=( "/mnt/d/PROIECTE/roa-flask/roa2web/ssh-tunnel-test.sh" "/mnt/d/proiecte/roa2web/roa2web/ssh-tunnel-test.sh" "./ssh-tunnel-test.sh" ) SSH_TUNNEL_STOPPED=false for tunnel_path in "${SSH_TUNNEL_PATHS[@]}"; do if [[ -f "$tunnel_path" ]]; then if $tunnel_path stop; then print_success "SSH tunnel stopped" SSH_TUNNEL_STOPPED=true break fi fi done if [[ $SSH_TUNNEL_STOPPED == false ]]; then print_warning "SSH tunnel script not found or may not have been running" fi # Kill any remaining processes related to ROA2WEB print_message "Cleaning up any remaining ROA2WEB processes..." # More comprehensive cleanup patterns pkill -f "uvicorn.*roa2web" 2>/dev/null || true pkill -f "uvicorn.*app.main:app" 2>/dev/null || true pkill -f "node.*roa.*frontend" 2>/dev/null || true pkill -f "vite.*roa" 2>/dev/null || true pkill -f "npm.*run.*dev.*roa" 2>/dev/null || true pkill -f "python.*telegram-bot" 2>/dev/null || true pkill -f "python.*app.main" 2>/dev/null || true # Kill processes in the specific directory structure pkill -f "/mnt/e/proiecte/roa2web/roa2web/reports-app/frontend" 2>/dev/null || true pkill -f "/mnt/e/proiecte/roa2web/roa2web/reports-app/backend" 2>/dev/null || true pkill -f "/mnt/e/proiecte/roa2web/roa2web/reports-app/telegram-bot" 2>/dev/null || true print_success "✅ All ROA2WEB services have been stopped!" exit 0 } # Function to stop individual service stop_service() { local service=$1 case $service in tunnel) print_message "Stopping SSH tunnel..." SSH_TUNNEL_PATHS=( "/mnt/d/PROIECTE/roa-flask/roa2web/ssh-tunnel-test.sh" "/mnt/e/proiecte/roa2web/roa2web/ssh-tunnel-test.sh" "./ssh-tunnel-test.sh" ) for tunnel_path in "${SSH_TUNNEL_PATHS[@]}"; do if [[ -f "$tunnel_path" ]]; then $tunnel_path stop print_success "SSH tunnel stopped" return 0 fi done print_warning "SSH tunnel script not found" ;; backend) print_message "Stopping backend..." if check_port 8001; then BACKEND_PIDS=$(lsof -ti:8001) if [[ -n $BACKEND_PIDS ]]; then echo $BACKEND_PIDS | xargs kill -TERM 2>/dev/null || true sleep 2 echo $BACKEND_PIDS | xargs kill -KILL 2>/dev/null || true print_success "Backend stopped" else print_message "Backend not running" fi else print_message "Backend not running on port 8001" fi ;; frontend) print_message "Stopping frontend..." for port in 3000 3001 3002 3003 3004 3005; do if check_port $port; then FRONTEND_PIDS=$(lsof -ti:$port) if [[ -n $FRONTEND_PIDS ]]; then echo $FRONTEND_PIDS | xargs kill -TERM 2>/dev/null || true sleep 2 echo $FRONTEND_PIDS | xargs kill -KILL 2>/dev/null || true print_success "Frontend stopped on port $port" return 0 fi fi done print_message "Frontend not running" ;; telegram|bot) print_message "Stopping Telegram bot..." if check_port 8002; then TELEGRAM_BOT_PIDS=$(lsof -ti:8002) if [[ -n $TELEGRAM_BOT_PIDS ]]; then echo $TELEGRAM_BOT_PIDS | xargs kill -TERM 2>/dev/null || true sleep 2 echo $TELEGRAM_BOT_PIDS | xargs kill -KILL 2>/dev/null || true print_success "Telegram bot stopped" else print_message "Telegram bot not running" fi else print_message "Telegram bot not running on port 8002" fi ;; *) print_error "Unknown service: $service" print_message "Valid services: tunnel, backend, frontend, telegram" exit 1 ;; esac } # Function to start individual service start_service() { local service=$1 case $service in tunnel) print_message "Starting SSH tunnel..." if ./ssh-tunnel-test.sh start; then print_success "SSH Tunnel started successfully" else print_error "Failed to start SSH tunnel" exit 1 fi ;; backend) print_message "Starting backend..." if check_port 8001; then print_warning "Port 8001 already in use. Backend might be running." return 1 fi # Load TEST environment variables from .env.test print_message "Loading TEST environment from .env.test..." if [ -f "reports-app/backend/.env.test" ]; then set -a source reports-app/backend/.env.test set +a print_success "TEST Oracle configuration: ${ORACLE_USER}@${ORACLE_DSN}" else print_error ".env.test not found!" exit 1 fi cd reports-app/backend/ install_python_dependencies "Backend" "venv" "requirements.txt" print_message "Starting uvicorn server..." # NOTE: --reload disabled for cache to work properly (global variables issue) nohup uvicorn app.main:app --host 0.0.0.0 --port 8001 > /tmp/roa2web_backend.log 2>&1 & sleep 2 for i in {1..10}; do if check_port 8001; then print_success "Backend started on http://localhost:8001" cd - > /dev/null return 0 fi sleep 1 done print_error "Backend failed to start" cd - > /dev/null exit 1 ;; frontend) print_message "Starting frontend..." for port in 3000 3001 3002 3003 3004 3005; do if check_port $port; then print_warning "Port $port already in use" fi done cd reports-app/frontend/ # Check node_modules NEED_REINSTALL=false if [ ! -d "node_modules" ] || [ ! -f "node_modules/.bin/vite" ] || [ -f "node_modules/.bin/vite.cmd" ]; then NEED_REINSTALL=true fi if [ "$NEED_REINSTALL" = true ]; then print_message "Reinstalling frontend dependencies for WSL..." rm -rf node_modules package-lock.json npm install fi print_message "Starting Vite development server..." nohup npm run dev > /tmp/roa2web_frontend.log 2>&1 & sleep 3 FRONTEND_PORT="" for i in {1..10}; do for port in 3000 3001 3002 3003 3004 3005; do if check_port $port; then FRONTEND_PORT=$port break 2 fi done sleep 1 done if [[ -n $FRONTEND_PORT ]]; then print_success "Frontend started on http://localhost:$FRONTEND_PORT" cd - > /dev/null return 0 else print_error "Frontend failed to start" cat /tmp/roa2web_frontend.log cd - > /dev/null exit 1 fi ;; telegram|bot) print_message "Starting Telegram bot..." if check_port 8002; then print_warning "Port 8002 already in use. Telegram bot might be running." return 1 fi cd reports-app/telegram-bot/ if [ ! -f ".env" ]; then print_error "Telegram bot .env file not found!" print_message "Please create .env file from .env.example" cd - > /dev/null exit 1 fi install_python_dependencies "Telegram Bot" "venv" "requirements.txt" print_message "Starting Telegram bot..." nohup python -m app.main > /tmp/roa2web_telegram.log 2>&1 & sleep 3 for i in {1..10}; do if check_port 8002; then print_success "Telegram bot started (Internal API: http://localhost:8002)" cd - > /dev/null return 0 fi sleep 1 done print_error "Telegram bot failed to start" cat /tmp/roa2web_telegram.log cd - > /dev/null exit 1 ;; *) print_error "Unknown service: $service" print_message "Valid services: tunnel, backend, frontend, telegram" exit 1 ;; esac } # Function to restart individual service restart_service() { local service=$1 print_message "Restarting $service..." stop_service $service sleep 2 start_service $service print_success "$service restarted successfully" } # Function to show service status show_status() { echo -e "${BLUE}ROA2WEB Services Status${NC}" echo # Check SSH tunnel if pgrep -f "ssh.*1526.*1521" > /dev/null; then echo -e " SSH Tunnel: ${GREEN}✓ Running${NC}" else echo -e " SSH Tunnel: ${RED}✗ Stopped${NC}" fi # Check backend if check_port 8001; then echo -e " Backend: ${GREEN}✓ Running${NC} (http://localhost:8001)" else echo -e " Backend: ${RED}✗ Stopped${NC}" fi # Check frontend FRONTEND_PORT="" for port in 3000 3001 3002 3003 3004 3005; do if check_port $port; then FRONTEND_PORT=$port break fi done if [[ -n $FRONTEND_PORT ]]; then echo -e " Frontend: ${GREEN}✓ Running${NC} (http://localhost:$FRONTEND_PORT)" else echo -e " Frontend: ${RED}✗ Stopped${NC}" fi # Check Telegram bot if check_port 8002; then echo -e " Telegram Bot: ${GREEN}✓ Running${NC} (http://localhost:8002)" else echo -e " Telegram Bot: ${RED}✗ Stopped${NC}" fi echo } # Function to show usage show_usage() { echo -e "${BLUE}ROA2WEB Testing Script${NC}" echo echo "Usage:" echo " ./start-dev.sh Start all services" echo " ./start-dev.sh start Start all services" echo " ./start-dev.sh stop Stop all services" echo " ./start-dev.sh status Show services status" echo echo " ./start-dev.sh restart Restart specific service" echo " ./start-dev.sh start Start specific service" echo " ./start-dev.sh stop Stop specific service" echo echo "Services:" echo " tunnel - SSH Tunnel (Oracle DB connection)" echo " backend - FastAPI (port 8001)" echo " frontend - Vue.js/Vite (port 3000-3005)" echo " telegram - Telegram Bot (port 8002)" echo echo "Examples:" echo " ./start-dev.sh restart telegram Restart only Telegram bot" echo " ./start-dev.sh stop backend Stop only backend" echo " ./start-dev.sh start frontend Start only frontend" echo } # Check command line arguments case $1 in stop) if [[ -n $2 ]]; then # Stop specific service stop_service $2 exit 0 else # Stop all services stop_services fi ;; start) if [[ -n $2 ]]; then # Start specific service start_service $2 exit 0 else # Continue with normal start process (start all) true fi ;; restart) if [[ -z $2 ]]; then print_error "Please specify which service to restart" echo show_usage exit 1 fi restart_service $2 exit 0 ;; status) show_status exit 0 ;; help|--help|-h) show_usage exit 0 ;; "") # No parameter - start all services true ;; *) print_error "Unknown parameter: $1" echo show_usage exit 1 ;; esac # Set up signal handlers trap cleanup SIGINT SIGTERM print_message "Starting ROA2WEB Testing Environment..." echo # Step 1: Start SSH Tunnel print_message "1. Starting SSH Tunnel..." if ./ssh-tunnel-test.sh start; then print_success "SSH Tunnel started successfully" else print_error "Failed to start SSH tunnel" exit 1 fi # Wait a moment for tunnel to establish sleep 2 # ============================================================================ # EXPORT TEST ENVIRONMENT VARIABLES # ============================================================================ # Load TEST environment variables from .env.test # Oracle TEST server: LXC 10.0.20.121 with Oracle in Docker print_message "Loading TEST environment from .env.test..." if [ -f "reports-app/backend/.env.test" ]; then set -a # Export all variables source reports-app/backend/.env.test set +a print_success "TEST Oracle configuration: ${ORACLE_USER}@${ORACLE_DSN}" else print_error ".env.test not found! Create reports-app/backend/.env.test" exit 1 fi # Step 2: Start Backend print_message "2. Starting Backend (FastAPI)..." # Check if backend port is already in use if check_port 8001; then print_warning "Port 8001 is already in use. Backend might already be running." read -p "Continue anyway? (y/n): " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then cleanup fi fi cd reports-app/backend/ # Check if virtual environment exists if [ ! -d "venv" ]; then print_message "Creating Python virtual environment..." python3 -m venv venv fi # Activate virtual environment source venv/bin/activate # Check if dependencies are installed in virtual environment if ! python -c "import fastapi, uvicorn" 2>/dev/null; then print_message "Installing backend dependencies in virtual environment..." pip install -r requirements.txt fi # Start backend in background print_message "Starting uvicorn server..." # NOTE: --reload disabled for cache to work properly (global variables issue) uvicorn app.main:app --host 0.0.0.0 --port 8001 & BACKEND_PID=$! # Wait for backend to start and check multiple times sleep 2 for i in {1..10}; do if check_port 8001; then print_success "Backend started successfully on http://localhost:8001" break fi if [ $i -eq 10 ]; then print_error "Backend failed to start after 10 attempts" cleanup fi sleep 1 done # Step 3: Start Frontend print_message "3. Starting Frontend (Vue.js)..." cd ../frontend/ # Check if node_modules exists and is valid for WSL NEED_REINSTALL=false if [ ! -d "node_modules" ]; then print_message "node_modules not found" NEED_REINSTALL=true elif [ ! -f "node_modules/.bin/vite" ]; then print_warning "vite not found (possibly Windows node_modules detected)" NEED_REINSTALL=true elif [ -f "node_modules/.bin/vite.cmd" ]; then print_warning "Windows node_modules detected (contains .cmd files)" NEED_REINSTALL=true fi if [ "$NEED_REINSTALL" = true ]; then print_message "Reinstalling frontend dependencies for WSL..." print_message "This happens after Windows deployment builds. Please wait..." rm -rf node_modules package-lock.json npm install print_success "Frontend dependencies installed for WSL" fi # Start frontend in background and capture output print_message "Starting Vite development server..." npm run dev > /tmp/vite_output.log 2>&1 & FRONTEND_PID=$! # Wait for frontend to start and detect the actual port sleep 3 FRONTEND_PORT="" for i in {1..10}; do # Check for common Vite ports for port in 3000 3001 3002 3003 3004 3005; do if check_port $port; then FRONTEND_PORT=$port break 2 fi done sleep 1 done # Check if frontend is running if [[ -n $FRONTEND_PORT ]]; then print_success "Frontend started successfully on http://localhost:$FRONTEND_PORT" else print_error "Frontend failed to start" cat /tmp/vite_output.log cleanup fi # Step 4: Start Telegram Bot print_message "4. Starting Telegram Bot..." # Check if telegram bot port is already in use if check_port 8002; then print_warning "Port 8002 is already in use. Telegram bot might already be running." read -p "Continue anyway? (y/n): " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then cleanup fi fi cd ../telegram-bot/ # Check if .env file exists if [ ! -f ".env" ]; then print_error "Telegram bot .env file not found!" print_message "Please create .env file from .env.example and configure TELEGRAM_BOT_TOKEN" cleanup fi # Check if virtual environment exists if [ ! -d "venv" ]; then print_message "Creating Python virtual environment for Telegram bot..." python3 -m venv venv fi # Activate virtual environment source venv/bin/activate # Check if dependencies are installed if ! python -c "import telegram" 2>/dev/null; then print_message "Installing Telegram bot dependencies in virtual environment..." pip install -r requirements.txt fi # Start Telegram bot in background print_message "Starting Telegram bot..." python -m app.main > /tmp/telegram_bot_output.log 2>&1 & TELEGRAM_BOT_PID=$! # Wait for Telegram bot to start sleep 3 for i in {1..10}; do if check_port 8002; then print_success "Telegram bot started successfully (Internal API on http://localhost:8002)" break fi if [ $i -eq 10 ]; then print_error "Telegram bot failed to start after 10 attempts" print_message "Check log at /tmp/telegram_bot_output.log for details" cat /tmp/telegram_bot_output.log cleanup fi sleep 1 done # Summary echo print_success "🚀 ROA2WEB Testing Environment is now running!" echo echo -e "${BLUE}Services:${NC}" echo " • SSH Tunnel: Active (Oracle DB connection)" echo " • Backend: http://localhost:8001" echo " • Frontend: http://localhost:${FRONTEND_PORT:-3000}" echo " • Telegram Bot: http://localhost:8002 (Internal API)" echo " • API Docs: http://localhost:8001/docs" echo echo -e "${YELLOW}Press Ctrl+C to stop all services${NC}" echo # Keep script running and wait for user interrupt wait