diff --git a/docs/architecture/build_archimate.py b/docs/architecture/build_archimate.py index 5ca654f..89a08ea 100644 --- a/docs/architecture/build_archimate.py +++ b/docs/architecture/build_archimate.py @@ -130,6 +130,13 @@ def obj(v, eid, x, y, w, h, parent=None): (parent["children"] if parent else v["objects"]).append(o) return o +def note(v, text, x, y, w, h, parent=None): + """Пояснительная надпись на схеме. Элементом модели не является: нужна легенде, + где подписать надо не архитектуру, а саму нотацию.""" + o = obj(v, None, x, y, w, h, parent) + o["note"] = text + return o + def conn(rtype, so, to): key = (rtype, so["el"], to["el"]) if key not in REL_INDEX: @@ -141,6 +148,12 @@ def conn(rtype, so, to): SERVICES = PROFILE["services"] SW = {s["id"]: s for s in PROFILE["software"]} +MIN_LINKS = 3 # порог, с которого сервису отводится отдельное представление +_tno = [2] # T1 и T2 названы явно, дальше нумерация сквозная по семейству + +def tnum(): + _tno[0] += 1 + return f"T{_tno[0]}" v1 = view("T1. Технологический слой", "Что развёрнуто в кластере и какие технологические сервисы это даёт. " @@ -242,7 +255,7 @@ if GROUPS: # --- представление «Внешние интеграции» IV = PROFILE.get("integration_view") if IV: - vi = view(f"T{len(views)+1}. {IV['name']}", IV.get("doc", "")) + vi = view(f"{tnum()}. {IV['name']}", IV.get("doc", "")) CW, CH = 320, 110 shown = {} for ci, col in enumerate(IV["columns"]): @@ -254,6 +267,44 @@ if IV: if src in shown and tgt in shown: conn(rtype, shown[src], shown[tgt]) +# --- прикладной слой: смысловые домены +# Строится последним из прикладного, чтобы захватить и компоненты, заданные +# в node_groups вручную: в матрице контура их нет. +DOMAINS = PROFILE.get("domains", []) +if DOMAINS: + app_ids = {e[1] for e in elements if e[0] == "application"} + claimed = {app_id.get(a, a) for g in DOMAINS + if isinstance(g.get("apps"), list) for a in g["apps"]} + for g in DOMAINS: + want = ([e for e in app_ids if e not in claimed] if g.get("apps") == "*" + else [app_id.get(a, a) for a in g.get("apps") or []]) + missing = [e for e in want if e not in app_ids] + if missing: + sys.exit(f"домен {g['id']}: нет таких компонентов — {', '.join(missing)}") + g["_apps"] = sorted(want) + # пустая группа — не элемент модели, а незаполненная строка профиля + DOMAINS = [g for g in DOMAINS if g["_apps"]] + for g in DOMAINS: + el("other", g["id"], "Grouping", g["name"], g.get("doc", "")) + for eid in g["_apps"]: + R("Aggregation", g["id"], eid) + + va = view("A0. Карта прикладного слоя", + f"Из чего состоит прикладной слой: {len(app_ids)} " + f"{plural(len(app_ids), 'компонент', 'компонента', 'компонентов')} по смысловым " + f"группам. Связи здесь намеренно не показаны — на таком числе компонентов они " + f"делают схему нечитаемой; для них есть представления A1 и далее. Вложенность " + f"означает aggregation: группа объединяет компоненты, но не владеет ими.") + PER = 7 + y = 20 + for g in DOMAINS: + rows = (len(g["_apps"]) + PER - 1) // PER + h = 34 + rows * 62 + 8 + og = obj(va, g["id"], 20, y, PER * 180 + 28, h) + for i, eid in enumerate(g["_apps"]): + obj(va, eid, 14 + (i % PER) * 180, 34 + (i // PER) * 62, 165, 50, og) + y += h + 20 + # --- прикладной слой: межсервисные вызовы if CALLS: import math, collections @@ -286,19 +337,48 @@ if CALLS: conn("Serving", core_obj[b], core_obj[a]) # A2…: по представлению на каждый сервис с тремя и более потребителями - a_no = 2 + a_no, hub_view = 2, {} for hub, n in inbound.most_common(): - if n < 3: + if n < MIN_LINKS: break callers = sorted(a for a, b, _ in calls if b == hub) v = view(f"A{a_no}. Зависят от: {hub}", f"К {hub} обращаются {n} {plural(n, 'сервис', 'сервиса', 'сервисов')}.") + hub_view[hub] = f"A{a_no}" a_no += 1 oh = obj(v, app_id[hub], 20, 20, 260, 60) for i, a in enumerate(callers): conn("Serving", oh, obj(v, app_id[a], 20 + (i % 6) * 190, 150 + (i // 6) * 80, 170, 55)) + # P1…: зеркало к A-представлениям. Те отвечают «кто сломается без сервиса», + # эти — «без чего не работает он сам»: технологические сервисы сверху, + # вызываемые им приложения снизу. + p_no = 1 + for hub, n in outbound.most_common(): + if n < MIN_LINKS: + break + callees = sorted({b for a, b, _ in calls if a == hub}) + uses = [ts for ts in SERVICES if hub in consumers[ts["id"]]] + back = (f"Кто зависит от самого {hub} — представление {hub_view[hub]}." + if hub in hub_view else + f"Входящих вызовов у {hub} меньше {MIN_LINKS}, отдельного представления для них нет.") + m = len(callees) + v = view(f"P{p_no}. Паспорт: {hub}", + f"Что нужно, чтобы {hub} работал: {len(uses)} " + f"{plural(len(uses), 'технологический сервис', 'технологических сервиса', 'технологических сервисов')} " + f"и {m} {plural(m, 'прикладной сервис', 'прикладных сервиса', 'прикладных сервисов')}. " + f"Стрелки, как и везде, идут от обслуживающего к обслуживаемому. {back}") + p_no += 1 + wide = min(6, max(len(uses), m)) + oh = obj(v, app_id[hub], 20 + max(0, (wide * 190 - 260) // 2), + 20 + 80 * ((len(uses) + 5) // 6), 260, 60) + for i, ts in enumerate(uses): + conn("Serving", obj(v, ts["id"], 20 + (i % 6) * 190, 20 + (i // 6) * 80, 170, 55), oh) + base = oh["b"][1] + 130 + for i, b in enumerate(callees): + conn("Serving", obj(v, app_id[b], 20 + (i % 6) * 190, base + (i // 6) * 80, 170, 55), oh) + PER_ROW = 6 for ts in SERVICES: lst = consumers[ts["id"]] @@ -306,7 +386,7 @@ for ts in SERVICES: if not lst and not extra: continue n = len(lst) - v = view(f"T{len(views)+1}. Потребители: {ts['name']}", + v = view(f"{tnum()}. Потребители: {ts['name']}", f"Сервисом {plural(n, 'пользуется', 'пользуются', 'пользуются')} " f"{n} из {len(DATA['apps'])} приложений контура.") ots = obj(v, ts["id"], 20, 20, 260, 60) @@ -316,8 +396,79 @@ for ts in SERVICES: conn("Serving", ots, obj(v, eid, 20 + (i % PER_ROW) * 190, 150 + (i // PER_ROW) * 80, 170, 55)) +# --- легенда нотации +# Собрана из настоящих элементов модели, а не из выдуманных ради неё: так легенда +# заодно оказывается разобранным примером и не может разойтись с остальными схемами. +LEG_TS = max((t for t in SERVICES if consumers[t["id"]] and t["realizers"][0] in SW), + key=lambda t: len(consumers[t["id"]]), default=None) +if LEG_TS and GROUPS and DOMAINS: + l_ss = LEG_TS["realizers"][0] + l_app = app_id[consumers[LEG_TS["id"]][0]] + l_gsw = next((g for g in GROUPS if l_ss in (g.get("runs_software") or [])), None) + l_gap = next((g for g in GROUPS if any(app_id[a] == l_app for a in g["_apps"])), None) + l_dm = next((g for g in DOMAINS if l_app in g["_apps"]), None) + l_art = next((e[1] for e in elements if e[2] == "Artifact"), None) + + vl = view("L1. Как читать схемы", + "Легенда нотации. Показан настоящий фрагмент модели, подписанный по типам: " + "каждый элемент и каждая линия здесь встречаются на остальных представлениях " + "в том же начертании.") + W, COL = 260, 320 + note(vl, "Стрелка serving читается не как «кто кого вызывает», а как «кто без кого не " + "работает»: она идёт от обслуживающего к обслуживаемому. Направление выбрано так " + "потому, что от схемы обычно нужен ответ на вопрос «что откажет, если убрать этот " + "элемент», — и он читается по стрелкам вперёд.", 20, 20, COL * 4 - 60, 66) + + row_a = [ + (nd_cluster, "Узел (Node) — вычислительная среда: кластер, группа серверов или " + "отдельный хост. Ромб на линии — composition: узел состоит из этого, " + "и отдельно от узла содержимое не существует."), + (l_ss, "Системное ПО (System Software) — платформенный компонент внутри узла. " + "Пунктир с полым треугольником — realization: компонент реализует " + "технологический сервис."), + (LEG_TS["id"], "Технологический сервис (Technology Service) — что платформа даёт " + "приложениям, без указания, чем именно это сделано. Приложение зависит " + "от сервиса, а не от конкретного продукта под ним."), + (l_app, "Прикладной компонент (Application Component) — сервис прикладного слоя. " + "Цветом различаются слои: голубой — прикладной, зелёный — технологический."), + ] + o_leg = {} + for i, (eid, txt) in enumerate(row_a): + o_leg[eid] = obj(vl, eid, 20 + i * COL, 120, W, 60) + note(vl, txt, 20 + i * COL, 190, W, 96) + conn("Composition", o_leg[nd_cluster], o_leg[l_ss]) + conn("Realization", o_leg[l_ss], o_leg[LEG_TS["id"]]) + conn("Serving", o_leg[LEG_TS["id"]], o_leg[l_app]) + + row_b = [ + (1, l_gsw and l_gsw["id"], l_ss, "Aggregation", + "Линия с полым ромбом — aggregation: группа объединяет элемент, но тот может " + "существовать и без неё. Так показано, на каких узлах работает системное ПО."), + (2, l_gap and l_gap["id"], l_app, "Assignment", + "Линия с шариком и закрашенной стрелкой — assignment: узел выделен под компонент, " + "и компонент на нём исполняется."), + (3, l_dm and l_dm["id"], l_app, "Aggregation", + "Смысловая группа (Grouping) — домен прикладного слоя. Тоже aggregation: " + "компонент принадлежит домену по смыслу, а не по месту размещения."), + ] + for i, src, tgt, rtype, txt in row_b: + if not src: + continue + os_ = obj(vl, src, 20 + i * COL, 320, W, 60) + note(vl, txt, 20 + i * COL, 390, W, 96) + conn(rtype, os_, o_leg[tgt]) + if l_art: + obj(vl, l_art, 20, 320, W, 60) + note(vl, "Артефакт (Artifact) — то, что физически лежит в хранилище: файл, " + "образ контейнера, дистрибутив.", 20, 390, W, 96) + +# --- порядок представлений в файле: легенда, технологический слой, прикладной, паспорта +ORDER = {"L": 0, "T": 1, "A": 2, "P": 3} +views.sort(key=lambda v: (ORDER.get(v["name"][0], 9), + int(re.match(r"[A-Z](\d+)", v["name"]).group(1)))) + # ---------------------------------------------------------------- сериализация -FOLDERS = [("Strategy", "strategy"), ("Business", "business"), ("Application", "application"), +FOLDERS =[("Strategy", "strategy"), ("Business", "business"), ("Application", "application"), ("Technology & Physical", "technology"), ("Motivation", "motivation"), ("Implementation & Migration", "implementation_migration"), ("Other", "other"), ("Relations", "relations"), ("Views", "diagrams")] @@ -329,6 +480,11 @@ def emit_obj(o, ind): p = " " * ind tgt = f' targetConnections={quoteattr(" ".join(o["tgt"]))}' if o["tgt"] else "" x, y, w, h = o["b"] + if "note" in o: + return (f'{p}\n' + f'{p} \n' + f'{p} {escape(o["note"])}\n' + f'{p}\n') s = f'{p}\n' s += f'{p} \n' for c in o["src"]: @@ -346,7 +502,7 @@ out = ['', for fname, ftype in FOLDERS: inner = "" - if ftype in ("technology", "application"): + if ftype in ("technology", "application", "other"): for folder, eid, etype, name, doc in elements: if folder != ftype: continue diff --git a/docs/architecture/contour-profile.example.json b/docs/architecture/contour-profile.example.json index f758523..8c10691 100644 --- a/docs/architecture/contour-profile.example.json +++ b/docs/architecture/contour-profile.example.json @@ -265,6 +265,88 @@ ] ] }, + "_домены": "Смысловая группировка прикладного слоя. Описывает продукт, а не инсталляцию, и от контура к контуру обычно не меняется. apps — имена приложений либо идентификаторы компонентов, заданных в node_groups; \"*\" в последней группе собирает всё, что не попало в предыдущие, — так новое приложение не исчезает с карты молча. Пустые группы в представление не выводятся.", + "domains": [ + { + "id": "dm-core", + "name": "Платформа", + "doc": "Общие механизмы, на которые опираются все прикладные домены: единая точка входа в интерфейс, вход и права, справочник атрибутов, рабочие пространства и проекты как контейнеры данных, журнал действий, уведомления, оркестрация процессов.\n\nПочти все связи прикладного слоя ведут сюда, поэтому изменения в этой группе стоят дороже всего: отказ любого её компонента виден сразу во всех доменах, тогда как отказ прикладного сервиса ограничен своей областью.", + "apps": [ + "control-interface", + "auth-flow", + "iam", + "ams-sync", + "django", + "eav", + "workspaces", + "projects", + "flows", + "faas", + "message-hub", + "subscriptions", + "system-log" + ] + }, + { + "id": "dm-pm", + "name": "Управление проектом", + "doc": "Планирование и учёт: календарно-сетевые планы, договоры и обязательства по ним, справочник ресурсов, рабочие заметки.\n\nГруппа потребляет данные остальных доменов чаще, чем отдаёт: план и договор ссылаются на документы, замечания и полевые измерения, обратные ссылки редки.", + "apps": [ + "pm", + "contracts", + "resources", + "notes" + ] + }, + { + "id": "dm-cde", + "name": "Документы и общая среда данных", + "doc": "Ядро CDE: хранение документов и их версий, связи между документами, вложения, комплекты передачи, чертежи и трёхмерные модели, подготовка САПР-моделей к просмотру, проверка штампов.\n\nСамая нагруженная группа по числу входящих ссылок — на документ ссылается почти каждый прикладной сценарий. Хранилище документов здесь же является и самым связанным компонентом всей платформы.", + "apps": [ + "cde", + "documentations", + "document-link", + "attachments", + "transmittal", + "drawings", + "bim", + "ac-bim-converter", + "stamp-verification" + ] + }, + { + "id": "dm-qc", + "name": "Контроль качества", + "doc": "Работа с несоответствиями: инспекции и чек-листы, замечания, проблемы, запросы информации, ревью, предписания, сравнение редакций чертежей.\n\nГруппа однородна по устройству — почти каждый её сервис читает документ, пишет запись о несоответствии и поднимает процесс в оркестраторе, — поэтому её компоненты сильнее прочих зависят от домена документов и от платформенных процессов.", + "apps": [ + "inspections", + "checklists", + "remarks", + "issues", + "rfi", + "reviews", + "prescriptions", + "comparisons" + ] + }, + { + "id": "dm-field", + "name": "Полевые данные", + "doc": "Данные, приходящие со стройплощадки: замеры, привязка к местности, сечения, а также обработка тяжёлых входных файлов.\n\nЕдинственная группа с существенной вычислительной нагрузкой: обработка вынесена на отдельные узлы, потому что её всплески не должны мешать интерактивной работе остальных сервисов.", + "apps": [ + "measurements", + "mapper", + "cross-section", + "processing" + ] + }, + { + "id": "dm-other", + "name": "Не отнесено", + "doc": "Приложения, не попавшие ни в одну группу выше. В норме группа пуста; появление компонента здесь означает, что группировку пора дополнить.", + "apps": "*" + } + ], "services": [ { "id": "ts-ingress", diff --git a/docs/architecture/example-technology.archimate b/docs/architecture/example-technology.archimate index 876edfe..8769fcc 100644 --- a/docs/architecture/example-technology.archimate +++ b/docs/architecture/example-technology.archimate @@ -373,7 +373,33 @@ - + + + Общие механизмы, на которые опираются все прикладные домены: единая точка входа в интерфейс, вход и права, справочник атрибутов, рабочие пространства и проекты как контейнеры данных, журнал действий, уведомления, оркестрация процессов. + +Почти все связи прикладного слоя ведут сюда, поэтому изменения в этой группе стоят дороже всего: отказ любого её компонента виден сразу во всех доменах, тогда как отказ прикладного сервиса ограничен своей областью. + + + Планирование и учёт: календарно-сетевые планы, договоры и обязательства по ним, справочник ресурсов, рабочие заметки. + +Группа потребляет данные остальных доменов чаще, чем отдаёт: план и договор ссылаются на документы, замечания и полевые измерения, обратные ссылки редки. + + + Ядро CDE: хранение документов и их версий, связи между документами, вложения, комплекты передачи, чертежи и трёхмерные модели, подготовка САПР-моделей к просмотру, проверка штампов. + +Самая нагруженная группа по числу входящих ссылок — на документ ссылается почти каждый прикладной сценарий. Хранилище документов здесь же является и самым связанным компонентом всей платформы. + + + Работа с несоответствиями: инспекции и чек-листы, замечания, проблемы, запросы информации, ревью, предписания, сравнение редакций чертежей. + +Группа однородна по устройству — почти каждый её сервис читает документ, пишет запись о несоответствии и поднимает процесс в оркестраторе, — поэтому её компоненты сильнее прочих зависят от домена документов и от платформенных процессов. + + + Данные, приходящие со стройплощадки: замеры, привязка к местности, сечения, а также обработка тяжёлых входных файлов. + +Единственная группа с существенной вычислительной нагрузкой: обработка вынесена на отдельные узлы, потому что её всплески не должны мешать интерактивной работе остальных сервисов. + + @@ -620,94 +646,201 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Легенда нотации. Показан настоящий фрагмент модели, подписанный по типам: каждый элемент и каждая линия здесь встречаются на остальных представлениях в том же начертании. + + + Стрелка serving читается не как «кто кого вызывает», а как «кто без кого не работает»: она идёт от обслуживающего к обслуживаемому. Направление выбрано так потому, что от схемы обычно нужен ответ на вопрос «что откажет, если убрать этот элемент», — и он читается по стрелкам вперёд. + + + + + + + + Узел (Node) — вычислительная среда: кластер, группа серверов или отдельный хост. Ромб на линии — composition: узел состоит из этого, и отдельно от узла содержимое не существует. + + + + + + + + Системное ПО (System Software) — платформенный компонент внутри узла. Пунктир с полым треугольником — realization: компонент реализует технологический сервис. + + + + + + + + Технологический сервис (Technology Service) — что платформа даёт приложениям, без указания, чем именно это сделано. Приложение зависит от сервиса, а не от конкретного продукта под ним. + + + + + + + Прикладной компонент (Application Component) — сервис прикладного слоя. Цветом различаются слои: голубой — прикладной, зелёный — технологический. + + + + + + + + Линия с полым ромбом — aggregation: группа объединяет элемент, но тот может существовать и без неё. Так показано, на каких узлах работает системное ПО. + + + + + + + + Линия с шариком и закрашенной стрелкой — assignment: узел выделен под компонент, и компонент на нём исполняется. + + + + + + + + Смысловая группа (Grouping) — домен прикладного слоя. Тоже aggregation: компонент принадлежит домену по смыслу, а не по месту размещения. + + + + + + + Артефакт (Artifact) — то, что физически лежит в хранилище: файл, образ контейнера, дистрибутив. + + Что развёрнуто в кластере и какие технологические сервисы это даёт. Приложения-потребители вынесены в отдельные представления T2 и далее. @@ -1071,1133 +1204,1943 @@ - - Восемь сервисов с наибольшим числом связей и вызовы между ними. Стрелка идёт от вызываемого к вызывающему (serving): кого лишишься — тот и сломается. Всего в контуре 86 межсервисных связей. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - К django обращаются 18 сервисов. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - К documentations обращаются 11 сервисов. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - К eav обращаются 9 сервисов. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - К resources обращаются 7 сервисов. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - К processing обращаются 6 сервисов. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - К iam обращаются 6 сервисов. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - К flows обращаются 4 сервиса. - - - - - - - - - - - - - - - - - - - - - - К workspaces обращаются 4 сервиса. - - - - - - - - - - - - - - - - - - - - - - К system-log обращаются 3 сервиса. - - - - - - - - - - - - - - - - - - К bim обращаются 3 сервиса. - - - - - - - - - - - - - - - - - - К pm обращаются 3 сервиса. - - - - - - - - - - - - - - - - - + Сервисом пользуется 21 из 37 приложений контура. - + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + Сервисом пользуются 25 из 37 приложений контура. - + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + Сервисом пользуются 26 из 37 приложений контура. - + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + Сервисом пользуются 24 из 37 приложений контура. - + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + Сервисом пользуются 5 из 37 приложений контура. - + - - - - - + + + + + - + - + - + - + - + - + - + - + Сервисом пользуются 14 из 37 приложений контура. - + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + Сервисом пользуются 12 из 37 приложений контура. - + - - - - - - - - - - - - - + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + Сервисом пользуется 1 из 37 приложений контура. - + - + - + - + - + - + Сервисом пользуются 16 из 37 приложений контура. - + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + Сервисом пользуются 6 из 37 приложений контура. - + - - - - - - + + + + + + - + - + - + - + - + - + - + - + + + Из чего состоит прикладной слой: 38 компонентов по смысловым группам. Связи здесь намеренно не показаны — на таком числе компонентов они делают схему нечитаемой; для них есть представления A1 и далее. Вложенность означает aggregation: группа объединяет компоненты, но не владеет ими. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Восемь сервисов с наибольшим числом связей и вызовы между ними. Стрелка идёт от вызываемого к вызывающему (serving): кого лишишься — тот и сломается. Всего в контуре 86 межсервисных связей. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + К django обращаются 18 сервисов. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + К documentations обращаются 11 сервисов. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + К eav обращаются 9 сервисов. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + К resources обращаются 7 сервисов. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + К processing обращаются 6 сервисов. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + К iam обращаются 6 сервисов. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + К flows обращаются 4 сервиса. + + + + + + + + + + + + + + + + + + + + + + К workspaces обращаются 4 сервиса. + + + + + + + + + + + + + + + + + + + + + + К system-log обращаются 3 сервиса. + + + + + + + + + + + + + + + + + + К bim обращаются 3 сервиса. + + + + + + + + + + + + + + + + + + К pm обращаются 3 сервиса. + + + + + + + + + + + + + + + + + + Что нужно, чтобы documentations работал: 7 технологических сервисов и 15 прикладных сервисов. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Кто зависит от самого documentations — представление A3. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Что нужно, чтобы flows работал: 7 технологических сервисов и 8 прикладных сервисов. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Кто зависит от самого flows — представление A8. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Что нужно, чтобы issues работал: 9 технологических сервисов и 7 прикладных сервисов. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Входящих вызовов у issues меньше 3, отдельного представления для них нет. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Что нужно, чтобы comparisons работал: 3 технологических сервиса и 6 прикладных сервисов. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Входящих вызовов у comparisons меньше 3, отдельного представления для них нет. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Что нужно, чтобы django работал: 8 технологических сервисов и 6 прикладных сервисов. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Кто зависит от самого django — представление A2. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Что нужно, чтобы faas работал: 0 технологических сервисов и 5 прикладных сервисов. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Входящих вызовов у faas меньше 3, отдельного представления для них нет. + + + + + + + + + + + + + + + + + + + + + + + + + + Что нужно, чтобы transmittal работал: 6 технологических сервисов и 5 прикладных сервисов. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Входящих вызовов у transmittal меньше 3, отдельного представления для них нет. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Что нужно, чтобы message-hub работал: 5 технологических сервисов и 4 прикладных сервиса. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Входящих вызовов у message-hub меньше 3, отдельного представления для них нет. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Что нужно, чтобы pm работал: 8 технологических сервисов и 4 прикладных сервиса. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Кто зависит от самого pm — представление A12. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Что нужно, чтобы processing работал: 5 технологических сервисов и 4 прикладных сервиса. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Кто зависит от самого processing — представление A6. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Что нужно, чтобы rfi работал: 7 технологических сервисов и 4 прикладных сервиса. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Входящих вызовов у rfi меньше 3, отдельного представления для них нет. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Что нужно, чтобы cde работал: 5 технологических сервисов и 3 прикладных сервиса. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Входящих вызовов у cde меньше 3, отдельного представления для них нет. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Что нужно, чтобы notes работал: 6 технологических сервисов и 3 прикладных сервиса. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Входящих вызовов у notes меньше 3, отдельного представления для них нет. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/architecture/example-technology.xml b/docs/architecture/example-technology.xml index d5921a1..eeff0ce 100644 --- a/docs/architecture/example-technology.xml +++ b/docs/architecture/example-technology.xml @@ -457,6 +457,36 @@ CAD ферма Узлы обработки исходных файлов BIM-моделей в проприетарных форматах NWD и RVT. Работают асинхронно: воркер разбирает очередь заданий, забирает исходный файл из объектного хранилища, конвертирует его в пригодный для просмотра и анализа вид и складывает результат обратно. Вынесены в отдельную группу, потому что требуют специфического окружения и дают тяжёлую неравномерную нагрузку — обработка одной модели занимает несоизмеримо больше времени, чем любой интерактивный запрос. В манифестах кластера этих компонентов нет: группа обслуживается вне GitOps-контура платформы. + + Платформа + Общие механизмы, на которые опираются все прикладные домены: единая точка входа в интерфейс, вход и права, справочник атрибутов, рабочие пространства и проекты как контейнеры данных, журнал действий, уведомления, оркестрация процессов. + +Почти все связи прикладного слоя ведут сюда, поэтому изменения в этой группе стоят дороже всего: отказ любого её компонента виден сразу во всех доменах, тогда как отказ прикладного сервиса ограничен своей областью. + + + Управление проектом + Планирование и учёт: календарно-сетевые планы, договоры и обязательства по ним, справочник ресурсов, рабочие заметки. + +Группа потребляет данные остальных доменов чаще, чем отдаёт: план и договор ссылаются на документы, замечания и полевые измерения, обратные ссылки редки. + + + Документы и общая среда данных + Ядро CDE: хранение документов и их версий, связи между документами, вложения, комплекты передачи, чертежи и трёхмерные модели, подготовка САПР-моделей к просмотру, проверка штампов. + +Самая нагруженная группа по числу входящих ссылок — на документ ссылается почти каждый прикладной сценарий. Хранилище документов здесь же является и самым связанным компонентом всей платформы. + + + Контроль качества + Работа с несоответствиями: инспекции и чек-листы, замечания, проблемы, запросы информации, ревью, предписания, сравнение редакций чертежей. + +Группа однородна по устройству — почти каждый её сервис читает документ, пишет запись о несоответствии и поднимает процесс в оркестраторе, — поэтому её компоненты сильнее прочих зависят от домена документов и от платформенных процессов. + + + Полевые данные + Данные, приходящие со стройплощадки: замеры, привязка к местности, сечения, а также обработка тяжёлых входных файлов. + +Единственная группа с существенной вычислительной нагрузкой: обработка вынесена на отдельные узлы, потому что её всплески не должны мешать интерактивной работе остальных сервисов. + @@ -704,95 +734,178 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + L1. Как читать схемы + Легенда нотации. Показан настоящий фрагмент модели, подписанный по типам: каждый элемент и каждая линия здесь встречаются на остальных представлениях в том же начертании. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + T1. Технологический слой Что развёрнуто в кластере и какие технологические сервисы это даёт. Приложения-потребители вынесены в отдельные представления T2 и далее. @@ -945,623 +1058,1035 @@ + + T4. Потребители: Маршрутизация HTTPS-трафика + Сервисом пользуется 21 из 37 приложений контура. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + T5. Потребители: Аутентификация OIDC + Сервисом пользуются 25 из 37 приложений контура. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + T6. Потребители: Управление секретами + Сервисом пользуются 26 из 37 приложений контура. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + T7. Потребители: Реляционное хранилище + Сервисом пользуются 24 из 37 приложений контура. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + T8. Потребители: Кэш + Сервисом пользуются 5 из 37 приложений контура. + + + + + + + + + + + + + + + + T9. Потребители: Событийная шина + Сервисом пользуются 14 из 37 приложений контура. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + T10. Потребители: Очередь сообщений AMQP + Сервисом пользуются 12 из 37 приложений контура. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + T11. Потребители: Оркестрация процессов BPMN + Сервисом пользуется 1 из 37 приложений контура. + + + + + + + + T12. Потребители: Объектное хранилище + Сервисом пользуются 16 из 37 приложений контура. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + T13. Потребители: Отправка почтовых уведомлений + Сервисом пользуются 6 из 37 приложений контура. + + + + + + + + + + + + + + + + - A1. Ядро прикладного слоя - Восемь сервисов с наибольшим числом связей и вызовы между ними. Стрелка идёт от вызываемого к вызывающему (serving): кого лишишься — тот и сломается. Всего в контуре 86 межсервисных связей. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + A0. Карта прикладного слоя + Из чего состоит прикладной слой: 38 компонентов по смысловым группам. Связи здесь намеренно не показаны — на таком числе компонентов они делают схему нечитаемой; для них есть представления A1 и далее. Вложенность означает aggregation: группа объединяет компоненты, но не владеет ими. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - A2. Зависят от: django - К django обращаются 18 сервисов. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + A1. Ядро прикладного слоя + Восемь сервисов с наибольшим числом связей и вызовы между ними. Стрелка идёт от вызываемого к вызывающему (serving): кого лишишься — тот и сломается. Всего в контуре 86 межсервисных связей. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - A3. Зависят от: documentations - К documentations обращаются 11 сервисов. - - - - - - - - - - - - - - - - - - - - - - - + A2. Зависят от: django + К django обращаются 18 сервисов. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - A4. Зависят от: eav - К eav обращаются 9 сервисов. - - - - - - - - - - - - - - - - - - - + A3. Зависят от: documentations + К documentations обращаются 11 сервисов. + + + + + + + + + + + + + + + + + + + + + + + - A5. Зависят от: resources - К resources обращаются 7 сервисов. - - - - - - - - - - - - - - - + A4. Зависят от: eav + К eav обращаются 9 сервисов. + + + + + + + + + + + + + + + + + + + - A6. Зависят от: processing - К processing обращаются 6 сервисов. - - - - - - - - - - - - - + A5. Зависят от: resources + К resources обращаются 7 сервисов. + + + + + + + + + + + + + + + - A7. Зависят от: iam - К iam обращаются 6 сервисов. - - - - - - - - - - - - - + A6. Зависят от: processing + К processing обращаются 6 сервисов. + + + + + + + + + + + + + - A8. Зависят от: flows - К flows обращаются 4 сервиса. - - - - - - - - - + A7. Зависят от: iam + К iam обращаются 6 сервисов. + + + + + + + + + + + + + - A9. Зависят от: workspaces - К workspaces обращаются 4 сервиса. - - - - - - - - - + A8. Зависят от: flows + К flows обращаются 4 сервиса. + + + + + + + + + - A10. Зависят от: system-log - К system-log обращаются 3 сервиса. - - - - - - - + A9. Зависят от: workspaces + К workspaces обращаются 4 сервиса. + + + + + + + + + - A11. Зависят от: bim - К bim обращаются 3 сервиса. - - - - - - - + A10. Зависят от: system-log + К system-log обращаются 3 сервиса. + + + + + + + - A12. Зависят от: pm - К pm обращаются 3 сервиса. - - - - - - - + A11. Зависят от: bim + К bim обращаются 3 сервиса. + + + + + + + - T16. Потребители: Маршрутизация HTTPS-трафика - Сервисом пользуется 21 из 37 приложений контура. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + A12. Зависят от: pm + К pm обращаются 3 сервиса. + + + + + + + - T17. Потребители: Аутентификация OIDC - Сервисом пользуются 25 из 37 приложений контура. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + P1. Паспорт: documentations + Что нужно, чтобы documentations работал: 7 технологических сервисов и 15 прикладных сервисов. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Кто зависит от самого documentations — представление A3. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - T18. Потребители: Управление секретами - Сервисом пользуются 26 из 37 приложений контура. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + P2. Паспорт: flows + Что нужно, чтобы flows работал: 7 технологических сервисов и 8 прикладных сервисов. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Кто зависит от самого flows — представление A8. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - T19. Потребители: Реляционное хранилище - Сервисом пользуются 24 из 37 приложений контура. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + P3. Паспорт: issues + Что нужно, чтобы issues работал: 9 технологических сервисов и 7 прикладных сервисов. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Входящих вызовов у issues меньше 3, отдельного представления для них нет. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - T20. Потребители: Кэш - Сервисом пользуются 5 из 37 приложений контура. - - - - - - - - - - - - - + P4. Паспорт: comparisons + Что нужно, чтобы comparisons работал: 3 технологических сервиса и 6 прикладных сервисов. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Входящих вызовов у comparisons меньше 3, отдельного представления для них нет. + + + + + + + + + + + + + + + + + + + - T21. Потребители: Событийная шина - Сервисом пользуются 14 из 37 приложений контура. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + P5. Паспорт: django + Что нужно, чтобы django работал: 8 технологических сервисов и 6 прикладных сервисов. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Кто зависит от самого django — представление A2. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - T22. Потребители: Очередь сообщений AMQP - Сервисом пользуются 12 из 37 приложений контура. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + P6. Паспорт: faas + Что нужно, чтобы faas работал: 0 технологических сервисов и 5 прикладных сервисов. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Входящих вызовов у faas меньше 3, отдельного представления для них нет. + + + + + + + + + + + - T23. Потребители: Оркестрация процессов BPMN - Сервисом пользуется 1 из 37 приложений контура. - - - - - + P7. Паспорт: transmittal + Что нужно, чтобы transmittal работал: 6 технологических сервисов и 5 прикладных сервисов. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Входящих вызовов у transmittal меньше 3, отдельного представления для них нет. + + + + + + + + + + + + + + + + + + + + + + + - T24. Потребители: Объектное хранилище - Сервисом пользуются 16 из 37 приложений контура. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + P8. Паспорт: message-hub + Что нужно, чтобы message-hub работал: 5 технологических сервисов и 4 прикладных сервиса. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Входящих вызовов у message-hub меньше 3, отдельного представления для них нет. + + + + + + + + + + + + + + + + + + + - T25. Потребители: Отправка почтовых уведомлений - Сервисом пользуются 6 из 37 приложений контура. - - - - - - - - - - - - - - - + P9. Паспорт: pm + Что нужно, чтобы pm работал: 8 технологических сервисов и 4 прикладных сервиса. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Кто зависит от самого pm — представление A12. + + + + + + + + + + + + + + + + + + + + + + + + + + + + P10. Паспорт: processing + Что нужно, чтобы processing работал: 5 технологических сервисов и 4 прикладных сервиса. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Кто зависит от самого processing — представление A6. + + + + + + + + + + + + + + + + + + + + + + P11. Паспорт: rfi + Что нужно, чтобы rfi работал: 7 технологических сервисов и 4 прикладных сервиса. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Входящих вызовов у rfi меньше 3, отдельного представления для них нет. + + + + + + + + + + + + + + + + + + + + + + + + + + P12. Паспорт: cde + Что нужно, чтобы cde работал: 5 технологических сервисов и 3 прикладных сервиса. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Входящих вызовов у cde меньше 3, отдельного представления для них нет. + + + + + + + + + + + + + + + + + + + + P13. Паспорт: notes + Что нужно, чтобы notes работал: 6 технологических сервисов и 3 прикладных сервиса. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Входящих вызовов у notes меньше 3, отдельного представления для них нет. + + + + + + + + + + + + + + + + + + + diff --git a/docs/architecture/preview.html b/docs/architecture/preview.html index 12cebfd..8905c87 100644 --- a/docs/architecture/preview.html +++ b/docs/architecture/preview.html @@ -16,7 +16,7 @@

Автогенерация из example-technology.archimate. Зелёный — технологический слой, голубой — прикладной. Пунктир с полым треугольником — realization, стрелка — serving, ромб — composition, линия с шариком — assignment.

-

T1. Технологический слой

Что развёрнуто в кластере и какие технологические сервисы это даёт. Приложения-потребители вынесены в отдельные представления T2 и далее.

+

L1. Как читать схемы

Легенда нотации. Показан настоящий фрагмент модели, подписанный по типам: каждый элемент и каждая линия здесь встречаются на остальных представлениях в том же начертании.

@@ -28,6 +28,22 @@ + + +Кластер k8s-prodVault + Agent InjectorУправление секретамиattachmentsГруппа узлов K8s (Поддерживающаяинфраструктура)Группа узлов generic (Сервераприложений)Документы и общая среда данныхHelm-чарты (OCI)Стрелка serving читается не как «кто кого вызывает», а как «кто без кого не работает»: она идёт от обслуживающего к обслуживаемому. Направление выбрано так потому, что от схемы обычно нужен ответна вопрос «что откажет, если убрать этот элемент», — и он читается по стрелкам вперёд.Узел (Node) — вычислительная среда:кластер, группа серверов или отдельныйхост. Ромб на линии — composition: узелсостоит из этого, и отдельно от узласодержимое не существует.Системное ПО (System Software) —платформенный компонент внутри узла.Пунктир с полым треугольником —realization: компонент реализуеттехнологический сервис.Технологический сервис (TechnologyService) — что платформа даётприложениям, без указания, чем именно этосделано. Приложение зависит от сервиса, ане от конкретного продукта под ним.Прикладной компонент (ApplicationComponent) — сервис прикладного слоя.Цветом различаются слои: голубой —прикладной, зелёный — технологический.Линия с полым ромбом — aggregation:группа объединяет элемент, но тот можетсуществовать и без неё. Так показано, накаких узлах работает системное ПО.Линия с шариком и закрашенной стрелкой —assignment: узел выделен под компонент, икомпонент на нём исполняется.Смысловая группа (Grouping) — доменприкладного слоя. Тоже aggregation:компонент принадлежит домену по смыслу, ане по месту размещения.Артефакт (Artifact) — то, что физическилежит в хранилище: файл, образконтейнера, дистрибутив.

T1. Технологический слой

Что развёрнуто в кластере и какие технологические сервисы это даёт. Приложения-потребители вынесены в отдельные представления T2 и далее.

+ + + + + + + + + + + + + Кластер k8s-prodCamunda Platformregistry.example.coms3.example.com — объектное хранилищеСетевое хранилище (StorageClass)Git-сервер контураsmtp.example.com — почтовый релейKeycloak — брокер идентификацииAD FS — служба федерацииActive Directory — каталог предприятияKerberos KDC — центр выдачи билетовfrontend-node-01Istio Ingress GatewayIstio Service Meshcert-managerZitadelVault + Agent InjectorPostgreSQLRedisKafkaRabbitMQZeebeZeebe GatewayOperateTasklistOptimizeIdentityConnectorsМаршрутизацияHTTPS-трафикаВыпускTLS-сертификатовАутентификация OIDCУправление секретамиРеляционное хранилищеКэшСобытийная шинаОчередь сообщенийAMQPОркестрация процессовBPMNОбъектное хранилищеОтправка почтовыхуведомленийHelm-чарты (OCI)Образы контейнеров

T2. Развёртывание по узлам

Какие группы узлов какие компоненты несут. Вложенность заменяет стрелки: хост внутри группы — composition, приложение — assignment, системное ПО — aggregation. Имена хостов заданы в профиле контура.

@@ -40,6 +56,8 @@ + + Группа узлов generic (Сервера приложений)Группа узлов K8s (Поддерживающая инфраструктура)Группа узлов processing (Сервера приложений)Объектное хранилищеГруппа узлов DB (Базы данных)Репозиторий компонентовCAD фермаprocessings3.example.com —объектное хранилищеPostgreSQLIstio Ingress GatewayIstio Service Meshcert-managerZitadelVault + Agent InjectorRedisKafkaRabbitMQCamunda Platformregistry.example.comGit-сервер контураКонвертер BIM-моделейams-syncattachmentsauth-flowbimcdechecklistscomparisonscontractscontrol-interfacecross-sectiondjangodocument-linkdocumentationsdrawingseavfaasflowsiaminspectionsissuesmappermeasurementsmessage-hubnotespmprescriptionsprojectsremarksresourcesreviewsrfistamp-verificationsubscriptionssystem-logtransmittalworkspaces

T3. Внешние интеграции

Системы за периметром контура, с которыми платформа обменивается данными, и направление зависимости. Слева — технологические сервисы, которые видят приложения; справа — то, чем эти сервисы обеспечены на стороне заказчика. Схем подключения каталога предприятия четыре, и в конкретном контуре работает одна: каталог напрямую к провайдеру идентификации платформы; каталог через брокер Keycloak; то же с доменным входом по Kerberos, который умеет проверять только брокер; либо служба федерации AD FS поверх того же каталога. Здесь показаны все четыре сразу — при развёртывании лишние узлы из профиля убираются.

@@ -54,7 +72,9 @@ -Аутентификация OIDCОтправка почтовых уведомленийZitadelsmtp.example.com — почтовый релейKeycloak — брокер идентификацииAD FS — служба федерацииActive Directory — каталог предприятияKerberos KDC — центр выдачи билетов

A1. Ядро прикладного слоя

Восемь сервисов с наибольшим числом связей и вызовы между ними. Стрелка идёт от вызываемого к вызывающему (serving): кого лишишься — тот и сломается. Всего в контуре 86 межсервисных связей.

+ + +Аутентификация OIDCОтправка почтовых уведомленийZitadelsmtp.example.com — почтовый релейKeycloak — брокер идентификацииAD FS — служба федерацииActive Directory — каталог предприятияKerberos KDC — центр выдачи билетов

T4. Потребители: Маршрутизация HTTPS-трафика

Сервисом пользуется 21 из 37 приложений контура.

@@ -66,7 +86,9 @@ -documentationsdjangoflowsprocessingeavresourcesissuespm

A2. Зависят от: django

К django обращаются 18 сервисов.

+ + +Маршрутизация HTTPS-трафикаIstio Ingress GatewayIstio Service Meshauth-flowbimcdechecklistscontrol-interfacedjangodocument-linkdocumentationseavflowsiaminspectionsissuespmprocessingremarksreviewsrfistamp-verificationtransmittalworkspaces

T5. Потребители: Аутентификация OIDC

Сервисом пользуются 25 из 37 приложений контура.

@@ -78,6 +100,162 @@ + + +Аутентификация OIDCZitadelams-syncauth-flowchecklistscomparisonscontractscontrol-interfacecross-sectiondjangodocumentationseavflowsiaminspectionsissuesmappernotespmprescriptionsprocessingprojectsremarksreviewsrfitransmittalworkspaces

T6. Потребители: Управление секретами

Сервисом пользуются 26 из 37 приложений контура.

+ + + + + + + + + + + + + +Управление секретамиVault + Agent Injectorattachmentsbimcdechecklistscomparisonscontractsdjangodocumentationsdrawingseavflowsiaminspectionsissuesmappermeasurementsmessage-hubnotespmprocessingresourcesrfisubscriptionssystem-logtransmittalworkspaces

T7. Потребители: Реляционное хранилище

Сервисом пользуются 24 из 37 приложений контура.

+ + + + + + + + + + + + + +Реляционное хранилищеPostgreSQLattachmentsbimchecklistscomparisonscontractsdjangodocumentationsdrawingseavflowsiaminspectionsissuesmappermessage-hubnotespmprocessingresourcesrfisubscriptionssystem-logtransmittalworkspaces

T8. Потребители: Кэш

Сервисом пользуются 5 из 37 приложений контура.

+ + + + + + + + + + + + + +КэшRedisdjangoissuesmappermessage-hubpm

T9. Потребители: Событийная шина

Сервисом пользуются 14 из 37 приложений контура.

+ + + + + + + + + + + + + +Событийная шинаKafkaams-synccontractsdjangodocumentationseavflowsiaminspectionsissuesmappermessage-hubnotespmsystem-log

T10. Потребители: Очередь сообщений AMQP

Сервисом пользуются 12 из 37 приложений контура.

+ + + + + + + + + + + + + +Очередь сообщений AMQPRabbitMQcdecontractsdjangodocumentationsflowsissuesmappernotespmprocessingrfitransmittalКонвертер BIM-моделей

T11. Потребители: Оркестрация процессов BPMN

Сервисом пользуется 1 из 37 приложений контура.

+ + + + + + + + + + + + + +Оркестрация процессов BPMNCamunda Platformcde

T12. Потребители: Объектное хранилище

Сервисом пользуются 16 из 37 приложений контура.

+ + + + + + + + + + + + + +Объектное хранилищеs3.example.com — объектное хранилищеattachmentscdecontractsdjangodocumentationseaviamissuesmappermeasurementsmessage-hubnotespmresourcesrfisubscriptionsКонвертер BIM-моделей

T13. Потребители: Отправка почтовых уведомлений

Сервисом пользуются 6 из 37 приложений контура.

+ + + + + + + + + + + + + +Отправка почтовых уведомленийsmtp.example.com — почтовый релейflowsinspectionsissuesrfisubscriptionstransmittal

A0. Карта прикладного слоя

Из чего состоит прикладной слой: 38 компонентов по смысловым группам. Связи здесь намеренно не показаны — на таком числе компонентов они делают схему нечитаемой; для них есть представления A1 и далее. Вложенность означает aggregation: группа объединяет компоненты, но не владеет ими.

+ + + + + + + + + + + + + +ПлатформаДокументы и общая среда данныхКонтроль качестваУправление проектомПолевые данныеams-syncauth-flowcontrol-interfacedjangoeavfaasflowsiammessage-hubprojectssubscriptionssystem-logworkspacescontractsnotespmresourcesattachmentsbimКонвертер BIM-моделейcdedocument-linkdocumentationsdrawingsstamp-verificationtransmittalchecklistscomparisonsinspectionsissuesprescriptionsremarksreviewsrficross-sectionmappermeasurementsprocessing

A1. Ядро прикладного слоя

Восемь сервисов с наибольшим числом связей и вызовы между ними. Стрелка идёт от вызываемого к вызывающему (serving): кого лишишься — тот и сломается. Всего в контуре 86 межсервисных связей.

+ + + + + + + + + + + + + +documentationsdjangoflowsprocessingeavissuesresourcespm

A2. Зависят от: django

К django обращаются 18 сервисов.

+ + + + + + + + + + + + + djangobimcomparisonsdocumentationsfaasflowsissuesmappermeasurementsmessage-hubnotespmprocessingresourcesrfisubscriptionssystem-logtransmittalworkspaces

A3. Зависят от: documentations

К documentations обращаются 11 сервисов.

@@ -90,6 +268,8 @@ + + documentationscomparisonsdjangofaasflowsissuesnotesprocessingrfisystem-logtransmittalworkspaces

A4. Зависят от: eav

К eav обращаются 9 сервисов.

@@ -102,6 +282,8 @@ + + eavcomparisonsdocumentationsfaasflowsinspectionsissuesmessage-hubpmrfi

A5. Зависят от: resources

К resources обращаются 7 сервисов.

@@ -114,6 +296,8 @@ + + resourcesdocumentationsflowsissuespmprocessingrfitransmittal

A6. Зависят от: processing

К processing обращаются 6 сервисов.

@@ -126,6 +310,8 @@ + + processingcomparisonsdjangodocumentationsflowsinspectionsissues

A7. Зависят от: iam

К iam обращаются 6 сервисов.

@@ -138,6 +324,8 @@ + + iamdocumentationsflowsissuespmprocessingtransmittal

A8. Зависят от: flows

К flows обращаются 4 сервиса.

@@ -150,6 +338,8 @@ + + flowscdedocumentationsissuestransmittal

A9. Зависят от: workspaces

К workspaces обращаются 4 сервиса.

@@ -162,6 +352,8 @@ + + workspacescdecomparisonsdjangodocumentations

A10. Зависят от: system-log

К system-log обращаются 3 сервиса.

@@ -174,6 +366,8 @@ + + system-logcdedocumentationssubscriptions

A11. Зависят от: bim

К bim обращаются 3 сервиса.

@@ -186,6 +380,8 @@ + + bimcomparisonsdjangodocumentations

A12. Зависят от: pm

К pm обращаются 3 сервиса.

@@ -198,7 +394,9 @@ -pmdjangoflowsmessage-hub

T16. Потребители: Маршрутизация HTTPS-трафика

Сервисом пользуется 21 из 37 приложений контура.

+ + +pmdjangoflowsmessage-hub

P1. Паспорт: documentations

Что нужно, чтобы documentations работал: 7 технологических сервисов и 15 прикладных сервисов. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Кто зависит от самого documentations — представление A3.

@@ -210,7 +408,9 @@ -Маршрутизация HTTPS-трафикаIstio Ingress GatewayIstio Service Meshauth-flowbimcdechecklistscontrol-interfacedjangodocument-linkdocumentationseavflowsiaminspectionsissuespmprocessingremarksreviewsrfistamp-verificationtransmittalworkspaces

T17. Потребители: Аутентификация OIDC

Сервисом пользуются 25 из 37 приложений контура.

+ + +documentationsМаршрутизацияHTTPS-трафикаАутентификация OIDCУправление секретамиРеляционное хранилищеСобытийная шинаОчередь сообщений AMQPОбъектное хранилищеattachmentsbimdjangodrawingseavflowsiaminspectionsnotesprocessingremarksresourcessubscriptionssystem-logworkspaces

P2. Паспорт: flows

Что нужно, чтобы flows работал: 7 технологических сервисов и 8 прикладных сервисов. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Кто зависит от самого flows — представление A8.

@@ -222,7 +422,9 @@ -Аутентификация OIDCZitadelams-syncauth-flowchecklistscomparisonscontractscontrol-interfacecross-sectiondjangodocumentationseavflowsiaminspectionsissuesmappernotespmprescriptionsprocessingprojectsremarksreviewsrfitransmittalworkspaces

T18. Потребители: Управление секретами

Сервисом пользуются 26 из 37 приложений контура.

+ + +flowsМаршрутизацияHTTPS-трафикаАутентификация OIDCУправление секретамиРеляционное хранилищеСобытийная шинаОчередь сообщений AMQPОтправка почтовыхуведомленийchecklistsdjangodocumentationseaviampmprocessingresources

P3. Паспорт: issues

Что нужно, чтобы issues работал: 9 технологических сервисов и 7 прикладных сервисов. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Входящих вызовов у issues меньше 3, отдельного представления для них нет.

@@ -234,7 +436,9 @@ -Управление секретамиVault + Agent Injectorattachmentsbimcdechecklistscomparisonscontractsdjangodocumentationsdrawingseavflowsiaminspectionsissuesmappermeasurementsmessage-hubnotespmprocessingresourcesrfisubscriptionssystem-logtransmittalworkspaces

T19. Потребители: Реляционное хранилище

Сервисом пользуются 24 из 37 приложений контура.

+ + +issuesМаршрутизацияHTTPS-трафикаАутентификация OIDCУправление секретамиРеляционное хранилищеКэшСобытийная шинаОчередь сообщений AMQPОбъектное хранилищеОтправка почтовыхуведомленийdjangodocumentationseavflowsiamprocessingresources

P4. Паспорт: comparisons

Что нужно, чтобы comparisons работал: 3 технологических сервиса и 6 прикладных сервисов. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Входящих вызовов у comparisons меньше 3, отдельного представления для них нет.

@@ -246,7 +450,9 @@ -Реляционное хранилищеPostgreSQLattachmentsbimchecklistscomparisonscontractsdjangodocumentationsdrawingseavflowsiaminspectionsissuesmappermessage-hubnotespmprocessingresourcesrfisubscriptionssystem-logtransmittalworkspaces

T20. Потребители: Кэш

Сервисом пользуются 5 из 37 приложений контура.

+ + +comparisonsАутентификация OIDCУправление секретамиРеляционное хранилищеbimdjangodocumentationseavprocessingworkspaces

P5. Паспорт: django

Что нужно, чтобы django работал: 8 технологических сервисов и 6 прикладных сервисов. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Кто зависит от самого django — представление A2.

@@ -258,7 +464,9 @@ -КэшRedisdjangoissuesmappermessage-hubpm

T21. Потребители: Событийная шина

Сервисом пользуются 14 из 37 приложений контура.

+ + +djangoМаршрутизацияHTTPS-трафикаАутентификация OIDCУправление секретамиРеляционное хранилищеКэшСобытийная шинаОчередь сообщений AMQPОбъектное хранилищеbimdocumentationsmeasurementspmprocessingworkspaces

P6. Паспорт: faas

Что нужно, чтобы faas работал: 0 технологических сервисов и 5 прикладных сервисов. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Входящих вызовов у faas меньше 3, отдельного представления для них нет.

@@ -270,7 +478,9 @@ -Событийная шинаKafkaams-synccontractsdjangodocumentationseavflowsiaminspectionsissuesmappermessage-hubnotespmsystem-log

T22. Потребители: Очередь сообщений AMQP

Сервисом пользуются 12 из 37 приложений контура.

+ + +faasdjangodocumentationseavreviewstransmittal

P7. Паспорт: transmittal

Что нужно, чтобы transmittal работал: 6 технологических сервисов и 5 прикладных сервисов. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Входящих вызовов у transmittal меньше 3, отдельного представления для них нет.

@@ -282,7 +492,9 @@ -Очередь сообщений AMQPRabbitMQcdecontractsdjangodocumentationsflowsissuesmappernotespmprocessingrfitransmittalКонвертер BIM-моделей

T23. Потребители: Оркестрация процессов BPMN

Сервисом пользуется 1 из 37 приложений контура.

+ + +transmittalМаршрутизацияHTTPS-трафикаАутентификация OIDCУправление секретамиРеляционное хранилищеОчередь сообщений AMQPОтправка почтовыхуведомленийdjangodocumentationsflowsiamresources

P8. Паспорт: message-hub

Что нужно, чтобы message-hub работал: 5 технологических сервисов и 4 прикладных сервиса. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Входящих вызовов у message-hub меньше 3, отдельного представления для них нет.

@@ -294,7 +506,9 @@ -Оркестрация процессов BPMNCamunda Platformcde

T24. Потребители: Объектное хранилище

Сервисом пользуются 16 из 37 приложений контура.

+ + +message-hubУправление секретамиРеляционное хранилищеКэшСобытийная шинаОбъектное хранилищеdjangoeavissuespm

P9. Паспорт: pm

Что нужно, чтобы pm работал: 8 технологических сервисов и 4 прикладных сервиса. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Кто зависит от самого pm — представление A12.

@@ -306,7 +520,9 @@ -Объектное хранилищеs3.example.com — объектное хранилищеattachmentscdecontractsdjangodocumentationseaviamissuesmappermeasurementsmessage-hubnotespmresourcesrfisubscriptionsКонвертер BIM-моделей

T25. Потребители: Отправка почтовых уведомлений

Сервисом пользуются 6 из 37 приложений контура.

+ + +pmМаршрутизацияHTTPS-трафикаАутентификация OIDCУправление секретамиРеляционное хранилищеКэшСобытийная шинаОчередь сообщений AMQPОбъектное хранилищеdjangoeaviamresources

P10. Паспорт: processing

Что нужно, чтобы processing работал: 5 технологических сервисов и 4 прикладных сервиса. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Кто зависит от самого processing — представление A6.

@@ -318,5 +534,49 @@ -Отправка почтовых уведомленийsmtp.example.com — почтовый релейflowsinspectionsissuesrfisubscriptionstransmittal
+ + +processingМаршрутизацияHTTPS-трафикаАутентификация OIDCУправление секретамиРеляционное хранилищеОчередь сообщений AMQPdjangodocumentationsiamresources

P11. Паспорт: rfi

Что нужно, чтобы rfi работал: 7 технологических сервисов и 4 прикладных сервиса. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Входящих вызовов у rfi меньше 3, отдельного представления для них нет.

+ + + + + + + + + + + + + +rfiМаршрутизацияHTTPS-трафикаАутентификация OIDCУправление секретамиРеляционное хранилищеОчередь сообщений AMQPОбъектное хранилищеОтправка почтовыхуведомленийdjangodocumentationseavresources

P12. Паспорт: cde

Что нужно, чтобы cde работал: 5 технологических сервисов и 3 прикладных сервиса. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Входящих вызовов у cde меньше 3, отдельного представления для них нет.

+ + + + + + + + + + + + + +cdeМаршрутизацияHTTPS-трафикаУправление секретамиОчередь сообщений AMQPОркестрация процессовBPMNОбъектное хранилищеflowssystem-logworkspaces

P13. Паспорт: notes

Что нужно, чтобы notes работал: 6 технологических сервисов и 3 прикладных сервиса. Стрелки, как и везде, идут от обслуживающего к обслуживаемому. Входящих вызовов у notes меньше 3, отдельного представления для них нет.

+ + + + + + + + + + + + + +notesАутентификация OIDCУправление секретамиРеляционное хранилищеСобытийная шинаОчередь сообщений AMQPОбъектное хранилищеattachmentsdjangodocumentations
\ No newline at end of file diff --git a/docs/architecture/render_preview.py b/docs/architecture/render_preview.py index 3808afb..60dd43e 100644 --- a/docs/architecture/render_preview.py +++ b/docs/architecture/render_preview.py @@ -12,8 +12,9 @@ LAYER = { # цвета Archi по слоям "ApplicationComponent": "#B5FFFF", "ApplicationService": "#B5FFFF", "Node": "#C9E7B7", "SystemSoftware": "#C9E7B7", "TechnologyService": "#C9E7B7", "Artifact": "#C9E7B7", + "Grouping": "#F4F4F4", } -STROKE = {"Application": "#2a7f8f", "Technology": "#4a7f3a"} +STROKE = {"Application": "#2a7f8f", "Technology": "#4a7f3a", "Grouping": "#888"} concepts, rels = {}, {} for folder in root.findall("folder"): @@ -24,17 +25,20 @@ for folder in root.findall("folder"): elif et != "ArchimateDiagramModel": concepts[e.get("id")] = (et, e.get("name") or "") -def collect(node, ox, oy, nodes, conns): +def collect(node, ox, oy, nodes, conns, notes): b = node.find("bounds") x, y = ox + int(b.get("x", 0)), oy + int(b.get("y", 0)) w, h = int(b.get("width", 120)), int(b.get("height", 55)) + if (node.get(XSI) or "") == "archimate:Note": + notes.append((node.findtext("content") or "", x, y, w, h)) + return nodes[node.get("id")] = (node.get("archimateElement"), x, y, w, h) for c in node.findall("sourceConnection"): conns.append((c.get("relationship"), c.get("source"), c.get("target"))) for ch in node.findall("child"): - collect(ch, x, y, nodes, conns) + collect(ch, x, y, nodes, conns, notes) -def wrap(s, width): +def wrap(s, width, limit=4): out, line = [], "" for word in s.split(): if len(line) + len(word) + 1 > width and line: @@ -43,7 +47,7 @@ def wrap(s, width): line = f"{line} {word}".strip() if line: out.append(line) - return out[:4] + return out[:limit] def edge_point(x, y, w, h, tx, ty): """Точка пересечения луча к (tx,ty) с границей прямоугольника.""" @@ -68,6 +72,8 @@ MARKERS = """ + + """ STYLE = { @@ -75,6 +81,7 @@ STYLE = { "Realization": ('stroke-dasharray="6,4"', 'marker-end="url(#hollow)"', ""), "Composition": ('stroke-dasharray="none"', "", 'marker-start="url(#diamond)"'), "Assignment": ('stroke-dasharray="none"', 'marker-end="url(#filled)"', 'marker-start="url(#ball)"'), + "Aggregation": ('stroke-dasharray="none"', "", 'marker-start="url(#odiamond)"'), } parts = [] @@ -82,13 +89,15 @@ views = [e for f in root.findall("folder") for e in f.findall("element") if (e.get(XSI) or "").endswith("ArchimateDiagramModel")] for v in views: - nodes, conns = {}, [] + nodes, conns, notes = {}, [], [] for ch in v.findall("child"): - collect(ch, 0, 0, nodes, conns) + collect(ch, 0, 0, nodes, conns, notes) if not nodes: continue - maxx = max(x + w for _, x, _, w, _ in nodes.values()) + 40 - maxy = max(y + h for _, _, y, _, h in nodes.values()) + 40 + boxes = [(x, y, w, h) for _, x, y, w, h in nodes.values()] + \ + [(x, y, w, h) for _, x, y, w, h in notes] + maxx = max(x + w for x, _, w, _ in boxes) + 40 + maxy = max(y + h for _, y, _, h in boxes) + 40 svg = [f'', MARKERS] @@ -110,7 +119,8 @@ for v in views: for nid, (eref, x, y, w, h) in sorted(nodes.items(), key=lambda kv: -kv[1][3] * kv[1][4]): etype, name = concepts.get(eref, ("", eref or "?")) fill = LAYER.get(etype, "#EEEEEE") - stroke = STROKE["Application"] if etype.startswith("Application") else STROKE["Technology"] + stroke = (STROKE["Grouping"] if etype == "Grouping" else + STROKE["Application"] if etype.startswith("Application") else STROKE["Technology"]) big = w * h > 60000 svg.append(f'') @@ -125,6 +135,14 @@ for v in views: svg.append(f'' f'{html.escape(ln)}') + + # надписи — поверх всего, без заливки слоя: это не элементы модели + for content, x, y, w, h in notes: + svg.append(f'') + for i, ln in enumerate(wrap(content, max(16, int(w / 6.2)), limit=int(h // 15))): + svg.append(f'' + f'{html.escape(ln)}') svg.append("") doc = v.find("documentation") diff --git a/docs/architecture/to_open_exchange.py b/docs/architecture/to_open_exchange.py index aac4e59..5dd416e 100644 --- a/docs/architecture/to_open_exchange.py +++ b/docs/architecture/to_open_exchange.py @@ -45,8 +45,10 @@ def flatten(node, ox=0, oy=0, out=None, conns=None): conns = [] if conns is None else conns b = node.find("bounds") x = ox + int(b.get("x", 0)); y = oy + int(b.get("y", 0)) + # у надписей (Note) нет archimateElement — в обменном формате это узел типа Label out.append((node.get("id"), node.get("archimateElement"), - x, y, int(b.get("width", 120)), int(b.get("height", 55)))) + x, y, int(b.get("width", 120)), int(b.get("height", 55)), + text(node, "content"))) for c in node.findall("sourceConnection"): conns.append((c.get("id"), c.get("relationship"), c.get("source"), c.get("target"))) @@ -88,9 +90,15 @@ for v in views: nodes, conns = [], [] for child in v.findall("child"): flatten(child, 0, 0, nodes, conns) - for nid, eref, x, y, w, h in nodes: - out.append(f' ') + for nid, eref, x, y, w, h, content in nodes: + if eref: + out.append(f' ') + else: + out.append(f' ') + out.append(f' ') + out.append(' ') for cid, rref, s, tg in conns: out.append(f' ') diff --git a/legend.png b/legend.png new file mode 100644 index 0000000..fdb516b Binary files /dev/null and b/legend.png differ