Files
aitbc/cli/commands/blockchain_event_bridge.py
aitbc 522655ef92
Some checks failed
API Endpoint Tests / test-api-endpoints (push) Successful in 10s
Blockchain Synchronization Verification / sync-verification (push) Failing after 3s
CLI Tests / test-cli (push) Failing after 4s
Documentation Validation / validate-docs (push) Successful in 8s
Documentation Validation / validate-policies-strict (push) Successful in 4s
Integration Tests / test-service-integration (push) Successful in 38s
Multi-Node Blockchain Health Monitoring / health-check (push) Successful in 2s
P2P Network Verification / p2p-verification (push) Successful in 3s
Security Scanning / security-scan (push) Successful in 40s
Smart Contract Tests / test-solidity (map[name:aitbc-token path:packages/solidity/aitbc-token]) (push) Successful in 15s
Smart Contract Tests / lint-solidity (push) Successful in 8s
Move blockchain app READMEs to centralized documentation
- Relocate blockchain-event-bridge README content to docs/apps/blockchain/blockchain-event-bridge.md
- Relocate blockchain-explorer README content to docs/apps/blockchain/blockchain-explorer.md
- Replace app READMEs with redirect notices pointing to new documentation location
- Consolidate documentation in central docs/ directory for better organization
2026-04-23 12:24:48 +02:00

350 lines
14 KiB
Python

"""
Blockchain Event Bridge CLI Commands for AITBC
Commands for managing blockchain event bridge service
"""
import click
import json
import requests
import subprocess
from datetime import datetime
from typing import Dict, Any, List, Optional
@click.group()
def bridge():
"""Blockchain event bridge management commands"""
pass
@bridge.command()
@click.option('--test-mode', is_flag=True, help='Run in test mode')
def health(test_mode):
"""Health check for blockchain event bridge service"""
try:
if test_mode:
# Mock data for testing
mock_health = {
"status": "healthy",
"service": "blockchain-event-bridge",
"version": "0.1.0",
"uptime_seconds": 86400,
"timestamp": datetime.utcnow().isoformat()
}
click.echo("🏥 Blockchain Event Bridge Health:")
click.echo("=" * 50)
click.echo(f"✅ Status: {mock_health['status']}")
click.echo(f"📦 Service: {mock_health['service']}")
click.echo(f"📦 Version: {mock_health['version']}")
click.echo(f"⏱️ Uptime: {mock_health['uptime_seconds']}s")
click.echo(f"🕐 Timestamp: {mock_health['timestamp']}")
return
# Fetch from bridge service
config = get_config()
response = requests.get(
f"{config.bridge_url}/health",
timeout=10
)
if response.status_code == 200:
health = response.json()
click.echo("🏥 Blockchain Event Bridge Health:")
click.echo("=" * 50)
click.echo(f"✅ Status: {health.get('status', 'unknown')}")
click.echo(f"📦 Service: {health.get('service', 'unknown')}")
click.echo(f"📦 Version: {health.get('version', 'unknown')}")
click.echo(f"⏱️ Uptime: {health.get('uptime_seconds', 0)}s")
click.echo(f"🕐 Timestamp: {health.get('timestamp', 'unknown')}")
else:
click.echo(f"❌ Health check failed: {response.text}", err=True)
except Exception as e:
click.echo(f"❌ Error checking health: {str(e)}", err=True)
@bridge.command()
@click.option('--test-mode', is_flag=True, help='Run in test mode')
def metrics(test_mode):
"""Get Prometheus metrics from blockchain event bridge service"""
try:
if test_mode:
# Mock data for testing
mock_metrics = """
# HELP bridge_events_total Total number of blockchain events processed
# TYPE bridge_events_total counter
bridge_events_total{type="block"} 12345
bridge_events_total{type="transaction"} 67890
bridge_events_total{type="contract"} 23456
# HELP bridge_events_processed_total Total number of events successfully processed
# TYPE bridge_events_processed_total counter
bridge_events_processed_total 103691
# HELP bridge_events_failed_total Total number of events that failed processing
# TYPE bridge_events_failed_total counter
bridge_events_failed_total 123
# HELP bridge_processing_duration_seconds Event processing duration
# TYPE bridge_processing_duration_seconds histogram
bridge_processing_duration_seconds_bucket{le="0.1"} 50000
bridge_processing_duration_seconds_bucket{le="1.0"} 100000
bridge_processing_duration_seconds_sum 45000.5
bridge_processing_duration_seconds_count 103691
""".strip()
click.echo("📊 Prometheus Metrics:")
click.echo("=" * 50)
click.echo(mock_metrics)
return
# Fetch from bridge service
config = get_config()
response = requests.get(
f"{config.bridge_url}/metrics",
timeout=10
)
if response.status_code == 200:
metrics = response.text
click.echo("📊 Prometheus Metrics:")
click.echo("=" * 50)
click.echo(metrics)
else:
click.echo(f"❌ Failed to get metrics: {response.text}", err=True)
except Exception as e:
click.echo(f"❌ Error getting metrics: {str(e)}", err=True)
@bridge.command()
@click.option('--test-mode', is_flag=True, help='Run in test mode')
def status(test_mode):
"""Get detailed status of blockchain event bridge service"""
try:
if test_mode:
# Mock data for testing
mock_status = {
"service": "blockchain-event-bridge",
"status": "running",
"version": "0.1.0",
"subscriptions": {
"blocks": {
"enabled": True,
"topic": "blocks",
"last_block": 123456
},
"transactions": {
"enabled": True,
"topic": "transactions",
"last_transaction": "0xabc123..."
},
"contract_events": {
"enabled": True,
"contracts": [
"AgentStaking",
"PerformanceVerifier",
"AgentServiceMarketplace"
],
"last_event": "0xdef456..."
}
},
"triggers": {
"agent_daemon": {
"enabled": True,
"events_triggered": 5432
},
"coordinator_api": {
"enabled": True,
"events_triggered": 8765
},
"marketplace": {
"enabled": True,
"events_triggered": 3210
}
},
"metrics": {
"events_processed": 103691,
"events_failed": 123,
"success_rate": 99.88
}
}
click.echo("📊 Blockchain Event Bridge Status:")
click.echo("=" * 50)
click.echo(f"📦 Service: {mock_status['service']}")
click.echo(f"✅ Status: {mock_status['status']}")
click.echo(f"📦 Version: {mock_status['version']}")
click.echo("")
click.echo("🔔 Subscriptions:")
for sub_type, sub_data in mock_status['subscriptions'].items():
click.echo(f" {sub_type}:")
click.echo(f" Enabled: {sub_data['enabled']}")
if 'topic' in sub_data:
click.echo(f" Topic: {sub_data['topic']}")
if 'last_block' in sub_data:
click.echo(f" Last Block: {sub_data['last_block']}")
if 'contracts' in sub_data:
click.echo(f" Contracts: {', '.join(sub_data['contracts'])}")
click.echo("")
click.echo("🎯 Triggers:")
for trigger_type, trigger_data in mock_status['triggers'].items():
click.echo(f" {trigger_type}:")
click.echo(f" Enabled: {trigger_data['enabled']}")
click.echo(f" Events Triggered: {trigger_data['events_triggered']}")
click.echo("")
click.echo("📊 Metrics:")
click.echo(f" Events Processed: {mock_status['metrics']['events_processed']}")
click.echo(f" Events Failed: {mock_status['metrics']['events_failed']}")
click.echo(f" Success Rate: {mock_status['metrics']['success_rate']}%")
return
# Fetch from bridge service
config = get_config()
response = requests.get(
f"{config.bridge_url}/",
timeout=10
)
if response.status_code == 200:
status = response.json()
click.echo("📊 Blockchain Event Bridge Status:")
click.echo("=" * 50)
click.echo(f"📦 Service: {status.get('service', 'unknown')}")
click.echo(f"✅ Status: {status.get('status', 'unknown')}")
click.echo(f"📦 Version: {status.get('version', 'unknown')}")
if 'subscriptions' in status:
click.echo("")
click.echo("🔔 Subscriptions:")
for sub_type, sub_data in status['subscriptions'].items():
click.echo(f" {sub_type}:")
click.echo(f" Enabled: {sub_data.get('enabled', False)}")
else:
click.echo(f"❌ Failed to get status: {response.text}", err=True)
except Exception as e:
click.echo(f"❌ Error getting status: {str(e)}", err=True)
@bridge.command()
@click.option('--test-mode', is_flag=True, help='Run in test mode')
def config(test_mode):
"""Show current configuration of blockchain event bridge service"""
try:
if test_mode:
# Mock data for testing
mock_config = {
"blockchain_rpc_url": "http://localhost:8006",
"gossip_backend": "redis",
"gossip_broadcast_url": "redis://localhost:6379",
"coordinator_api_url": "http://localhost:8011",
"coordinator_api_key": "***",
"subscriptions": {
"blocks": True,
"transactions": True
},
"triggers": {
"agent_daemon": True,
"coordinator_api": True,
"marketplace": True
},
"polling": {
"enabled": False,
"interval_seconds": 60
}
}
click.echo("⚙️ Blockchain Event Bridge Configuration:")
click.echo("=" * 50)
click.echo(f"🔗 Blockchain RPC URL: {mock_config['blockchain_rpc_url']}")
click.echo(f"💬 Gossip Backend: {mock_config['gossip_backend']}")
if mock_config.get('gossip_broadcast_url'):
click.echo(f"📡 Gossip Broadcast URL: {mock_config['gossip_broadcast_url']}")
click.echo(f"🎯 Coordinator API URL: {mock_config['coordinator_api_url']}")
click.echo(f"🔑 Coordinator API Key: {mock_config['coordinator_api_key']}")
click.echo("")
click.echo("🔔 Subscriptions:")
for sub, enabled in mock_config['subscriptions'].items():
status = "" if enabled else ""
click.echo(f" {status} {sub}")
click.echo("")
click.echo("🎯 Triggers:")
for trigger, enabled in mock_config['triggers'].items():
status = "" if enabled else ""
click.echo(f" {status} {trigger}")
click.echo("")
click.echo("⏱️ Polling:")
click.echo(f" Enabled: {mock_config['polling']['enabled']}")
click.echo(f" Interval: {mock_config['polling']['interval_seconds']}s")
return
# Fetch from bridge service
config = get_config()
response = requests.get(
f"{config.bridge_url}/config",
timeout=10
)
if response.status_code == 200:
service_config = response.json()
click.echo("⚙️ Blockchain Event Bridge Configuration:")
click.echo("=" * 50)
click.echo(f"🔗 Blockchain RPC URL: {service_config.get('blockchain_rpc_url', 'unknown')}")
click.echo(f"💬 Gossip Backend: {service_config.get('gossip_backend', 'unknown')}")
if service_config.get('gossip_broadcast_url'):
click.echo(f"📡 Gossip Broadcast URL: {service_config['gossip_broadcast_url']}")
click.echo(f"🎯 Coordinator API URL: {service_config.get('coordinator_api_url', 'unknown')}")
else:
click.echo(f"❌ Failed to get config: {response.text}", err=True)
except Exception as e:
click.echo(f"❌ Error getting config: {str(e)}", err=True)
@bridge.command()
@click.option('--test-mode', is_flag=True, help='Run in test mode')
def restart(test_mode):
"""Restart blockchain event bridge service (via systemd)"""
try:
if test_mode:
click.echo("🔄 Blockchain event bridge restart triggered (test mode)")
click.echo("✅ Restart completed successfully")
return
# Restart via systemd
try:
result = subprocess.run(
["sudo", "systemctl", "restart", "aitbc-blockchain-event-bridge"],
capture_output=True,
text=True,
timeout=30
)
if result.returncode == 0:
click.echo("🔄 Blockchain event bridge restart triggered")
click.echo("✅ Restart completed successfully")
else:
click.echo(f"❌ Restart failed: {result.stderr}", err=True)
except subprocess.TimeoutExpired:
click.echo("❌ Restart timeout - service may be starting", err=True)
except FileNotFoundError:
click.echo("❌ systemctl not found - cannot restart service", err=True)
except Exception as e:
click.echo(f"❌ Error restarting service: {str(e)}", err=True)
# Helper function to get config
def get_config():
"""Get CLI configuration"""
try:
from config import get_config
return get_config()
except ImportError:
# Fallback for testing
from types import SimpleNamespace
return SimpleNamespace(
bridge_url="http://localhost:8204",
api_key="test-api-key"
)
if __name__ == "__main__":
bridge()