Skip to content

Commit f9b7a9d

Browse files
committed
refactor: address review feedback - dedup scripts, add validation, fix curl error handling
- Extract common setup/watch logic to lib/setup-trigger.sh and lib/watch-trigger.sh; per-demo scripts are now thin wrappers setting ENTITY_TYPE/ENTITY_ID/INJECT_HINT - Add trigger_id validation in delete_trigger and watch_trigger_events - Fix curl error handling in create_fault_trigger: capture failure explicitly instead of swallowing with || true
1 parent 7a6cc0c commit f9b7a9d

9 files changed

Lines changed: 116 additions & 194 deletions

File tree

Lines changed: 5 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,9 @@
11
#!/bin/bash
22
# Create fault-monitoring trigger for moveit pick-and-place demo
33
# Alerts on any fault change reported by the manipulation monitor
4-
set -eu
5-
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
6-
# shellcheck disable=SC1091
7-
source "${SCRIPT_DIR}/../../lib/triggers-api.sh"
8-
9-
ENTITY_TYPE="apps"
4+
export ENTITY_TYPE="apps"
105
# Uses ROS node name (underscore) - must match reporting_sources in FaultEvent
11-
ENTITY_ID="manipulation_monitor"
12-
13-
# Check for existing active trigger
14-
existing=$(find_active_trigger "$ENTITY_TYPE" "$ENTITY_ID")
15-
if [ -n "$existing" ]; then
16-
echo "Active trigger already exists: ${existing}"
17-
echo "Run ./watch-triggers.sh to connect, or delete it first:"
18-
echo " curl -X DELETE ${GATEWAY_URL}/api/v1/${ENTITY_TYPE}/${ENTITY_ID}/triggers/${existing}"
19-
exit 0
20-
fi
21-
22-
echo "Setting up fault trigger for ${ENTITY_TYPE}/${ENTITY_ID}..."
23-
echo ""
24-
25-
result=$(create_fault_trigger "$ENTITY_TYPE" "$ENTITY_ID")
26-
trigger_id=$(echo "$result" | jq -r '.id')
27-
28-
if [ -z "$trigger_id" ] || [ "$trigger_id" = "null" ]; then
29-
echo "Failed to parse trigger response." >&2
30-
echo "$result" >&2
31-
exit 1
32-
fi
33-
34-
status=$(echo "$result" | jq -r '.status')
35-
event_source=$(echo "$result" | jq -r '.event_source')
36-
37-
echo "Trigger created successfully!"
38-
echo " ID: ${trigger_id}"
39-
echo " Status: ${status}"
40-
echo " Events: ${GATEWAY_URL}${event_source}"
41-
echo ""
42-
echo "To watch for events:"
43-
echo " ./watch-triggers.sh ${trigger_id}"
44-
echo ""
45-
echo "Then inject a fault in another terminal:"
46-
echo " ./inject-planning-failure.sh"
6+
export ENTITY_ID="manipulation_monitor"
7+
export INJECT_HINT="./inject-planning-failure.sh"
8+
# shellcheck disable=SC1091
9+
source "$(cd "$(dirname "$0")" && pwd)/../../lib/setup-trigger.sh"
Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,7 @@
11
#!/bin/bash
22
# Watch trigger events for moveit pick-and-place demo
33
# Connects to SSE stream and prints fault events in real time
4-
set -eu
5-
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
4+
export ENTITY_TYPE="apps"
5+
export ENTITY_ID="manipulation_monitor"
66
# shellcheck disable=SC1091
7-
source "${SCRIPT_DIR}/../../lib/triggers-api.sh"
8-
9-
ENTITY_TYPE="apps"
10-
ENTITY_ID="manipulation_monitor"
11-
12-
trigger_id="${1:-}"
13-
14-
if [ -z "$trigger_id" ]; then
15-
# Auto-detect: find first active trigger
16-
trigger_id=$(find_active_trigger "$ENTITY_TYPE" "$ENTITY_ID")
17-
if [ -z "$trigger_id" ]; then
18-
echo "No active triggers found for ${ENTITY_TYPE}/${ENTITY_ID}."
19-
echo "Create one first: ./setup-triggers.sh"
20-
exit 1
21-
fi
22-
echo "Found active trigger: ${trigger_id}"
23-
echo ""
24-
fi
25-
26-
watch_trigger_events "$ENTITY_TYPE" "$ENTITY_ID" "$trigger_id"
7+
source "$(cd "$(dirname "$0")" && pwd)/../../lib/watch-trigger.sh" "$@"
Lines changed: 5 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,9 @@
11
#!/bin/bash
22
# Create fault-monitoring trigger for sensor diagnostics demo
33
# Alerts on any new fault reported via the diagnostic bridge
4-
set -eu
5-
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
6-
# shellcheck disable=SC1091
7-
source "${SCRIPT_DIR}/../../lib/triggers-api.sh"
8-
9-
ENTITY_TYPE="apps"
4+
export ENTITY_TYPE="apps"
105
# Uses ROS node name (underscore) - must match reporting_sources in FaultEvent
11-
ENTITY_ID="diagnostic_bridge"
12-
13-
# Check for existing active trigger
14-
existing=$(find_active_trigger "$ENTITY_TYPE" "$ENTITY_ID")
15-
if [ -n "$existing" ]; then
16-
echo "Active trigger already exists: ${existing}"
17-
echo "Run ./watch-triggers.sh to connect, or delete it first:"
18-
echo " curl -X DELETE ${GATEWAY_URL}/api/v1/${ENTITY_TYPE}/${ENTITY_ID}/triggers/${existing}"
19-
exit 0
20-
fi
21-
22-
echo "Setting up fault trigger for ${ENTITY_TYPE}/${ENTITY_ID}..."
23-
echo ""
24-
25-
result=$(create_fault_trigger "$ENTITY_TYPE" "$ENTITY_ID")
26-
trigger_id=$(echo "$result" | jq -r '.id')
27-
28-
if [ -z "$trigger_id" ] || [ "$trigger_id" = "null" ]; then
29-
echo "Failed to parse trigger response." >&2
30-
echo "$result" >&2
31-
exit 1
32-
fi
33-
34-
status=$(echo "$result" | jq -r '.status')
35-
event_source=$(echo "$result" | jq -r '.event_source')
36-
37-
echo "Trigger created successfully!"
38-
echo " ID: ${trigger_id}"
39-
echo " Status: ${status}"
40-
echo " Events: ${GATEWAY_URL}${event_source}"
41-
echo ""
42-
echo "To watch for events:"
43-
echo " ./watch-triggers.sh ${trigger_id}"
44-
echo ""
45-
echo "Then inject a fault in another terminal:"
46-
echo " ./inject-nan.sh"
6+
export ENTITY_ID="diagnostic_bridge"
7+
export INJECT_HINT="./inject-nan.sh"
8+
# shellcheck disable=SC1091
9+
source "$(cd "$(dirname "$0")" && pwd)/../../lib/setup-trigger.sh"
Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,7 @@
11
#!/bin/bash
22
# Watch trigger events for sensor diagnostics demo
33
# Connects to SSE stream and prints fault events in real time
4-
set -eu
5-
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
4+
export ENTITY_TYPE="apps"
5+
export ENTITY_ID="diagnostic_bridge"
66
# shellcheck disable=SC1091
7-
source "${SCRIPT_DIR}/../../lib/triggers-api.sh"
8-
9-
ENTITY_TYPE="apps"
10-
ENTITY_ID="diagnostic_bridge"
11-
12-
trigger_id="${1:-}"
13-
14-
if [ -z "$trigger_id" ]; then
15-
# Auto-detect: find first active trigger
16-
trigger_id=$(find_active_trigger "$ENTITY_TYPE" "$ENTITY_ID")
17-
if [ -z "$trigger_id" ]; then
18-
echo "No active triggers found for ${ENTITY_TYPE}/${ENTITY_ID}."
19-
echo "Create one first: ./setup-triggers.sh"
20-
exit 1
21-
fi
22-
echo "Found active trigger: ${trigger_id}"
23-
echo ""
24-
fi
25-
26-
watch_trigger_events "$ENTITY_TYPE" "$ENTITY_ID" "$trigger_id"
7+
source "$(cd "$(dirname "$0")" && pwd)/../../lib/watch-trigger.sh" "$@"
Lines changed: 5 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,9 @@
11
#!/bin/bash
22
# Create fault-monitoring trigger for turtlebot3 integration demo
33
# Alerts on any fault change reported by the anomaly detector
4-
set -eu
5-
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
6-
# shellcheck disable=SC1091
7-
source "${SCRIPT_DIR}/../../lib/triggers-api.sh"
8-
9-
ENTITY_TYPE="apps"
4+
export ENTITY_TYPE="apps"
105
# Uses ROS node name (underscore) - must match reporting_sources in FaultEvent
11-
ENTITY_ID="anomaly_detector"
12-
13-
# Check for existing active trigger
14-
existing=$(find_active_trigger "$ENTITY_TYPE" "$ENTITY_ID")
15-
if [ -n "$existing" ]; then
16-
echo "Active trigger already exists: ${existing}"
17-
echo "Run ./watch-triggers.sh to connect, or delete it first:"
18-
echo " curl -X DELETE ${GATEWAY_URL}/api/v1/${ENTITY_TYPE}/${ENTITY_ID}/triggers/${existing}"
19-
exit 0
20-
fi
21-
22-
echo "Setting up fault trigger for ${ENTITY_TYPE}/${ENTITY_ID}..."
23-
echo ""
24-
25-
result=$(create_fault_trigger "$ENTITY_TYPE" "$ENTITY_ID")
26-
trigger_id=$(echo "$result" | jq -r '.id')
27-
28-
if [ -z "$trigger_id" ] || [ "$trigger_id" = "null" ]; then
29-
echo "Failed to parse trigger response." >&2
30-
echo "$result" >&2
31-
exit 1
32-
fi
33-
34-
status=$(echo "$result" | jq -r '.status')
35-
event_source=$(echo "$result" | jq -r '.event_source')
36-
37-
echo "Trigger created successfully!"
38-
echo " ID: ${trigger_id}"
39-
echo " Status: ${status}"
40-
echo " Events: ${GATEWAY_URL}${event_source}"
41-
echo ""
42-
echo "To watch for events:"
43-
echo " ./watch-triggers.sh ${trigger_id}"
44-
echo ""
45-
echo "Then inject a fault in another terminal:"
46-
echo " ./inject-nav-failure.sh"
6+
export ENTITY_ID="anomaly_detector"
7+
export INJECT_HINT="./inject-nav-failure.sh"
8+
# shellcheck disable=SC1091
9+
source "$(cd "$(dirname "$0")" && pwd)/../../lib/setup-trigger.sh"
Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,7 @@
11
#!/bin/bash
22
# Watch trigger events for turtlebot3 integration demo
33
# Connects to SSE stream and prints fault events in real time
4-
set -eu
5-
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
4+
export ENTITY_TYPE="apps"
5+
export ENTITY_ID="anomaly_detector"
66
# shellcheck disable=SC1091
7-
source "${SCRIPT_DIR}/../../lib/triggers-api.sh"
8-
9-
ENTITY_TYPE="apps"
10-
ENTITY_ID="anomaly_detector"
11-
12-
trigger_id="${1:-}"
13-
14-
if [ -z "$trigger_id" ]; then
15-
# Auto-detect: find first active trigger
16-
trigger_id=$(find_active_trigger "$ENTITY_TYPE" "$ENTITY_ID")
17-
if [ -z "$trigger_id" ]; then
18-
echo "No active triggers found for ${ENTITY_TYPE}/${ENTITY_ID}."
19-
echo "Create one first: ./setup-triggers.sh"
20-
exit 1
21-
fi
22-
echo "Found active trigger: ${trigger_id}"
23-
echo ""
24-
fi
25-
26-
watch_trigger_events "$ENTITY_TYPE" "$ENTITY_ID" "$trigger_id"
7+
source "$(cd "$(dirname "$0")" && pwd)/../../lib/watch-trigger.sh" "$@"

lib/setup-trigger.sh

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/bin/bash
2+
# Generic trigger setup - called by per-demo setup-triggers.sh wrappers
3+
# Requires ENTITY_TYPE, ENTITY_ID, and INJECT_HINT to be set before sourcing
4+
set -eu
5+
6+
if [ -z "${ENTITY_TYPE:-}" ] || [ -z "${ENTITY_ID:-}" ]; then
7+
echo "ENTITY_TYPE and ENTITY_ID must be set before sourcing this script." >&2
8+
exit 1
9+
fi
10+
11+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
12+
# shellcheck disable=SC1091
13+
source "${SCRIPT_DIR}/triggers-api.sh"
14+
15+
# Check for existing active trigger
16+
existing=$(find_active_trigger "$ENTITY_TYPE" "$ENTITY_ID")
17+
if [ -n "$existing" ]; then
18+
echo "Active trigger already exists: ${existing}"
19+
echo "Run ./watch-triggers.sh to connect, or delete it first:"
20+
echo " curl -X DELETE ${GATEWAY_URL}/api/v1/${ENTITY_TYPE}/${ENTITY_ID}/triggers/${existing}"
21+
exit 0
22+
fi
23+
24+
echo "Setting up fault trigger for ${ENTITY_TYPE}/${ENTITY_ID}..."
25+
echo ""
26+
27+
result=$(create_fault_trigger "$ENTITY_TYPE" "$ENTITY_ID")
28+
trigger_id=$(echo "$result" | jq -r '.id')
29+
30+
if [ -z "$trigger_id" ] || [ "$trigger_id" = "null" ]; then
31+
echo "Failed to parse trigger response." >&2
32+
echo "$result" >&2
33+
exit 1
34+
fi
35+
36+
status=$(echo "$result" | jq -r '.status')
37+
event_source=$(echo "$result" | jq -r '.event_source')
38+
39+
echo "Trigger created successfully!"
40+
echo " ID: ${trigger_id}"
41+
echo " Status: ${status}"
42+
echo " Events: ${GATEWAY_URL}${event_source}"
43+
echo ""
44+
echo "To watch for events:"
45+
echo " ./watch-triggers.sh ${trigger_id}"
46+
echo ""
47+
echo "Then inject a fault in another terminal:"
48+
echo " ${INJECT_HINT:-./inject-nan.sh}"

lib/triggers-api.sh

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,13 @@ create_fault_trigger() {
5050

5151
local result
5252
local http_code
53-
result=$(curl -s -w "\n%{http_code}" -X POST \
53+
if ! result=$(curl -s -w "\n%{http_code}" -X POST \
5454
"${API_BASE}/${entity_type}/${entity_id}/triggers" \
5555
-H "Content-Type: application/json" \
56-
-d "$body" 2>/dev/null) || true
56+
-d "$body" 2>/dev/null); then
57+
echo "Failed to reach gateway at ${GATEWAY_URL}." >&2
58+
return 1
59+
fi
5760

5861
http_code=$(echo "$result" | tail -1)
5962
result=$(echo "$result" | sed '$d')
@@ -85,6 +88,11 @@ delete_trigger() {
8588
local entity_id="$2"
8689
local trigger_id="$3"
8790

91+
if [[ ! "$trigger_id" =~ ^[a-zA-Z0-9_-]+$ ]]; then
92+
echo "Invalid trigger ID: '${trigger_id}'" >&2
93+
return 1
94+
fi
95+
8896
check_gateway
8997

9098
local http_code
@@ -106,6 +114,11 @@ watch_trigger_events() {
106114
local entity_id="$2"
107115
local trigger_id="$3"
108116

117+
if [[ ! "$trigger_id" =~ ^[a-zA-Z0-9_-]+$ ]]; then
118+
echo "Invalid trigger ID: '${trigger_id}'" >&2
119+
return 1
120+
fi
121+
109122
check_gateway
110123

111124
local url="${API_BASE}/${entity_type}/${entity_id}/triggers/${trigger_id}/events"

lib/watch-trigger.sh

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#!/bin/bash
2+
# Generic trigger watcher - called by per-demo watch-triggers.sh wrappers
3+
# Requires ENTITY_TYPE and ENTITY_ID to be set before sourcing
4+
set -eu
5+
6+
if [ -z "${ENTITY_TYPE:-}" ] || [ -z "${ENTITY_ID:-}" ]; then
7+
echo "ENTITY_TYPE and ENTITY_ID must be set before sourcing this script." >&2
8+
exit 1
9+
fi
10+
11+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
12+
# shellcheck disable=SC1091
13+
source "${SCRIPT_DIR}/triggers-api.sh"
14+
15+
trigger_id="${1:-}"
16+
17+
if [ -z "$trigger_id" ]; then
18+
# Auto-detect: find first active trigger
19+
trigger_id=$(find_active_trigger "$ENTITY_TYPE" "$ENTITY_ID")
20+
if [ -z "$trigger_id" ]; then
21+
echo "No active triggers found for ${ENTITY_TYPE}/${ENTITY_ID}."
22+
echo "Create one first: ./setup-triggers.sh"
23+
exit 1
24+
fi
25+
echo "Found active trigger: ${trigger_id}"
26+
echo ""
27+
fi
28+
29+
watch_trigger_events "$ENTITY_TYPE" "$ENTITY_ID" "$trigger_id"

0 commit comments

Comments
 (0)