#!/usr/bin/env python3 from __future__ import annotations import os from pathlib import Path import sys import time import urllib.parse import urllib.request ROOT = Path(__file__).resolve().parents[1] ENV_PATH = ROOT / ".env" def load_env(path: Path) -> dict[str, str]: values: dict[str, str] = {} if not path.exists(): return values for raw in path.read_text(encoding="utf-8").splitlines(): line = raw.strip() if not line or line.startswith("#") or "=" not in line: continue key, value = line.split("=", 1) values[key.strip()] = value.strip().strip('"').strip("'") return values ENV = {**load_env(ENV_PATH), **os.environ} NACOS_BASE_URL = ENV.get("NACOS_BASE_URL", "http://127.0.0.1:8848").rstrip("/") NAMESPACE_ID = ENV.get("NACOS_NAMESPACE_ID", "RedCircleServiceTest") NAMESPACE_NAME = ENV.get("NACOS_NAMESPACE_NAME", NAMESPACE_ID) JAVA_SOURCE_DIR = Path(ENV.get("JAVA_SOURCE_DIR", str(ROOT / "sources" / "chatapp3-java"))) def request(method: str, path: str, data: dict[str, str] | None = None) -> str: url = f"{NACOS_BASE_URL}{path}" body = None headers = {"User-Agent": "chatapp-testbox/1.0"} if data is not None: body = urllib.parse.urlencode(data).encode("utf-8") headers["Content-Type"] = "application/x-www-form-urlencoded; charset=utf-8" req = urllib.request.Request(url, data=body, headers=headers, method=method) with urllib.request.urlopen(req, timeout=15) as resp: return resp.read().decode("utf-8", errors="replace") def wait_nacos() -> None: for _ in range(90): try: text = request("GET", "/nacos/v1/console/health/readiness") if "UP" in text or "OK" in text: return except Exception: pass time.sleep(2) raise RuntimeError("nacos readiness timeout") def ensure_namespace() -> None: data = { "customNamespaceId": NAMESPACE_ID, "namespaceName": NAMESPACE_NAME, "namespaceDesc": "single-node chatapp testbox", } try: request("POST", "/nacos/v1/console/namespaces", data) except Exception as exc: print(f"warn: namespace create skipped: {exc}", file=sys.stderr) def publish_config(group: str, data_id: str, content: str) -> None: payload = { "tenant": NAMESPACE_ID, "group": group, "dataId": data_id, "type": "yaml" if data_id.endswith((".yml", ".yaml")) else "text", "content": content, } result = request("POST", "/nacos/v1/cs/configs", payload).strip() if result.lower() == "false": raise RuntimeError(f"nacos rejected config {group}/{data_id}") def main() -> int: config_root = JAVA_SOURCE_DIR / "nacos_config" if not config_root.is_dir(): raise RuntimeError(f"missing nacos_config: {config_root}") wait_nacos() ensure_namespace() count = 0 for path in sorted(config_root.glob("*/*")): if not path.is_file(): continue group = path.parent.name data_id = path.name publish_config(group, data_id, path.read_text(encoding="utf-8")) count += 1 print(f"published {group}/{data_id}") print(f"nacos import ok: namespace={NAMESPACE_ID} configs={count}") return 0 if __name__ == "__main__": raise SystemExit(main())