공부/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에 저장하도록 수행
- 변경이 없으면 무시,