Web Service 첨부파일

몇달동안 프로젝트로 인해 정리를 못했다.
Web Service 첨부파일에 대한 개괄적인 설명서이다.
webservice_attachment_analysis.doc

by lovemade | 2007/07/31 14:37 | WS-FirstGeneration | 트랙백 | 덧글(0)
WS Example1 - JMS를 이용한 비동기식 웹 서비스
제목에서와 같이 이번장은 JMS를 이용한 비동기식 웹 서비스를 구현하는데 JMS및 MDB(Message Driven Bean)에 대한 얘기는 하지 않는다. 본문을 보고싶다면
http://www.ibm.com/developerworks/kr/library/ws-tip-altdesign1/ 를 참조하고 나는 부가적인 설명을 하면서 정리해나가도록 하겠다.

우선 웹서비스에서는 기본적인 4가지의 메세지 교환패턴(MEP)이 있는데 다음과 같다.

  1. Request - Response : 가장 흔히 사용되는 형태의 MEP이다. 메세지가 서비스 요청자로부터 서비스 제공자로 전송되는 단순한 형태의 교환이다. 메세지를 받으면 서비스 제공자는 서비스 요청자에게 메세지로 응답한다. 동기, 비동기 방식 모두 쓰인다,
  2. Fire and Forget : 서비스 요청자에서 서비스 제공자로 메세지를 보내고 응답을 기다리지 않는다. 가장 단순한 비동기 방식이다.
  3. 기억안남.(기대 - 응답인가?)
  4. 기억안남. 책보고 정리하자. (Notification인가?)
여하튼, WSDL1.1에서는 위의 1,2를 권고하고 있다.사실 위의 MEP는 새로운 것이 못되고 단지 웹서비스에 적용하기 위해 정리한 것에 불과하다. 이번장에서 사용할 MEP는 비동기방식의 1번방식인 요청-응답 패턴이다.

Figure1. 비동기식 쿼리패턴




Figure1의 flow는 다음과 같다.
1. 요청자는 서비스 공급자(Service Provider)에게 요청을 제출한다. 서비스 공급자는 메시지를 대기열에 넣고
   (queue) 요청자(Requester)가 요청 상태를 확인할 때 사용할 수 있는 코릴레이션 ID를 리턴한다.
   여기서 코릴레이션 ID는 활성화된 즉, 실행중인 서비스에 대한 식별키라고 보는 것이 맞을 것이다.
2. 요청 프로세서는 요청을 대기열에서 빼고(dequeue) 이를 처리한다. 일반적으로 이 요청 프로세싱은 장기 실행이
   다. 일단 프로세싱이 완료되면 프로세서(Processor)는 응답 메시지를 대기열에 넣는다.
3. 어떤 지점에서 그 요청에 대한 응답이 준비가 되면 요청자는 서비스 공급자에게 요청한다. 응답이 대기열에 들어가
   면 공급자는 요청자에게 응답을 리턴한다. 응답을 사용할 수 없다면 공급자는 이를 요청자에게 보고한다. 요청자는
   요청을 취소하거나 계속 기다릴 수 있다. 선택된 기간 동안, 응답이 사용 가능하게 될 때까지 공급자는 폴링(polling)
   한다.

간단하게 관련지식을 알았으면 예제로 들어가 보자.

[  서비스 인터페이스 설계 ]

List1. AsyncService.wsdl

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions
  targetNamespace="http://one.wspattern.developerworks.ibm.com"
  xmlns:impl="http://one.wspattern.developerworks.ibm.com"
  xmlns:intf="http://one.wspattern.developerworks.ibm.com"
  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
  xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">

  <wsdl:types>
  <schema
    targetNamespace="http://one.wspattern.developerworks.ibm.com"
    xmlns="http://www.w3.org/2001/XMLSchema"
    xmlns:impl="http://one.wspattern.developerworks.ibm.com"
    xmlns:intf="http://one.wspattern.developerworks.ibm.com"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <complexType name="ResponseCheck">
    <sequence>
     <element name="correlationID" nillable="true" type="xsd:string"/>
    </sequence>
   </complexType>
   <element name="ResponseCheck" nillable="true" type="impl:ResponseCheck"/>
   <complexType name="Response">
    <sequence>
     <element name="type" type="xsd:int"/>
     <element name="correlationID" nillable="true" type="xsd:string"/>
     <element name="refresh" type="xsd:int"/>
     <element name="a" nillable="true" type="xsd:string"/>
     <element name="b" nillable="true" type="xsd:string"/>
     <element name="c" nillable="true" type="xsd:string"/>
    </sequence>
   </complexType>
   <element name="Response" nillable="true" type="impl:Response"/>
   <complexType name="Request">
    <sequence>
     <element name="a" nillable="true" type="xsd:string"/>
     <element name="b" nillable="true" type="xsd:string"/>
     <element name="c" nillable="true" type="xsd:string"/>
    </sequence>
   </complexType>
   <element name="Request" nillable="true" type="impl:Request"/>
  </schema>
 </wsdl:types>

   <wsdl:message name="submitRequestRequest">
      <wsdl:part name="request" type="intf:Request"/>
   </wsdl:message>
   <wsdl:message name="checkResponseResponse">
      <wsdl:part name="checkResponseReturn" type="intf:Response"/>
   </wsdl:message>
   <wsdl:message name="checkResponseRequest">
      <wsdl:part name="check" type="intf:ResponseCheck"/>
   </wsdl:message>
   <wsdl:message name="submitRequestResponse">
      <wsdl:part name="submitRequestReturn" type="intf:Response"/>
   </wsdl:message>

   <wsdl:portType name="AsyncService">
      <wsdl:operation name="checkResponse" parameterOrder="check">
         <wsdl:input message="intf:checkResponseRequest" name="checkResponseRequest"/>
         <wsdl:output message="intf:checkResponseResponse" name="checkResponseResponse"/>
      </wsdl:operation>
      <wsdl:operation name="submitRequest" parameterOrder="request">
         <wsdl:input message="intf:submitRequestRequest" name="submitRequestRequest"/>
         <wsdl:output message="intf:submitRequestResponse" name="submitRequestResponse"/>
      </wsdl:operation>
   </wsdl:portType>
  
   <wsdl:binding name="AsyncServiceSoapBinding" type="intf:AsyncService">
      <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
      <wsdl:operation name="checkResponse">
         <wsdlsoap:operation soapAction=""/>
         <wsdl:input name="checkResponseRequest">
            <wsdlsoap:body namespace="http://one.wspattern.developerworks.ibm.com" use="literal"/>
         </wsdl:input>
         <wsdl:output name="checkResponseResponse">
            <wsdlsoap:body namespace="http://one.wspattern.developerworks.ibm.com" use="literal"/>
         </wsdl:output>
      </wsdl:operation>
      <wsdl:operation name="submitRequest">
         <wsdlsoap:operation soapAction=""/>
         <wsdl:input name="submitRequestRequest">
            <wsdlsoap:body namespace="http://one.wspattern.developerworks.ibm.com" use="literal"/>
         </wsdl:input>
         <wsdl:output name="submitRequestResponse">
            <wsdlsoap:body namespace="http://one.wspattern.developerworks.ibm.com" use="literal"/>
         </wsdl:output>
      </wsdl:operation>
   </wsdl:binding>

   <wsdl:service name="AsyncServiceService">
      <wsdl:port binding="intf:AsyncServiceSoapBinding" name="AsyncService">
         <wsdlsoap:address location="http://localhost:8088/ws/services/AsyncService"/>
      </wsdl:port>
   </wsdl:service>
</wsdl:definitions>


List1은 비동기 응답-요청이 적용된 WSDL파일이다. 해석하는 것이 가능한가? 가능하면 OK~~ 계속진행해도 좋다. 가능하지 않다면 기본학습을 하고 읽자.

으~~ 간만에 이어서 쓰게 된다. 회사일이 너무 바빠서....

위에 적힌 WSDL을 가지고 Tmax JEUS에서 실행시켜보기로 하겠다. 우선 Tmax Technet에 가서 JEUS 5 Fix#18을 받은 후 적절한 디렉토리에 설치한다. 또한 JMaker 최신 Version을 받아서 설치하자. JMaker는 JEUS환경의 Eclipse기반 개발툴이다. 손쉽게 웹서비스를 구축할 수 있기 때문에 WSDL2JAVA, JAVA2WSDL, java mapping 파일 같은 중노동(?)을 하지 않아도 된다......고 Tmax에서는 얘기하겠지만 천만의 말씀, 만만의 콩떡이다.말그대로 JEUS환경에 적절한 WSDL을 갖고는 손쉽게 구축이 가능한데 위와 같이 비 JEUS 친화적인(?) WSDL로는 generate된 java파일과 여러 Descriptor파일들의 설정이 맞지 않는다. 우선 WSDL2JAVA와 같은 command로 웹서비스를 생성시켜 직접 Deploy해보는것도 학습에는 여러 도움이 된다. 그래야 JMaker생성시킨 엉뚱한 결과물에도 대처가 가능하다. 어찌됐든 개발의 편의성이 있는것만은 사실이다. 하기 귀찮은 사람은 다음 파일을 다운받아서 Deplo시키자.wsexer002ear.ear 이 파일은 JMaker에서 생성시킨파일을 토대로 약간의 수정작업을 거친 ear파일이다. 열어보면 알겠지만 위의 WSDL과 차이점이 있는걸 발견할 수 있다. 여하튼 이런 얘기는 여기까지 하기로 하고 직접 작성한 것이든 위의 파일이든 JEUS 웹어드민을 통해 Deploy시키자.
 

by lovemade | 2007/02/21 23:26 | WS-FirstGeneration | 트랙백 | 덧글(0)
시작하며...
SOA의 구현측면을 봤을때 SOA의 핵심 solution이라고 할 수 있는 ESB를 가장 먼저 시장에 내세운 업체가 BEA이다. 국내에서는 TmaxSoft가 심혈을 기울여 개발하고 있기는 한데......

따라서 BEA가 SOA 선점을 위해 자사 핵심 solution으로 내세우고 있는 AquaLogic을 살펴보는 것도 나름대로의 의미가 있다고 봤기에 관련 학습을 하기로 했다. 나도 BEA Product에 대해서는 무지하기에 나름대로 힘든 여정이 될 것 같기도 한다. 그럼 시작해볼까나?
by lovemade | 2007/02/20 21:02 | SOA - BEA | 트랙백 | 덧글(0)
SOAP Part3 - Axis Practice
그럼 실질적으로 한번 구현을 해보자.
SOAP Part2에서 마지막에 첨부시킨 간단한 Hello 웹 서비스를 바탕으로 코드생성법과 해당코드에 대한 간단한 설명과 함께....
web service를 구현하는 방식에는 2가지가 있는데
첫번째는 Java 파일을 coding한 후 해당 Java파일을 바탕으로 WSDL파일을 생성한 후 deploy 시키는 방법과
두번째는 WSDL 파일로 Java파일을 생성한 후 deploy시키는 방법이 있다. 첫번째 방법은 서비스제공자를 만들때 많이 쓰이며 두번째 방법은 서비스 요청자를 만들때 많이 쓰인다.


[ JAVA2WSDL ]

- STEP1. Java Class생성

 Java파일을 작성한 후 웹 서비스를 생성할때 작성할 Java파일은 Interface Class와 해당 Interface를 Implement한 Java Class파일 2개가 필요하다라고 문서에는 나와있는데 Interface파일만 있어도 가능하다.다음 파일을 작성 및 complie한 후 적절한 디렉토리에 배치한다. 여기서는 Tomcat\webapps\axis\WEB-INF\classes 에 배치하고 있다.


List1. Java Interface File

package webservice.hello;
public interface HelloIF extends java.rmi.Remote {
      public String hello(java.lang.String name) throws java.rmi.RemoteException;
}




- STEP2. 구현된 Class로부터 WSDL생성.

Axis에서는 Axis.jar파일에 Java2Wsdl이라는 Class파일을 제공하고 있다. 해당 파일의 역할은 STEP1에서 구현한 2개의 Java Class로부터 WSDL파일을 생성하는 것인데 SOAP Part2에서 제공한 문서를 보면 사용법에 대한 자세한 사항이 나와있으니 참조하고.......다음과 같이 실행하자.

java org.apache.axis.wsdl.Java2WSDL -o c:\test\webservice\hello\Hello.wsdl
-l http://localhost:8080/axis/services/Hello -n http://hello.webservice -u literal -pwebservice.hello http://hello.webservice webservice.hello.HelloIF

부연해서 설명하자면 -l 옵션은 실제 웹서비스 URL경로를 지정하는데 WSDL문서를 받은 서비스요청자에서 실제 호출경로로 사용하므로 정확히 작성해야 한다. -n 옵션은 WSDL 문서에서 사용할 targetNamespace의 값을 설정한다. targetNamespace는 해당 문서에서 정의된 XML Element들을 식별하기 위한 것이다. 생성이 잘 되었다면 다음과 같을 것이다.

List2. Hello WSDL

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions
    targetNamespace="http://hello.webservice"
    xmlns:apachesoap="http://xml.apache.org/xml-soap"
    xmlns:impl="http://hello.webservice"
    xmlns:intf="http://hello.webservice"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/
    xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <!--WSDL created by Apache Axis version: 1.4 Built on Apr 22, 2006 (06:55:48 PDT)-->
  
   <wsdl:message name="helloResponse">
      <wsdl:part name="helloReturn" type="xsd:string"/>
   </wsdl:message>
   <wsdl:message name="helloRequest">
      <wsdl:part name="in0" type="xsd:string"/>
   </wsdl:message>

   <wsdl:portType name="HelloIF">
      <wsdl:operation name="hello" parameterOrder="in0">
         <wsdl:input message="impl:helloRequest" name="helloRequest"/>
         <wsdl:output message="impl:helloResponse" name="helloResponse"/>
      </wsdl:operation>
   </wsdl:portType>

   <wsdl:binding name="HelloSoapBinding" type="impl:HelloIF">
      <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
      <wsdl:operation name="hello">
         <wsdlsoap:operation soapAction=""/>
         <wsdl:input name="helloRequest">
            <wsdlsoap:body namespace="http://hello.webservice" use="literal"/>
         </wsdl:input>
         <wsdl:output name="helloResponse">
            <wsdlsoap:body namespace="http://hello.webservice" use="literal"/>
         </wsdl:output>
      </wsdl:operation>
   </wsdl:binding>

   <wsdl:service name="HelloIFService">
      <wsdl:port binding="impl:HelloSoapBinding" name="Hello">
         <wsdlsoap:address location="http://localhost:8080/axis/service/Hello"/>
      </wsdl:port>
   </wsdl:service>
</wsdl:definitions>

 List1의 WSDL파일을 보면 portType의 name이 HelloIF, operation의 name이 hello인데 HelloIF.java의 class명과 method명과 일치함을 알 수 있다. targetNamespace는 -n 옵션에서 정의한 값이 설정되어 있고 location에는 -l 옵션에서 정의한 값이 설정되어 있다. Bold된 단어를 하나씩 비교해가면서 확인해보면 연관성을 알 수 있을 것이다.

- STEP3. WSDD파일 및 Java파일 생성

WSDD(Web Service Deployment Descriptor)파일의 용도는 새로운 Handler, Chain 그리고 서비스를 올리기 위해 AdminClient에서 사용하는 설정파일이다. WSDD에 대한 자세한 사항은 해당 사이트를 참조하도록하자. AdminClient는 관리툴로서, Handler나 Chain같은 Axis리소스를 올리거나 내릴때 사용한다.
http://ws.apache.org/axis/java/reference.html#DeploymentWSDDReference

cmd#> java org.apache.axis.wsdl.WSDL2Java -o d:\ -d Application -s d:\Hello.wsdl

여기서는 d:\ 디렉토리에 wsdd파일 및 Java파일을 생성했다. 생성된 파일목록은 다음과 같다.
deploy.wsdd
undeploy.wsdd
HelloIF.java
HelloIFService.java
HelloIFServiceLocator.java
HelloSoapBindingImpl.java
HelloSoapBindingStub.java

java 파일에 대한 자세한 설명은 J2EE Web Service에서 자세히 다루기로 하고
deploy.wsdd와 undeploy.wsdd파일은 말그대로 deploy, undeploy 설정파일이다. HelloIF를 implement한 것이 HelloSoapBindingImpl이므로 해당 파일의 hello 메소드에 관련 로직을 작성하면 된다.


- STEP4. 서비스 deploy


java org.apache.axis.client.AdminClient -lhttp://localhost:8080/axis/services/AdminService deploy.wsdd


서비스 deploy를 완료한 후 http://localhost:8080/axis/servlet/AxisServlet에서 해당 서비스에 대한 deploy완료여부를 확인할 수 있다. 아니면 http://localhost:8080/axis/services/Hello?wsdl 로 확인가능하다.

 
by lovemade | 2007/02/20 20:44 | WS-FirstGeneration | 트랙백(2) | 핑백(1) | 덧글(0)


< 이전페이지 다음페이지 >