198 lines
7.4 KiB
Bash
Executable File
198 lines
7.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# seed-demo.sh — Popola ASF con i dati DEMO del tenant t-demo-003.
|
|
#
|
|
# Sequenza (idempotente dal lato API - POST ritorna 201 per nuovi artifact,
|
|
# ma se seed precedenti esistono già verrà creato duplicato perché non abbiamo
|
|
# un controllo unique ext_id in questa fase MVP. Per sicurezza cancella TUTTI
|
|
# artifacts + jobs prima di ricreare quando si specifica --clean.
|
|
#
|
|
# Usage:
|
|
# ./scripts/seed-demo.sh # seeds normali (3 blocchi trace + code + extra)
|
|
# ./scripts/seed-demo.sh --clean # PURGA artifacts + jobs t-demo-003 POI seed
|
|
# ./scripts/seed-demo.sh --jobs # + 5 job echo demo in coda (devops/testing/...)
|
|
#
|
|
# Richiede:
|
|
# • ASF Core attivo su http://localhost:8000 (scripts/start-stack.sh)
|
|
# • Python .venv attivo o eseguibile in /root/ASF/.venv/bin/python
|
|
# • Worker attivo se usi --jobs (altrimenti jobs stanno in QUEUED)
|
|
#
|
|
|
|
set -euo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
PY="$ROOT/.venv/bin/python"
|
|
CORE_URL="${ASF_CORE_URL:-http://localhost:8000}"
|
|
TENANT="${X_ASF_TENANT_ID:-t-demo-003}"
|
|
USER="${X_ASF_USER_ID:-u-mario}"
|
|
|
|
CLEAN=0
|
|
JOBS=0
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--clean) CLEAN=1 ;;
|
|
--jobs) JOBS=1 ;;
|
|
-h|--help)
|
|
sed -n '2,26p' "$0"
|
|
exit 0 ;;
|
|
esac
|
|
done
|
|
|
|
log() { printf " \033[1;34m→\033[0m %s\n" "$*"; }
|
|
ok() { printf " \033[1;32m✔\033[0m %s\n" "$*"; }
|
|
fail() { printf " \033[1;31m✘\033[0m %s\n" "$*" >&2; exit 1; }
|
|
|
|
curl_h() {
|
|
# $1 = method, $2 = path, stdin optional body. Prints status + JSON body.
|
|
local m="$1" p="$2"
|
|
shift 2
|
|
curl -s -X "$m" -H "X-ASF-Tenant-Id: $TENANT" -H "X-ASF-User-Id: $USER" \
|
|
-H "Content-Type: application/json" \
|
|
"${CORE_URL}/api/v1${p}" "$@"
|
|
}
|
|
|
|
# --- Sanity check: Core UP ---
|
|
log "ASF Core health check su $CORE_URL"
|
|
H=$(curl -s -o /dev/null -w "%{http_code}" "${CORE_URL}/api/v1/health" || true)
|
|
if [[ "$H" != "200" ]]; then
|
|
fail "ASF Core non risponde (HTTP $H). Avvia con: bash scripts/start-stack.sh"
|
|
fi
|
|
ok "ASF Core UP (health=$H)"
|
|
|
|
# --- Cleanup (opzionale) ---
|
|
if [[ $CLEAN == 1 ]]; then
|
|
log "Cleanup artifacts + jobs per tenant $TENANT (DELETE /artifacts e /jobs listati)"
|
|
|
|
# MVP: asf-core non espone DELETE /artifacts bulk. Useremo GET lista + DELETE /artifacts/{id}.
|
|
A_IDS=$(curl_h GET "/artifacts?limit=500" | "$PY" -c '
|
|
import json,sys
|
|
d=json.load(sys.stdin)
|
|
for a in d: print(a["id"])
|
|
')
|
|
N_A=$(echo -n "$A_IDS" | grep -c . || true)
|
|
log " DELETE $N_A artifacts..."
|
|
if [[ -n "$A_IDS" ]]; then
|
|
while read -r id; do
|
|
curl -s -o /dev/null -X DELETE \
|
|
-H "X-ASF-Tenant-Id: $TENANT" -H "X-ASF-User-Id: $USER" \
|
|
"${CORE_URL}/api/v1/artifacts/${id}" || true
|
|
done <<< "$A_IDS"
|
|
fi
|
|
|
|
J_IDS=$(curl_h GET "/jobs?limit=500" | "$PY" -c '
|
|
import json,sys
|
|
d=json.load(sys.stdin)
|
|
for j in d: print(j["id"])
|
|
' 2>/dev/null || true)
|
|
N_J=$(echo -n "$J_IDS" | grep -c . || true)
|
|
log " PATCH CANCEL $N_J jobs..."
|
|
if [[ -n "$J_IDS" ]]; then
|
|
while read -r id; do
|
|
curl -s -o /dev/null -X PATCH \
|
|
-H "X-ASF-Tenant-Id: $TENANT" -H "X-ASF-User-Id: $USER" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"status":"cancelled"}' \
|
|
"${CORE_URL}/api/v1/jobs/${id}" || true
|
|
done <<< "$J_IDS"
|
|
fi
|
|
ok "Cleanup completato"
|
|
fi
|
|
|
|
# --- Seeds ---
|
|
log "Seed 1/4: Traceability artifacts (REQ → TASK → PR → TEST/BUILD → DEPLOY)"
|
|
"$PY" "$ROOT/scripts/seed-traceability.py" >/tmp/seed1.log 2>&1 \
|
|
|| fail "seed-traceability fallito. Log: /tmp/seed1.log"
|
|
ok " OK ($(wc -l < /tmp/seed1.log) righe log)"
|
|
|
|
log "Seed 2/4: Relazioni traceability (5 edges: implements/verifies/deployed_as/generated_from)"
|
|
"$PY" "$ROOT/scripts/seed-rels-only.py" >/tmp/seed2.log 2>&1 \
|
|
|| fail "seed-rels fallito. Log: /tmp/seed2.log"
|
|
ok " OK ($(wc -l < /tmp/seed2.log) righe log)"
|
|
|
|
log "Seed 3/4: Source files + Code smells (3 files, 3 smells)"
|
|
"$PY" "$ROOT/scripts/seed-code-artifacts.py" >/tmp/seed3.log 2>&1 \
|
|
|| fail "seed-code-artifacts fallito. Log: /tmp/seed3.log"
|
|
ok " OK ($(wc -l < /tmp/seed3.log) righe log)"
|
|
|
|
log "Seed 4/4: Extra DOC / COMMIT / SEC / INC + 4 relazioni (densify graph)"
|
|
"$PY" "$ROOT/scripts/seed-extra-rels.py" >/tmp/seed4.log 2>&1 \
|
|
|| fail "seed-extra-rels fallito. Log: /tmp/seed4.log"
|
|
ok " OK ($(wc -l < /tmp/seed4.log) righe log)"
|
|
|
|
# --- Jobs demo (opzionale) ---
|
|
if [[ $JOBS == 1 ]]; then
|
|
log "Enqueue 5 demo jobs (echo handler DEVOPS/TESTING/...)"
|
|
OUT=$(curl -s -X POST \
|
|
-H "X-ASF-Tenant-Id: $TENANT" -H "X-ASF-User-Id: $USER" \
|
|
-H "Content-Type: application/json" \
|
|
--data-raw '{
|
|
"jobs": [
|
|
{"type":"devops","priority":"normal","payload":{"name":"deploy-dev","env":"dev"}},
|
|
{"type":"testing","priority":"high","payload":{"name":"smoke-tests","framework":"pytest"}},
|
|
{"type":"devops","priority":"normal","payload":{"name":"build-image","image":"asf/app:latest"}},
|
|
{"type":"notifications","priority":"low","payload":{"channel":"email","to":"admins"}},
|
|
{"type":"indexing","priority":"normal","payload":{"source":"github/asf","branch":"main"}}
|
|
]
|
|
}' "${CORE_URL}/api/v1/jobs/batch" 2>&1 || echo "fallback")
|
|
# Fallback per /batch non esistente (MVP usa singolo POST per job)
|
|
if [[ "$OUT" == *"fallback"* || "$OUT" == *"Not Found"* || "$OUT" == *"404"* || "$OUT" == *"405"* ]]; then
|
|
log " /batch non disponibile → 5 POST singoli:"
|
|
TYPES=("devops" "testing" "devops" "notifications" "indexing")
|
|
PAYLOADS=(
|
|
'{"name":"deploy-dev","env":"dev"}'
|
|
'{"name":"smoke-tests","framework":"pytest"}'
|
|
'{"name":"build-image","image":"asf/app:latest"}'
|
|
'{"channel":"email","to":"admins"}'
|
|
'{"source":"github/asf","branch":"main"}'
|
|
)
|
|
PRIO=("normal" "high" "normal" "low" "normal")
|
|
for i in 0 1 2 3 4; do
|
|
JS=$(curl -s -X POST \
|
|
-H "X-ASF-Tenant-Id: $TENANT" -H "X-ASF-User-Id: $USER" \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"type\":\"${TYPES[$i]}\",\"priority\":\"${PRIO[$i]}\",\"payload\":${PAYLOADS[$i]}}" \
|
|
"${CORE_URL}/api/v1/jobs/submit")
|
|
echo -n "$JS" | "$PY" -c 'import json,sys; j=json.load(sys.stdin); print(" - job id=", j.get("id","?")[:8]+"…", "accepted=", j.get("accepted"))' 2>/dev/null
|
|
done
|
|
else
|
|
ok " /batch accettato"
|
|
fi
|
|
ok "5 demo jobs accodati (avvia asf-worker per completarli)"
|
|
fi
|
|
|
|
# --- Report finale ---
|
|
log "Report finale tenant $TENANT:"
|
|
echo ""
|
|
curl_h GET "/artifacts?limit=500" | "$PY" - <<'PY'
|
|
import json,sys
|
|
from collections import Counter
|
|
d=json.load(sys.stdin)
|
|
c=Counter(a.get("type","?") for a in d)
|
|
print(" Artifacts totali:", len(d))
|
|
for k,v in sorted(c.items(), key=lambda x:-x[1]):
|
|
print(f" - {k:18s} {v}")
|
|
PY
|
|
echo ""
|
|
curl_h GET "/traceability/graph" 2>/dev/null | "$PY" -c '
|
|
import json,sys
|
|
g=json.load(sys.stdin)
|
|
print(f" Traceability graph: nodes={len(g.get(\"nodes\",[]))} edges={len(g.get(\"edges\",[]))}")
|
|
' 2>/dev/null || true
|
|
echo ""
|
|
curl_h GET "/jobs" 2>/dev/null | "$PY" - <<'PY'
|
|
import json,sys
|
|
from collections import Counter
|
|
d=json.load(sys.stdin)
|
|
c=Counter(j.get("status","?") for j in d)
|
|
print(" Jobs totali:", len(d))
|
|
for k,v in sorted(c.items(), key=lambda x:-x[1]):
|
|
print(f" - {k:10s} {v}")
|
|
PY
|
|
echo ""
|
|
ok "SEED DEMO completato."
|
|
echo ""
|
|
echo " Suggerimenti:"
|
|
echo " • Apri http://localhost:3000 per vedere UI (hard refresh Ctrl+Shift+R se serve)"
|
|
echo " • bash scripts/status-stack.sh per stato core/web/worker"
|
|
echo " • bash scripts/seed-demo.sh --clean --jobs per ricreare TUTTO da zero"
|