|
| 1 | +import json |
1 | 2 | import os |
2 | 3 | import base64 |
3 | 4 | from flask import jsonify, request |
|
6 | 7 | from utils.datetime_utils import timeNowUTC |
7 | 8 | from messaging.in_app import write_notification |
8 | 9 |
|
9 | | -INSTALL_PATH = os.getenv("NETALERTX_APP", "/app") |
10 | | - |
11 | 10 | # Make sure log level is initialized correctly |
12 | 11 | lggr = Logger(get_setting_value('LOG_LEVEL')) |
13 | 12 |
|
14 | 13 |
|
15 | 14 | def handle_sync_get(): |
16 | 15 | """Handle GET requests for SYNC (NODE → HUB).""" |
17 | 16 |
|
18 | | - # get all dwevices from the api endpoint |
| 17 | + # get all devices from the api endpoint |
19 | 18 | api_path = os.environ.get('NETALERTX_API', '/tmp/api') |
20 | 19 |
|
21 | 20 | file_path = f"/{api_path}/table_devices.json" |
@@ -47,40 +46,100 @@ def handle_sync_get(): |
47 | 46 |
|
48 | 47 | def handle_sync_post(): |
49 | 48 | """Handle POST requests for SYNC (HUB receiving from NODE).""" |
50 | | - body = request.get_json(silent=True) or {} |
| 49 | + |
| 50 | + mylog("debug", [ |
| 51 | + "[SYNC API] ENTER handle_sync_post", |
| 52 | + f"method={request.method}", |
| 53 | + f"content_type={request.content_type}", |
| 54 | + f"content_length={request.content_length}", |
| 55 | + f"remote_addr={request.remote_addr}" |
| 56 | + ]) |
| 57 | + |
| 58 | + # ---- RAW BODY (critical for debugging encoding / encryption issues) |
| 59 | + try: |
| 60 | + raw = request.get_data(cache=False) |
| 61 | + mylog("debug", [ |
| 62 | + f"[SYNC API] raw_bytes_len={len(raw)} raw_preview={raw[:200]}" |
| 63 | + ]) |
| 64 | + except Exception as e: |
| 65 | + mylog("none", [f"[SYNC API] FAILED reading raw body: {e}"]) |
| 66 | + write_notification("[SYNC API] FAILED reading raw body - see app.log", 'alert', timeNowUTC()) |
| 67 | + return jsonify({"error": "failed reading body"}), 400 |
| 68 | + |
| 69 | + # ---- JSON PARSE (from already-read raw bytes to avoid empty-stream re-read) |
| 70 | + try: |
| 71 | + body = json.loads(raw) |
| 72 | + mylog("debug", [f"[SYNC API] parsed_json={body}"]) |
| 73 | + except Exception as e: |
| 74 | + msg = f"[SYNC API] JSON_PARSE_FAILED={e}" |
| 75 | + mylog("none", [msg]) |
| 76 | + write_notification(msg, 'alert', timeNowUTC()) |
| 77 | + return jsonify({"error": "invalid json"}), 400 |
| 78 | + |
| 79 | + # ---- EXTRACT FIELDS |
51 | 80 | data = body.get("data", "") |
52 | 81 | node_name = body.get("node_name", "") |
53 | 82 | plugin = body.get("plugin", "") |
54 | 83 |
|
55 | | - storage_path = INSTALL_PATH + "/log/plugins" |
56 | | - os.makedirs(storage_path, exist_ok=True) |
57 | | - |
58 | | - encoded_files = [ |
59 | | - f |
60 | | - for f in os.listdir(storage_path) |
61 | | - if f.startswith(f"last_result.{plugin}.encoded.{node_name}") |
62 | | - ] |
63 | | - decoded_files = [ |
64 | | - f |
65 | | - for f in os.listdir(storage_path) |
66 | | - if f.startswith(f"last_result.{plugin}.decoded.{node_name}") |
67 | | - ] |
68 | | - file_count = len(encoded_files + decoded_files) + 1 |
| 84 | + mylog("debug", [ |
| 85 | + f"[SYNC API] node_name={repr(node_name)} plugin={repr(plugin)} data_type={type(data).__name__} data_len={len(data) if isinstance(data, str) else 'non-string'}" |
| 86 | + ]) |
| 87 | + |
| 88 | + storage_path = os.getenv("NETALERTX_PLUGINS_LOG", "/tmp/log/plugins") |
| 89 | + |
| 90 | + try: |
| 91 | + os.makedirs(storage_path, exist_ok=True) |
| 92 | + mylog("debug", [f"[SYNC API] storage_path_ready={storage_path}"]) |
| 93 | + except Exception as e: |
| 94 | + msg = f"[SYNC API] MKDIR_FAILED={e}" |
| 95 | + mylog("none", [msg]) |
| 96 | + write_notification(msg, 'alert', timeNowUTC()) |
| 97 | + return jsonify({"error": "storage path error"}), 500 |
69 | 98 |
|
| 99 | + # ---- FILE COUNT LOGIC |
| 100 | + try: |
| 101 | + encoded_files = [ |
| 102 | + f for f in os.listdir(storage_path) |
| 103 | + if f.startswith(f"last_result.{plugin}.encoded.{node_name}") |
| 104 | + ] |
| 105 | + decoded_files = [ |
| 106 | + f for f in os.listdir(storage_path) |
| 107 | + if f.startswith(f"last_result.{plugin}.decoded.{node_name}") |
| 108 | + ] |
| 109 | + file_count = len(encoded_files + decoded_files) + 1 |
| 110 | + |
| 111 | + mylog("debug", [f"[SYNC API] encoded_files={len(encoded_files)} decoded_files={len(decoded_files)} file_count={file_count}"]) |
| 112 | + except Exception as e: |
| 113 | + msg = f"[SYNC API] LISTDIR_FAILED={e}" |
| 114 | + mylog("none", [msg]) |
| 115 | + write_notification(msg, 'alert', timeNowUTC()) |
| 116 | + return jsonify({"error": "listdir failed"}), 500 |
| 117 | + |
| 118 | + # ---- FILE PATH |
70 | 119 | file_path_new = os.path.join( |
71 | | - storage_path, f"last_result.{plugin}.encoded.{node_name}.{file_count}.log" |
| 120 | + storage_path, |
| 121 | + f"last_result.{plugin}.encoded.{node_name}.{file_count}.log" |
72 | 122 | ) |
73 | 123 |
|
| 124 | + mylog("verbose", [f"[SYNC API] file_path_new={file_path_new}"]) |
| 125 | + |
74 | 126 | try: |
| 127 | + if not isinstance(data, str): |
| 128 | + data = str(data) |
| 129 | + |
75 | 130 | with open(file_path_new, "w") as f: |
76 | 131 | f.write(data) |
| 132 | + |
77 | 133 | except Exception as e: |
78 | | - msg = f"[Plugin: SYNC] Failed to store data: {e}" |
79 | | - write_notification(msg, "alert", timeNowUTC()) |
80 | | - mylog("verbose", [msg]) |
81 | | - return jsonify({"error": msg}), 500 |
| 134 | + |
| 135 | + msg = f"[Plugin: SYNC] Data write failed ({file_path_new}): {e}" |
| 136 | + mylog("none", [msg]) |
| 137 | + write_notification(msg, 'alert', timeNowUTC()) |
| 138 | + return jsonify({"error": str(e)}), 500 |
82 | 139 |
|
83 | 140 | msg = f"[Plugin: SYNC] Data received ({file_path_new})" |
84 | | - write_notification(msg, "info", timeNowUTC()) |
| 141 | + if lggr.isAbove('verbose'): |
| 142 | + write_notification(msg, 'info', timeNowUTC()) |
85 | 143 | mylog("verbose", [msg]) |
| 144 | + |
86 | 145 | return jsonify({"message": "Data received and stored successfully"}), 200 |
0 commit comments