SpringBoot Activiti6系列教程(四)-流程部署

說明

上一章節中,介紹瞭如何基於bpmn2.0的xml文件發起流程和獲取待辦,其中流程文件和代碼打包在一起,但實際項目中很少會把流程文件和代碼一起打包部署,這樣的話,每次流程更新或者發佈新流程都需要重新部署應用,因此我們制定了以下部署方案:

  • 提供流程部署接口,可以通過上傳流程文件對流程進行部署。
  • 如果流程文件沒有發生變化,不做新的部署,防止因爲重新部署導致版本號上升。

資源部署

activit部署資源文件需要通過RepositoryService創建一個deployment,通過該deployment進行資源的部署,不單單是bpmn流程文件,activiti可以部署任何文件。

上傳資源到activiti
@Service
public class DeploymentService {

    @Autowired
    private RepositoryService repositoryService;

    /**
     * deploy resource
     *
     * @param name resource name
     * @param fin  resource inputstream
     * @return
     */
    public String deploy(String name, InputStream fin) {
        String deploymentId = repositoryService.createDeployment()
                .addInputStream(name, fin)
                .name(name)
                .key(name)
                .deploy()
                .getId();
        return deploymentId;
    }
}

部署的時候指定部署的namekey,方便後續對部署進行進一步操作。

聲明restController
@RestController
public class DeploymentController {

    @Autowired
    private DeploymentService service;

    @PostMapping(value = "/deploy")
    public String deploy(@RequestParam("file") MultipartFile file) {
        try {
            return service.deploy(file.getOriginalFilename(), file.getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("upload failed");
        }
    }
}

這裏以文件名作爲部署的名稱,可以根據實際情況指定名稱。

測試(可以通過postman進行測試,這裏使用curl工具進行上傳測試)
curl -X POST -F '[email protected]' http://localhost:8080/deploy
25001

返回的25001就是部署id。

當執行deploy操作時,activiti後臺做了以下事

  • 在表ACT_RE_DEPLOYMENT創建一條記錄
  • 將資源存儲至表ACT_GE_BYTEARRAY,字段BYTES_存儲文件內容

流程部署

流程部署和資源部署一樣,但有一點需要注意,部署流程時,資源的名稱必須以bpmn20.xml或者bpmn結尾,否則activiti會當作普通資源上傳,你可以在controller上加個判斷避免用戶上錯錯誤文件。

 @PostMapping(value = "/deployBpmn")
public String deployBpmn(@RequestParam("file") MultipartFile file) {
    try {
        String name = file.getOriginalFilename();
        if (!name.endsWith(".bpmn20.xm") && !name.endsWith(".bpmn")) {
            name = name + ".bpmn";
        }
        return service.deploy(name, file.getInputStream());
    } catch (IOException e) {
        e.printStackTrace();
        throw new RuntimeException("upload failed");
    }
}

當部署流程後,activit後臺除了執行部署資源的動作外,還額外執行以下動作

  • 在表ACT_RE_PROCDEF上創建一條記錄,引用deployment_id

流程部署優化

以上我們實現了流程的部署,但每次部署都會導致流程版本遞增,我們的方案是如果文件不發生變化則不執行部署操作,保持流程版本好不變,不至於讓版本號升的太快,也節省系統資源。那麼我們需要完成以下兩個邏輯

  • 根據key查詢到最新的一次部署
  • 獲取最新的一次流程源文件
  • 因爲xml是文本文件,我們可以進行文本比對,如果內容一致就認爲版本不變

代碼如下:

/**
 * deploy resource
 *
 * @param name resource name
 * @param fin  resource inputstream
 * @return
 */
public String noChangeNoDeploy(String name, InputStream fin) {
    //獲取最新的一次部署
    Deployment latestDeployment = repositoryService.createDeploymentQuery()
            .deploymentName(name)
            .deploymentKey(name)
            .latest()
            .singleResult();
    String sbpmn = ActivitiUtil.text(fin);
    if (latestDeployment != null) {
        //檢測是否內容發生變化,只重新部署有修改的流程
        InputStream input = repositoryService.getResourceAsStream(latestDeployment.getId(), name);
        String dbpmn = ActivitiUtil.text(input);
        if (sbpmn.length() == dbpmn.length() && sbpmn.equals(dbpmn)) {
            return latestDeployment.getId();
        }
    }
    String deploymentId = repositoryService.createDeployment()
            .addString(name, sbpmn)
            .name(name)
            .key(name)
            .deploy()
            .getId();
    return deploymentId;
}

測試:

curl -X POST -F '[email protected]' http://localhost:8080/deployBpmn
27501                                                                                                                                             curl -X POST -F '[email protected]' http://localhost:8080/deployBpmn
27501        

可以看到,如果兩次內容一樣deployid不會改變

其他

除了通過addInputStream增加資源文件外,RepositoryService還提供了其他api進行資源的添加。如下

DeploymentBuilder addInputStream(String resourceName, InputStream inputStream);
DeploymentBuilder addClasspathResource(String resource);
DeploymentBuilder addString(String resourceName, String text);
DeploymentBuilder addBytes(String resourceName, byte[] bytes);
DeploymentBuilder addZipInputStream(ZipInputStream zipInputStream);
DeploymentBuilder addBpmnModel(String resourceName, BpmnModel bpmnModel);
本文所有代碼已經上傳至github,倉庫地址爲https://github.com/wls1036/springboot-activiti6-tutorial歡迎star
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章