1. iModel Bank

编辑:陈俊兴

一个 iModelBank 是一个基于 Node.js 的服务器应用程序,它管理着历史和 iModel 的内容,并且提供访问它们的方法。它可以被部署为一个单一应用程序,或者是作为在 K8S 集群编排中的运行的一个 Docker 容器。每一个 iModel 都由一个独立的 iModelBank 应用程序实例表示,该实例应由现有基础架构中的其他微服务进行部署和公开(暴露)。我们建议的 iModelBank 基础架构包括以下这些服务:

  • Gateway:唯一公开的服务,该服务提供用于创建和访问 iModelBank 应用程序实例的 API
  • Orchestrator:内部服务,负责部署(启动)和销毁(关闭)其他微服务
  • iModel Manager:内部服务,负责管理 iModel 以及其对应的 iModelBank 应用程序实例的创建和删除
  • Licensing Service:内部服务,负责验证当前许可证是否有效
  • iModelBank 实例:内部服务,用于管理不同 iModel 的存储和访问操作

1.1. 架构

1.1.1. 程序包

iModelBank 提供了两个主要的程序包:

  • @bentley/imodel-bank-server - 可以为单个 iModel 启动 iModelBank 服务实例的程序包
  • @bentley/imodel-bank-licensing-server - iModelBank 运行所需的许可服务

我们还提供了其他一些程序包作为示例,可以与 iModelBank 一起部署:

  • @bentley/imodel-bank-gateway - 该程序包执行身份验证和请求的路由
  • @bentley/imodel-bank-local-orchestrator - 该程序包将启动并关闭其他微服务
  • @bentley/imodel-bank-local-imodel-manager - 该程序包管理iModel的创建、删除和查询

1.1.2. 流程图

Gateway(又名网关) 作为唯一外部可访问的服务,客户端只能向网关发送请求。在本 iModelBank 的网关事例中,网关会根据不同的请求路径,将请求导向不同的服务。如果请求路径是 iModeljs backend 相关的路径,则不进行权限验证。如果请求路径是 Licensing 路径或者 Repositories 路径,则会进行权限验证。

Orchestrator 是第一个应该启动的服务,在启动 Orchestrator 服务的同时,会初始化其他服务,如 Messaging 服务(如配置中有 Messaging 服务的配置)、Licensing 服务、IModelManager服务、Gateway服务。在 Orchestrator 服务中,运行着一个 Fastify 的服务器作为 End Point,接收来自 Orchestrator Client 的请求。网关根据不同的请求路径,通过 Orchestrator Client 向 Orchestrator 服务中的 End Point 发起请求,拿到想要请求的服务的 URL,并通过 Proxy Server 向该服务转发请求。

1.1.3. 架构图

以下架构图来自 Global 团队:

1.2. Gateway

Gateawy(网关)是集群的入口点(这是集群中唯一可从外部访问的服务)。我们可以直接暴露 iModelBank 的实例,但在那种情况下,当您想要在 iModel 之间切换时,您需要为每一个实例配置 SSL 认证证书以及为客户端配置主机名。对整个 iModelBank 的部署来说,只有一个 URL 是更方便的。

在 iModelBank Gateway 的实例程序中,身份验证是由非常简单的基本身份验证方案实现,它不适合生产环境使用。您可能需要向群集中可能部署的其他服务添加其他转发。如果您收到大量请求,单个网关实例可能不够,因此您可能需要部署多个网关实例,并在它们之前安装负载均衡器。

1.2.1. 程序包

@bentley/imodel-bank-gateway 是用于 iModelBank 部署的代理服务的例子。您可以将网关作为部署中的单个入口点,而不是直接公开 iModelBank 的每个实例,并将网关的请求转发到适当的实例上。 这种做法有以下几个优点:

  • 客户端只需要知道一个网关 URL,而不必在切换到其他 iModel 的时候更改主机或端口
  • 您只需要在网关上配置 SSL 证书,而不是在每个实例上都有不同的证书
  • 您可以在网关上执行身份验证并缓存结果,而不是对每个服务都进行身份验证

如果要运行所有 iModelBank 的示例服务,则应该启动 Gateway 的程序包,它会自动将其他示例作为子进程启动。更多相关信息,请参阅文档。

Gateway 核心代码走读

1.3. Local Orchestrator

Orchestrator 是我们提供的另一个示例,它是业务流程的简化示例。它充当 Orchestrator 系统和其他服务(网关和 iModel manager)之间的抽象层。它可以启动或停止其他服务的实例,因此它是您应该启动的第一个服务。

如果它收到启动请求,并且已经有一个实例在运行,它将返回该实例,否则它将尝试启动这个实例。根据 orchestrator.orchestratorType 设置的值,它要么将新实例作为子进程启动,要么将实例作为 Kubernetes 中单独的 pod 进行部署(当前仅支持 iModelBank 服务实例的部署)。当网关尝试将请求路由到新服务或尝试关闭整个群集时,网关会调用 Orchestrator 服务。当 iModel manager 收到删除 iModel 的请求时,也会调用 Orchestrator 服务,因此可以关闭可能正在为该 iModel 运行的 iModelBank 实例。

1.3.1. 程序包

@bentley/imodel-bank-local-orchestrator 是如何启动其他服务的示例。它管理着启动(或停止)其他服务(iModelBank,iModel Manager)实例的请求。它可以是网关服务的一部分,但我们选择将此示例作为独立额服务提供,因为其他内部服务也可能需要管理实例(例如,通过 iModel Manager 删除 iModel 时,我们可能需要停止正在运行的 iModelBank 实例)。

它可以将所有其他的服务作为子进程启动,但也可以将它配置为在单独的 Pod 中启动 iModelBank 实例。

命令:

node lib/HubApi/LocalOrchestrator/server.js configDir port
  • configDir 是一个包含服务器和日志记录配置文件的目录
  • port 是 Orchestrator 示例应在其上运行的端口

Orchestrator 核心代码走读

1.4. iModel Manager

与 iModelHub 不同,iModelBank 在每一个 iModel 上运行一个实例,而每个实例并不知晓其他的 iModel。如果要有多个 iModel,您需要某种方式来创建这些 iModel,然后对其进行查询。iModelManager 是一个作为如何在不破坏 iModelHub API 的情况下进行工作的示例。它缺少与项目管理系统的集成,它在查询 iModel 的时候会扫描所有的目录,而不是在数据库中存储信息,并且仅支持从空模板(您无法上传自己的基准文件)创建 iModel。

1.4.1. 程序包

@bentley/imodel-bank-local-imodel-manager 是处理在 iModel 文件系统中创建,删除和查询 iModel 上下文的请求的服务的示例。

imodel-bank-local-imodel-manager 实现了 iModelHub REST API 中 iModel 的管理部分,它包括:

  • ContextScope/iModel
  • iModelScope/SeedFile

iModel Manager 还实现了一些新的 REST API:

  • POST /sv1.0/Repositories/IModelBankFileSystem--main/IModelBankFileSystem/Context
    • 创建一个上下文。 Body 必须是 JSON 编码的 IModelFileSystemContextProps 对象。
  • DELETE /sv1.0/Repositories/IModelBankFileSystem--main/IModelBankFileSystem/Context/{id}
    • 删除上下文。 请求路径上的最后一项必须是要删除的上下文的 GUID。
  • GET /sv1.0/Repositories/IModelBankFileSystem--main/IModelBankFileSystem/Context
  • GET /sv1.0/Repositories/IModelBankFileSystem--main/IModelBankFileSystem/Context?$filter=...
    • 查询上下文。 支持 ODATA 样式的过滤器。
    • 返回一个 JSON 编码的 IModelFileSystemContextProps 数组。

想要启动 iModel Manager,执行:

node Run.js  imodelFsRootDir configDir orchestratorUrl port

其中:

  • imodelFsRootDir 是 iModel 文件系统根目录的完整路径
  • configDir 是包含服务器和日志记录配置文件的目录路径
  • orchestratorUrl 是正在运行的 @bentley / imodel-bank-local-orchestrator 示例的 URL
  • port 是应该启动此 iModel Manager 的端口

1.5. iModelBank Licensing Server

1.5.1. 程序包

@bentley/imodel-bank-licensing-server 提供 iModelBank 实例运行所需的许可服务。

1.6. iModelBank Server

1.6.1. 程序包

@bentley/imodel-bank-server 是 iModelBank 的主要程序包。您可以运行 “Run.js” 来启动 iModelBank 的实例。要获取有关设置以及如何运行此程序包的更多信息,请参考 iModelBank 文档。

下图是一个例子:

1.7. iModel Bank Common Orchestration

1.7.1. 程序包

@bentley/imodel-bank-common-orchestration 提供了一些工具程序,用于以子进程或 Kubernetes Pod 启动其他微服务。

1.8. Bridge Job

1.8.1. 程序包

@bentley/imodel-bank-bridge-job 包含 Run.js 脚本,可以调用该脚本执行 iModelBridges 并将 changes 结果推送到正在运行的 iModelBank 服务器。

1.8.2. 安装 Bridge 产品

想要安装 Bridge 产品,您可参考这篇文章

1.8.3. Define a Bridge Job

一个 bridge job 由一个包含一组控制文件和子文件夹的目录所定义,如下所示:

  • configuration.json
  • logging.config.xml
  • input
    • rootFiles.txt
    • bridgeArgs.json
    • files
      • source files...
  • output
    • ...

configuration.json 的内容必须采用以下的格式:

{
/** The id of the iModel that the bridges should update */
 iModelId: string;
/** The id of the context where that iModel can be found */
 contextId: string;
/** The URL, including the port, of the iModelBank server to be used to access the iModel */
 iModelBankUrl: string;
/** Type of the storage that this iModelBank server uses */
 storageType: "localhost" | "azure" | "servicestorage";
/** The string that will be used as Authorization header to access the iModel */
 accessToken: any;
}

例如:

{
  "iModelId": "233e1f55-561d-42a4-8e80-d6f91743863e",
  "contextId": "ee023a97-e04e-40b8-9c5c-a0b01286658d",
  "iModelBankUrl": "https://localhost:4000",
  "storageType": "localhost",
  "accessToken": "Basic dGVzdDp0ZXN0"
}

logging.config.xml 必须是标准的 log4cxx 日志记录配置文件。

input/files subdirectory 必须包含 bridges 要处理的所有主文件,参考文件可以在此目录或其子目录中。

input/rootFiles.txt 必须是包含每个主文件名的简单 ASCII 文本文件(utf8 编码)。也就是说,如果文件目录中包含一个主文件及其所参考的所有参考文件,则应仅在 rootFiles.txt 文件中记录该主文件的名称,参考文件的文件名不应记录在 rootFiles.txt 中。

input/bridgeArgs.json file 是可选的。如果它存在,它将指定另外一些应该传递给每一个 bridge 的命令行参数。文件格式是 BridgeArgs[],其中 BridgeArgs 是:

class BridgeArgs {
    /** The registry subkey of a bridge. **/
    bridge: string;
    /** The additional command-line arguments to pass to the bridge **/
    args: string[];
}

例子:

[
  {
    "bridge": "iModelBridgeForMstn",
    "args": ["--DGN-Install=\"d:\\Program Files (x86)\\Bentley\\MicroStation V8i (SELECTseries)\\MicroStation\"", "--DGN-Project=General", "--DGN-User=examples", "--V8I"]
  }
]

在这个例子中,bridge 是通用的 MicroStation Bridge。这些参数指定了 MicroStation 的安装位置、要使用的项目名和用户的名称、以及工作空间采用旧V8格式。

有关 bridge job 定义目录的完整示例,请参见目录 imodel-bank\bridges-test\job1。

1.8.4. 执行一个 Bridge Job

使用以下命令行执行 Bridge Job 程序:

node Run.js <configFile> <jobDir>

jobDir 必须是 Bridge Job 定义目录的完整路径。

configFile 必须指向一个 .json 的文件。通常,配置文件将是一个空对象 {}。如果需要覆盖 iModelBridgeFwk.exe 或 iModelBridgeFwkAssign.exe 程序的位置的话,您可以设置这两个属性 fwkExe 、assignExe,取决您要覆盖哪个执行程序的路径。您也可以不必这样做,因为 Bridge Job 的 Run.js 脚本可以为您找到这些程序。

注意:目标 iModelBank 服务器必须已经在 Bridge Job 定义目录中配置文件指定的 URL 上运行。 Bridge Job 程序不会部署或运行 iModelBank 实例。

以下是 Global 提供的 Bridge Job 如何发现匹配的 bridge 和执行 bridge、以及如何将变更集上传到正在运行的 iModelBank 服务器的概述图,第二张图片稍微详细地描述了中间的流程。

文件以方框形式展现,程序以圆角矩形的形式展现,带有虚线轮廓的文件是中间流程中生成的并且是临时的。绿色框描述了一些输入文件, 蓝色框描述了一些输出文件。

注意:切勿删除输出目录中的文件,这些文件包含 bridge “检测更改” 所需的信息。如果 syncinfo 文件被删除,则 bridge 将生成重复的数据。

1.8.5. Bridge 如何检测变更和上载变更

运行 Bridge Job 与在本地发布不一样。

一个 Bridge Job 必须定义在专用机器上。对于给定的 iModel,它的源文件集必须仅分配给一个 Bridge Job,Bridge Job 的输出目录必须被保存。理想情况下,Bridge Job 的输入和输出目录应位于可靠的文件共享上,并应经常备份。

一个 Bridge Job 会有许多用户执行。如果多个用户正在修改源文件,们必须将其文件提交到诸如 ProjectWise 的中央位置,然后必须将这些文件复制到 jobdir 的input/files目录中。稍后,Bridge Job 应在专用计算机上运行。

Bridge Job 无法从文档管理系统获取源文件。用户可以在执行 Bridge Job 之前将源文件的更新副本放入 Bridge Job 的 input/files 目录中。

1.9. StorageService

@bentley/imodel-bank-storage-service provides a server that can be used to store iModel Bank binary files. It can be used instead of local storage or Azure Blob storage.

imodel-bank-storage-service supports:

  • HEAD /container/{containerId}
    • Check if container exists.
  • POST /container/{containerId}
    • Create container.
  • DELETE /container/{containerId}
    • Delete container.
  • HEAD /file/{containerId}/{fileId}
    • Check if file exists and get file size.
  • GET /file/{containerId}/{fileId}
    • Download file.
  • POST /file/{containerId}/{fileId}
    • Upload file.
  • DELETE /file/{containerId}/{fileId}
    • Delete file.

imodel-bank-storage-service uses shared access signature authorization.

To start imodel-bank-storage-service:

node storage-service/lib/server.js --configDir configDirectory

where:

  • rootDirectory is a root directory of the storage service project.
  • configDirectory is a directory where configuration is placed.

Configuration sample:

{
  "default": {
    "iModelStorage": {
      "type": "storageservice"
    },
  },
  "storage-service": {
    "port": 5000,
    "secret": "{storage secret, used when generating URLs}",
    "fileUploadLimitInBytes": 5368709120, // 5 GB
    "rootDir": "{storage directory}" // can be different from rootDir for other services
  },

1.10. Checkpoint Job Scheduler

1.10.1. 程序包

@bentley/imodel-bank-checkpoint-job-scheduler 是一个应用程序,可定期检查是否应生成任何快照(checkpoints),并计划是否需要任何 checkpoints 生成作业。它旨在通过将服务调度为定期作业来启动。

命令:

node lib/Run.js --configDir <configuration files directory> --orchestratorUrl <Orchestrator Service URL>

其中:

  • configDir 是包含应用程序和日志记录配置文件的目录
  • orchestratorUrl 是 Orchestrator 服务的 URL

results matching ""

    No results matching ""