私有应用开放文档

在DM Hub的私有云部署环境中,经常会面临客户的定制化需求以及对接客户现有系统的要求。但是,为了保证核心产品的可维护性以及后续产品持续的升级,应禁止直接在核心产品的code line上进行修改或定制开发。借助于DM Hub的开放平台,可以很方便的将定制化服务集成到产品中,既满足了客户需求,又避免了对产品代码的直接改动。本文将描述私有云环境中应用的开发方式和开发流程。

快速开始

应用项目的开发可以使用如下的项目模板来快速开始:

git clone https://github.com/xsio/plugin-quick-starter.git

或者点击 plugin-quick-starter-v1.0.zip 下载。

前端开发指引

从上面的项目模板开始,可以快速开始应用前端代码的开发。此处的前端是指应用管理段的界面,即从DM Hub应用市场打开应用时访问的界面。产品自动流程和微页面模板相关的前端开发请参考功能开发文档章节。

具体的开发步骤和流程,请参考下面的文档:

应用前端开发指引

后端开发指引

从上面的项目模板开始,可以快速搭建应用后端的服务。该部分包括项目的结构说明、需要配置的点、示例代码以及开发中的注意事项等。

具体的开发步骤和流程,请参考下面的文档:

应用后端开发指引

其中应用与产品的对接部分,请参考下面章节中的“应用服务与产品进行对接的方式”部分。

应用授权开发指引

应用与产品的集成一般通过DM Hub的open API来实现。私有云环境下更多的对接方式参考下面的“应用服务与产品进行对接的方式”章节。

为了调用DM Hub的open API,需要在开放平台上创建一个应用(创建方式参考下面“应用功能开发指引”章节),获取到clientId和clientSecret,并设置应用的授权回调地址。私有云部署方式下的授权回调地址格式一般为:http(s)://{app域名}/plugin/{服务名称}/oauth2,例如:

https://app.convertlab.com/plugin/myservice/oauth2

根据clientId,clientSecret和授权回调地址就可以开始进行授权集成,从而获取到调用DM Hub open API所必须的access token。集成方式请参阅下面的文档:

应用授权开发指引

应用功能开发指引

目前的开放平台支持自动流程action、微页面模块、自定义事件和自定义身份的集成,后续新增集成点会持续更新,请关注本文档。

上述集成点的配置 v2.6 之前的版本开发方式请参阅功能开发文档v2.6 及之后版本的开发方式参阅 微前端应用功能开发文档

应用服务与产品进行对接的方式

  1. 对于静态资源,访问的路径为: /extension/{myservice}/path/to/resource。其中/extension为添加在应用服务静态资源路径上的前缀,后面是应用微服务的名称,如myservice。在访问该路径时,产品nginx会根据规则将访问请求重定向到对应名称(如myservice)的应用的/path/to/resource路径上。

注:服务名称一般与build.gradle文件中指定的war.baseName一致,请与运维人员确认最终的名称。

  1. 由应用页面发起的对应用服务的接口调用,统一使用产品的proxy服务,格式如下: /dynamic/{myservice}/path/to/api。当发起该接口调用时,产品中app服务会自动将该请求重定向至myservice服务的/path/to/api。

1.83及之后的版本配置方法如下:

私有云插件一般和产品部署在同一VPC中(如果有单独的VPC,请参照公有云的对接方式来配置)。请确保全局configMap中的变量ext_app_vpc_internal_url没有配置或值为空。此时,proxy服务会将请求转发到全局configMap中{myservice}_internal_url变量对应的地址。如果插件服务是通过SRE部署,一般会自动生成该变量,请确保该变量的值正确无误。如果是手动部署的,或者没有生成该变量,可以手动配置该变量。

1.82及之前的版本请按照如下方式配置:

myservice对应的微服务地址需要在service_registry表中进行注册。该表结构如下:

字段类型说明
idBIGINT自增ID
versionBIGINT
service_nameVARCHAR(255)服务名称,如myservice
addressVARCHAR(255)微服务对应的地址,一般为内部地址
date_createdDATETIME
last_updatedDATETIME

由于app在进行请求转发时会自动在请求头添加tenant和当前用户的信息,可以在拦截器里统一获取。参考grails-app/controllers/interceptor/TenantInterceptor.groovy中的示例代码:

/**
    内部应用和私有云应用如果使用了产品app服务的dynamic接口,则用下面的方法获取tenantId。否则使用公有云对接时的方法。
*/
def tenantParameter = request.getHeader(LogUtils.X_TENANT_ID)
if (!tenantParameter) {
    tenantParameter = params.x_tenant_id
    if (!tenantParameter) {
        return false
    }
}
try {
    Long tenantId = tenantParameter as Long
    currentTenant.set(tenantId)
} catch (NumberFormatException e) {
    log.error "invalid tenant id $tenantParameter"
    return false
}
return true
  1. 如果应用服务需要调用产品的接口,可以使用产品的openAPI或internalAPI。对于internalAPI的调用,应该使用产品的InternalAPI Gateway,尽量不要直接调用微服务内部的接口,否则后续产品升级容易造成接口的不兼容。

  2. 如果应用服务需要和产品进行大量的数据交换,API无法满足性能的情况下,可以共享产品的消息队列,请谨慎使用。

  3. 客户系统与产品的对接,可以通过应用服务进行集成,也可以直接使用产品的open API进行对接。

私有云的部署方式

私有云的应用服务可以和产品部署在同一个VPC中。应用服务承担定制化服务或与客户自有系统进行对接的任务。