本文详解如何在 basyx 1.3 环境中,通过 connectedassetadministrationshell 手动上传子模型并配合 aasregistryproxy 显式注册至外部可访问地址,解决 aas 仓库内网访问与注册地址不一致的核心问题。
在生产级部署中,AAS 仓库(AAS Server)通常运行于内网(如 http://localhost:8081/aasServer),而对外服务需暴露统一的外部地址(如 http://aas.example.com:17081/aas)。此时,AAS Registry 中存储的 Shell 和 Submodel 描述符(AASDescriptor / SubmodelDescriptor)必须使用外部地址,否则客户端将无法通过注册中心发现并访问真实资源。
BaSyx SDK 当前(v1.3)并未为 SubmodelAggregator 提供类似 AASAggregatorProxy 的开箱即用远程代理类,且 ConnectedAssetAdministrationShellManager 默认仅使用内部仓库地址注册子模型——这正是问题的根源。但 SDK 提供了更底层、更可控的替代路径:直接操作 ConnectedAssetAdministrationShell 实例。
该实例代表一个已连接至远程 AAS 仓库的 Shell 客户端,支持本地管理子模型生命周期,并允许开发者自主构造符合外部地址要求的描述符。完整流程如下:
- 先通过 ConnectedAssetAdministrationShellManager 创建并注册 AAS(自动使用 basyxaas_registry_host 配置的外部地址);
- 获取该 AAS 的 ConnectedAssetAdministrationShell 实例;
- 调用 .addSubmodel() 上传子模型(此操作走内网地址,不影响注册逻辑);
- 手动构造 SubmodelDescriptor,显式指定外部子模型访问地址;
- 使用 AASRegistryProxy 将该描述符注册至 Registry。
以下是可直接复用的示例代码:
public void uploadShellWithExternalSubmodels(AASBundle bundle) {
// Step 1: 获取注册中心代理(已配置 external host)
AASRegistryProxy registry = getRegistry(); // 已注入 basyxaas_registry_host
// Step 2: 使用 ConnectedAssetAdministrationShellManager 创建并注册 AAS
ConnectedAssetAdministrationShellManager caasm = new ConnectedAsse
tAdministrationShellManager(registry);
AssetAdministrationShell aas = (AssetAdministrationShell) bundle.getAAS();
caasm.createAAS(aas, config.repository()); // 内部地址用于通信
// Step 3: 获取已连接的 Shell 实例
ConnectedAssetAdministrationShell connectedAAS = caasm.retrieveAAS(aas.getIdentification());
// Step 4: 逐个上传子模型(走内部仓库地址)
List submodelDescriptors = new ArrayList<>();
for (Object smObj : bundle.getSubmodels()) {
if (smObj instanceof Submodel submodel) {
connectedAAS.addSubmodel(submodel); // 同步上传至 AAS Server
// Step 5: 手动构建 SubmodelDescriptor —— 关键!使用外部地址
String externalSubmodelUrl = config.repoExternal() + "/submodels/" +
URLEncoder.encode(submodel.getIdentification().getId(), StandardCharsets.UTF_8);
SubmodelDescriptor smDescr = new SubmodelDescriptor(
submodel,
externalSubmodelUrl, // ✅ 外部可访问 URL
config.repoExternal() // ✅ 所属 AAS 的外部地址(确保与 AASDescriptor 一致)
);
submodelDescriptors.add(smDescr);
}
}
// Step 6: 批量注册所有子模型描述符
submodelDescriptors.forEach(registry::register);
} ⚠️ 关键注意事项:
- config.repoExternal() 必须返回完整的、外部可路由的子模型基础 URL(例如 "http://aas.example.com:17081/aas"),SDK 不会自动拼接路径,需自行补全 /submodels/{id};
- 子模型 ID 必须进行 URL 编码(如含特殊字符),避免注册失败;
- 确保 AASRegistryProxy 初始化时已正确加载 basyxaas_registry_host 环境变量,否则 AAS 注册本身也会出错;
- 此方案绕过了 SubmodelAggregator 的缺失限制,同时完全规避了 ConnectedAssetAdministrationShellManager 的硬编码注册逻辑,具备生产环境所需的确定性与可审计性。
综上,虽然 BaSyx 当前 API 在子模型注册的“外部地址适配”上存在抽象层级缺口,但通过组合 ConnectedAssetAdministrationShell 与手动 SubmodelDescriptor 构造,即可精准控制注册行为,满足云原生与混合网络部署的合规要求。

tAdministrationShellManager(registry);
AssetAdministrationShell aas = (AssetAdministrationShell) bundle.getAAS();
caasm.createAAS(aas, config.repository()); // 内部地址用于通信
// Step 3: 获取已连接的 Shell 实例
ConnectedAssetAdministrationShell connectedAAS = caasm.retrieveAAS(aas.getIdentification());
// Step 4: 逐个上传子模型(走内部仓库地址)
List






