Skip to content

Commit baa5970

Browse files
committed
modify appjoint implement doc
1 parent 8fb5ac0 commit baa5970

File tree

1 file changed

+131
-11
lines changed

1 file changed

+131
-11
lines changed

docs/zh_CN/ch4/第三方系统接入DSS指南.md

Lines changed: 131 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,28 +31,142 @@
3131
        NodeService是用来解决用户在DSS提交的任务在第三方系统生成相应的任务的问题。用户如果在DSS系统的工作流中新建了一个工作流节点并进行任务的编辑,第三方系统需要同步感知到
3232
- 4.getNodeExecution
3333

34-
        NodeExecution接口是用来将任务提交到第三方系统进行执行的接口,NodeExecution接口有支持短时间任务的NodeExecution和支持长时间任务的LongTermNodeExecution。一般短时间任务,如邮件发送等,可以直接实现NodeExecution接口,并重写execute方法,DSS系统同步等待任务结束。另外的长时间任务,如数据质量检测等,可以实现LongTermNodeExecution接口,并重写submit方法,返回一个NodeExecutionAction,DSS系统通过这个NodeExecutionAction可以向第三方系统获取任务的日志、状态等。
34+
        NodeExecution接口是用来将任务提交到第三方系统进行执行的接口,NodeExecution
35+
接口有支持短时间任务的NodeExecution和支持长时间任务的LongTermNodeExecution。一般短时间任务,如邮件发送等,可以直接实现NodeExecution接口,并重写execute方法,DSS系统同步等待任务结束。另外的长时间任务,如数据质量检测等,可以实现LongTermNodeExecution接口,并重写submit方法,返回一个NodeExecutionAction,DSS系统通过这个NodeExecutionAction可以向第三方系统获取任务的日志、状态等。
3536

3637
#### 3.第三方系统接入DSS的实现(以Visualis为例)
3738

38-
        Visualis是微众银行WeDataSphere开源的一款商业BI工具,DSS集成Visualis系统之后可以获得数据可视化的能力。Visualis接入DSS系统的代码在DSS项目中已经同步开源,下面将以开源代码为例,对步骤进行罗列分析。
39+
        Visualis是微众银行WeDataSphere开源的一款商业BI工具,DSS集成Visualis系统之后可以获得数据可视化的能力。
40+
Visualis接入DSS系统的代码在DSS项目中已经同步开源,下面将以开源代码为例,对步骤进行罗列分析。
3941
Visualis接入的DSS系统的步骤如下:
4042

4143
**3.1.Visualis实现AppJoint接口**
4244

43-
        Visualis实现的 AppJoint接口的实现类是VisualisAppjoint。查看VisualisAppjoint的代码可知,它在init方法时候,初始化了自己实现的SecurityService、 NodeService以及NodeExecution。
45+
        Visualis实现的 AppJoint接口的实现类是VisualisAppjoint。查看VisualisAppjoint的代码可知,它在init方法时候,
46+
初始化了自己实现的SecurityService、 NodeService以及NodeExecution。
47+
```java
48+
public void init(String baseUrl, Map<String, Object> params) {
49+
securityService = new VisualisSecurityService();
50+
securityService.setBaseUrl(baseUrl);
51+
nodeExecution = new VisualisNodeExecution();
52+
nodeExecution.setBaseUrl(baseUrl);
53+
nodeService = new VisualisNodeService();
54+
nodeService.setBaseUrl(baseUrl);
55+
}
56+
```
4457

4558
**3.2.Visualis实现SecurtyService接口**
4659

47-
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Visualis实现的SecurityService接口的类名是VisualisSecurityService,并重写了login方法,为了能够进行授权登陆,Visualis采用了提供token的方式,DSS的网关对该token进行授权,这样就能够做到用户鉴权。
60+
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Visualis实现的SecurityService接口的类名是VisualisSecurityService,
61+
并重写了login方法,为了能够进行授权登陆,Visualis采用了提供token的方式,DSS的网关对该token进行授权,这样就能够做到用户鉴权。
62+
63+
```java
64+
public class VisualisSecurityService extends AppJointUrlImpl implements SecurityService {
65+
@Override
66+
public Session login(String user) throws AppJointErrorException {
67+
VisualisSession visualisSession = new VisualisSession();
68+
visualisSession.setUser(user);
69+
visualisSession.getParameters().put("Token-User",user);
70+
visualisSession.getParameters().put("Token-Code","172.0.0.1");
71+
return visualisSession;
72+
}
73+
74+
@Override
75+
public void logout(String user) {
76+
77+
}
78+
}
79+
```
4880

4981
**3.3.Visualis实现的NodeService接口**
5082

51-
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Visualis实现的NodeService接口的类是VisualisNodeService,并重写了createNode,deleteNode和updateNode三个方法,这三个方法是进行在第三方系统同步生成任务元数据。例如createNode方法是通过调用visualis的HTTP接口在Visualis系统生成同一工程下面的Visualis任务。
83+
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Visualis实现的NodeService接口的类是VisualisNodeService,并重写了createNode,
84+
deleteNode和updateNode三个方法,这三个方法是进行在第三方系统同步生成任务元数据。例如createNode方法是通过调用visualis的HTTP接口在Visualis系统生成同一工程下面的Visualis任务。
85+
86+
```java
87+
@Override
88+
public Map<String, Object> createNode(Session session, AppJointNode node,
89+
Map<String, Object> requestBody) throws AppJointErrorException {
90+
if (DisplayNodeService.getNodeType().equals(node.getNodeType())) {
91+
return DisplayNodeService.createNode(session, getBaseUrl(), String.valueOf(node.getProjectId()), node.getNodeType(), requestBody);
92+
} else if (DashboardNodeService.getNodeType().equals(node.getNodeType())) {
93+
return DashboardNodeService.createNode(session, getBaseUrl(), String.valueOf(node.getProjectId()), node.getNodeType(), requestBody);
94+
} else {
95+
throw new AppJointErrorException(42002, "cannot recognize the nodeType " + node.getNodeType());
96+
}
97+
}
98+
99+
@Override
100+
public void deleteNode(Session session, AppJointNode node) throws AppJointErrorException {
101+
if (DisplayNodeService.getNodeType().equals(node.getNodeType())) {
102+
DisplayNodeService.deleteNode(session, getBaseUrl(), String.valueOf(node.getProjectId()), node.getNodeType(), node.getJobContent());
103+
} else if (DashboardNodeService.getNodeType().equals(node.getNodeType())) {
104+
DashboardNodeService.deleteNode(session, getBaseUrl(), String.valueOf(node.getProjectId()), node.getNodeType(), node.getJobContent());
105+
} else {
106+
throw new AppJointErrorException(42002, "cannot recognize the nodeType " + node.getNodeType());
107+
}
108+
}
109+
110+
@Override
111+
public Map<String, Object> updateNode(Session session, AppJointNode node,
112+
Map<String, Object> requestBody) throws AppJointErrorException {
113+
if (DisplayNodeService.getNodeType().equals(node.getNodeType())) {
114+
return DisplayNodeService.updateNode(session, getBaseUrl(), node.getProjectId(), node.getNodeType(), requestBody);
115+
} else if (DashboardNodeService.getNodeType().equals(node.getNodeType())) {
116+
return DashboardNodeService.updateNode(session, getBaseUrl(), node.getProjectId(), node.getNodeType(), requestBody);
117+
} else {
118+
throw new AppJointErrorException(42002, "cannot recognize the nodeType " + node.getNodeType());
119+
}
120+
}
121+
```
52122

53123
**3.4.Visualis实现NodeExecution接口**
54124

55-
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Visualis实现的NodeExecution接口的类是VisualisNodeExecution,并重写了execute方法,该方法传入的两个参数为Node和NodeContext,从NodeContext中我们可以拿到用户、DSS的网关地址,还有网关验证的Token。通过这些,我们可以封装成一个HTTP的请求发送到第三方系统Visualis并从Visualis获取响应结果,NodeContext提供写入结果集的方法,如Visualis的结果集一般是以图片的形式展示,在execute方法的最后,Visualis通过nodeContext获取到一个支持图片写入的PictureResultSetWriter方法,并将结果集进行写入。
125+
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Visualis实现的NodeExecution接口的类是VisualisNodeExecution,并重写了execute方法,
126+
该方法传入的两个参数为Node和NodeContext,从NodeContext中我们可以拿到用户、DSS的网关地址,还有网关验证的Token。
127+
通过这些,我们可以封装成一个HTTP的请求发送到第三方系统Visualis并从Visualis获取响应结果,NodeContext提供写入结果集的方法,
128+
如Visualis的结果集一般是以图片的形式展示,在execute方法的最后,Visualis通过nodeContext获取到一个支持图片写入的PictureResultSetWriter方法,并将结果集进行写入。
129+
```scala
130+
override def execute(node: AppJointNode, nodeContext: NodeContext, session: Session): NodeExecutionResponse = node match {
131+
case commonAppJointNode: CommonAppJointNode =>
132+
val appJointResponse = new CompletedNodeExecutionResponse()
133+
val idMap = commonAppJointNode.getJobContent
134+
val id = idMap.values().iterator().next().toString
135+
val url = if(commonAppJointNode.getNodeType.toLowerCase.contains(DISPLAY)) getDisplayPreviewUrl(nodeContext.getGatewayUrl, id)
136+
else if(commonAppJointNode.getNodeType.toLowerCase.contains(DASHBOARD)) getDashboardPreviewUrl(nodeContext.getGatewayUrl, id)
137+
else {
138+
appJointResponse.setIsSucceed(false)
139+
appJointResponse.setErrorMsg("不支持的appJoint类型:" + node.getNodeType)
140+
return appJointResponse
141+
}
142+
var response = ""
143+
val headers = nodeContext.getTokenHeader(nodeContext.getUser)
144+
nodeContext.appendLog(LogUtils.generateInfo(s"Ready to download preview picture from $url."))
145+
Utils.tryCatch(download(url, null, headers.toMap,
146+
input => Utils.tryFinally{
147+
val os = new ByteArrayOutputStream()
148+
IOUtils.copy(input, os)
149+
response = new String(Base64.getEncoder.encode(os.toByteArray))
150+
//response = IOUtils.toString(input, ServerConfiguration.BDP_SERVER_ENCODING.getValue)
151+
}(IOUtils.closeQuietly(input)))){ t =>
152+
val errException = new ErrorException(70063, "failed to do visualis request")
153+
errException.initCause(t)
154+
appJointResponse.setException(errException)
155+
appJointResponse.setIsSucceed(false)
156+
appJointResponse.setErrorMsg(s"用户${nodeContext.getUser}请求Visualis失败!URL为: " + url)
157+
return appJointResponse
158+
}
159+
nodeContext.appendLog(LogUtils.generateInfo("Preview picture downloaded, now ready to write results."))
160+
val imagesBytes = response
161+
val resultSetWriter = nodeContext.createPictureResultSetWriter()
162+
Utils.tryFinally{
163+
resultSetWriter.addMetaData(new LineMetaData())
164+
resultSetWriter.addRecord(new LineRecord(imagesBytes))
165+
}(IOUtils.closeQuietly(resultSetWriter))
166+
appJointResponse.setIsSucceed(true)
167+
appJointResponse
168+
}
169+
```
56170

57171
**3.5.数据库内容的更新(dss-application模块)**
58172

@@ -66,7 +180,7 @@ Visualis接入的DSS系统的步骤如下:
66180
| url | 10 |http://127.0.0.1:8080 |
67181
| is_user_need_init | 是否需要用户初始化 | 默认否 |
68182
| user_init_url | 用户初始化url | 默认空 |
69-
| exists_project_service | 是否存在自己的projectService服务, 存在的话要自己写appjoint实现projectService0 | |
183+
| exists_project_service | 是否存在自己的projectService服务, 存在的话要自己写appjoint实现projectService | |
70184
| enhance_json | 加强json,在appjoint初始化的时候会作为map进行传入 | |
71185
| homepage_url | 接入的系统主页url | |
72186
| direct_url | 接入的系统重定向url | |
@@ -97,19 +211,25 @@ Visualis接入的DSS系统的步骤如下:
97211
**3.6.前端的修改**
98212

99213
- 3.6.1 增加节点类型
100-
修改src/js/service/nodeType.js文件,增加Qualitis节点类型
214+
修改src/js/service/nodeType.js文件,增加Visualis节点类型
101215
- 3.6.2 增加节点图标
102216
将节点图标复制到src/js/module/process/images/路径下,目前只支持SVG格式。
103217
- 3.6.3 新增节点配置
104-
修改src/js/module/process/shape.js文件,增加Qualitis的节点配置信息
218+
修改src/js/module/process/shape.js文件,增加Visualis的节点配置信息
105219
- 3.6.4 修改首页单击节点事件
106220
修改src/js/module/process/index.vue文件,增加节点单击事件以及单击事件的处理逻辑。
107221
- 3.6.5 修改工作流节点双击事件
108222
修改src/js/view/process/index.vue以及src/js/module/process/index.vue,增加节点双击事件以及双击事件的处理逻辑。
109223

110224
**3.7.编译打包成jar包放置到指定位置**
111225

112-
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;实现了上述的接口之后,一个AppJoint就已经实现了。打包之后,需要放置到指定的位置。jar包需要放置到dss-server和linkis-appjoint-entrance两个微服务中,以linkis-appjoint-entrance 为例(dss-server与linkis-appjoint-entrance一致),在linkis-appjont-entrance下面的lib的同级目录有一个appjoints目录,目录下面层次如图3-3所示。
226+
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;实现了上述的接口之后,一个AppJoint就已经实现了。打包之后,需要放置到指定的位置。
227+
jar包需要放置到dss-server和linkis-appjoint-entrance两个微服务中,以linkis-appjoint-entrance 为例(dss-server与linkis-appjoint-entrance一致),
228+
在linkis-appjont-entrance下面的lib的同级目录有一个appjoints目录,目录下面层次如图3-3所示。
113229
![appjoints目录示例](/images/zh_CN/chapter4/appjoints.png)<br>
114230
图3-3 appjoints目录示例
115-
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在appjoints目录下面新建一个visualis目录。visualis目录下面要求有lib目录,lib目录存放的是visualis在实现VisualisAppJoint的编译的jar包,当然如果有引入dss系统没有带入的jar包,也需要放置到lib目录中,如sendemail Appjoint需要发送邮件功能的依赖包,所以需要将这些依赖包和已经实现的jar包统一放置到lib目录中。另外可以将本AppJoint所需要的一些配置参数放置到appjoints.properties,DSS系统提供的AppJointLoader会将这些配置的参数读取,放置到一个Map中,在AppJoint调用init方法的时候传入。
231+
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在appjoints目录下面新建一个visualis目录。
232+
visualis目录下面要求有lib目录,lib目录存放的是visualis在实现VisualisAppJoint的编译的jar包,
233+
当然如果有引入dss系统没有带入的jar包,也需要放置到lib目录中,如sendemail Appjoint需要发送邮件功能的依赖包,
234+
所以需要将这些依赖包和已经实现的jar包统一放置到lib目录中。
235+
另外可以将本AppJoint所需要的一些配置参数放置到appjoints.properties,DSS系统提供的AppJointLoader会将这些配置的参数读取,放置到一个Map中,在AppJoint调用init方法的时候传入。

0 commit comments

Comments
 (0)