공부/Camunda

Camunda 수동적 배포 관리

726582776982 2024. 1. 1. 14:33
@Service("DeploymentService")
public class DeploymentServiceImpl extends AppContextManager
		implements DeploymentService {
	private static final Logger logger = LoggerFactory.getLogger(DeploymentServiceImpl.class);

	private final RuntimeService runtimeService;
	private final HistoryService historyService;
	private final RepositoryService repositoryService;

	@Autowired
	public DeploymentServiceImpl(RuntimeService runtimeService, HistoryService historyService,
			RepositoryService repositoryService) {
		this.runtimeService = runtimeService;
		this.historyService = historyService;
		this.repositoryService = repositoryService;
	}

	@PostConstruct
	public void initialize() {
		logger.info("[This Camunda BPMNFile Deploying]");

		Stream<Path> paths = null;
		String latestInstanceId = "";
        String filePathlocal = "C:/camunda/test"
		try {			
			
            //진행하던 Instance정보 저장
			List<String> resumeInstanceList = recoveryPreviousProcessDefinitions();
			//진행하던 Instance 삭제 및 진행여부 판단
			deletePreviousProcessDefinitions(resumeInstanceList);
            //사전 정의된 파일 패스정보를 변수에 저장
			TaSConstantDefVO filePath = filePathlocal;
			String bpmnDirectory = filePath.getConstantValue();

			// Get all BPMN files in the directory
			Path folderPath = Paths.get(bpmnDirectory);

			if (!Files.exists(folderPath)) 
			{
				Files.createDirectory(folderPath);
		        logger.info("Folder created successfully.");
			}
			
			paths = Files.list(folderPath);
			
            //bpmn파일 정보들 저장
			List<File> bpmnFiles = paths.filter(path -> path.toString().endsWith(".bpmn"))
										.map(Path::toFile)
										.collect(Collectors.toList());
			
			for (File bpmnFile : bpmnFiles) {
				// Read the BPMN file contents
				byte[] bpmnBytes = Files.readAllBytes(bpmnFile.toPath());
				// Check if a process with the same name is already deployed
				String processName = bpmnFile.getName().replaceAll("\\.bpmn$", "");
				
				ProcessDefinitionQuery processQuery = repositoryService.createProcessDefinitionQuery()
						.processDefinitionNameLike(processName);
				
				//해당 모델링의 프로세스모델이 정의 되어있는지 여부 확인.
				boolean processExists = processQuery.count() > 0;
				
				if(processExists)
				{
					ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery()
							.processDefinitionId(processQuery.latestVersion().singleResult().getId());
					
					
					if(processInstanceQuery.count()>0)
						latestInstanceId = processInstanceQuery.list().get(0).getProcessInstanceId();
				}
				
//				if(!resumeInstanceList.contains(latestInstanceId))
//				{
					// If the process is not deployed yet or the deployed process has a different
					// version, deploy the new process
					if (!processExists || isProcessDefinitionUpdated(processQuery, processName, new ByteArrayInputStream(bpmnBytes))) {
						Deployment deployment = repositoryService.createDeployment()
								.addInputStream(processName + ".bpmn", new ByteArrayInputStream(bpmnBytes)).deploy();
						
						logger.info(String.format("[Success deployment => %s ] ", deployment));
					}
//				}
//				else 
//				{
//					logger.info(String.format("[Resume Instnace => %s", latestInstanceId));
//					
//				}
				
			}
		} catch (IOException e) {
			logger.error("Error while deploying BPMN files", e);
		} catch (Exception e) {
			logger.error("Unexpected error while deploying BPMN files", e);
		} finally {
			if(paths != null)
			{
				paths.close();
			}
			
		}
	}

	private boolean isProcessDefinitionUpdated(ProcessDefinitionQuery processQuery, String processName, ByteArrayInputStream bpmnBytes) 
	{
        if (processQuery.count() == 0) {
            return true;
        }
        
        ProcessDefinition processDef = processQuery.processDefinitionKeyLike(processName).latestVersion().singleResult();
        if(CommonUtils.isNullOrEmpty(processDef))
    		return true;
        
        String processDefinitionId = processDef.getId();
        ByteArrayInputStream deployedBpmnBytes = (ByteArrayInputStream) repositoryService.getProcessModel(processDefinitionId);
        //길이가 다르면 true return
        if (deployedBpmnBytes.available() != bpmnBytes.available()) {
            return true;
        }
        int size = deployedBpmnBytes.available();
        byte[] buffer1 = new byte[size];
        byte[] buffer2 = new byte[size];
        deployedBpmnBytes.read(buffer1, 0, size);
        bpmnBytes.read(buffer2, 0, size);
        // 읽어들인 bpmnBytes가 최종버전과 동일하면 False return 
        return !Arrays.equals(buffer1, buffer2);
    }

	private void deletePreviousProcessDefinitions(List<String> resumeList) 
	{	
        // Delete all running process instances
        runtimeService.createProcessInstanceQuery().list()
                .forEach(instance -> {
                    try {
                    	if(!resumeList.contains(instance.getId()))
                    		runtimeService.deleteProcessInstance(instance.getId(), "Deleting previous process definition", true, true, true, true);
                    } catch (Exception e) {
                        logger.error(String.format("Error while deleting process instance %s", instance.getId()), e);
                    }
                });
	}	
}

 

 

개요 (코드 정보는 일부입니다.)

  • 전제조건, 
    • 서버 가동시 수행되는 로직
    • 진행중인 Instance 확인
      • 해당인스턴스 판단 ( 삭제, 진행 )
    • 지정 경로에 BPMN파일 수집
    • 각 파일들에 대한 업데이트 정보와 Engine 규격 ( camunda규격 ) 에 맞는 xml정보들인지 판단
    • 만일 진행중인 instance의 모델링정보가 변경이 있는 경우 판단
      • 변경이 있으면 Instance삭제 
    • 가장 최신정보와 변경점이 있는지 비교
      • 변경이 있으면, 변경된 파일을 최신버전으로 DB에 저장하도록 수행
      • 변경이 없으면 무시,