mirror of
https://github.com/hansjone/netx.git
synced 2026-10-09 00:50:46 +08:00
fix(netx): prefer UUID net_id from ME{} in objectName
Only treat UUID-like values as net_id. Prefer extracting ME{uuid} from objectName and ignore ME{numeric} wrappers found in alarmkey so alarms join inventory correctly.
Also constrain legacy alarmkey split formats (#, csv, space) to UUID-like prefixes.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
15d9cb5db3
commit
16607db3cd
2 changed files with 39 additions and 11 deletions
|
|
@ -67,28 +67,48 @@ def _derive_ne_id_from_alarm(alarm: dict[str, Any]) -> str:
|
|||
if ne_id:
|
||||
return ne_id
|
||||
|
||||
def _uuid_like(s: str) -> bool:
|
||||
return bool(
|
||||
re.fullmatch(
|
||||
r"[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}",
|
||||
str(s or "").strip(),
|
||||
)
|
||||
)
|
||||
|
||||
# Prefer UUID net_id in objectName, e.g. "... ME{33a3e8f4-a76e-40fd-a0ba-045371a5f234} ..."
|
||||
object_name = _s(_pick(alarm, "objectName", "object-name"))
|
||||
if object_name:
|
||||
m_obj = re.search(r"ME\{([^}]+)\}", object_name, flags=re.IGNORECASE)
|
||||
if m_obj:
|
||||
candidate = _s(m_obj.group(1))
|
||||
if _uuid_like(candidate):
|
||||
return candidate
|
||||
|
||||
alarm_key = _s(_pick(alarm, "alarmKey", "alarm-key", "alarmkey"))
|
||||
if not alarm_key:
|
||||
return ""
|
||||
|
||||
# If alarmkey contains ME{...}, only accept it when it looks like a UUID.
|
||||
m0 = re.search(r"ME\{([^}]+)\}", alarm_key, flags=re.IGNORECASE)
|
||||
if m0:
|
||||
candidate = _s(m0.group(1))
|
||||
if _uuid_like(candidate):
|
||||
return candidate
|
||||
|
||||
# Common UME formats observed:
|
||||
# 1) "<net_id>#<suffix>"
|
||||
# 2) "<net_id>, <x>, <y>"
|
||||
# 3) "<net_id> <x> <y>"
|
||||
if "#" in alarm_key:
|
||||
return _s(alarm_key.split("#", 1)[0])
|
||||
candidate = _s(alarm_key.split("#", 1)[0])
|
||||
return candidate if _uuid_like(candidate) else ""
|
||||
if "," in alarm_key:
|
||||
return _s(alarm_key.split(",", 1)[0])
|
||||
candidate = _s(alarm_key.split(",", 1)[0])
|
||||
return candidate if _uuid_like(candidate) else ""
|
||||
parts = [p for p in alarm_key.split() if p]
|
||||
if len(parts) >= 2:
|
||||
return _s(parts[0])
|
||||
|
||||
# Fallback: some alarms encode net_id as ME{<net_id>} in objectName.
|
||||
object_name = _s(_pick(alarm, "objectName", "object-name"))
|
||||
if object_name:
|
||||
m = re.search(r"ME\{([^}]+)\}", object_name, flags=re.IGNORECASE)
|
||||
if m:
|
||||
return _s(m.group(1))
|
||||
if len(parts) >= 2 and ":" not in parts[0]:
|
||||
candidate = _s(parts[0])
|
||||
return candidate if _uuid_like(candidate) else ""
|
||||
return ""
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -488,6 +488,10 @@ class UmeSyncServiceTests(unittest.TestCase):
|
|||
alarm_csv = {"alarmkey": "00ceb960-1b62-478e-8303-0935ffea1d28, 4237, 79"}
|
||||
alarm_space = {"alarmkey": "00ceb960-1b62-478e-8303-0935ffea1d28 4205 3588"}
|
||||
alarm_object_name_me = {"alarmkey": "no-net-id-here", "objectName": "OLT/ME{00ceb960-1b62-478e-8303-0935ffea1d28}/PON-1"}
|
||||
alarm_key_me_wrapped = {
|
||||
"alarmkey": "BN:ME{353319917}:35 1778634688",
|
||||
"objectName": "ME{33a3e8f4-a76e-40fd-a0ba-045371a5f234},PWR={/module=3}",
|
||||
}
|
||||
|
||||
self.assertEqual(
|
||||
_derive_ne_id_from_alarm(alarm_hash),
|
||||
|
|
@ -505,6 +509,10 @@ class UmeSyncServiceTests(unittest.TestCase):
|
|||
_derive_ne_id_from_alarm(alarm_object_name_me),
|
||||
"00ceb960-1b62-478e-8303-0935ffea1d28",
|
||||
)
|
||||
self.assertEqual(
|
||||
_derive_ne_id_from_alarm(alarm_key_me_wrapped),
|
||||
"33a3e8f4-a76e-40fd-a0ba-045371a5f234",
|
||||
)
|
||||
|
||||
def test_serialize_ume_alarm_raw_row_select_fields(self):
|
||||
alarm = UmeAlarmCurrent(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue