用途
本技能用于把应用从 Neo 环境的 ECM Service(com.sap.ecm.api.EcmService)迁移到 SAP Document Management Service(SDM),迁移后通过 CMIS 协议、使用 OpenCMIS 客户端库访问 SDM。
适用检测条件
满足以下任一模式即适用:
- web.xml 中存在:
<resource-ref>
<res-ref-name>EcmService</res-ref-name>
<res-type>com.sap.ecm.api.EcmService</res-type>
</resource-ref>
- Java 源文件中存在
import com.sap.ecm.api.EcmService;、import com.sap.ecm.api.RepositoryOptions;、@Resource(name = "EcmService")或 JNDI 查找ctx.lookup("java:comp/env/EcmService")。
前置条件
- 工作目录:必须在应用由
jakarta-java25-migration或neo-to-cf-migration-orchestrator创建的-cf-migration副本内运行;若当前目录不以-cf-migration结尾,需先切换。 - 必须先执行
sdk-replacement技能(用于配置 SAP Cloud SDK),这是本技能的必需前置。 - 子账户中需要具备 SDM 服务权限(entitlement)。
主要能力与转换步骤
步骤 1:从 web.xml 中移除资源引用 —— 删除上述 EcmService 的 resource-ref。
步骤 2:添加 OpenCMIS 依赖 —— 在 pom.xml 中加入 chemistry-opencmis-client-impl、chemistry-opencmis-client-api(版本 1.1.0)、httpclient 与 jackson-databind。注意:scp-cf 与 sdk-modules-bom 应由 sdk-replacement 前置技能提供,本技能不重复添加;不要以 compile 作用域直接添加 com.sap.cloud.environment.servicebinding:*,否则会因不同类加载器导致运行时 ServiceConfigurationError: SapVcapServicesServiceBindingAccessor not a subtype。另注意 OpenCMIS 尚未迁移到 Jakarta EE,仍使用 javax.* 命名空间。
步骤 3:创建服务绑定访问器 —— 复制 assets/ServiceBindingAccessor.java,其功能为:从 VCAP_SERVICES 读取 SDM 服务绑定、使用客户端凭证获取 OAuth2 令牌、缓存令牌并自动刷新。
步骤 4:创建文档服务客户端 —— 复制 assets/DocumentServiceClient.java 与 assets/RepositoryAlreadyExistsException.java(两者声明包 com.example.document;,需改为自己项目的包)。功能包括创建 CMIS 会话、仓库管理(创建、删除、列表、存在性检查)、OAuth2 认证集成,以及在创建前预检查是否存在。注意标识符区别:CMIS browser binding(SessionParameter.REPOSITORY_ID)用仓库名称,REST DELETE(DELETE /rest/v2/repositories/{X})用 SDM 内部 UUID。资产提供两个方法:getRepositoryId(name) 返回名称(用于 CMIS),getRepositoryUuid(name) 返回 UUID(用于 DELETE),不可合并。Neo 的 ecmService.deleteRepository(name, ...) 与 ecmService.forceDeleteRepository(name, ...) 都改由 documentClient.deleteRepository(name) 处理。
步骤 5:更新应用代码 —— 用 DocumentServiceClient 替换注入的 EcmService,示例见技能内 Before/After 代码(含创建仓库、获取 CMIS 会话、上传与列举文档、删除仓库、创建仓库等)。注意使用 jakarta.servlet.* 而非 javax.servlet.*。创建仓库重复时,SDM 的 REST API 返回 201(不报错),资产通过预检查抛出 RepositoryAlreadyExistsException,应用可映射为 HTTP 412,以匹配原 Neo 应用契约。
步骤 6:更新 MTA 描述符 —— 在现有 app 模块的 requires: 中加入 ${app-name}-sdm,并添加资源:
resources:
- name: ${app-name}-sdm
type: org.cloudfoundry.managed-service
parameters:
service: sdm
service-plan: standard
验证方式
- 编译检查:
mvn clean compile - 部署与测试:
mvn clean package,cf deploy . -f,curl "https://${app-url}/documents" - 检查服务绑定:
cf env ${app-name} | grep -A 30 "sdm"
常见问题
ServiceConfigurationError: SapVcapServicesServiceBindingAccessor not a subtype:WAR 内打包了com.sap.cloud.environment.servicebinding.*。解决方法是移除 pom.xml 中对com.sap.cloud.environment.servicebinding:*的直接依赖,依赖由sdk-replacement添加的sdk-modules-bom在 provided 作用域管理;修复后运行mvn dependency:tree -Dincludes=com.sap.cloud.environment.servicebinding确认每行以:provided结尾。- "SDM service not bound":SDM 服务未绑定,检查 mtad.yaml 的 requires 并重新部署。
- OAuth token 错误:检查 SDM 服务绑定是否包含 UAA 凭证。
- ecmservice 端点在 CF 上可能是嵌套 Map(如
{"timeout": 900000, "url": "https://..."})而非字符串;ServiceBindingAccessor.getEcmServiceUrl()以 instanceof 兼容两种格式,并去除尾部斜杠。 - URL 拼接缺少斜杠:剥离尾部斜杠后拼接
rest/v2/repositories/会产生畸形 URL,应始终使用带前导/的+ "/rest/v2/repositories/"或normalizeUrl()。 - 集成测试期望重复创建返回 HTTP 412 却得到 201:SDM REST API
POST /rest/v2/repositories/无论同名仓库是否存在都返回 201,需通过预检查弥补。
配置与 CF 服务
无需额外配置文件,服务绑定在运行时读取。CF 服务:sdm,standard 计划,用途为 Document Management Service。
限制
OpenCMIS 库尚未迁移到 Jakarta EE,仍使用 javax.* 命名空间(因自包含而可接受)。