Metro와 .NET 간의 상호운용성 테스트
저자 썬 마이크로시스템즈에서 엔터프라이즈 웹 서비스 상호운용성에 대한 엔지니어링 리더 Harold Carr
이 팁은 Java EE 5의 오픈 소스 참조 구현인 GlassFish와 오픈 소스 NetBeans IDE 5.5.1을 사용하여 작성했습니다. GlassFish는 GlassFish 커뮤니티 다운로드 페이지에서 다운로드할 수 있습니다. NetBeans IDE 5.5.1은 NetBeans 페이지에서 다운로드할 수 있습니다.
Metro와 .NET 간의 상호운용성 테스트 팁에 대한 샘플 아카이브는 여기에서 다운로드할 수 있습니다. 아래에 있는 이 코드 및/또는 정보의 사용은 라이센스 계약 조건에 따릅니다.
2007년 3월의 Tech Tip, WSIT를 사용한 웹 서비스 보안에서 이미WSIT(Web Services Interoperability Technology)를 소개한 바 있으며, 이것은 오픈 웹 서비스 기술을 구현한 것으로 Java EE와 .NET 간의 상호 운용을 가능하게 합니다. XML 기반 서비스용 Java API와 함께 WSIT(JAX-WS)는 GlassFish v2의 웹 서비스 기술 스택으로 구성됩니다. GlassFish v2의 웹 서비스 스택을 Project Metro 또는 줄여서 Metro라고 부릅니다. Metro는 썬 자바 시스템 애플리케이션 서버 9.1로 구축합니다. Metro는 또한 Tomcat과 같은 다른 컨테이너에서도 수행됩니다.
WSIT은 Project Tango라고도 불리며, 연결된 시스템을 구축 및 구동하기 위한 기술의 집합인 .NET의 WCF(Windows Communication Foundation)와의 고급 웹 서비스 상호 운용성을 실현하는 기능을 포함합니다. WSIT은 또한 신뢰성 있는 메시징, 트랜잭션 핸들링 및 보안과 같은 웹 서비스 상호운용성의 주요한 측면을 다룹니다. 이는 Metro 기반 및 WCF 기반 클라이언트와 서비스의 모든 조합이 신뢰성 있는 메시징, 트랜잭션 핸들링 및 보안을 지원하면서 상호 운용될 수 있음을 의미합니다.
WCF와 Metro 기술 스택이 올바르게 상호 작용하고 적절한 지원을 제공하도록 하기 위해, 마이크로소프트와 썬의 엔지니어들은 "plug-fests"라는 종합적인 상호운용성 테스트를 수행합니다. 테스트 시나리오를 비롯한 plug-fests에 대한 자세한 정보는 Web Services Interoperability Plug-Fest 홈 페이지를 참조하십시오. 모든 테스트는 현재 수준의 .NET 및 Metro에서 진행됩니다. .NET 3.0 및 Metro 1.0.
본 팁에서는 Metro 기반의 클라이언트가 WCF 기반의 서비스와 통신하는 상호운용성 테스트를 구축 및 수행할 것입니다. 상호운용성 테스트 코드가 수록된 패키지가 본 팁과 제공됩니다. 이 팁의 코드 예제는 해당 패키지에 포함된 샘플의 소스 코드에서 따온 것입니다.
신뢰성 있는 단방향 상호운용성 테스트
본 팁에서 구축 및 수행할 상호운용성 테스트는 "신뢰성 있는 단방향 테스트"입니다. 본 테스트 유형은 "시나리오 #1.1. 단방향의 익명 클라이언트"에 기술되어 있으며WCF (Indigo) Introperability Lab: Reliable Messaging 문서에 수록되어 있습니다. 이러한 유형은 전형적인 엔터프라이즈의 사용 형태로, 클라이언트가 처리를 위해 서비스로 데이터를 전송하지만 응답을 기다리지 않습니다. 이것이 "단방향"으로 불리는 이유입니다. 그러나 클라이언트는 서비스가 메시지를 수신했는지에 대해 보장해 주기를 원합니다.
이 테스트의 메시지 플로우는 다음과 같습니다.
- 클라이언트가
CreateSequence프로토콜 메시지를 송신하여 신뢰성 있는 통신 채널이 생성되도록 초기화합니다.
- 서비스에서는 신뢰성 있는 채널을 유일하게 식별하기 위한 시퀀스 식별자를 생성합니다. 서비스 쪽에서 이 식별자를
CreateSequenceResponse프로토콜 메시지에 넣어 응답합니다.
- 클라이언트는 세 가지의 애플리케이션 메시지를 전송합니다. 이들 각 메시지에는 채널에 대한 시퀀스 식별자와 메시지를 식별하는 메시지 번호를 포함한 헤더 정보가 들어 있습니다.
- 수신된 각 애플리케이션 메시지에 대해, 서비스는 어떤 메시지가 수신되었는지를 확인할 수 있도록
SequenceAcknowledgement와 함께 응답합니다. 서비스는 비즈니스 로직이 처리 완료될 때까지 기다리지 않고 이 작업을 수행합니다.
- 클라이언트가 자신이 송신한 메시지 일부가 수신되지 않았음을 확인하면 해당 메시지를 재전송합니다. (이 상황은 본 팁에서 테스트하지 않습니다.)
- 클라이언트는 채널이 더 이상 필요하지 않은 경우 채널을 닫습니다. 이 때
LastMessage프로토콜 메시지가 송신됩니다.
- 서비스는 어떤 메시지가 수신되었는지를 나타내는
SequenceAcknowledgement프로토콜 메시지로 응답합니다.
- 다시, 클라이언트는 자신이 보낸 메시지 일부가 수신되지 않았음을 확인하면 해당 메시지를 재전송합니다. 이 경우 또 다른
LastMessage가 뒤따릅니다.LastMessage-resend시퀀스는 서비스 쪽에서 모든 메시지를 수신할 때까지 반복됩니다. (이 부분은 본 팁에서 다루지 않습니다.)
- 클라이언트가
TerminateSequence프로토콜 메시지를 전송합니다.
- 서비스는 처리 요청이 받아들여졌음을 나타내는 HTTP 202로 응답합니다.
Metro 기반 클라이언트
Metro 기반 클라이언트를 작성해 봅시다. ReliableOneWay.java 파일에서 클라이언트용 소스 코드를 볼 수 있습니다. 다음은 그 파일의 소스 코드 일부를 발췌한 것입니다.
package reliableoneway.client; import org.tempuri.IPing; import org.tempuri.PingService; public class ReliableOneWay { public ReliableOneWay() {} public static void main(final String[] args) { try { PingService service = new PingService(); IPing port = service.getCustomBindingIPing(); msg(null, "BEFORE FIRST MESSAGE"); msg(port, "FIRST MESSAGE"); msg(port, "SECOND MESSAGE"); msg(port, "THIRD MESSAGE"); msg(null, "TERMINATE"); ((com.sun.xml.ws.Closeable)port).close();
RM(reliable messaging) 기반 웹 서비스의 사용은 SOAP 기반의 웹 서비스를 사용하는 것과 차이가 없습니다. 먼저 서비스에 대한 프록시를 생성합니다(wsimport 수행 섹션 참조). 여기에서 서비스는 PingService이며 WSDL에서 정의됩니다(WSDL 섹션 참조). 그리고 나서 해당 서비스에서 정의된 포트를 획득합니다. 이 경우에는 CustomBindingIPing입니다. 그 후에 포트에서 ping 메소드를 호출하여 해당 서비스로 애플리케이션 메시지를 송신할 수 있습니다. 이 때 port가 null 이 아닐 때 msg 메소드는 port.ping(String)을 호출합니다. 본 예제에서는 세 개의 메시지를 송신합니다.
이 단계들은 모든 SOAP 기반의 웹 서비스 사용 단계와 동일합니다. 포트에서 close 를 호출하는 단계가 추가됩니다. 이것은 Metro에게 서비스가 RM을 사용하고 있는 경우 해당 RM 채널을 종료하라는 신호입니다. 일반적으로 포트가 더 이상 필요하지 않을 때 닫는 것이 좋습니다. 이렇게 하면 Metro는 해당 포트가 사용하던 자원을 다시 이용할 수 있습니다.
WSDL
서비스에 대한 WSDL(Web Service Definition Language) 파일로부터 PingService 프록시를 생성합니다. 서비스를 위한 WSDL에 대한 정보는 Web Services Interoperability Plug-Fest 홈 페이지를 참조하십시오. "RM Endpoints(WS-Addressing 1.0)" 링크를 클릭한 후, "OneWay.svc" 링크를 클릭하십시오. WSDL의 주소는 http://131.107.72.15/ReliableMe입니다.
WSDL 파일은 보안과 관련된 시나리오 1.1외에도 기타 테스트 시나리오를 위해 사용되므로 상당히 큽니다. 본 팁에서 사용한 포트를 CustomBinding_IPing으로 명명합니다. 그것은 다음과 같은 policy binding을 참조합니다.
<wsp:Policy wsu:Id="CustomBi <wsp:ExactlyOne> <wsp:All> <wsrm:RMAssertion> <wsrm:InactivityTime <wsrm:Acknowledgemen </wsrm:RMAssertion> <wsaw:UsingAddressing </wsp:All> </wsp:ExactlyOne> </wsp:Policy>
policy binding에서 RMASssertion은 서비스에 대한 RM policy 선언을 명시하는 부분입니다. 선언(assertion) 부분에서 InactivityTimeout 매개변수는 닫기 전에 서비스가 비활성 상태로 남아 있는 시간 간격을 설정합니다. AcknowledgementInterval 매개변수는 신뢰성 있는 채널을 통해 메시지 소스로 응답(acknowledgment)을 보내기 전에 목적지에서 기다리는 시간 간격을 나타냅니다. RM policy 선언에 대한 자세한 정보는 WS-ReliableMessaging Policy specification을 참조하십시오. 여기에서 요점은 WSDL에 RMAssertion이 포함되며 CustomBinding_IPing 포트에서 사용되는 CustomBinding_IPing 바인딩에서 그 선언(assertion)을 참조함으로써 해당 포트에서의 연산은 신뢰성 있는 메시징을 이용할 수 있다는 것입니다.
테스트 구조
본 팁에서는 ant를 사용하여 프록시를 생성하고 코드를 컴파일하며 클라이언트 테스트를 수행할 것입니다. 또한 NetBeans도 사용할 수 있습니다. 자세한 정보는 WSIT Tutorial을 참조하십시오.
아직 안 했으면 GlassFish v2를 다운로드하고 설치하십시오. 그리고 팁의 샘플 애플리케이션을 다운로드하고 압축을 풉니다. 이제 새로 생성된 <sample_install_dir>/interop 디렉토리를 볼 수 있을 것입니다. 이 때 <sample_install_dir>은 샘플 애플리케이션을 설치한 디렉토리입니다. 예를 들어, Windows 시스템에서 C:\ 디렉토리에서 압축을 풀었다면 새로 생성된 디렉토리는 C:\interop일 것입니다.
본 팁에서는 하나의 시나리오만 설명하고 있지만 interop 디렉토리 아래의 디렉토리 구조는 다른 테스트에서도 사용할 수 있도록 공통된 산출물로 구성됩니다. 디렉토리 구조는 다음과 같습니다.
common.xml rm build.xml netbeans ReliableOneWayServic ... src reliableoneway build.props build.xml client ReliableOneW ... server etc EchoServ Reliable
디렉토리의 최상위 레벨에서 build.xml 파일은 common.xml을 임포트하며, 이 파일에서 실제 액션이 일어나며 하나의 target: run-reliableoneway를 정의합니다. run-reliableoneway 파일은 build 디렉토리를 지웁니다. 그 후에는 다음을 수행합니다.
wsimport를 수행- 생성된 코드와
ReliableOneWay.java코드를 컴파일 - 테스트 수행
wsimport 수행
다음은 wsimport 를 수행하는 build.xml의 코드 일부를 발췌한 것입니다.
<target name="run-reliableon <ant target="run antfile="src inheritall="false
rm/src/reliableoneway 디렉토리의 build.xml 파일을 사용한다는 것에 주의하십시오. 그 파일에서 이번에는 rm/src/reliableoneway 디렉토리의 rbuild.props 파일을 사용합니다. 다음은 build.props의 내용입니다.
test.wsdl= http://131.107.72.15 client.dir=client className=reliableoneway
build.props 파일은 속성 파일로, test.wsdl이 서비스의 WSDL 파일 위치가 되도록 정의합니다. 또한 common.xml 에서 사용되는 두 개의 다른 매개변수도 설정하여, 본 팁에서는 다루지 않지만 다른 테스트에서 사용될 수 있도록 합니다.
rm/src/reliableoneway 디렉토리의 build.xml 파일은 이후 common.xml 파일에서의 run-wsimport target을 사용합니다.
wsimport 태스크는 test.wsdl 매개변수에 지정된 WSDL 파일을 가져옵니다. 그리고 나서 프록시 코드는 rm/build/classes/org/tempuri 디렉토리에, 데이터 스키마 클래스는 rm/build/classes/com/microsoft 디렉토리에 생성합니다. 이 클래스는 모든 상호운용성 테스트 시나리오의 수퍼셋이므로 크기가 큽니다.
코드 컴파일 및 테스트 수행
run-reliableoneway target의 마지막 두 단계는 다음과 같습니다.
<ant target="compile" antfile="src/reliableon inheritall="false"/> <ant target="run-tests" antfile="src/reliableon inheritall="false"/>
컴파일 단계에서는 Java 프로그래밍 언어 컴파일러인 javac를 개발자가 작성한 코드인 ReliableOneWay.java에 대해 수행합니다. run-tests 단계에서는 build.props 파일에서 설정한 className 매개변수에 지정한 대로 메인 test 클래스를 실행합니다. 이 경우, className은 reliableoneway.client.ReliableO로 설정됩니다.
sysproperty는 common.xml 파일의 run-tests target에서 설정됨에 유의하십시오.
<sysproperty key="com.sun.xml.ws.transpor value="true"/>
이것은 클라이언트가 메시지를 송수신할 수 있도록 해줍니다.
환경 변수 설정
4 개의 ant 매개변수는 환경변수로부터 설정됩니다(여기에서는 bash 문법으로 보여줌).
export PROXY_HOST=-DproxyHos export PROXY_PORT=-DproxyPor export METRO_HOME=/glassfish export TEST_HOME=~/metro
사용자가 방화벽 뒤에 있지 않은 경우 명시적으로 PROXY_*에 아무것도 설정하지 마십시오.
export PROXY_HOST= export PROXY_PORT=
METRO_HOME은 GlassFish의 최상위 설치 위치로 설정하십시오. 그러한 설정값은 $METRO_HOME/lib의 webservices-rt.jar 및 webservices-tools.jar와 같은 Metro JAR 파일의 위치를 찾는 데 사용됩니다. (Tomcat 또는 다른 웹 컨테이너를 사용하는 경우 common.xml을 수정하여 Metro JAR 파일의 위치를 올바르게 참조할 수 있도록 해야합니다.)
테스트 실행
아직 GlassFish를 수행하지 않은 경우 다음 명령을 입력하여 GlassFish를 시작하십시오.
$METRO_HOME/bin/asadmin
그리고 $TEST_HOME 디렉토리로 변경하고 다음 명령문을 명령행에 입력하십시오.
ant
참고: 이 테스트는 JDK 5로 수행하도록 설계된 것입니다. JDK6으로 테스트를 수행하려면 Java Endorsed Standards Override Mechanism을 사용해야 합니다.
테스트 결과
테스트 결과는 rm/src/reliableoneway/client 디렉토리의 example-output-wcf-endpoint.txt 파일의 내용과 유사한 형태일 것입니다.
다음과 같은 테스트 수행 초반의 모든 WARNING 메시지는 무시해도 좋습니다.
[java] WARNING: WSP0075: "{http://docs.oasis-open was evaluated as "UNKNOWN".
이러한 경고는 본 테스트에서 사용되지 않은 WSDL의 바인딩에 대한 수많은 policy로부터 나온 것입니다. 이와 유사하게 run-wsimport 단계에서의 비 표준 SOAP 1.2 바인딩 경고 메시지도 무시합니다.
결과에서 BEFORE FIRST MESSAGE 부분을 찾으십시오. 이 부분은 port.ping을 처음 호출하기 직전에 콘솔로 출력합니다. port.ping이 호출되면 RM 인프라스트럭처는 애플리케이션 메시지를 보류합니다. 먼저 CreateSequence 프로토콜 메시지를 전송하여 신뢰성 있는 채널을 설정합니다.
Content-Type: application/soap+xml;charset="utf-8";
action="http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequence"
Content-Type: application/soap+xml;charset="utf-8";
action="http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequence"서비스에서 리턴된 CreateSequenceResponse 프로토콜 메시지에는 신뢰성 있는 채널을 식별하는 데 사용될 식별자(Identifier)가 포함됩니다.
신뢰성 있는 채널이 성립된 후, 애플리케이션 메시지는 Body 요소에 <Text>FIRST MESSAGE</Text>를 포함하여 송신됩니다. 헤더에는 신뢰성 있는 채널의 Identifier가 MessageNumber(이 경우, 숫자 1)와 함께 포함된 Sequence 요소 정보가 있습니다.
<S:Envelope xmlns:..."><S <ns2:MessageNumber>1</ns2 </S:Header>...<Text>FIRST </S:Envelope>
이것은 단방향 메시지이므로 이 메시지에 대한 응답에는 Body가 비어 있습니다. 헤더에는 SequenceAcknowledgement 요소가 포함되어 있으며 그 요소에는 Identifier 및 AcknowledgementRange가 포함됩니다. 이 때 AcknowledgementRange는 속성으로 Lower와 Upper를 가지며, 이 경우 값은 각기 숫자 1, 1입니다.
<s:Envelope xmlns:...><s <r:SequenceAcknowledgement> <r:Identifier>urn:...</r <r:AcknowledgementRange </r:SequenceAcknowledgement </r:SequenceAcknowledgement>
이는 서비스에서 수신한 가장 낮은 메시지 번호가 1이었으며 가장 높은 메시지 번호도 1이었음을 의미합니다. 응답 범위(acknowledgement range)에 있어서 차이가 있는 경우 클라이언트 RM 인프라스트럭처는 잃어버린 메시지를 재전송합니다. 그러한 메시지에 대한 응답(acknowledgement)을 받은 후에 가비지 콜렉션을 위해 메시지 사본을 해제합니다.
MessageNumbers가 각기 2와 3인 애플리케이션 메시지를 두 개 더 전송합니다.
<S:Envelope xmlns:...><S <ns2:MessageNumber>2</ns2 </S:Header>...><Text>SECOND </S:Envelope> <S:Envelope xmlns:...><S <ns2:MessageNumber>3</ns2 </S:Header>...<Text>THIRD </S:Envelope>
응답에는 Lower/Upper 속성이 각기 1/2 및 1/3인 AcknowledgementRanges가 포함됩니다.
TERMINATE가 콘솔로 출력된 후 port.close()가 호출됩니다. 이로 인해 RM 인프라스트럭처는 Body가 비어 있는 메시지를 전송하게 됩니다. 이 메시지의 헤더에는 Identifier와 값이 4인 MessageNumber를 포함하는 Sequence 요소가 있습니다. 헤더에는 또한 신뢰할 수 있는 채널이 곧 닫힐 것이라는 것을 서비스에게 알려주기 위해 LastMessage임을 나타내는 Action 요소도 포함되어 있습니다.
<S:Envelope xmlns:...><S <ns2:MessageNumber>4</ns2 <ns2:LastMessage/>... < <Action xmlns=..."> http://schemas.xmlsoap.org </Action>...
서비스는 모든 메시지를 수신했음을 나타내는 AcknowledgementRange 1/4를 포함하는 SequenceAcknowledgement로 응답합니다.
<s:Envelope xmlns:...><s <r:SequenceAcknowledgement> <r:AcknowledgementRange </r:SequenceAcknowledgement </s:Envelope>
메시지를 빠뜨린 경우 클라이언트는 해당 메시지를 재전송합니다.
클라이언트 RM 인프라스트럭처는 LastMessage를 보내고 모든 메시지가 수신되었음을 나타내는 SequenceAcknowledgement 응답을 받은 후에, TerminateSequence를 포함하는 Action 헤더 요소가 있는 메시지를 전송합니다.
Content-Type: application action= "http://schemas.xmlsoap.org
이것을 통해 서비스는 해당 Identifier 요소에 의해 식별되는 신뢰할 수 있는 채널과 연관된 모든 자원을 해제할 수 있다는 것을 알게 됩니다. 서비스는 HTTP 202로 응답합니다.
null: HTTP/1.1 202
요약
본 팁에서는 신뢰성 있는 메시징 테스트를 구축하고 수행하는 방법을 제시합니다. 이 때 Metro 기반의 클라이언트가 WCF 기반의 서비스 즉, 공개 WCF 엔드포인트와 통신합니다.
물론, WCF 기반의 클라이언트 또는 Metro 기반의 서비스를 사용하여 동일한 상호운용성 테스트 또는 다른 상호운용성 테스트를 수행할 수도 있습니다. Metro 기반 및 WCF 기반의 클라이언트와 서버의 다양한 조합으로 테스트를 수행함으로써 Metro와 .NET 간의 상호운용성을 검증할 수 있을 것입니다. 또한 그것을 통해 오픈 소스 Metro 프로젝트를 위한 기여자가 되어 사용자 자신이 제공한 코드의 상호운용성을 테스트할 수도 있을 것입니다.
이 아티클의 영문 원본은
http://java.sun.com/mailers/techtips/en ··· html%232
에서 볼수 있습니다.
"Java EE" 카테고리의 다른 글
- JAXR (JAVA API FOR XML REGISTRIES) (댓글 1개 / 트랙백 0개) 2005/05/18
- JAVA 트랜잭션 API 소개 (댓글 1개 / 트랙백 0개) 2005/03/23
- 환경 엔트리를 이용해서 배포의 사용자 정의하기 (댓글 2개 / 트랙백 0개) 2003/12/24
- EJB 세션 빈(Session Bean)을 모델 파사드(Model Facade)로 사용하기 (댓글 4개 / 트랙백 0개) 2007/04/10
- 레슨: JavaBeans의 개념 (댓글 0개 / 트랙백 0개) 2008/02/20
- Model Facade 사용하기 (댓글 4개 / 트랙백 0개) 2006/12/22
- 자바 기술을 이용한 AJAX의 활용 (댓글 1개 / 트랙백 0개) 2005/12/27
- JAVAMAIL API를 사용해서 HTML 이메일 보내기 (댓글 1개 / 트랙백 0개) 2004/04/28
- Java에서 RESTful 웹 서비스 구현하기 (댓글 1개 / 트랙백 0개) 2007/12/04
- 스키마 검증 프레임워크 (댓글 1개 / 트랙백 0개) 2005/11/22

댓글을 달아 주세요