Move blockchain app READMEs to centralized documentation
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
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
- 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
This commit is contained in:
349
cli/commands/blockchain_event_bridge.py
Normal file
349
cli/commands/blockchain_event_bridge.py
Normal file
@@ -0,0 +1,349 @@
|
||||
"""
|
||||
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()
|
||||
Reference in New Issue
Block a user