背景
之前已简单使用ES及Kibana和在线转Base64工具实现了检索文档的demo,预期建设方案是使用触发器类型从公共的文档源拉取最新的文件,然后调用Java将文件转Base64后入ES建索引,再提供封装接口给前端做查询之用。
由于全部内容过长,为了便于阅读,按照大的章节分为三部分,第一部分讲述基于WebHook的触发机制怎么搭建,包含全部实现细节!
使用Git Hook获取文件变化
我们内部使用了GitBucket,因此方案采用它的WebHook功能来实现。
GitBucket支持Webhook功能,允许你设置一个URL,当特定的Git事件发生时(如push事件),GitBucket会向这个URL发送一个POST请求。
这个功能可以在【设置】-【Service Hooks】找到!
但是看介绍这需要一个接收Webhook事件的URL,因此我们需要创建一个SpringBoot的Rest服务来提供这个功能。
SpringBoot脚手架
使用阿里云脚手架创建初始化项目:https://start.aliyun.com/
创建一个hello world接口:
@GetMapping("/hello")
public String hello() { // 获取当前日期和时间 LocalDateTime dateTime = LocalDateTime.now(); // 定义日期和时间格式 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); return "Welcome! Now is:" + dateTime.format(formatter) + "\n";
}
启动应用进行冒烟测试,使用浏览器访问:http://localhost:8080/hello
返回:Welcome! Now is:2024-03-05 15:45:57
完美!
上述测试成功后,创建一个Webhook的测试接口,代码如下:
package com.es.file.search; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController; @RestController
public class MyController { @PostMapping("/gitbucket/webhook") public ResponseEntity<?> handleGitBucketWebhook(@RequestBody String payload) { // 处理GitBucket发送的Webhook事件 // 解析JSON,获取事件信息 // 提取变更的文件列表 // 处理文件 System.out.println(payload); return ResponseEntity.ok().build(); }
}
测试一下接口,使用后台curl命令发送请求:
curl -XPOST -H "Content-Type: application/json" -d '{"key1":"value1", "key2":"value2"}' http://localhost:8080/gitbucket/webhook
上述命令发送后,后台打印:
至此本地的测试Rest接口已经大功告成了。
Hook实测
登录到GitBucket,打开想监控的仓库设置,找到Webhook部分并添加一个新的Webhook:
- Payload URL: 填写你的服务接收Webhook事件的URL,就是上面的测试接口。
- Content type: 选择
application/json
。 - Events: 选择
push
,这样只有当有新的提交推送到仓库时,你的服务才会收到通知。 - Active: 确保这个Webhook是激活状态。
上面第一个参数的url填好之后,它右侧直接就有一个测试按钮,点击测试通过的结果是这样的(注意响应码是200):
然后我们给仓库推送一个更新,看看打印的内容是什么。
格式化打印
在此之前我们先做一个json格式化的操作,以免打印的内容过长无法阅读。
首先引入一个新的依赖:
<dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20210307</version>
</dependency>
然后打印的代码修改如下:
import org.json.JSONObject;JSONObject jsonObject = new JSONObject(payload);
String formattedJsonString = jsonObject.toString(4);
System.out.println(formattedJsonString);
重启应用。
我在后台push了一条变更之后,应用立即收到更新消息,Server端的打印截图:
WebHook发送消息体内容较多,至少包含了该提交增删改查的信息,如removed
表示删除了哪些内容,added
额度表示新增了哪些文件,我们可以重点关注added
和modified
,针对新增和修改的内容进行进一步的处理。
下一步动作
总体思路,基于前面已经搭建的WebHook触发流程,接收到push更新消息之后,使用本地的git工具拉取最新变动。这些文件与我们的ES应用在同一台机器上,然后Java可以读取这些文件转码并交给ES处理。