이 예제에서(그림 1), 고객은 대출 요청을 보낸다. 요청이 처리되면 고객은 대출의 승인 여부를 알 수 있다. 처음에는 중간 단계에 애플리케이션을 금융 기관을 사용할 수 있는 웹 서비스에 보내는 것과 고객에게 결정 사항을 알려주는 것이 포함될 것이다. 고객의 관점에서 보면 프로세스는 이 애플리케이션을 소비하고 그런다음 답을 보내는 것이다. 아래 다이어그램은 대출 요청 처리를 외부에서 보는 모습이다.
그림 1. 대출 승인 프로세스
위 작동은 메시지를 받고 금융 기관의 웹 서비스를 호출하고 마지막으로 고객에게 응답하는 것으로 구성되어
있다. 이 세 가지 액션은 <receive>, <invoke>,
<reply>액티비티를 사용하여 BPEL로 정의된다. 하지만 프로세스는
이같은 간단한 액티비티들의 관계를 정의해야 한다. 실행 시킬 방법과 시기를 알기 위함이다. 관계들은 액티비티를
실행하는 방법에 대한 제한을 정의하는 구조화된 액티비티를 사용하여 BPEL로 정의된다. 이 예제에서 위
세 가지가 순서 대로 일어나기를 원한다. 이 순서는 <sequence> 액티비티를 사용하여 BPEL로
만들어지게 된다. 여기에는 우선 <receive>가 포함되어 메시지를
소비하고 그 다음 <invoke>로 금융 기관과 통신하게 된다. 그리고
<reply>로 응답을 고객에게 보낸다. 따라서 위 구름에는 이 세 가지
액티비티의 순서로 이루어진 프로세스를 포함하게 된다. 그리고 다음과 같이 금융 기관을 호출할 수 있다.
( 그림 2).
그림 2. 대출 승인 프로세스
프로세스를 완성하기 전에 개입된 당사자들과 교환 및 조작될 메시지에 대한 공식 디스크립션을 제공해야 한다.
BPEL 컴포지션은 개입된 서비스들의 WSDL 디스크립션에 상당히 많이 의존한다. 교환되는 메시지, 호출되는 작동, 이 작동들이 속해있는 portType 등을 참조하기 위해서이다. 이 예제에서 금융 기관의 디스크립션과 프로세스 자체의 디스크립션이 필요하다. (Listing 1).
Listing 1: Loan Definitions WSDL (loandefinitions.wsdl)
<definitions targetNamespace="http://tempuri.org/services/loandefinitions"
xmlns:tns="http://tempuri.org/services/loandefinitions"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.xmlsoap.org/wsdl/">
<message name="creditInformationMessage">
<part name="firstName" type="xsd:string"/>
<part name="name" type="xsd:string"/>
<part name="amount" type="xsd:integer"/>
</message>
<message name="loanRequestErrorMessage">
<part name="errorCode" type="xsd:integer"/>
</message>
</definitions>
|
대출 승인 서비스를 제공하고 아래 Listing 2에 의해 기술되는 금융 기관을 안다고 가정해 보자. 여기에는 "approve"라고 하는 하나의 오퍼레이션을 포함하고 있는데 이것은 대출 요청의 상태를 결정하는데 사용된다. 이 오퍼레이션은 인풋으로 고객 정보를 받고 응답을 포함하고 있는 승인 메시지를 아웃풋으로 내보낸다. 인풋 메시지에 대한 정의는 위 loandefintion에 정의되어 있다.
Listing 2: Loan Approver WSDL(loanapprover.wsdl)
<definitions targetNamespace="http://tempuri.org/services/loanapprover"
xmlns:tns="http://tempuri.org/services/loanapprover"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:loandef="http://tempuri.org/services/loandefinitions"
xmlns="http://schemas.xmlsoap.org/wsdl/">
<import namespace="http://tempuri.org/services/loandefinitions"
location="http://localhost:8080/bpws-samples/loanapproval/loandefinitions.wsdl"/>
<message name="approvalMessage">
<part name="accept" type="xsd:string"/>
</message>
<portType name="loanApprovalPT">
<operation name="approve">
<input message="loandef:creditInformationMessage"/>
<output message="tns:approvalMessage"/>
<fault name="loanProcessFault"
message="loandef:loanRequestErrorMessage"/>
</operation>
</portType>
<binding ...> ... </binding>
<service name="LoanApprover">....</service>
</definitions>
|
프로세스 자체는 인풋과 아웃풋 메시지를 이 서비스로 전달하고 전달받는다. 따라서 이는 위 portType을
참조함으로서 사용자에게 같은 디스크립션을 보일 것이다. 하나 더 필요한 것은 사용되는 서비스를 위해 serviceLinkType을
정의하는 것이다. serviceLinkType은 서로 연결되어 있는 두 개의 서비스들에
의해 제공되고 요구되는 portType을 참조하는 두 개의 역할을 정의한다. 이 예제의 경우 이 serviceLinkType은
고객을 프로세스에 연결하는데 사용될 것이고 프로세스를 대출 승인자에게 연결하는데 사용될 것이다. 프로세스와
대출 승인자 서비스가 "approver" portType을 제공하기 때문에 오직 한 가지 역할이 필요하다.
이들 중 어떤 것도 사용자가 다른 portType을 지원하는 것을 요구하지 않는다. (Listing
3):
Listing 3: Loan Approval WSDL(loan-approval.wsdl)
<definitions
targetNamespace="http://loans.org/wsdl/loan-approval"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:slnk="http://schemas.xmlsoap.org/ws/2002/06/service-link/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:lns="http://loans.org/wsdl/loan-approval"
xmlns:apns="http://tempuri.org/services/loanapprover">
<import namespace="http://tempuri.org/services/loanapprover"
location="http://localhost:8080/bpws-samples/loanapproval/loanapprover.wsdl"/>
<import namespace="http://tempuri.org/services/loandefinitions"
location="http://localhost:8080/bpws-samples/loanapproval/loandefinitions.wsdl"/>
<slnk:serviceLinkType name="loanApprovalLinkType">
<slnk:role name="approver">
<portType name="apns:loanApprovalPT"/>
</slnk:role>
</slnk:serviceLinkType>
<service name="loanapprovalServiceBP"/>
</definitions>
|
<process name="loanApprovalProcess"
targetNamespace="http://acme.com/simpleloanprocessing"
xmlns="http://schemas.xmlsoap.org/ws/2002/07/business-process/"
xmlns:lns="http://loans.org/wsdl/loan-approval"
xmlns:loandef="http://tempuri.org/services/loandefinitions"
xmlns:apns="http://tempuri.org/services/loanapprover">
|
다음 단계는 개입된 당사자들을 정의한다.(그림 1 & 2).
<partners>
<partner name="customer"
serviceLinkType="lns:loanApproveLinkType"
myRole="approver"/>
<partner name="approver"
serviceLinkType="lns:loanApprovalLinkType"
partnerRole="approver"/>
</partners>
|
파트너를 정의한 후에 컴포지션을 형성하는 액티비티를 추가할 준비가 거의 다 된것이다. 프로세스에게 기대하는 것이 무엇인지를 생각해보라. 대출 요청을 위해서 고객은 프로세스를 메시지로 보내고 프로세스는 금융 기관에 대출 애플리케이션을 수락할 것인지의 여부를 묻고 이를 고객에게 응답한다. 이를 BPEL로 어떻게 할 것인가? 우선 BPEL 액티비티가 액세스 할 수 있는 곳에 인커밍 메시지를 둔다. BPEL로 데이터는 작성되고 데이터 콘테이너에서 액세스된다. 여기에는 특정 WSDL 메시지 타입의 인스턴스가 포함될 수 있다.
고객 파트너와 loanApprovalPT의 정의에 따라 고객은 creditInformationMessage
유형의 메시지를 보내고 approvalMessage 유형의 응답을 받는다. (그림
2):
<containers>
<container name="request" messageType="loandef:CreditInformationMessage"/>
<container name="approvalInfo" messageType="apns:approvalMessage"/>
</containers>
|
프로세스에는 단지 하나의 액티비티를 포함할수도 있다. 이 경우 <sequence>가
될 것이다. 이제 여기에 고객의 메시지를 가져올 수 있는 receive 액티비티를 추가하여
적절한 콘테이너에 놓을 수 있다. receive 액티비티의 정의에는 메시지를 보낼 파트너,
파트너가 메시지를 보내고자 하는 타겟의 port type과 프로세스의 오퍼레이션이 포함된다. 이 정보에
따라 일단 프로세스가 메시지를 받으면 활성 receive 액티비티를 찾는다. 그런 다음 이
액티비티는 특정 콘테이너에 메시지를 놓는다. sequence 액티비티를 시작하고 여기에
receive를 추가할 수 있다:
<sequence>
<receive name="receive1" partner="customer"
portType="apns:loanApprovalPT"
operation="approve" container="request"
createInstance="yes">
</receive>
|
다음 단계는 웹 서비스가 가능한 금융기관이 대출을 수락할지의 여부를 묻는 것이다. 이는 규칙적인 웹
서비스 호출로 수행된다. 이는 Invoke 액티비티에 의해 프로세스에서 정의된다. 이 액티비티가 실행되면
인풋 콘테이너의 메시지를 사용하여 웹 서비스에 특정 호출이 발생하고 아웃풋 콘테이너에 도착한 응답을 놓고
끝난다. approve 작동을 수행하는 "approver" 파트너에게
호출이 발생한다.
<invoke name="invokeapprover"
partner="approver"
portType="apns:loanApprovalPT"
operation="approve"
inputContainer="request"
outputContainer="approvalInfo">
</invoke>
|
프로세스가 고객의 요청에 응답하기위해 Reply 액티비티를 사용한다. 일단 Reply 액티비티가 도착하면 partner-portType-operation는 누구에게 응답을 보내야 하는지를 결정하는데 사용된다. 따라서 receive 액티비티를 통해 도착한 메시지에 응답하려면 같은 트리플릿(partner-portType-operation)을 갖춘 Reply 액티비티가 필요하다.
<reply name="reply" partner="customer" portType="apns:loanApprovalPT"
operation="approve" container="approvalInfo">
</reply>
</sequence>
</process>
|
프로세스가 전개되면 누군가 이를 시작할 때 까지 기다린다. 이미 알고 있겠지만 receive는 true로 설정된 'createInstance'라는 애트리뷰트를 포함하고 있다. 이는 프로세스로 가는 엔트리 포인트를 보여준다. 다음은 대출 승인 프로세스의 실행 방법이다.(그림 3).
그림 3. 대출 승인 프로세스 실행
그림 설명: 화살표 옆의 숫자들은 단계 발생 순서이다. 검은 봉투는 대출 요청을 포함하고 있는 메시지이다. 빨간 봉투는 그 요청에 대한 응답을 담고있는 메시지이다.
일단 클라이언트가 적절한 트리플릿으로 프로세스 매니저에게 메시지를 보내면 프로세스 인스턴스가 생성되고 실행을 시작한다.
- developerWorks worldwide 사이트에서 이 기사에 관한 영어원문.
- BPEL4WS version
1.0 스팩. BPEL4WS1.1.
- BPEL4WS 이해하기, Part 1.
- Business
Processes for Web Services Java Runtime: alphaWorks.
- Business
Process Execution Language for Web services 스팩.
- 관련 기술자료: Business
Processes in a Web services World.