|
| 1 | +#!/bin/bash |
| 2 | +# ═══════════════════════════════════════════════════════════════════════════════ |
| 3 | +# NitroWebExpress™ — Verify Module Deploy Locations |
| 4 | +# Checks that deployed webapps in Tomcat have all classes, JARs, and configs |
| 5 | +# that their WEB-INF/web.xml references actually present. |
| 6 | +# |
| 7 | +# Verifies: |
| 8 | +# 1. Every <servlet-class> in web.xml has a matching .class file in WEB-INF/classes |
| 9 | +# 2. Every <filter-class> in web.xml has a matching .class file in WEB-INF/classes |
| 10 | +# 3. JDBC driver JAR present in WEB-INF/lib (if db.properties exists) |
| 11 | +# 4. db.properties exists and has real credentials |
| 12 | +# 5. JSP files referenced by web.xml welcome-file-list exist |
| 13 | +# 6. Source webapp matches deployed webapp (drift detection) |
| 14 | +# |
| 15 | +# Usage: bash scripts/verify-module-deploy-location.sh [tomcat_home] |
| 16 | +# ═══════════════════════════════════════════════════════════════════════════════ |
| 17 | +set -uo pipefail |
| 18 | + |
| 19 | +PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)" |
| 20 | +TOMCAT_HOME="${1:-${CATALINA_HOME:-/home/mearvk/tomcat}}" |
| 21 | +WEBAPPS_DIR="$TOMCAT_HOME/webapps" |
| 22 | + |
| 23 | +PASS=0; FAIL=0; WARN=0 |
| 24 | +pass() { PASS=$((PASS+1)); echo " [PASS] $1"; } |
| 25 | +fail() { FAIL=$((FAIL+1)); echo " [FAIL] $1"; } |
| 26 | +warn() { WARN=$((WARN+1)); echo " [WARN] $1"; } |
| 27 | + |
| 28 | +# context|source_webapp_dir |
| 29 | +declare -A MODULE_SOURCES=( |
| 30 | + ["california-fbi"]="modules/fbi/servlets/servlet/src/main/webapp" |
| 31 | + ["california-cia"]="modules/cia/servlets/servlet/src/main/webapp" |
| 32 | + ["california-nsa"]="modules/nsa/servlets/servlet/src/main/webapp" |
| 33 | + ["california-duke"]="modules/duke/servlets/servlet/src/main/webapp" |
| 34 | + ["library"]="modules/library/servlets/servlet/src/main/webapp" |
| 35 | + ["ae6e66"]="modules/AE6E66/servlets/servlet/src/main/webapp" |
| 36 | + ["futures"]="modules/red/Futures/servlets/servlet/src/main/webapp" |
| 37 | + ["gdgh"]="modules/Green.Durham.Grass.and.Herb/servlets/servlet/src/main/webapp" |
| 38 | + ["gray-registry"]="modules/gray/servlets/servlet/src/main/webapp" |
| 39 | + ["gray85-registry"]="modules/gray.a85/servlets/servlet/src/main/webapp" |
| 40 | + ["blackbelt"]="modules/black-belt/servlets/servlet/src/main/webapp" |
| 41 | + ["languages"]="modules/languages/servlets/servlet/src/main/webapp" |
| 42 | + ["brarner.m.alete"]="modules/black/presidential/Brarner.M.Alete/servlets/servlet/src/main/webapp" |
| 43 | +) |
| 44 | + |
| 45 | +echo "" |
| 46 | +echo "╔═══════════════════════════════════════════════════════════════════════════╗" |
| 47 | +echo "║ NitroWebExpress™ — Verify Module Deploy Locations ║" |
| 48 | +echo "║ Tomcat webapps: $WEBAPPS_DIR" |
| 49 | +echo "║ Project root: $PROJECT_ROOT" |
| 50 | +echo "╚═══════════════════════════════════════════════════════════════════════════╝" |
| 51 | + |
| 52 | +for CONTEXT in $(echo "${!MODULE_SOURCES[@]}" | tr ' ' '\n' | sort); do |
| 53 | + SRC_REL="${MODULE_SOURCES[$CONTEXT]}" |
| 54 | + SRC_DIR="$PROJECT_ROOT/$SRC_REL" |
| 55 | + DEPLOY_DIR="$WEBAPPS_DIR/$CONTEXT" |
| 56 | + |
| 57 | + echo "" |
| 58 | + echo "── /$CONTEXT ──" |
| 59 | + |
| 60 | + # 1. Check deployed directory exists |
| 61 | + if [ ! -d "$DEPLOY_DIR" ]; then |
| 62 | + fail "Webapp not deployed: $DEPLOY_DIR missing" |
| 63 | + continue |
| 64 | + fi |
| 65 | + |
| 66 | + # 2. Check web.xml exists |
| 67 | + WEB_XML="$DEPLOY_DIR/WEB-INF/web.xml" |
| 68 | + if [ ! -f "$WEB_XML" ]; then |
| 69 | + fail "No WEB-INF/web.xml — Tomcat won't load this context" |
| 70 | + continue |
| 71 | + fi |
| 72 | + pass "web.xml present" |
| 73 | + |
| 74 | + # 3. Check every <servlet-class> has a .class file |
| 75 | + SERVLET_CLASSES=$(grep -oP '(?<=<servlet-class>)[^<]+' "$WEB_XML" 2>/dev/null | grep -v "org.apache") |
| 76 | + for CLASS in $SERVLET_CLASSES; do |
| 77 | + CLASS_FILE="$DEPLOY_DIR/WEB-INF/classes/$(echo "$CLASS" | tr '.' '/').class" |
| 78 | + if [ -f "$CLASS_FILE" ]; then |
| 79 | + pass "servlet-class: $CLASS → found" |
| 80 | + else |
| 81 | + fail "servlet-class: $CLASS → MISSING at $CLASS_FILE" |
| 82 | + # Check if it's in a JAR instead |
| 83 | + if ls "$DEPLOY_DIR/WEB-INF/lib/"*.jar &>/dev/null; then |
| 84 | + for JAR in "$DEPLOY_DIR/WEB-INF/lib/"*.jar; do |
| 85 | + if jar tf "$JAR" 2>/dev/null | grep -q "$(echo "$CLASS" | tr '.' '/').class"; then |
| 86 | + warn " (found in JAR: $(basename "$JAR") — OK if intended)" |
| 87 | + break |
| 88 | + fi |
| 89 | + done |
| 90 | + fi |
| 91 | + fi |
| 92 | + done |
| 93 | + |
| 94 | + # 4. Check every <filter-class> has a .class file |
| 95 | + FILTER_CLASSES=$(grep -oP '(?<=<filter-class>)[^<]+' "$WEB_XML" 2>/dev/null | grep -v "org.apache") |
| 96 | + for CLASS in $FILTER_CLASSES; do |
| 97 | + CLASS_FILE="$DEPLOY_DIR/WEB-INF/classes/$(echo "$CLASS" | tr '.' '/').class" |
| 98 | + if [ -f "$CLASS_FILE" ]; then |
| 99 | + pass "filter-class: $CLASS → found" |
| 100 | + else |
| 101 | + fail "filter-class: $CLASS → MISSING at $CLASS_FILE" |
| 102 | + echo " Tomcat will fail to start this webapp (ClassNotFoundException)" |
| 103 | + fi |
| 104 | + done |
| 105 | + |
| 106 | + # 5. Check JDBC driver if db.properties exists |
| 107 | + DB_PROPS="$DEPLOY_DIR/WEB-INF/db.properties" |
| 108 | + if [ -f "$DB_PROPS" ]; then |
| 109 | + JDBC_JAR=$(find "$DEPLOY_DIR/WEB-INF/lib" -name "mysql-connector*" 2>/dev/null | head -1) |
| 110 | + if [ -n "$JDBC_JAR" ]; then |
| 111 | + pass "JDBC driver: $(basename "$JDBC_JAR")" |
| 112 | + else |
| 113 | + fail "db.properties exists but NO JDBC driver in WEB-INF/lib/" |
| 114 | + echo " JSP database queries will throw ClassNotFoundException for com.mysql.cj.jdbc.Driver" |
| 115 | + fi |
| 116 | + |
| 117 | + # Check credentials |
| 118 | + if grep -q "db.password=." "$DB_PROPS" 2>/dev/null && ! grep -q "CHANGE_ME\|PLACEHOLDER" "$DB_PROPS" 2>/dev/null; then |
| 119 | + pass "db.properties has credentials" |
| 120 | + else |
| 121 | + fail "db.properties missing or placeholder password" |
| 122 | + fi |
| 123 | + fi |
| 124 | + |
| 125 | + # 6. Check welcome files exist |
| 126 | + WELCOME_FILES=$(grep -oP '(?<=<welcome-file>)[^<]+' "$WEB_XML" 2>/dev/null) |
| 127 | + for WF in $WELCOME_FILES; do |
| 128 | + if [ -f "$DEPLOY_DIR/$WF" ]; then |
| 129 | + pass "welcome-file: $WF → found" |
| 130 | + else |
| 131 | + fail "welcome-file: $WF → MISSING (causes 404 on /)" |
| 132 | + fi |
| 133 | + done |
| 134 | + |
| 135 | + # 7. Source vs deployed drift detection |
| 136 | + if [ -d "$SRC_DIR" ]; then |
| 137 | + SRC_JSPS=$(find "$SRC_DIR" -maxdepth 1 -name "*.jsp" 2>/dev/null | wc -l) |
| 138 | + DEPLOY_JSPS=$(find "$DEPLOY_DIR" -maxdepth 1 -name "*.jsp" 2>/dev/null | wc -l) |
| 139 | + if [ "$SRC_JSPS" -ne "$DEPLOY_JSPS" ]; then |
| 140 | + warn "JSP count mismatch: source=$SRC_JSPS deployed=$DEPLOY_JSPS (redeploy needed?)" |
| 141 | + fi |
| 142 | + |
| 143 | + SRC_WEBXML_HASH=$(sha256sum "$SRC_DIR/WEB-INF/web.xml" 2>/dev/null | cut -d' ' -f1) |
| 144 | + DEPLOY_WEBXML_HASH=$(sha256sum "$WEB_XML" 2>/dev/null | cut -d' ' -f1) |
| 145 | + if [ -n "$SRC_WEBXML_HASH" ] && [ "$SRC_WEBXML_HASH" != "$DEPLOY_WEBXML_HASH" ]; then |
| 146 | + warn "web.xml differs between source and deployed (redeploy needed)" |
| 147 | + fi |
| 148 | + else |
| 149 | + warn "Source webapp not found: $SRC_DIR" |
| 150 | + fi |
| 151 | +done |
| 152 | + |
| 153 | +# ── Summary ─────────────────────────────────────────────────────────────────── |
| 154 | +echo "" |
| 155 | +echo "╔═══════════════════════════════════════════════════════════════════════════╗" |
| 156 | +printf "║ Results: PASS=%-3d WARN=%-3d FAIL=%-3d ║\n" "$PASS" "$WARN" "$FAIL" |
| 157 | +if [ "$FAIL" -gt 0 ]; then |
| 158 | + echo "║ ║" |
| 159 | + echo "║ Common fixes: ║" |
| 160 | + echo "║ Missing .class: bash scripts/compile-all-modules.sh ║" |
| 161 | + echo "║ bash deploy-all.sh ║" |
| 162 | + echo "║ Missing JDBC: cp jars/mysql/mysql-connector-j-9.7.0.jar ║" |
| 163 | + echo "║ → <webapp>/WEB-INF/lib/ ║" |
| 164 | + echo "║ db.properties: bash scripts/populate-db-properties.sh ║" |
| 165 | + echo "║ Drift detected: bash deploy-all.sh (redeploys all) ║" |
| 166 | +fi |
| 167 | +echo "╚═══════════════════════════════════════════════════════════════════════════╝" |
| 168 | +echo "" |
0 commit comments