Activiti BPMN 프로세스 정의 관리 핵심 기법

프로세스 정의 배포

Activiti 엔진 초기화 시 classpathactiviti.cfg.xml을 자동으로 로드합니다. ProcessEngine에서 RepositoryService를 획득한 뒤 DeploymentBuilder를 통해 배포 설정을 구성합니다.

리소스 로딩 방식

단일 파일 로딩:

DeploymentBuilder builder = repositoryService.createDeployment();
builder.addClasspathResource("processes/orderApproval.bpmn");
builder.addClasspathResource("processes/orderApproval.png");

ZIP 아카이브 로딩:

InputStream zipStream = getClass().getClassLoader()
    .getResourceAsStream("packages/processBundle.zip");
ZipInputStream zis = new ZipInputStream(zipStream);
builder.addZipInputStream(zis);

ZIP 압축 시 폴더 구조 없이 bpmn/png 파일을 루트에 배치해야 합니다.

배포 예시

@Test
public void deployWorkflow() {
    RepositoryService repoSvc = engine.getRepositoryService();
    
    DeploymentBuilder deployBuilder = repoSvc.createDeployment()
        .name("주문 승인 프로세스");
    
    // ZIP 방식 적용
    InputStream archive = this.getClass().getClassLoader()
        .getResourceAsStream("archives/orderFlow.zip");
    deployBuilder.addZipInputStream(new ZipInputStream(archive));
    
    Deployment result = deployBuilder.deploy();
    
    System.out.println("배포 ID: " + result.getId());
    System.out.println("배포명: " + result.getName());
}

배포 영향 테이블

테이블설명
act_re_deployment배포 메타정보 저장, 배포 시마다 신규 레코드 추가
act_re_procdef프로세스 정의 속성, 동일 key 배포 시 버전 자동 증가
act_ge_bytearray바이너리 리소스 저장 (bpmn, 이미지)
act_ge_propertynext.dbid 기반 고유 ID 생성 전략 관리

프로세스 정의 조회

ProcessDefinitionQuery를 활용한 상세 검색:

@Test
public void queryProcessDefinitions() {
    RepositoryService repoSvc = engine.getRepositoryService();
    
    ProcessDefinitionQuery query = repoSvc.createProcessDefinitionQuery()
        .orderByProcessDefinitionVersion().asc();
    
    // 필터링 옵션
    // .deploymentId("5001")
    // .processDefinitionKey("orderFlow")
    // .processDefinitionNameLike("%승인%");
    
    List<ProcessDefinition> definitions = query.list();
    
    for (ProcessDefinition def : definitions) {
        System.out.println("정의 ID: " + def.getId());           
        // 형식: {key}:{version}:{generated-id}
        System.out.println("프로세스명: " + def.getName());        
        // bpmn의 name 속성
        System.out.println("키: " + def.getKey());                
        // bpmn의 id 속성
        System.out.println("버전: " + def.getVersion());          
        // 동일 key 재배포 시 자동 증가
        System.out.println("BPMN 파일: " + def.getResourceName());
        System.out.println("이미지 파일: " + def.getDiagramResourceName());
        System.out.println("배포 ID: " + def.getDeploymentId());
    }
}

프로세스 정의 삭제

일반 삭제는 실행 중인 인스턴스가 없을 때만 가능하며, 강제 삭제는 cascade 옵션으로 처리합니다:

@Test
public void removeDefinition() {
    String deployId = "15001";
    RepositoryService svc = engine.getRepositoryService();
    
    // 일반 삭제: 미실행 프로세스만 가능
    // svc.deleteDeployment(deployId);
    
    // 강제 삭제: 실행 중인 인스턴스 포함 전체 제거
    svc.deleteDeployment(deployId, true);
}

프로세스 이미지 리소스 추출

@Test
public void extractDiagram() throws IOException {
    RepositoryService svc = engine.getRepositoryService();
    String deployId = "1";
    
    // 배포된 전체 리소스명 조회
    List<String> resourceNames = svc.getDeploymentResourceNames(deployId);
    
    String imageName = resourceNames.stream()
        .filter(name -> name.endsWith(".png"))
        .findFirst()
        .orElseThrow();
    
    InputStream imageStream = svc.getResourceAsStream(deployId, imageName);
    
    // 파일로 저장
    Path target = Paths.get("/tmp/export", imageName);
    Files.copy(imageStream, target, StandardCopyOption.REPLACE_EXISTING);
}

최신 버전 프로세스 조회

버전 기준 정렬 후 LinkedHashMap으로 덮어쓰기 방식 적용:

@Test
public void fetchLatestVersions() {
    List<ProcessDefinition> allDefs = engine.getRepositoryService()
        .createProcessDefinitionQuery()
        .orderByProcessDefinitionVersion().asc()
        .list();
    
    Map latestMap = new LinkedHashMap<>();
    for (ProcessDefinition def : allDefs) {
        latestMap.put(def.getKey(), def);  // 동일 key는 상위 버전으로 대체
    }
    
    Collection<ProcessDefinition> latestOnly = latestMap.values();
    latestOnly.forEach(def -> {
        System.out.printf("키: %s, 버전: %d, ID: %s%n", 
            def.getKey(), def.getVersion(), def.getId());
    });
}

특정 키 전 버전 일괄 삭제

@Test
public void purgeByProcessKey() {
    String targetKey = "orderFlow";
    
    List<ProcessDefinition> versions = engine.getRepositoryService()
        .createProcessDefinitionQuery()
        .processDefinitionKey(targetKey)
        .list();
    
    RepositoryService repo = engine.getRepositoryService();
    for (ProcessDefinition version : versions) {
        repo.deleteDeployment(version.getDeploymentId(), true);
    }
}

태그: Activiti BPMN Workflow ProcessEngine RepositoryService

7월 10일 18:39에 게시됨