Mule ESB 와 Groovy 로 RESTful 서 비 스 를 편성 합 니 다.

http://www.infoq.com/cn/articles/restful-services-mule
지난 몇 년 동안 REST 스타일 의 소프트웨어 구 조 는 점점 더 많은 인정 을 받 았 다.이것 은 주로 시스템 이 움 직 이 는 부품 에 대한 수 요 를 줄 이 는 동시에 시스템 의 결합 성 을 더욱 낮 추고 탄력 이 좋 기 때문이다.
현재 점점 더 많은 REST 자원 이 기업 응용 에 나타 나 기 때문에 이런 자원 을 편성 하 는 것 이 매우 중요 하 다.예 를 들 어 전형 적 인 업무 활동 은 자원 의 생 성 을 포함 하고 그 다음 에 자원 의 검색 과 다른 자원 의 생 성 등 을 포함한다.
본질 적 으로 RESTful 서비스 와 의 상호작용 은 상당히 간단 하 다.적당 한 요청(요청 헤드 와 요청 체)을 구성 하고 보 낸 다음 에 되 돌아 오 는 응답(응답 헤드 와 응답 체)을 분석 해 야 한다.이 처 리 를 완성 하려 면 특별한 도구 나 프레임 워 크 가 필요 하지 않 습 니 다.사용 하기 좋 은 HTTP 클 라 이언 트 라 이브 러 리 만 있 으 면 됩 니 다.그 밖 에 RESTful 상호작용 과정 에서 관련 된 서로 다른 실 체 는 이른바 마이크로 형식 으로 정의 되 기 때문에 이런 실 체 를 쉽게 해석 하거나 출력 할 수 있 는 능력 이 매우 중요 하 다.
편성 과 여러 자원 의 상호작용 은 까다 로 운 문제 이다.우 리 는 편성,처리 오 류 를 정의 하고 끊임없이 시도 해 야 하 며,동시에 시스템 은 반드시 스트레스 를 받 아 양호 하 게 표현 할 수 있어 야 한다.Mule 은 통합 프레임 워 크 로 서 우리 가 필요 로 하 는 모든 것 을 제공 합 니 다.
예 를 들 어 한 상업 시스템 이 새로운 주문 에 대한 처 리 는 다음 과 같이 편성 해 야 한다.
서비스 에 XML 실 체 를 보 내 서 새 주문 서 를 만 듭 니 다.
새로 만 든 주문 자원 을 찾 아 확인 정 보 를 추출 합 니 다.
확인 정보 에 따라 메 일 게 이 트 웨 이 를 통 해 고객 에 게 확인 메 시 지 를 보 냅 니 다.
우 리 는 본 고 에서 위의 모든 상호작용 과정 을 상세 하 게 분석 하 는 동시에 상기 상호작용 을 얻 기 위해 필요 한 Mule 동 부품 과 Groovy 특성 도 소개 할 것 이다.
전체적인 편성 은 특정 경로,필터,메모리 메시지 큐(aka VM 큐)를 통 해 연 결 된 Mule 서 비 스 를 포함한다.최근 인 포 큐 에 올 라 온 이 글 은 뮬 의 메시지 경 로 를 소 개 했 으 니 한 번 살 펴 보 자.
Mule 의 REST 지원
Mule 은 간단 하면 서도 강력 한 방식 으로 RESfFul 서비스 와 상호작용 을 제공 했다.그것 이 바로 Mule RESTPack 이다.
Mule RESTPack 은 사용자 가 새로운 RESTful 응용 프로그램 을 만 들 수 있 도록 전체 커 넥 터 와 완전한 안내 서 를 제공 합 니 다.본 고 를 작성 할 때 이 패 키 지 는 세 가지 전송 기 를 제 공 했 는데 각각 세 가지 유행 하 는 REST 구 조 를 바탕 으로 한다.즉,Abdera,Jersey 와 Restlet 이다.이렇게 하면 우 리 는 새로운 자원 을 쉽게 공개 할 수 있 지만,어떻게 기 존의 REST 자원 을 통합 합 니까?
좋 은 소식 은 Mule 표준 스 크 립 트 모듈 이 제공 하 는 Groovy 지원 이 Mule HTTP 전송 기 사용 에 도움 이 되 고 RESTful 서비스 와 성공 적 으로 상호작용 할 수 있 습 니 다.
Mule 에 POST 요청 보 내기
우선 첫 번 째 상호작용 을 살 펴 보 자.HTTP 는 다음 세 션 과 같이 특정한 자원 에 XML 실 체 를 보 내 주문 서 를 만 듭 니 다.
POST /orders HTTP 1.1
...
<order xmlns='urn:acme:order:3:1'>
   <customerId>123456</customerId>
   <productId>P987C</productId>
   <quantity>2</quantity>
</order>

성공 한 서버 의 응답 은 다음 과 같 습 니 다:
201 Created
Location: http://acme.com/order/O13579
...

Mule 에서 우 리 는 간단 한 HTTP 출력 점(outbound endpoint)을 통 해 이 상호작용 을 실현 할 수 있 습 니 다.대화 자체 가 주문 생 성 서비스 에 요청 값(고객 과 제품 ID,수량)을 포함 하 는 맵 을 보 내 서 촉발 되 었 음 을 알 수 있 습 니 다.이 서 비 스 는 다음 과 같다.
<service name="OrderCreationService"> 
  <inbound> 
    <inbound-endpoint ref="OrderCreationQueue" /> 
  </inbound> 
  <outbound> 
    <chaining-router> 
        <http:outbound-endpoint synchronous="true" 
              responseTimeout="15" method="POST" 
              host="${acme.order.hostname}" 
              port="${acme.order.port}" path="orders" 
              user="${acme.order.username}" 
              password="${acme.order.password}" 
              contentType="application/vnd.acme+xml" encoding="UTF-8"> 
              <transformers> 
                <transformer ref="OrderMapToMicroformat" /> 
              </transformers> 
              <response-transformers> 
                  <message-properties-transformer> 
                        <add-message-property key="OrderPlaced" 
                            value="#[groovy:message.getStringProperty('http.status','ERR')=='201']" /> 
                        <add-message-property 
                            key="OrderResourceLocation" 
                            value="#[groovy:message.getStringProperty('Location','')]" /> 
                  </message-properties-transformer> 
                  <object-to-string-transformer /> 
              </response-transformers> 
         </http:outbound-endpoint> 
         <outbound-endpoint ref="OrderCreationResultQueue" /> 
   </chaining-router>     
  </outbound> 
</service>

이것 은 모두 XML 입 니 다.자세히 분석 해 보 겠 습 니 다.
OrderCreation Queue 라 는 파이프(VM 대기 열 이나 JMS 대기 열 일 수 있 음)에서 메 시 지 를 받 습 니 다.
받 은 메 시 지 는 다른 경로 로 직접 전 달 됩 니 다.이 경 로 는 HTTP POST 결 과 를 다음 서비스 로 보 냅 니 다.이 서 비 스 는 OrderCreation ResultQueue(비동기 VM 대기 열)라 는 파 이 프 를 통 해 호출 결 과 를 분석 합 니 다.
표준 출력 점 을 통 해 Groovy 변환기 에서 이 HTTP POST 요청 을 실행 합 니 다.
주문 서 를 요청 하 는 마이크로 형식 은 특정한 전송 기 를 통 해 만 들 어 졌 으 며,다음 절 에 서 는 상세 하 게 소개 할 것 입 니 다.
스 크 립 트 를 통 해 결과 코드 를 추출 하여 기대 치 와 비교 합 니 다.비교 하 는 목적 은 뒤의 서 비 스 를 순수한 HTTP 와 분리 하 는 것 입 니 다.우리 가 만 든 boolean 형식의 속성 OrderPlaced 는 독립 적 이 고 그 이름 은 진행 하 는 편성 과 밀접 한 관 계 를 가 집 니 다.
유사 한 것 은 문맥 적 의 미 를 가 진 OrderResourceLocation 이름 에서 Location 헤드 를 복사 합 니 다.이 머리 를 잃 어 버 릴 수 있 습 니 다.(실패 한 경우)이 경우,우 리 는 null 속성 을 메시지 에 추가 하지 않도록 기본 값 을 빈 문자열 로 설정 합 니 다.
우 리 는 HTTP 응답 을 분리 하기 위해 대상 문자열 변환 기 를 사용 했다.이 변환기 덕분에 흐름 이 완전히 처리 되 었 고 그 내용 도 HTTP 교환 과 관련 된 인 코딩 을 통 해 문자열 로 변환 되 었 습 니 다.스 트림 이 닫 혔 을 때 HTTP 연결 이 풀 렸 습 니 다.우 리 는 그것 을 계속 켜 고 뒤에 있 는 서비스 가 OrderCreation ResultQueue 에서 응답 메 시 지 를 꺼 내 기 를 기다 리 고 싶 지 않 습 니 다.
Groovy Markup Builder 의 장점
OrderMapToMicroformat 컨버터 는 서비스 에서 중요 한 장면 을 완 성 했 고 Groovy 의 MarkupBuilder 에 의 해 이 루어 졌 다.MarkupBuilder API 는 특정 마이크로 형식 과 호 환 되 는 XML 실 체 를 자 연 스 럽 게 생 성 합 니 다.
<scripting:transformer name="OrderMapToMicroformat"> 
   <scripting:script engine="groovy"> <![CDATA[ 
        def writer = new StringWriter() 
        def xml = new groovy.xml.MarkupBuilder(writer) 
        xml.order(xmlns: 'urn:acme:order:3:1') { 
          customerId(payload.clientId) 
          productId(payload.productCode) 
          quantity(payload.quantity) 
        } 
        result = writer.toString() ]]> 
    </scripting:script> 
</scripting:transformer>

map payload 의 값 이 XML 요 소 를 조립 하 는 데 어떻게 사용 되 는 지 주의 하 십시오.이것 은 일치 하지 않 는 명명 약속(예 를 들 어 clientId 를 customerId 로 변환 하 는 것)을 해결 합 니 다.
원 하 는 대로 이 컨버터 는 다음 과 같은 입력 을 만 들 었 습 니 다.
<order xmlns='urn:acme:order:3:1'> 
   <customerId>123456</customerId> 
   <productId>P987C</productId> 
   <quantity>2</quantity> 
</order> 

정확 한 콘 텐 츠 유형 을 제외 하고 모두 주문 한 RESTful 서 비 스 는 새로운 자원 을 만 드 는 데 필요 한 내용 입 니 다.
분석 하 다.
이제 주문 생 성 결 과 를 비동기 적 으로 분석 하고 더 편성 해 야 할 서 비 스 를 결정 합 니 다.
<service name="OrderCreationResultProcessor"> 
  <inbound> 
    <inbound-endpoint ref="OrderCreationResultQueue" /> 
     <selective-consumer-router> 
        <message-property-filter pattern="OrderPlaced=true" /> 
     </selective-consumer-router> 
     <logging-catch-all-strategy /> 
  </inbound> 
  <outbound> 
    <pass-through-router> 
      <outbound-endpoint ref="SuccessfulOrderQueue" /> 
    </pass-through-router> 
  </outbound> 
</service> 

우리 가 사용 하 는 선택 적 소비자(selective consumer)가 받 은 메시지 에는 반드시 주문 이 성공 적 으로 처 리 된 헤더 정보 가 포함 되 어야 합 니 다.이 헤더 정보 가 true 라면 SuccessfulOrderQueue 라 는 메모리 큐 를 통 해 이 메 시 지 를 세 번 째(최종)서비스 에 전달 합 니 다.이 서 비 스 는 주문 서 를 성공 적 으로 만 든 메 시 지 를 처리 합 니 다.이 예 에서 우 리 는 오류 메 시 지 를 로그 로 간단하게 기록 할 뿐 이지 만 실제 응용 에서 오류 메 시 지 를 전문 적 인 대기 열 에 보 내 후속 분석 이나 신속 한 피드백 을 해 야 합 니 다.
Mule 에 GET 요청 보 내기
이 편성 을 구성 하 는 마지막 서 비 스 는 HTTP GET 처 리 를 담당 합 니 다.새로 만 든 주문 서 를 받 을 수 있 습 니 다.주문 에는 이메일 게 이 트 웨 이 를 사용 할 수 있 는 합 법 적 인 메 시 지 를 만 들 기 위해 추가 값 이 포함 되 어 있 습 니 다.다음 과 같은 예제 대화 입 니 다.
GET /order/O13579 HTTP 1.1
200 OK
Content-Type: application/vnd.acme+xml
...
<order xmlns='urn:acme:order:3:1'> 
  <customerId>123456</customerId> 
  <productId>P987C</productId> 
  <quantity>2</quantity> 
  <customerEmail>[email protected]</customerEmail> 
  <estimatedShipping>2009-31-12T00:00:00Z</estimatedShipping>
</order>

좋 은 소식 은 Mule 의 HTTP 전송 은 rest-service component 라 는 구성 요 소 를 포함 하고 있 으 며,이 구성 요 소 는 서비스 와 REST 자원 의 상호작용 을 간소화 합 니 다.다행히 이러한 구성 요소 가 있어 서 우 리 는 GET 작업 결 과 를 다음 서비스 에 보 낼 필요 가 없 으 며,반대로 단독 서비스 에서 모든 것 을 완성 할 수 있 습 니 다.이외에 도 동적 으로 구 축 된 URL 과 연결 할 수 있 도록 설정 에 표현 식 을 사용 하 는 것 을 지원 합 니 다.
<service name="SuccessfulOrderProcessor"> 
<inbound> 
  <inbound-endpoint ref="SuccessfulOrderQueue" /> 
</inbound> 
<http:rest-service-component httpMethod="GET" 
   serviceUrl="#[header:OrderResourceLocation]" /> 
<outbound> 
  <pass-through-router> 
    <outbound-endpoint ref="EmailGatewayQueue"> 
      <transformers> 
       <object-to-string-transformer /> 
       <transformer ref="OrderMicroformatToEmailMap" /> 
      </transformers> 
    </outbound-endpoint> 
  </pass-through-router> 
</outbound> 
</service>

성공 적 인 주문 메 시 지 를 받 은 후,이 서 비 스 는 REST 서비스 구성 요 소 를 사용 하여 HTTP GET 요청 을 생 성하 고,이 요청 을 이전에 OrderResourceLocation 속성(aka heade)에 저 장 된 URL 로 보 냅 니 다.우리 가 어떻게 Mule 표현 식 프레임 워 크(사용\#[...]문법)를 통 해 구성 요소 에 동적 URL 을 주입 하 는 지 알 수 있 습 니 다.
GET 요청 의 응답 을 이메일 게 이 트 웨 이와 통신 하 는 서비스 에 보 내기 전에 우 리 는 XML 주문 실 체 를 두 번 전환 했다.
위 에서 말 한 바 와 같이 우 리 는 응답 실 체 를 분리 했다.
변환기 로 XML 실 체 를 분석 하고 다음 서비스 에 사용 할 수 있 도록 맵 을 구축 합 니 다.이번 에는 그루 브 이의 강력 한 기능 을 이용 했다.
Groovy's XmlSlurper Happiness
Groovy 의 XmlSlurper 는 XML 마이크로 형식 을 해석 하 는 이상 적 인 도구 로 DSL 과 유사 한 API 덕분 입 니 다.
다음 코드 는 OrderMicroformatToEmailMap 변환기 의 실현 을 보 여 줍 니 다.
<scripting:transformer name="OrderMicroformatToEmailMap"> 
  <scripting:script engine="groovy"><![CDATA[ 
    def order = new XmlSlurper().parseText(payload)
				.declareNamespace(acme: 'urn:acme:order:3:1') 
    result = [emailId:'OrderConfirmation', 
		emailAddress:order.'acme:customerEmail'.text(), 
		orderId:[email protected]()] 
   ]]> 
  </scripting:script> 
</scripting:transformer>

맞습니다.Groovy 코드 두 줄 만 있 습 니 다.우 리 는 네 임 스페이스 에서 감지 하 는 XML 해상도 와 map 구축 기 를 사 용 했 습 니 다.그 장점 은 정말 믿 기 어렵 지만 이것 이 바로 map(email 게 이 트 웨 이 서비스 가 기대 하 는)를 만 드 는 데 필요 한 모든 내용 입 니 다.
최종 REST
본 논문 에서 우 리 는 사전에 정 의 된 편성 에 따라 새로운 주문 자원 의 URL 은 유일한 동적 요소 이다.개발 자 는 예제 에 소 개 된 변환기 와 표현 식 을 이용 하여 더 많은 동적 인 상호작용 을 지원 할 수 있 습 니 다.HATEOAS 노선 을 따 르 려 면 모든 것 을 얻 을 수 있 습 니 다.만약 사실 이 이렇다면 다른 Mule 루트 는 손 쉽게 얻 을 수 있 을 것 이다.예 를 들 어 幂 등 수신 자의 루트 를 만 들 수 있다.너 도 Groovy 의 강력 한 기능 과 민첩 성,그리고 Mule 의 통신 능력 이 RESTful 서비스 와 의 상호작용 을 크게 간소화 한 것 을 보 았 다.Mule 의 표현 식 과 소량의 Groovy 스 크 립 트 는 Mule 설정 을 효과적으로 동적 으로 정의 할 수 있 습 니 다.그 밖 에 비동기 적 인 VM 대기 열 을 사용 하여 편 성 된 각 단 계 를 연결 하면 최대 부하 에서 우아 하 게 등급 을 낮 출 수 있 습 니 다.이것 은 Mule 내 재 된 SEDA 구조 덕분 입 니 다.
이런 강력 한 도구 에 힘 입 어 REST 자원 을 통합 하 는 것 은 매우 간단 해 졌 다.
행운 을 빕 니 다!
여러분http://dossot.net/datastore/mule-groovy-rest.tar.gz전체 설정 과 관련 된 테스트 자원 을 다운로드 합 니 다.이것 은 독립 된 Maven 프로젝트 입 니 다.
영어 원문 보기:Orchestrating RESTful Services With Mule ESB And Groovy.
http://www.infoq.com/articles/restful-services-mule

좋은 웹페이지 즐겨찾기