Saltar al contenido principal

Puntos finales de la API y Gestión de Configuración

API REST para Gestionar la Configuración y Operaciones de Dispositivos RAN

Guía para gestionar la configuración de estaciones base, consultar el estado del dispositivo y automatizar operaciones RAN utilizando la API independiente del proveedor


Tabla de Contenidos

  1. Descripción general
  2. Arquitectura de la API
  3. Autenticación y Acceso
  4. Referencia de Puntos Finales
  5. Gestión de Configuración
  6. Operaciones de Recuperación de Datos
  7. Flujos de Trabajo Comunes
  8. Manejo de Errores
  9. Ejemplos de API

Descripción general

RAN Monitor expone una API REST integral para gestionar la configuración de dispositivos RAN y consultar datos operativos. La API proporciona una interfaz independiente del proveedor que abstrae los protocolos de comunicación de dispositivos subyacentes. La API permite:

  • Gestión de Dispositivos - Registrar, anular registro y monitorear dispositivos
  • Consultas de Configuración - Recuperar parámetros de dispositivos y estado del sistema
  • Recopilación de Datos - Obtener métricas de rendimiento, alarmas y topología
  • Control de Sesiones - Gestionar sesiones de comunicación con dispositivos
  • Operaciones de Red - Automatizar tareas de gestión rutinarias

Arquitectura de la API

Características de la API

  • Diseño RESTful - Métodos HTTP estándar (GET, POST, PUT, DELETE)
  • Formato JSON - Todas las solicitudes y respuestas son JSON
  • Abstracción de Proveedor - API unificada a través de diferentes proveedores de dispositivos
  • Operaciones con Estado - Mantiene sesiones y estado de dispositivos
  • Manejo de Errores - Mensajes de error detallados y códigos de estado
  • Procesamiento Asíncrono - Solicitudes no bloqueantes para operaciones largas

Autenticación y Acceso

Registro de Dispositivos

Antes de cualquier operación, un dispositivo debe ser registrado en RAN Monitor. El registro establece la conexión entre RAN Monitor y el dispositivo utilizando el mecanismo de autenticación nativo de cada proveedor.

Proceso de Registro:

  1. Las credenciales del dispositivo (nombre de usuario/contraseña o claves API) se almacenan de forma segura
  2. La prueba de conectividad inicial verifica que el dispositivo sea accesible
  3. El dispositivo se registra y está listo para operaciones
  4. Comienza el monitoreo continuo de salud

Control de Acceso a la API

Actualmente, la API de RAN Monitor es accesible dentro de la red de gestión. Para implementaciones en producción, considere:

  • Métodos de Autenticación:

    • Clave API en el encabezado: Authorization: Bearer <api-key>
    • OAuth2 para integración con proveedores de identidad
    • Control de acceso basado en red (firewall/VPN)
  • Limitación de Tasa:

    • Límites por cliente para prevenir abusos
    • Límites por dispositivo para la frecuencia de operación
  • Registro de Auditoría:

    • Todas las llamadas a la API se registran con marcas de tiempo e información del usuario/cliente
    • Los cambios de configuración se rastrean con valores antes/después

Referencia de Puntos Finales

Gestión de Dispositivos

Listar Todos los Dispositivos

GET /api/v1/devices

Respuesta:

{
"devices": [
{
"id": "nokia_bs1",
"name": "SITE_A_BS1",
"vendor": "Nokia",
"address": "192.168.1.100",
"port": 8080,
"status": "registered",
"registered_at": "2025-12-10T14:30:00Z",
"session_active": true,
"software_version": "BSC-2250.5.0",
"license_required": false
}
]
}

Obtener Detalles del Dispositivo

GET /api/v1/devices/:id

Respuesta:

{
"device": {
"id": "nokia_bs1",
"name": "SITE_A_BS1",
"vendor": "Nokia",
"address": "192.168.1.100",
"registration_status": "registered",
"registration_key": "base64_encoded_key",
"session_id": "nonuniquesession",
"session_expiry": "2025-12-11T14:30:00Z",
"device_info": {
"type": "AirScale",
"software_release": "5.0.0",
"hardware_version": "2.0",
"agent_unique_id": "airscale-001"
}
}
}

Registrar un Dispositivo

PUT /api/v1/devices/:id/register
Content-Type: application/json

{
"address": "192.168.1.100:8080",
"web_username": "admin",
"web_password": "password",
"webhook_url": "http://manager.example.com:9076/webhook",
"private_key_path": "/etc/certs/private.key",
"public_key_path": "/etc/certs/public.key"
}

Respuesta:

{
"result": "Success",
"registration_key": "base64_encoded_nonce",
"device_id": "nokia_bs1",
"message": "Device registered successfully"
}

Códigos de Estado:

  • 200 - Registro exitoso
  • 400 - Parámetros inválidos o error del dispositivo
  • 409 - Dispositivo ya registrado
  • 500 - Error interno

Anular Registro de un Dispositivo

DELETE /api/v1/devices/:id

Respuesta:

{
"result": "Success",
"message": "Device unregistered",
"device_id": "nokia_bs1"
}

Gestión de Sesiones

Iniciar una Sesión

PUT /api/v1/devices/:id/sessions
Content-Type: application/json

{
"session_id": "session_unique_identifier"
}

Respuesta:

{
"result": "Success",
"session_id": "session_unique_identifier",
"session_timeout": 86400,
"expires_at": "2025-12-11T14:30:00Z"
}

Duración de la Sesión:

  • Tiempo de espera predeterminado: 24 horas
  • Se requiere mantener la conexión antes del tiempo de espera
  • Renovación automática cada 20 horas

Comprobar el Estado de la Sesión

GET /api/v1/devices/:id/sessions

Respuesta:

{
"session": {
"active": true,
"session_id": "session_unique_identifier",
"expires_at": "2025-12-11T14:30:00Z",
"time_remaining_seconds": 82400,
"last_activity": "2025-12-10T14:30:00Z"
}
}

Mantener la Sesión Activa

POST /api/v1/devices/:id/sessions/keep-alive

Respuesta:

{
"result": "Success",
"new_expiry": "2025-12-11T14:30:00Z"
}

Gestión de Configuración

Consultar Configuración

Recuperar parámetros de configuración del dispositivo:

PUT /api/v1/devices/:id/config/upload
Content-Type: application/json

{
"filter": {
"uploadType": "configuration",
"objects": [
{
"sdn": "/BSC-1/BTS-23/*",
"depth": 100
}
],
"objectClass": ""
}
}

Respuesta:

{
"result": "Success",
"configuration": {
"timestamp": "2025-12-10T14:30:00Z",
"device_id": "nokia_bs1",
"parameters": {
"/BSC-1/BTS-23": {
"BtsBasics": {
"BtsName": "CELL_A",
"BtsType": "MACRO",
"EnvironmentalSpecifications": {
"TemperatureRange": "Industrial"
}
},
"CarrierAggregation": {
"CarrierAggregationCapability": true,
"MaxUECarriers": 5
}
}
}
}
}

Establecer Parámetro de Configuración

PUT /api/v1/devices/:id/config/set
Content-Type: application/json

{
"parameter_path": "/BSC-1/BTS-23/BtsBasics/BtsName",
"value": "NEW_CELL_NAME",
"value_type": "string"
}

Respuesta:

{
"result": "Success",
"parameter": "/BSC-1/BTS-23/BtsBasics/BtsName",
"old_value": "CELL_A",
"new_value": "NEW_CELL_NAME",
"applied_at": "2025-12-10T14:30:45Z"
}

Parámetros de Configuración Comunes:

ParámetroTipoEjemploPropósito
BtsNameString"SITE_A_Cell_1"Identificador de celda/estación base
MaxUEsServedInteger256Máximo de UEs simultáneas
CellTXPowerInteger40 (dBm)Nivel de potencia de transmisión
EnableCarrierAggBooleantrueSoporte para agregación de portadoras
HandoverHysteresisInteger3 (dB)Sensibilidad de traspaso

Obtener Historial de Configuración

GET /api/v1/devices/:id/config/history?limit=10&days=7

Respuesta:

{
"history": [
{
"timestamp": "2025-12-10T14:30:45Z",
"change_type": "parameter_modified",
"parameter": "/BSC-1/BTS-23/BtsBasics/BtsName",
"old_value": "CELL_A",
"new_value": "NEW_CELL_NAME",
"reason": "Actualización de configuración manual"
}
]
}

Recuperación de Datos

Obtener Métricas de Rendimiento

Recuperar datos de contadores de rendimiento:

PUT /api/v1/devices/:id/metrics/upload
Content-Type: application/json

{
"filter": {
"uploadType": "measurement",
"objects": [
{
"sdn": "*",
"depth": 100
}
]
}
}

Respuesta:

{
"result": "Success",
"metrics": {
"timestamp": "2025-12-10T14:30:00Z",
"measurement_interval": 300,
"counters": [
{
"id": "M1C1",
"name": "DL Cell Throughput",
"value": 125.4,
"unit": "Mbps",
"cell_dn": "/BSC-1/BTS-23/Cell-1"
},
{
"id": "M1C2",
"name": "UL Cell Throughput",
"value": 89.2,
"unit": "Mbps",
"cell_dn": "/BSC-1/BTS-23/Cell-1"
}
]
}
}

Obtener Alarmas Activas

PUT /api/v1/devices/:id/alarms/upload
Content-Type: application/json

{
"filter": {
"uploadType": "active_faults"
}
}

Respuesta:

{
"result": "Success",
"alarms": [
{
"alarm_id": "a1b2c3d4",
"severity": "Critical",
"probable_cause": "Cell Unavailable",
"specific_problem": "Power Supply Failure",
"affected_dn": "/BSC-1/BTS-23/Cell-1",
"event_time": "2025-12-10T14:15:30Z",
"description": "Cell 1 is unavailable due to power supply failure"
}
]
}

Obtener Topología del Dispositivo

PUT /api/v1/devices/:id/topology/upload
Content-Type: application/json

{
"filter": {
"uploadType": "topology",
"objects": [
{
"sdn": "*",
"depth": 100
}
]
}
}

Respuesta:

{
"result": "Success",
"topology": {
"device_dn": "/BSC-1",
"managed_elements": [
{
"name": "BTS-23",
"type": "BaseTransceiverStation",
"dn": "/BSC-1/BTS-23",
"cells": [
{
"name": "Cell-1",
"type": "EUtranCell",
"physical_cell_id": 100,
"frequency": 2110
}
]
}
]
}
}

Comprobaciones de Salud

Hacer Ping al Dispositivo

PUT /api/v1/devices/:id/ping

Respuesta:

{
"result": "Success",
"device_id": "nokia_bs1",
"latency_ms": 45,
"status": "reachable"
}

Obtener Salud del Sistema

GET /api/v1/health/status

Respuesta:

{
"status": "healthy",
"devices": {
"total": 50,
"registered": 48,
"active_sessions": 45,
"unreachable": 2
},
"database": {
"mysql": "connected",
"influxdb": "connected"
},
"timestamp": "2025-12-10T14:30:00Z"
}

Gestión de Configuración

Modelo de Datos de Configuración

La configuración de Nokia eNodeB está organizada jerárquicamente:

/SystemFunctions
├── /BSC-1 (Controlador de Estación Base)
│ └── /BTS-23 (Estación Transceptora Base)
│ ├── BtsBasics (Nombre, tipo, ubicación)
│ ├── /Cell-1
│ │ ├── CellCommonData
│ │ ├── CellAdvanced
│ │ └── CarrierAggregation
│ └── /Cell-2
│ └── ...
└── /Connectivity
├── S1Interface
├── X2Interface
└── NetworkConfiguration

Tareas Comunes de Configuración

Habilitar/Deshabilitar una Celda

{
"parameter_path": "/BSC-1/BTS-23/Cell-1/CellCommonData/AdminState",
"value": "UNLOCKED",
"value_type": "enum"
}

Valores posibles: LOCKED, UNLOCKED, SHUTTING_DOWN

Ajustar Potencia de la Celda

{
"parameter_path": "/BSC-1/BTS-23/Cell-1/CellAdvanced/CellTXPower",
"value": "35",
"value_type": "integer"
}

Rango: 0-46 dBm (dependiente del dispositivo)

Configurar Histeresis de Traspaso

{
"parameter_path": "/BSC-1/BTS-23/Cell-1/CellAdvanced/HandoverHysteresis",
"value": "3",
"value_type": "integer"
}

Unidad: dB, rango típico: 0-8 dB

Establecer Máximo de Usuarios Conectados

{
"parameter_path": "/BSC-1/BTS-23/MaxUEsServed",
"value": "256",
"value_type": "integer"
}

Límite dependiente del dispositivo


Flujos de Trabajo Comunes

Flujo de Trabajo 1: Incorporación de Dispositivos

Ejemplo:

# 1. Crear entrada de dispositivo
curl -X POST http://localhost:4000/api/v1/devices \
-H "Content-Type: application/json" \
-d '{
"id": "site_a_bs1",
"name": "SITE_A_BS1",
"vendor": "Nokia",
"address": "192.168.1.100:8080",
"credentials": {
"username": "admin",
"password": "password"
}
}'

# 2. Registrar con el dispositivo
curl -X PUT http://localhost:4000/api/v1/devices/site_a_bs1/register \
-H "Content-Type: application/json" \
-d '{
"webhook_url": "http://manager.example.com:9076/webhook"
}'

# 3. Iniciar sesión
curl -X PUT http://localhost:4000/api/v1/devices/site_a_bs1/sessions \
-H "Content-Type: application/json" \
-d '{"session_id": "session_001"}'

# 4. Obtener configuración
curl -X PUT http://localhost:4000/api/v1/devices/site_a_bs1/config/upload \
-H "Content-Type: application/json" \
-d '{
"filter": {
"uploadType": "configuration",
"objects": [{"sdn": "*", "depth": 100}]
}
}'

Flujo de Trabajo 2: Actualización de Configuración

# 1. Consultar valor actual
curl -X PUT http://localhost:4000/api/v1/devices/site_a_bs1/config/upload \
-H "Content-Type: application/json" \
-d '{
"filter": {
"uploadType": "configuration",
"objects": [{"sdn": "/BSC-1/BTS-23/Cell-1", "depth": 10}]
}
}' | jq '.configuration.parameters["/BSC-1/BTS-23/Cell-1"]'

# 2. Modificar parámetro
curl -X PUT http://localhost:4000/api/v1/devices/site_a_bs1/config/set \
-H "Content-Type: application/json" \
-d '{
"parameter_path": "/BSC-1/BTS-23/Cell-1/CellAdvanced/CellTXPower",
"value": "38",
"value_type": "integer"
}'

# 3. Verificar cambio
curl -X PUT http://localhost:4000/api/v1/devices/site_a_bs1/config/upload \
-H "Content-Type: application/json" \
-d '{
"filter": {
"uploadType": "configuration",
"objects": [{"sdn": "/BSC-1/BTS-23/Cell-1/CellAdvanced", "depth": 5}]
}
}' | jq '.configuration.parameters["/BSC-1/BTS-23/Cell-1/CellAdvanced/CellTXPower"]'

Flujo de Trabajo 3: Monitoreo de Rendimiento

# Bucle de monitoreo continuo (script de ejemplo)
#!/bin/bash

DEVICE="site_a_bs1"
INTERVAL=300 # 5 minutos

while true; do
# Obtener métricas
METRICS=$(curl -s -X PUT http://localhost:4000/api/v1/devices/$DEVICE/metrics/upload \
-H "Content-Type: application/json" \
-d '{
"filter": {
"uploadType": "measurement",
"objects": [{"sdn": "*", "depth": 100}]
}
}')

# Extraer métricas clave
DL=$(echo $METRICS | jq '.metrics.counters[] | select(.id=="M1C1") | .value')
CELLS=$(echo $METRICS | jq '.metrics.counters | length')

echo "$(date): DL=$DL Mbps, Celdas=$CELLS"

# Comprobar alarmas
ALARMS=$(curl -s -X PUT http://localhost:4000/api/v1/devices/$DEVICE/alarms/upload \
-H "Content-Type: application/json" \
-d '{
"filter": {
"uploadType": "active_faults"
}
}' | jq '.alarms | length')

if [ "$ALARMS" -gt 0 ]; then
echo "ADVERTENCIA: $ALARMS alarmas activas"
fi

sleep $INTERVAL
done

Manejo de Errores

Códigos de Estado HTTP

CódigoSignificadoEjemplo
200ÉxitoConfiguración recuperada
201CreadoDispositivo registrado
400Solicitud IncorrectaJSON o parámetros inválidos
401No AutorizadoClave API faltante/inválida
404No EncontradoEl dispositivo no existe
409ConflictoDispositivo ya registrado
500Error del ServidorFallo en la conexión a la base de datos
503No DisponibleModo de mantenimiento

Formato de Respuesta de Error

{
"error": {
"code": "DEVICE_NOT_FOUND",
"message": "Dispositivo 'site_a_bs1' no encontrado",
"details": {
"device_id": "site_a_bs1",
"timestamp": "2025-12-10T14:30:00Z"
}
}
}

Errores Comunes

Dispositivo No Registrado:

{
"error": {
"code": "NOT_REGISTERED",
"message": "El dispositivo debe estar registrado antes de las operaciones",
"solution": "Llamar a PUT /api/devices/:id/register primero"
}
}

Sesión Expirada:

{
"error": {
"code": "SESSION_EXPIRED",
"message": "La sesión del dispositivo ha expirado",
"solution": "Llamar a PUT /api/devices/:id/sessions para iniciar una nueva sesión"
}
}

Parámetro de Configuración Inválido:

{
"error": {
"code": "INVALID_PARAMETER",
"message": "Valor del parámetro fuera de rango",
"details": {
"parameter": "/BSC-1/BTS-23/Cell-1/CellAdvanced/CellTXPower",
"value": "99",
"valid_range": "0-46 dBm"
}
}
}

Ejemplos de API

Ejemplo de Cliente Python

import requests
import json

class RanMonitorClient:
def __init__(self, base_url="http://localhost:4000/api/v1"):
self.base_url = base_url
self.session = requests.Session()

def register_device(self, device_id, address, username, password):
"""Registrar un nuevo dispositivo"""
url = f"{self.base_url}/devices/{device_id}/register"
payload = {
"address": address,
"web_username": username,
"web_password": password,
"webhook_url": "http://manager:9076/webhook"
}
response = self.session.put(url, json=payload)
return response.json()

def get_config(self, device_id, sdn="*", depth=100):
"""Recuperar configuración del dispositivo"""
url = f"{self.base_url}/devices/{device_id}/config/upload"
payload = {
"filter": {
"uploadType": "configuration",
"objects": [{"sdn": sdn, "depth": depth}]
}
}
response = self.session.put(url, json=payload)
return response.json()

def set_config(self, device_id, parameter_path, value, value_type="string"):
"""Actualizar un parámetro de configuración"""
url = f"{self.base_url}/devices/{device_id}/config/set"
payload = {
"parameter_path": parameter_path,
"value": value,
"value_type": value_type
}
response = self.session.put(url, json=payload)
return response.json()

def get_metrics(self, device_id):
"""Recuperar métricas de rendimiento"""
url = f"{self.base_url}/devices/{device_id}/metrics/upload"
payload = {
"filter": {
"uploadType": "measurement",
"objects": [{"sdn": "*", "depth": 100}]
}
}
response = self.session.put(url, json=payload)
return response.json()

# Ejemplo de uso
client = RanMonitorClient()

# Registrar dispositivo
result = client.register_device(
device_id="site_a_bs1",
address="192.168.1.100:8080",
username="admin",
password="password"
)
print(f"Registro: {result}")

# Obtener configuración
config = client.get_config("site_a_bs1")
print(f"Config: {json.dumps(config, indent=2)}")

# Actualizar parámetro
update = client.set_config(
"site_a_bs1",
"/BSC-1/BTS-23/Cell-1/CellAdvanced/CellTXPower",
"38",
"integer"
)
print(f"Actualización: {update}")

Ejemplos de cURL

Registrar Dispositivo:

curl -X PUT http://localhost:4000/api/v1/devices/site_a_bs1/register \
-H "Content-Type: application/json" \
-d '{
"address": "192.168.1.100:8080",
"web_username": "admin",
"web_password": "password",
"webhook_url": "http://manager:9076/webhook"
}'

Obtener Estado del Dispositivo:

curl -X GET http://localhost:4000/api/v1/devices/site_a_bs1

Consultar Configuración:

curl -X PUT http://localhost:4000/api/v1/devices/site_a_bs1/config/upload \
-H "Content-Type: application/json" \
-d '{
"filter": {
"uploadType": "configuration",
"objects": [{"sdn": "/BSC-1/*", "depth": 50}]
}
}' | jq '.'