상단

BPM 솔루션인 JBoss jBPM을 정리 한다.

 

Eclipse 모델링 환경 구축


JBoss jBPM에 jpdl을 모델링하기 위한 Eclipse 모델링 환경을 구축해 보자.

 
  • 다운로드 사이트에서 jbpm-4.3.zip 을 다운로드 하여 c:/zzdir/ 폴더 아래에 압축을 풀어 둔다.

  • Eclipse에 GPD plugin을 설치 한다.

    • Eclipse에서 "Help -> Install New Software..." 메뉴를 선택 한다.

    • "Add..." 버튼을 누른 후 "Archive..." 버튼을 눌러 c:/zzdir/jbpm-4.3/install/src/gpd/jbpm-gpd-site.zip 파일을 선택 한다.

    • "OK" 버튼을 누르고, 목록에 표시된 것을 모두 선택한 후 설치 한다.

     
  • Eclipse에 jBPM 실행환경을 설정 한다.

    • "Window -> Preferences -> JBoss jBPM -> jBPM 4 --> Runtime Locations" 메뉴를 선택 한다.

    • "Add..." 버튼을 눌러 다음과 같이 등록 한다.

      • Name : "jbpm-4.0"

      • Location : "c:/zzdir/jbpm-4.3"

     
  • Eclipse에 jBPM 사용자 라이브러리를 등록 한다.

    • "Window -> Preferences -> Java -> Build Path -> User Libraries" 메뉴를 선택 한다.

    • "New..." 버튼을 선택한 후 User library name에 "jBPM Libraries"을 입력한 후 "OK" 버튼을 누른다.

    • "jBPM Libraries"을 선택한 후 "Add JARs..." 버튼을 눌러 jBPM에 c:/zzdir/jbpm-4.3/lib/ 폴더에 있는 모든 jar 파일을 등록 한다.

    • "jBPM Libraries"을 선택한 후 "Add JARs..." 버튼을 눌러 jBPM에 c:/zzdir/jbpm-4.3/jbpm.jar 파일을 등록 한다.

     
  • Eclipse에 jPDL 4 schema를 등록 한다.

    • "Window -> Preferences -> XML -> XML Catalog" 메뉴를 선택 한다.

    • "Add..." 버튼을 누른 후 "File System..." 버튼을 눌러 c:/zzdir/jbpm-4.3/src/jpdl-4.0.xsd 파일을 선택하여 등록 한다.

 
 

jBPM Command Line 실행 환경 구축


JBoss jBPM을 실행하기 위한 환경을 구축해 보자.

 
  • 다운로드 사이트에서 jbpm-4.3.zip 을 다운로드 하여 c:/zzdir/ 폴더 아래에 압축을 풀어 둔다.

  • Eclipse에서 jBPM 이라는 Java Project를 생성 한다. 앞으로 jBPM 프로젝트의 홈 디렉토리를 $JBPM_HOME 이라 한다.

  • [Eclipse 모델링 환경 구축](JBPM.md#Eclipse 모델링 환경 구축.md)에서 생성한 "jBPM Libraries"를 Java Build Path에 아래와 같이 등록 한다.

    • "jBPM"을 선택한 후 오른쪽 마우스를 눌러 "Properties" 메뉴을 선택 한다.

    • "Java Build Path -> Libraries -> Add Library..."를 선택 한다.

    • "User Library"를 선택한 후 "jBPM Libraries"를 선택하여 등록 한다.

     
  • $JBPM_HOME/src/jbpm.cfg.xml 파일을 생성 한다.

 
 
 
   
   
   
   
 
 
  • $JBPM_HOME/src/jbpm.hibernate.cfg.xml 파일을 생성 한다.

    • Database에 대한 접속 정보를 관리 한다. 여기서는 HSQLDB의 메모리 DB를 사용 한다.

 
 
 
 
 
   
      org.hibernate.dialect.HSQLDialect
      org.hsqldb.jdbcDriver
      jdbc:hsqldb:mem:.
      sa
      
      
      create-drop
      true
      
      
      
      
      
      
   
 

  • 자 여기까지 진행이 되었으면 JBoss jBPM을 실행할 환경의 구성은 완료 되었다. JBoss jBPM에서도 HelloWrold를 만들어 정상적으로 동작하는지 확인해 보자.

  • $JBPM_HOME/src/printHelloWorld.jpdl.xml 파일을 생성 한다.

    • JBoss jBPM에서 실행할 프로세스 정의 파일을 생성 한다.

 
 
 
 	
 		
 	
 	
 		
 	 
 	
 
 
  • $JBPM_HOME/src/com/jopenbusiness/jbpm/cli/Printer.java 파일을 생성 한다.

 
``` package com.jopenbusiness.jbpm.cli;

import java.io.BufferedWriter; 
import java.io.File; import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date;

import org.jbpm.api.Configuration; 
import org.jbpm.api.ExecutionService; import org.jbpm.api.ProcessEngine; import org.jbpm.api.RepositoryService;

//--- http://www.javaplex.com/blog/getting-started-with-jbpm/ 
public class Printer { //--- http://docs.jboss.com/jbpm/v4/userguide/html_single/#services 
public static void main(String args) { 
ProcessEngine processEngine = null; RepositoryService repositoryService = null; ExecutionService executionService = null;

 
		processEngine = new Configuration().setResource("jbpm.cfg.xml").buildProcessEngine();
		repositoryService = processEngine.getRepositoryService();
		executionService = processEngine.getExecutionService();
		
		repositoryService.createDeployment().addResourceFromClasspath("printHelloWorld.jpdl.xml").deploy();
		executionService.startProcessInstanceByKey("helloWorld");
	}
	
    //--- JBoss jBPM의 프로세스 정의 파일에 정의되어 호출되는 함수
	public void printHelloWorld() {
		File tmpFile = null;
		BufferedWriter out = null; 
		SimpleDateFormat formatDate = null;

		tmpFile = new File("c:/jbpm.out");
		try {
			formatDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			out = new BufferedWriter(new FileWriter(tmpFile));
			out.append("jBPM: printHelloWorld - " + formatDate.format(new Date()));
		} catch (FileNotFoundException e) { 
		    e.printStackTrace();
		} catch (IOException e) {
		    e.printStackTrace();
		} finally {
		    if (out != null) {
		        try {
		        	out.close();
		        } catch (IOException e) {
		            e.printStackTrace();
		        }
		    }
		    out = null;
		}
	}

}


  
- 작성된 Print.java를 실행하여 c:/jbpm.out 파일이 잘 생성 되는지 확인해 보자.  
  - Eclipse에서 Print.java를 선택한 후 오른쪽 마우스를 누른다.  
  - "Run AS -> 2 Java Application" 메뉴을 선택 한다.  
  - c:/jbpm.out 파일이 잘 생성 되었는지 확인 한다.  
  

## 사용자 가이드

### jBPM service API
{|cellspacing="0" cellpadding="2" border="1" width="100%" bgcolor="#FFFFFF" align="center"
|-
|width="30%" align="center" style="color:#15470a; background-color:#91ce5c;"|RepositoryService
|width="70%"|
- 프로세스 정의 데이터를 관리  
- JPDL로 정의된 프로세스를 등록할 수 있음  
|-
|align="center" style="color:#15470a; background-color:#91ce5c;"|IdentityService
|
- User와 Group 관리  
|-
|align="center" style="color:#15470a; background-color:#91ce5c;"|ExecutionService
|
- 프로세스 실행 및 관리  
- 실행되고 있는 Process Instance 목록 등을 제공  
|-
|align="center" style="color:#15470a; background-color:#91ce5c;"|TaskService
|
- 프로세스의 각 단위 작업을 관리  
- 사용자에 의해서 실행되는 Task를 관리하는 서비스  
- Process Instance에서 사용자별로 할당된 Task 목록 등을 제공  
|-
|align="center" style="color:#15470a; background-color:#91ce5c;"|HistoryService
|
- 프로세스의 실행 내역 관리  
|-
|align="center" style="color:#15470a; background-color:#91ce5c;"|ManagementService
|
- jBPM을 관리하기 위해서 jBPM 관리 콘솔에서 사용하는 서비스  
|}
  

### RepositoryService

import org.jbpm.api.Configuration; 
import org.jbpm.api.ProcessEngine; import org.jbpm.api.RepositoryService;

ProcessEngine processEngine = null; 
RepositoryService repositoryService = null; String deploymentId = null;

processEngine = new Configuration().setResource("jbpm.cfg.xml").buildProcessEngine(); 
repositoryService = processEngine.getRepositoryService();

//--- jPDL deploy 
deploymentId = repositoryService.createDeployment().addResourceFromClasspath("printHelloWorld.jpdl.xml").deploy(); //--- repositoryService.deleteDeployment(deploymentId);

  

### IdentityService

import org.jbpm.api.IdentityService;

IdentityService identityService = processEngine.getIdentityService();

identityService.createGroup("sales-dept");

identityService.createUser("johndoe", "firstName", "lastName", "email"); 
identityService.createMembership("johndoe", "sales-dept");

identityService.createUser("joesmoe", "joesmoe", "Joe", "Smoe"); 
identityService.createMembership("joesmoe", "sales-dept");

  

//--- groupid를 반환 한다. 
String createGroup(String groupName); String createGroup(String groupName, String groupType) String createGroup(String groupName, String groupType, String parentGroupId);

  

### ExecutionService

#### ExecutionService

import org.jbpm.api.ExecutionService; 
import org.jbpm.api.ProcessInstance;

//--- Process 관리 
ExecutionService executionService = null; ProcessInstance processInstance = null; String pid = null;

executionService = processEngine.getExecutionService();

Map<String,Object> variables = new HashMap<String,Object>(); 
variables.put("customer", "홍길동"); //--- jpdl에서 #{customer} 라는 이름으로 지정 가능 variables.put("type", "Accident"); variables.put("amount", new Float(283.2));

//--- Start new process 
//--- processInstance = executionService.startProcessInstanceByKey("hello"); processInstance = executionService.startProcessInstanceById("hello-1", variables); pid = processInstance.getId();

  

#### State

Execution executionInA = processInstance.findActiveExecutionIn("a"); 
assertNotNull(executionInA); processInstance = executionService.signalExecutionById(executionInA.getId());

processInstance = executionService.signalExecutionById(executionId, "accept");

  

#### Decision
- 사례 1  

Map<String, Object> variables = new HashMap<String, Object>(); 
variables.put("content", "good"); ProcessInstance processInstance = executionService.startProcessInstanceByKey("DecisionConditions", variables); assertTrue(processInstance.isActive("submit document"));

  
- 사례 2  

Map<String, Object> variables = new HashMap<String, Object>(); 
variables.put("content", "good"); ProcessInstance processInstance = executionService.startProcessInstanceByKey("DecisionExpression", variables);

  
- 사례 3  

public class ContentEvaluation implements DecisionHandler { 
public String decide(OpenExecution execution) { String content = (String) execution.getVariable("content"); if (content.equals("you're great")) { return "good"; } if (content.equals("you gotta improve")) { return "bad"; } return "ugly"; } }

  

#### sub-process
- 사례 1  

<sub-process name="review" sub-process-key="SubProcessReview"> 
 
 
 
</sub-process>

```
  • 사례 2

 
 <sub-process name="review"
               sub-process-key="SubProcessReview"
               outcome="#{result}">
    
    
    
  </sub-process>
 
  • 사례 3

 
 <sub-process name="review"
               sub-process-key="SubProcessReview">
    
    
    
  </sub-process>
  
 
               
    
    
    
  
   
  
  
  
 

java

  • JBoss jBPM에 의해서 자동으로 실행되는 단계로 특정 Java Class의 Method를 호출 한다.

 
 

{|cellspacing="0" cellpadding="2" border="1" width="100%" bgcolor="#FFFFFF" align="center" 
|- |width="30%" style="background-color:#eee;" align="center" valign="middle"|name="이름" |width="70%"|

  • 이 단계의 이름, 분기(transition)시 사용 한다.
    style="background-color:#eee;" align="center" valign="middle"
    width="75%"
  • 실행할 Java 클래스 지정

  • class 대신 expr="#{변수}" 를 사용하여 실행할 Java 클래스를 지정할 수도 있다.
    style="background-color:#eee;" align="center" valign="middle"
  • Java 클래스에서 실행될 함수명(Method)을 지정 한다.
    style="background-color:#eee;" align="center" valign="middle"
  • 반환되는 객체가 저장될 변수명을 정의 한다.

  • 다른 단계에서 "#{반환되는 객체명}" 으로 지정하여 사용할 수 있다.
    style="background-color:#eee;" align="center" valign="middle"
  • 이 단계를 그림으로 그릴 때 표시되는 위치
    style="background-color:#eee;" align="center" valign="middle"
  • Java Method에 인수로 전달하는 값을 정의

  • 문자열 : -> String

  • 숫자 : -> Integer

  • 객체 : -> Object 또는 해당 객체의 타입
    style="background-color:#eee;" align="center" valign="middle"
  • 함수에 전달되는 값이 아닌 Java 클래스에 선언된 변수에 전달되는 값을 정의 한다.

  • 변수값은 위 에 전달되는 값과 동일한 문법을 사용하여 정의 한다.
    style="background-color:#eee;" align="center" valign="middle"
  • Java 클래스의 함수를 실행한 후 분기할 다음 단계를 명시 한다.
    |}

  • JBoss jBPM의 java 실행 사례

 
    //--- com.groupware.approve.manager.ApproveWorkflowManager 클래스의 documentMove 함수가 자동 실행 된다.
    //--- processInfo는 Process를 처음 실행할 때 전달된 HashMap
    
   		
   		
   		
   		
   		
   		
   		
        
    
 
    import com.groupware.approve.manager;
    public class ApproveWorkflowManager {
        public String documentMove(String stepInfo, HashMap processInfo,
                String beforeUser, String beforeBox, String afterUser, String afterBox) {
            processInfo.put("result", "ok");
            return "result";
        }
    }
 

script

 
  
 
  • 사례 2

 
  
 

hql

  • 사례 1

 
 
    
      select activity.name
      from org.jbpm.pvm.internal.model.ActivityImpl as activity
      where activity.name like :activityName
    
    
      
    
    
  
   
  
    
      select count(*)
      from org.jbpm.pvm.internal.model.ActivityImpl
    
    
  
 

mail

  • 사례 1

 
 
    
    Reminder: ${person} celebrates his birthday!
    Do not forget: ${date} is the birthday of ${person} 
    
  
 

event

 
 
  
    
      
    
  
 
  
    
  
 
  
    
      
        
      
    
    
      
        
      
    
    
      
        
      
    
  
   
  
 
 
 
 public class LogListener implements EventListener {
 	
  // value gets injected from process definition
  String msg;
  
  public void notify(EventListenerExecution execution) {
    List logs = (List) execution.getVariable("logs");
    if (logs==null) {
      logs = new ArrayList();
      execution.setVariable("logs", logs);
    }
     
    logs.add(msg);
 
    execution.setVariable("logs", logs);
  }
 }
 

timer

  • jbmp.cfg.xml

 
 
      
        
        
        
        
        
        
      
  
 
  • Dudate 문법

 
 quantity [business](business.md) {second | seconds | minute | minutes | 
                     hour | hours | day | days | week | 
                     weeks | month | months | year | years}
  • 사례 1

 
 
    
    
      
    
  
 
  • 사례 2

 
 
    
      
      
    
    
  
 

group

  • group

  • group timer

 
 

TaskService

 import org.jbpm.api.TaskService;
 import org.jbpm.api.task.Task;
 
 TaskService taskService = null;
 List taskList = null;
 Task task = null;
 String taskId = null;
 
 taskService = processEngine.getTaskService();
 
 //--- 사용자의 Task 목록을 반환
 taskList = taskService.findPersonalTasks("johndoe");
 //--- 그룹의 Task 목록을 반환
 //--- taskService.findGroupTasks(groupid);
 task = taskList.get(0);
 taskId = task.getId();
 
 Set variableNames = taskService.getVariableNames(taskId);
 Map variables = taskService.getVariables(taskId, variableNames);
 
 variables = new HashMap();
 variables.put("category", "small");
 variables.put("lires", 923874893);
 taskService.setVariables(taskId, variables);
 
 String outcome = null;
 taskService.completeTask(taskId);
 taskService.completeTask(taskId, variables);
 taskService.completeTask(taskId, outcome);
 taskService.completeTask(taskId, outcome, variables);
 

Task

  • 사용자에게 할당되어 실행되는 단계
    {|cellspacing="0" cellpadding="2" border="1" width="100%" bgcolor="#FFFFFF" align="center" 
    |- 
    |width="30%" style="background-color:#eee;" align="center" valign="middle"|name="이름" 
    |width="70%"|

  • 이 단계의 이름, 분기(transition)시 사용 한다.
    style="background-color:#eee;" align="center" valign="middle"
  • Task 단계에 할당된 사용자 아이디
    style="background-color:#eee;" align="center" valign="middle"
  • Task 단계를 종료할 수 있도록 할당된 사용자 아이디 목록
    style="background-color:#eee;" align="center" valign="middle"
  • Task 단계를 종료할 수 있도록 할당된 그룹 아이디 목록
    |}

  • jPDL에서 Task 정의

 
 
     
 
 
  • 사례

 
 //--- 특정 Process에서 특정 사용자의 특정 Task를 가져 온다.
 public Task getTask(String processid, String userid, String taskname) {
 	TaskService taskService = null;
 	TaskQuery query = null;
 	List taskList = null;
 	
 	taskService = WorkflowManager.getProcessEngine().getTaskService();
 	query = taskService.createTaskQuery();
 	taskList = query.processInstanceId(processid).assignee(userid).activityName(taskname).list();
 	if (0 < taskList.size()) {
 		return taskList.get(0);
 	} 
 	return null;
 }
 
  • 사례 1

 
 
     
 
 
 public class Order implements Serializable {
  String owner;
 
  public Order(String owner) {
    this.owner = owner;
  }
 
  public String getOwner() {
    return owner;
  }
 
  public void setOwner(String owner) {
    this.owner = owner;
  }
 }
 
 Map variables = new HashMap(); 
 variables.put("order", new Order("johndoe"));
 ProcessInstance processInstance = executionService
    .startProcessInstanceByKey("TaskAssignee", variables);
 
 List taskList = taskService.findPersonalTasks("johndoe");
 
  • 사례 2

 
 
      
 
 
 taskService.getAssignedTasks("johndoe");
 taskService.findGroupTasks("johndoe");
 
 taskService.takeTask(task.getDbid(), "johndoe");
 
  • 사례 3

 
 
    
      
        
      
    
    
  
 
 public class AssignTask implements AssignmentHandler {
  String assignee;
 
  public void assign(Assignable assignable, OpenExecution execution) {
    assignable.setAssignee(assignee);
  }
 }
 
  • 사례 4

 
 
 
 
    
  
 
  • 사례 5

 
 
     
 
 

HistoryService

 import org.jbpm.api.HistoryService;
 import org.jbpm.api.history.HistoryProcessInstance;
 import org.jbpm.api.history.HistoryProcessInstanceQuery;
 
 HistoryService historyService = null;
 List historyProcessInstances = null;
 
 historyService = processEngine.getHistoryService();
 historyProcessInstances = historyService.createHistoryProcessInstanceQuery()
     .processDefinitionId("hello-1")
     .orderAsc(HistoryProcessInstanceQuery.PROPERTY_STARTTIME)
     .list();
 

ManagementService

 import org.jbpm.api.ManagementService;
 
 ManagementService managementService = null;
 
 managementService = processEngine.getManagementService();
 

Migration

  • foobar.jpdl.xml

 
 
     
     
 
     
         
         
     
 
     
         
     
 
 
  • Migration in Java program

 
 ProcessDefinition pd1 = deployProcessDefinition("foobar", originalVersion);
 ProcessDefinition pd5 = deployProcessDefinition("foobar", versionWithAbsoluteVersionRange);
 

관리자 가이드


jBPM 엔진 및 도구

 
 

참고 문헌


 
 

분류: 오픈소스

최종 수정일: 2024-09-30 12:26:18

이전글 :
다음글 :