UDDI 이용

본 장에서는 UDDI에 대한 기본 개념과 JEUS에서의 UDDI 사용 방법에 대해서 설명한다. 또한, UDDI 레지스트리를 프로그램적으로 접근할 수 있는 UDDI 클라이언트를 설명하며, UDDI 레지스트리에 쉽게 접근하기 위한 웹 기반 사용자 인터페이스에 대해서도 설명한다.

1. 개요

UDDI(Universal Description, Discovery and Integration) 스펙은 웹 서비스에 대한 정보의 공개 및 검색에 대한 방법을 정의한다. UDDI는 XML(Extensible Markup Language)과 SOAP(Simple Object Access Protocol)과 같은 기존 표준에 기반하고 있다.

UDDI는 일반적인 XML 형태로 구현된 비즈니스들과 그것들의 서비스 기술(description)에 대한 분산 레지스트리에 기반한 접근법을 취한다. UDDI 프로젝트의 핵심 컴포넌트는 UDDI 비즈니스의 등록과 비즈니스 Entity를 기술한 XML 파일과 그 웹 서비스이다.

UDDI는 프로그래밍 모델과 스키마를 제공하고 이것은 레지스트리를 사용하여 규칙을 정의한다. UDDI 스펙의 모든 API는 XML로 정의되어 있고, SOAP envelope으로 래핑(Wrapping)되어 있으며, HTTP를 통해 전송된다.

1.1. UDDI 이용

UDDI는 웹에서 비즈니스 레지스트리의 공유 오퍼레이션을 포함하고 있다. 대부분의 경우 프로그램과 프로그래머는 서비스의 정보를 위치시킬 때 특히 프로그래머의 경우에는 알려진 웹 서비스와의 호환성있는 시스템을 준비하거나, 자신의 웹 서비스를 다른 사람이 호출할 수 있게 기술하는데 UDDI 비즈니스 레지스트리를 사용한다. 이것은 UDDI 비즈니스 레지스트리에 지정된 정보를 사용한다.

UDDI 비즈니스 레지스트리는 비즈니스 레벨에서 사용되며 주어진 파트너가 특정 웹 서비스 인터페이스를 가지고 있는지 확인하거나, 해당 서비스를 가지고 해당 산업에 있는 회사를 찾거나 서비스에 대한 기술 정보를 얻기 위해 어떻게 파트너가 웹 서비스를 export시켰는지에 대한 정보를 위치시킨다.

UDDI Data 구조

UDDI 레지스트리에서 사용하는 핵심 정보 모델은 XML 스키마로 정의된다.

UDDI XML 스키마는 4개의 핵심 타입의 정보로 구성되어 있으며 기술자들이 파트너의 웹 서비스들을 사용하기 위해 알아야 하는 정보를 제공한다. 이 4가지는 시비스의 스펙에 대한 비즈니스 정보(<businessEntity>), 서비스 정보(<businessService>), 바인딩 정보(<bindingTemplate>) 그리고 기술 모델 정보(<tModel>)이다.

웹 서비스에 대한 정보를 기술하거나 검색할 때 사용되는 정보 계층 구조와 XML 태그를 아래 그림에서 보여주고 있다.

figure image014
정보 계층과 주요 XML 태그 이름
  • 비즈니스 정보(<businessEntity>)

    웹 서비스를 제공하는 비즈니스 혹은 기관을 기술한다. 이 Entity는 비즈니스의 기본 정보(이름, 수행하고 있는 비즈니스 설명, 연락처)를 나타낸다. Dun & Bradstreet D-U-N-S® Number 같은 비즈니스용 식별자들도 포함되어 있다.

  • 비즈니스 서비스(<businessService>)

    비즈니스 Entity에 의해 기술된 기관이 제공하는 관련 웹 서비스의 그룹을 기술한다. 이것은 하나의 비즈니스 Entity의 논리적 자식이다.

  • 서비스 바인딩(<bindingTemplate>)

    특정 웹 서비스를 이용하는 데 필요한 기술 모델을 기술한다. 이 Entity는 서비스와 관련된 바인딩 정보와 그러한 서비스들이 구현한 기술 스팩에 대한 레퍼런스를 제공하고 다양한 파일과 URL 기반의 발견 메커니즘에 대한 포인터도 제공한다.

  • 기술 모델 정보(<tModel>)

    웹 서비스 유형, 웹 서비스에서 사용하는 프로토콜, 분류 시스템과 같은 재사용이 가능한 개념을 나타내는 "technical model"을 기술한다. 이 기술 모델은 비즈니스 간에 주고받는 표준, 웹 서비스 인터페이스 정의 같은 모든 종류의 것을 포함한다. 그래서 새로운 웹 서비스를 구성하여 WSDL 문서를 기술했다면, 이 WSDL 정의는 기술 모델에 저장된다.

2. JEUS에서 UDDI 서버 운영

JEUS의 UDDI는 UDDI 레지스트리 서버와 UDDI 클라이언트 라이브러리, 웹 기반 사용자 인터페이스로 구성되어 있다. JEUS의 UDDI는 UDDI 버전 2.0과 버전 3.0의 데이터 구조와 프로그래밍 API를 지원한다.

본 절에서는 JEUS에 UDDI 모듈을 deploy하는 방법과 JEUS UDDI 서버 기동에 대해 설명한다.

  • JEUS UDDI DataStore를 생성하는 방법

  • JEUS UDDI 서버를 deploy하는 방법

  • JEUS UDDI 서버를 구성하고 설정하는 방법

JEUS UDDI 패키지의 핵심 라이브러리는 JEUS_HOME/lib/system 디렉터리에 위치하며 웹 인터페이스를 포함한 웹 컨텍스트에 관련된 모듈은 EAR 포맷으로 제공된다.

2.1. UDDI DataStore 생성

JEUS의 UDDI 서버는 데이터 영속성을 위해서 관계형 DB가 필요하다. JEUS UDDI 서버는 ANSI 표준 SQL을 지원하는 어떤 관계형 DB라도 사용할 수 있다.

JEUS UDDI DataStore는 JDBC를 사용하며 설정 과정은 간단하다. 첫 번째로 JEUS UDDI 서버 패키지와 함께 제공되는 DB 스크립트를 사용하여 새로운 UDDI DB를 생성한다(DB 스크립트는 JEUS_HOME/lib/systemapps/uddi/dbscripts 디렉터리에 위치한다). DataStore의 구성 설정을 하기 위해서는 JEUS에서 'uddiDB’라는 데이터소스를 설정해야 한다.

JEUS_HOME/lib/systemapps/uddi/conf 디렉터리의 예제 파일을 참고한다.

2.2. UDDI 서버 Deploying

UDDI DB 구성 설정이 완료되었다면 JEUS UDDI 서버를 deploy해야 한다.

JEUS UDDI 서버 EAR 패키지는 JEUS가 설치될 때 JEUS_HOME/lib/systemapps/uddi 디렉터리에 생성된다(파일 이름은 jeusuddi_v2c.ear과 jeusuddi_v3c.ear이다).

JEUS UDDI 서버를 deploy하는 것은 다른 EAR 애플리케이션을 deploy하는 과정과 같다. 예제에서는 컨텍스트 이름이 'uddi’로 UDDI가 deploy되는 것을 가정한다.

UDDI 서버 Deploying : <jeus-web-dd.xml>
<jeus-web-dd>
    <res-ref>
        <jndi-info>
            <ref-name>jdbc/uddiDB</ref-name>
            <export-name>UDDIDB</export-name>
        </jndi-info>
    </res-ref>
</jeus-web-dd>
UDDI 서버 Deploying : <web.xml>
<web-app>
    . . .
    <resource-ref>
        <res-ref-name>jdbc/uddiDB</res-ref-name>
        . . .
    </resource-ref>
</web-app>

JNDI 데이터소스 이름인 'jdbc/uddiDB’는 기본값으로 사용되는 JNDI 데이터소스 이름이다. 서버에 설정된 실제 데이터소스와 연결하는 <export-name>은 'UDDIDB’이다. 다른 JNDI 데이터소스 이름을 사용한다면 이 구성 설정 파일들을 수정한다.

2.3. UDDI 서버 구성 설정

JEUS UDDI 서버를 구성하기 위해서는 있는 설정 파일 uddi.properties를 수정해야 한다. 파일은 JEUS_HOME/lib/application 디렉터리에 위치한다. 만약 이 설정 파일 존재하지 않으면 deploy할 때 기본 설정 파일을 자동으로 생성한다.

다음은 uddi.properties 파일의 기본 설정에 대한 설명이다.

UDDI Property Key 설명

uddi.operatorName

UDDI 오퍼레이터 이름이다.

uddi.operatorURL

UDDI 오퍼레이터 사이트 URL이다.

uddi.auth

현재 사용 중인 UDDI 인증 모듈이다.

(기본값 : 'jeus.webservices.uddi.auth.DefaultAuthenticator')

uddi.dataSource

현재 사용 중인 UDDI DataStore 모듈이다.

(기본값 : 'java:comp/env/jdbc/uddiDB')

2.4. 새로운 사용자 추가

UDDI 레지스트리에 UDDI 데이터를 공개하기 위해서는 UDDI 레지스트리의 인증을 얻어야 한다.

JEUS UDDI 레지스트리의 Publisher의 인증은 2단계 과정을 거친다.

  1. 사용자 ID/password를 통해 사용자를 인증

    JEUS UDDI 레지스트리는 기본 인증 모듈인 jeus.webservices.uddi.auth.DefaultAuthenticator를 가지고 있다. 기본적인 인증 모듈은 인증 시도에 대해 간단하게 승인한다. 이것은 단순히 UDDI 사용자의 userid를 인증할 뿐이다.

    JEUS UDDI 레지스트리는 추가적인 인증 모듈인 jeus.webservices.uddi.auth.XMLDocAuthenticator를 제공한다. 이것은 XML 문서를 바탕으로 하며, ’JEUS_HOME/lib/application’에 있는 uddi-user.xml를 추가하거나 수정해야 한다.

    다음은 예제 XML 문서이다.

    <?xml version="1.0" encoding="UTF-8"?>
    <uddi-users>
        <user userid="administrator" password="jeusadmin" />
        <user userid="tmaxsoft" password="password" />
        <user userid="jeus" password="password" />
        <user userid="webservices" password="password" />
    </uddi-users>

    개발자는 Custom 인증 모듈을 개발할 수 있다. 전형적으로 UDDI 레지스트리는 외부의 인증 메커니즘을 사용할 수 있음을 의미한다. 추가적인 JEUS UDDI 인증 모듈은 JEUS UDDI 사용자가 특정 환경에서 어떻게 인증될지 결정함에 따라서 JEUS UDDI 사용자에 의해 개발될 수 있다.

    다음 코드는 Custom JEUS UDDI 인증 모듈을 개발하는 방법에 대한 예제이다.

    import jeus.webservices.uddi.auth.BaseAuthenticator;
    import org.apache.juddi.error.RegistryException;
    
    public class SampleAuthenticator implements BaseAuthenticator {
    
        public SampleAuthenticator() {
        }
    
        public String authenticate(String userID, String credential)
            throws RegistryException {
            // TODO Part implemented by developer.
            return userID;
        }
    }
  2. 인증된 사용자를 UDDI 레지스트리 사용자로 등록

    등록하는 방법에는 UDDI 웹 사용자 인터페이스를 이용하는 방법과 DataStore에 직접 등록하는 방법이 있다. 본 절에서는 DataStore에 직접 등록하는 방법만을 설명하고 UDDI 웹 인터페이스를 사용하는 방법은 JEUS 서버에서의 UDDI Explorer 사용을 참고한다.

    UDDI 레지스트리의 사용자인 Publisher가 UDDI DataStore에 정의되었는지 확인한다. Publisher는 UDDI DB의 PUBLISHER 테이블에 Publisher를 식별하는 Row가 있을 때 정의된다. SQL을 사용하여 사용자를 정의할 수 있다.

    다음은 'jeus’라는 새로운 publisher를 정의하는 예이다.

    INSERT INTO PUBLISHER (PUBLISHER_ID,PUBLISHER_NAME,ADMIN)
    VALUES ('jeus','JEUS','false');
    컬럼명 설명

    PUBLISHER_ID

    Publisher의 user ID는 인증할 때 사용된다. 외부의 인증 서비스를 통하여 인증할 때 사용되는 값과 동일해야 한다.

    PUBLISHER_NAME

    Publisher의 이름(또는 UDDI 안에 검증된 이름)이다.

    ADMIN

    Publisher가 관리적인 권한을 가졌는지 여부를 나타낸다. 이 컬럼의 값은 true 또는 false이다.

2.5. UDDI 서버 실행

JEUS 서버를 기동시킨다. UDDI 서버의 URL은 다음과 같은 형태이다.

http://hostname:port/context/

기본적으로 JEUS UDDI 서버의 context path는 '/uddi’이다. 여기서 JEUS HTTP Listener의 기본 포트 8088을 사용한다고 가정한다면 URL은 다음과 같다.

http://localhost:8088/uddi/

웹 브라우저에서 이 URL을 호출하였다면 다음과 같은 화면으로 이동한다.

figure image016
JEUS UDDI 레지스트리 초기 화면

3. JEUS 서버에서의 UDDI Explorer 사용

JEUS UDDI Explorer는 UDDI 레지스트리의 UDDI 데이터의 등록, 수정, 질의, 삭제 등의 작업을 하기 위한 웹 애플리케이션이다.

JEUS UDDI Explorer는 다음과 같은 기능들을 제공한다.

  • Private UDDI 레지스트리에 대한 Querying

  • Private UDDI 레지스트리에 대한 Publish

  • JEUS UDDI Explorer 설정

본 절에서는 JEUS UDDI Explorer 웹 사용자 인터페이스의 사용 방법에 대해서 설명한다.

3.1. UDDI 레지스트리 Querying

JEUS UDDI Explorer의 Search을 이용하면 이름으로 Business, Service, Technical Model을 검색할 수 있다.

'UDDI Registry'를 사용해서 UDDI 레지스트리 오퍼레이터를 선택할 수 있고, 'Search For a'에서 Entity 타입을 선택할 수 있다. UDDI Registry와 Entity 타입(Business, Service, Technical Model)을 선택한 후 아래의 텍스트 필드에 찾을 이름의 일부 또는 이름 전체를 입력한다. 와일드 카드로 '%' 심볼을 이용할 수 있다. 'exact name' 또는 'case sensitive'를 사용해서 결과를 필터링할 수 있다.

figure image018
UDDI Search 입력 폼 화면

찾을 이름을 입력 후 [submit] 버튼을 클릭하면 검색을 시작한다. 선택된 UDDI 레지스트리는 사용자가 입력한 이름으로 시작하는 Businesses, Services, Technical Model들의 목록을 조회한다.

JEUS UDDI Explorer는 찾은 Entity에 대한 상세 내역을 다음과 같이 출력한다.

figure image020
UDDI 레지스트리에서 찾은 결과 화면

3.2. UDDI 레지스트리에 대한 Publish

UDDI 레지스트리에 Publish하기 위해서는 사용자 ID와 패스워드를 사용하여 UDDI 레지스트리에 로그인해야 한다. 사용자가 접속한 후 JEUS UDDI Explorer는 사용자가 등록한 비즈니스들의 목록과 Technical Model들을 조회한다. 등록한 비즈니스 또는 Technical Model은 왼쪽 트리의 [+]를 클릭하면 등록된 서비스들 및 기타 정보들을 간략하게 확인할 수 있고, 다시 오른쪽 화면에서는 이에 대한 상세한 정보 열람 및 수정이 가능하다.

[Add Provider], [Add TModel] 버튼을 클릭해서 기본적인 비즈니스나 Technical Model을 추가할 수 있다. 만약 등록된 레지스트리를 삭제하나 수정하는 경우는 [Delete], [Edit] 버튼을 사용한다.

figure image022
등록한 entry 화면
비즈니스 추가

다음은 비즈니스를 추가하는 과정에 대한 설명이다.

  1. RegisteredInfo 화면에서 [Add Provider] 버튼을 클릭하면 화면은 Provider 화면으로 이동하면 기본값 'New Provider’라는 이름을 가진 비즈니스가 추가된 것을 확인할 수 있다. 화면에서 사용자는 [Edit] 버튼 등을 통해 이름을 포함한 여러 정보들을 수정할 수 있다. 'Name' 항목에 'JEUS Web Services’로 입력하고 [Update] 버튼을 클릭한다.

  2. Provider 화면[Detail], [Contact], [Identifier], [Category], [Discovery URL] 탭에서는 비즈니스 설명이나 사용자의 연락처, Discovery URL, 카테고리 그리고 식별자 같은 부가 정보를 추가할 수 있다. 'Description' 항목을 'eBiz using Webservices’로 입력한다.

    figure image024
    Provider 수정 화면
서비스 추가

다음은 서비스를 추가하는 과정에 대한 설명이다.

  1. Provider 화면[Service] 탭에서 [Add Service] 버튼을 클릭한다. 서비스들은 항상 비즈니스와 연관되기 때문에 클릭하면 이 비즈니스와 연관된 서비스가 새로 생성되고 Service 화면으로 이동한다.

  2. Service 화면Provider 화면과 같이 각각의 탭들을 통해 여러 가지 정보들을 수정하거나 조회할 수 있다.

    figure image026
    서비스 추가 화면
tModel 추가

다음은 tModel을 추가하는 과정에 대한 설명이다.

  1. RegisteredInfo 화면으로 돌아와서 [Add TModel] 버튼을 클릭하면 기본값인 'New TModel’이라는 이름을 가진 사용자의 새로 추가된 테크니컬 모델과 함께 TModel 화면으로 이동한다.

  2. TModel 화면에서는 부가적인 정보인 테크니컬 모델에 대한 설명, Overview URL, Category 그리고 Identifier을 추가할 수 있다. 'Name' 항목을 'tModel for eBiz’로 입력한다.

  3. TModel 화면에서 [Overview Document] 탭으로 이동한 후 [Add OverviewDoc] 버튼을 클릭하면 사용자의 테크니컬 모델에 대한 Overview Doc 정보를 제공하는 화면으로 이동한다. 화면에서 'OverviewURL' 샘플 주소에 'http://localhost:8088/ws/tmodel.wsdl’로 입력한다.

  4. [Add] 버튼을 클릭하면 테크니컬 모델에 저장한다.

    figure image028
    tModel 저장 결과 화면
서비스 바인딩(bindingTemplate) 추가

다음은 서비스 바인딩(bindingTemplate)을 추가하는 과정에 대한 설명이다.

  1. 화면 왼쪽의 트리뷰에서 비즈니스와 관련되는 [+]를 클릭한다. 비즈니스에 연관된 서비스를 클릭하면 오른쪽 화면에 서비스에 대한 자세한 내용이 조회된다.

  2. 서비스 바인딩을 추가하려면 [Binding] 탭에서 [Add Binding] 버튼을 클릭하면 Binding 화면으로 이동한다.

    figure image030
    서비스 바인딩(bindingTemplate) 추가 화면
  3. Binding 화면[Detail] 탭에는 Access Point에 대한 주소를 수정할 수 있다. 화면에서 'Address' 항목을 'http://localhost:8088/uddi’로 입력한다.

  4. [Instance Info] 탭으로 이동하여 [Add Instance Info] 버튼을 클릭한다. [Search] 버튼을 클릭하면 사용자가 공개된 tModel들을 찾을 수 있는 화면을 나타난다. 찾을 tModel의 전체 이름이나 처음 몇 자를 'Search for tModel names containing'에 입력하여 찾을 수 있다.해당 항목에 'tModel’로 입력한다.

  5. 화면 왼쪽의 트리뷰에서 'tModel for eBiz'를 선택한 후 [Add Instance Info] 버튼을 클릭하면 테크니컬 모델을 바인딩한 서비스가 저장된다.

    figure image032
    서비스 바인딩(bindingTemplate) 저장 결과 화면

3.3. UDDI Explorer 설정

JEUS UDDI Explorer에서 JEUS UDDI 레지스트리를 사용하기 위한 사용자를 등록할 수 있다. 우선, 관리자 권한을 가진 사용자로 로그인을 해야 한다. 로그인한 후에 메뉴에서 User 링크를 선택하면 다음과 같은 화면이 나타난다. 이 화면에서 관리자는 새로운 사용자를 추가, 수정, 삭제를 할 수 있다.

[Add User] 버튼을 클릭하면 다음과 같은 신규 사용자 등록 화면이 나타난다.

figure image036
JEUS UDDI Explorer 사용자 관리 화면

화면에서 'Username''Fullname'은 필수 입력 사항이다. 'Username'은 JEUS UDDI Explorer에 로그인과 UDDI Data를 공개하기 위한 사용자 ID이다. 입력값을 입력한 후에 [Add]를 클릭하면 사용자가 등록된다.

figure image038
JEUS UDDI Explorer 사용자 등록 화면

4. UDDI 클라이언트 생성

JEUS UDDI 클라이언트 라이브러리는 UDDI 레지스트리에 대한 Java 인터페이스를 제공한다. 이를 통해 구축한 웹 서비스들을 공개할 수 있고, 필요한 웹 서비스를 검색할 수 있다. JEUS UDDI 클라이언트 라이브러리는 일종의 Java 클래스 라이브러리이며, UDDI 레지스트리와 상호 작용하는 API를 제공한다.

본 절에서는 UDDI 클라이언트 라이브러리를 사용해서 UDDI 클라이언트를 작성, 컴파일, 실행하는 방법을 설명한다. 제시된 예제는 UDDI v2.0 기반의 UDDI 클라이언트이며, UDDI v3.0 기반의 UDDI 클라이언트도 유사한 방법으로 사용할 수 있다.

4.1. UDDI 클라이언트 작성

다음은 UDDI 클라이언트를 작성하는 과정에 대한 설명이다.

  • UDDI 클라이언트 클래스

    UDDI 클라이언트 애플리케이션의 핵심 클래스이다. 이것은 UDDI 레지스트리에 연결하고 질의를 수행하며 결과를 처리하는 모든 메소드를 가지고 있다.

    다음의 예제 코드는 어떻게 객체를 생성하고 UDDI 레지스트리를 참조하는지 보여준다. 여기에 제시된 예제 애플리케이션에서 'UDDIClient’는 UDDI 레지스트리와 상호 작용을 하기 위해 사용하는 것이다.

    UDDIClient client = new UDDIClient();
    client.setInquiryURL("http://localhost:8088/uddi/inquiry");
    client.setPublishURL("http://localhost:8088/uddi/publish");
  • UDDI 레지스트리에서 비즈니스 질의

    Vector inNames = new Vector();
    inNames.add(new Name("test_Biz"));
    
    BusinessList list = client.find_business(null, inNames, null, null, null, null, 0);

    find_business 메소드는 다수의 매개변수를 갖는다. 2번째 매개변수는 검색어이고, 7번째 매개변수는 조건에 부합하는 리턴 값의 최대 개수이다(0은 조건에 부합하는 모든 값을 리턴함을 의미한다).

    보다 상세한 검색을 위해서 식별자(identifiers), 분류자(categories), URL, 기술 모델(tModel) 등을 검색 조건에 추가할 수 있다. 위 방법을 통해 조건에 부합하는 비즈니스 리스트를 조회할 수 있다.

    다음은 리스트에 포함된 비즈니스들의 이름을 출력하는 예제 코드이다.

    BusinessInfos infos = list.getBusinessInfos();
    Vector businesses = infos.getBusinessInfoVector();
    if (businesses != null) {
        for (int i = 0; i < businesses.size(); i++) {
            BusinessInfo info = (BusinessInfo)businesses.elementAt(i);
            Vector outNames = info.getNameVector();
            for (int j = 0; j < outNames.size(); j++) {
                Name name = (Name)outNames.elementAt(j);
                System.out.println(name.getValue());
            }
        }
    }
  • UDDI 레지스트리에서 비즈니스 공개

    새로운 UDDI 데이터를 UDDI 레지스트리에 공개하기 위해서는 그 UDDI 레지스트리로부터 인증을 얻어야 한다.

    다음은 UDDI 레지스트리로부터 인증을 얻는 코드이다.

    AuthToken authToken = client.get_authToken(“userID”, “password”);

    다음 단계는 새로운 비즈니스 Entity를 생성하고 이것을 인증을 얻은 UDDI 레지스트리에 공개하는 것이다. 예제에서는 단순하게 비즈니스 이름만을 정의하였다.

    BusinessEntity businessEntity = new BusinessEntity();
    businessEntity.setBusinessKey("");
    businessEntity.addName(new Name("TmaxSoft", "en"));
    
    Vector businessVector = new Vector();
    businessVector.add(businessEntity);
    BusinessDetail detail = client.save_business(
        authToken.getAuthInfoString(), businessVector);
  • UDDI 레지스트리에서 비즈니스 삭제

    Vector inNames = new Vector();
    inNames.add(new Name("TmaxSoft"));
    
    BusinessList list = client.find_business(null, inNames, null, null, null, null, 0);

    위의 방법을 통해서 공개된 비즈니스 리스트를 얻었다. 이제 각각의 비즈니스를 삭제할 것이다.

    다음은 이에 대한 예제 코드이다.

    Vector businessInfoVector = list.getBusinessInfos().getBusinessInfoVector();
    for (int i = 0; i < businessInfoVector.size(); i++) {
        BusinessInfo info = (BusinessInfo)businessInfoVector.elementAt(i);
        DispositionReport dispositionReport = client.delete_business(
            authToken.getAuthInfoString(), info.getBusinessKey());
    }

4.2. UDDI 클라이언트 컴파일

UDDI 클라이언트 코드를 컴파일하려면 클라이언트 소스 코드가 위치한 디렉터리로 이동한다. 예제에서는 JEUS_HOME/samples/webservice/uddi/client 디렉터리에서 다음의 명령어를 실행한다.

JEUS_HOME/samples/webservice/uddi/client$ ant build

4.3. UDDI 클라이언트 실행

UDDI 클라이언트 코드를 실행하려면 클라이언트 소스 코드가 위치한 디렉터리로 이동한다. 예제에서는 JEUS_HOME/samples/webservice/uddi/client 디렉터리에서 다음의 명령어를 실행한다.

JEUS_HOME/samples/webservice/uddi/client$ ant

실행 결과는 다음과 유사할 것이다.

##### Running FindBusinessSample #####
Found Business name: test_Biz
##### Done #####

5. XML 디지털 서명 사용법

본 절에서는 XML 디지털 서명의 개념과 생성 및 검증 방법에 대해 설명한다.

5.1. 디지털 서명(Digital Signature)

UDDI v3.0 스펙(specification)에서의 중요한 변화 중 하나는 디지털 서명의 지원이다. UDDI Entity가 디지털 서명되면 데이터 무결성(integrity)과 확실성(authenticity)이 UDDI에 의해 전달된다. UDDI 레지스트리에 대한 요청자(inquirer)는 서명된 데이터만을 요청하도록 질의(Query)를 조정할 수 있고, 요청자가 UDDI 레지스트리로부터 가져온 데이터를 검증할 때 데이터가 정확하게 공개자(Publisher)가 의도한 것인지를 확신할 수 있게 된다.

UDDI 레지스트리에 대한 공개자는 UDDI Entity를 소유하였다고 주장하는 누군가에 의해 잘못 전달되지 않을 것을 확신할 수 있게 되고, 공개자가 서명된 데이터를 가지게 되면, 공개자는 그 데이터의 무결성에 대해 확신할 수 있게 된다.

디지털 서명은 UDDI의 데이터 품질을 향상시키고, 높은 신뢰성을 필요로 하는 웹 서비스 환경에서 요구하는 데이터 보호와 부인 방지를 가능하게 한다.

UDDI v3.0 사양에서는 XML 서명 구문과 처리 방법(http://www.w3.org/TR/xmldsig-core/)을 사용하여 다음의 상위 수준 UDDI Entity에 대한 XML 디지털 서명을 지원한다.

  • 비즈니스 Entity(businessEntity)

  • 비즈니스 서비스(businessService)

  • 서비스 바인딩(bindingTemplate)

  • 기술 모델(tModel)

  • publisherAssertion

UDDI v3.0 스펙은 XML 서명과 검증을 클라이언트의 역할로 정의하고 있다. 그에 따라 JEUS 환경에서도 클라이언트의 XML 서명과 검증을 지원하고 있으며, 본 안내서에서 기술하고 있는 UDDI 클라이언트는 JEUS UDDI 클라이언트를 사용하고 있음을 가정한다.

XML 디지털 서명의 지원에 대한 보다 많은 정보는 UDDI v3.0 스펙의 "Appendix I, Support For Digital Signatures"를 참고한다.

5.2. UDDI 클라이언트 XML 서명 생성 방법

XML 서명은 공개(publication) API 호출에 대한 결과로써 UDDI 레지스트리에 저장되는 상위 수준 element에 대하여 계산된다.

각 API의 호출별 수행되는 element는 다음과 같다.

API element

save_business

businessEntity

save_service

businessService

save_binding

bindingTemplate

save_tModel

tModel

set_publisherAssertions

add_publisherAssertions

publisherAssertion

JEUS UDDI 클라이언트는 'java.security.*'의 java.security.PrivateKey 객체와 java.security.cert.X509Certificate 객체를 사용하여 상위 수준 UDDI Entity를 서명한다.

다음은 PrivateKey 객체와 X509Certificate 객체를 얻는 간단한 예제이다.

import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
...

String keystoreType = "JKS";
String privateKeyAlias = "...";
String privateKeyPasswd = "...";
String certificateAlias = "...";
...
KeyStore keyStore = KeyStore.getInstance(keystoreType);
keyStore.load(...);

PrivateKey privateKey = (PrivateKey)keyStore.getKey(
    privateKeyAlias, privateKeyPasswd.toCharArray());
X509Certificate certificate =
    (X509Certificate)keyStore.getCertificate(certificateAlias);

얻어진 PrivateKey 객체와 X509Certificate 객체를 사용하여 XML 서명을 지원하는 JEUS UDDI 클라이언트 프로그래밍 방법은 기본적으로 기존의 JEUS UDDI 클라이언트 프로그래밍 방법과 동일하다. 자세한 프로그래밍 방법은 UDDI 클라이언트 생성을 참고한다.

공개되는 UDDI Entity는 jeus.uddi.v3.client.UDDIClient 클래스에서 제공하는 다음의 메소드를 사용하여 서명된다.

public BindingDetail save_binding(
       String authInfo, bindingTemplate bindingTemplate,
       PrivateKey privateKey, X509Certificate certificate)
public BusinessDetail save_business(
       String authInfo, BusinessEntity businessEntity,
       PrivateKey privateKey, X509Certificate certificate)
public ServiceDetail save_service(
       String authInfo, BusinessService businessService,
       PrivateKey privateKey, X509Certificate certificate)
public TModelDetail save_tModel(
       String authInfo, TModel tModel,
       PrivateKey privateKey, X509Certificate certificate)
public PublisherAssertions set_publisherAssertions(
       String authInfo, PublisherAssertion publisherAssertion,
       PrivateKey privateKey, X509Certificate certificate)

서명할 UDDI Entity는 Entity key를 포함해야 한다. Entity key가 없는 UDDI Entity를 공개할 경우 UDDI 레지스트리는 그 UDDI Entity에 대하여 새로운 Entity key를 할당하게 되고, 이것은 그 UDDI Entity에 대한 서명을 유효하지 않게 만든다. 그러므로 공개자는 Entity key가 포함된 UDDI Entity를 공개할 역할이 있다.

예를 들어 businessService는 serviceKey와 businessKey를 포함해야 한다. businessService가 bindingTemplate을 포함하고 있으면, bindingTemplate은 bindingKey와 serviceKey를 포함하고 있어야 한다.

5.3. UDDI 클라이언트 XML 서명 검증

XML 서명 검증은 요청(inquiry) API 호출에 대한 결과로써 응답되는 상위 수준 element에 대해 수행된다.

각 API의 호출별 수행되는 element는 다음과 같다.

API element

get_businessDetail

businessEntity

get_serviceDetail

businessService

get_bindingDetail

bindingTemplate

get_tModelDetail

tModel

find-relatedBusinesses API

publisherAssertion

전형적으로 UDDI 레지스트리는 클라이언트의 서명 검증을 하지 않는다. JEUS UDDI 클라이언트는 서명 검증을 위한 별도의 방법을 제공하지 않는다. 해당 요청 API 호출에 대한 응답에 서명 element가 포함된 경우 내부적으로 서명 검증을 자동 수행한다. 서명이 유효하지 않을 때 java.sercurity.SignatureException을 던진다.

6. UDDI subscription 사용법

본 절에서는 UDDI subscription의 개념과 생성 방법, 클라이언트 프로그래밍 및 이메일을 받기 위한 서버 설정 방법에 대해 설명한다.

6.1. 기본 개념

UDDI v3.0 스펙(specification)의 새로운 subscription API는 동기적(synchronous), 비동기적(asynchronous)인 방법으로 공지(notification) 기능을 지원한다.

subscription API는 UDDI 레지스트리를 추적할 수 있는 방법을 제공한다. 이를 사용하여 가입자(subscriber)는 특별한 질의(Query) 또는 가입자가 관심을 갖는 Entity를 기반으로 subscription을 수립할 수 있다. 이 subscription을 기반으로 하여 UDDI 정보에 대한 동기식 요청 또는 레지스트리에 의해 가입자에게 이루어지는 비동기식 공지를 통해 UDDI 레지스트리의 내용 변경을 추적할 수 있다.

figure image040
UDDI subscription 흐름도

UDDI subscription은 다음의 경우에 유용하다.

  • UDDI 레지스트리에 등록된 신규 비즈니스 또는 서비스에 대한 공지

  • 기존 비즈니스 또는 서비스에 대한 변화를 감지

6.2. 생성 방법

subscription의 수립과 그 결과의 감시는 일반적으로 여러 단계가 필요한 과정이다.

  1. UDDI 레지스트리가 제공하는 비동기식 공지를 받기 위해서는 서비스를 생성해야 한다(가입자가 동기식 요청만을 사용한다면 이 단계를 생략할 수 있다). 가입자는 가입자가 구현한 HTTP/SOAP 웹 서비스나 이메일를 통해서 subscription 결과를 받도록 선택할 수 있다.

  2. subscription을 사용하기 위한 필터 조건을 선택한다. 이것은 응답된 결과에 대한 분석이 용이하도록 보다 제한적으로 조건을 선택해야 한다. 일반적으로 가입자는 그가 사용한 subscription 필터[subscriptionFilter] 조건이 가능한 제한적임을 보증해야 한다.

  3. save_subscription API를 사용하여 subscription 요청을 저장한다.

  4. 필요에 따라 HTTP/SOAP 또는 이메일에 의한 공지를 처리한다.

6.3. UDDI subscription 예제

본 절에서는 비동기식 공지와 동기식 요청 예제에 대해서 설명한다.

비동기식 공지

다음은 간단한 비동기식 공지 형태의 subscription 작동 예제이다.

  1. 비즈니스의 변화를 추적할 subscription을 생성한다.

    이를 위하여 가입자는 bindingTemplate을 가진 서비스를, 공지를 전달할 UDDI 레지스트리에 등록해야 하고, 이 bindingTemplate에는 'notify_subscriptionListener' 서비스 또는 이메일을 통해 공지를 받을 수 있도록 Endpoint를 표시한다.

    <save_binding xmlns="urn:uddi-org:api_v3">
        <authInfo>myAuthCode</authInfo>
        <bindingTemplate bindingKey="" serviceKey="uddi:myservicekey">
           <description>notify_subscriptionListener binding for
               my subscription.
           </description>
           <accessPoint URLType="https">
               https://www.myCompany.com/services/notify_subscriptionListener
           </accessPoint>
           <tModelInstanceDetails>
               <tModelInstanceInfo
                   tModelKey="uddi:uddi.org:v3_subscriptionlistener"/>
           </tModelInstanceDetails>
        </bindingTemplate>
    </save_binding>
    <save_binding xmlns="urn:uddi-org:api_v3">
        <authInfo>myAuthCode</authInfo>
        <bindingTemplate  bindingKey="" serviceKey="uddi:myservicekey">
           <description>
               E-mail binding for my subscription.
           </description>
           <accessPoint URLType="email">
               mailto:mySubscriberEmail@xyz.com
           </accessPoint>
        </bindingTemplate>
    </save_binding>
  2. 주기적(예제에서는 매 5일마다)으로 공지하도록 subscription을 생성하고 저장한다. 예에서 'brief' 속성은 공지되는 결과에 단지 Entity key만을 사용하도록 제한하기 위해 사용하였다.

    <save_subscription xmlns="urn:uddi-org:sub_v3">
        <authInfo>myAuthCode</authInfo>
        <subscriptions>
            <subscription brief="true">
                <subscriptionFilter>
                    <find_service xmlns="urn:uddi-org:api_v3" >
                        <findQualifiers>
                            <findQualifier>
                                uddi:uddi.org:findqualifier:sql99:like
                            </findQualifier>
                        </findQualifiers>
                        <categoryBag>
                            <keyedReference
                                tModeKey="uddi:uddi.org:ubr:taxonomy:naics"
                                keyName="Motor Vehicle Parts"
                                keyValue="42112_"/>
                        </categoryBag>
                    </find_service>
                </subscriptionFilter>
                    <bindingKey>
                         bindingKeyOfTheClientsNotifySubscriptionListenerService
                    </bindingKey>
                    <notificationInterval>P5D</notificationInterval>
                    <maxEntities>1000</maxEntities>
            </subscription>
        </subscriptions>
    </save_subscription>
  3. 다음은 notify_subscriptionListener API를 구현한 클라이언트의 호출로 공지되는 결과이다. 'brief' 속성을 'true’로 설정한 subscription은 결과를 단지 Entity key만으로 공지한다. Entity key는 <keyBag>에 포함되어 공지되며, 이미 삭제된 Entity의 key들을 포함한 <keyBag>은 <deleted>가 'true’로 설정되어 공지된다.

    <notify_subscriptionListener>
        <subscriptionResultsList>
            <coveragePeriod>
                <startPoint>20020101T00:00:00</startPoint>
                <endPoint>20020131T00:00:00</endPoint>
            </coveragePeriod>
            <subscription brief="true">
                <subscriptionFilter>
                    <find_service xmlns="urn:uddi-org:api_v3" >
                        <findQualifiers>
                            <findQualifier>
                                uddi:uddi.org:findqualifier:sql99:like
                            </findQualifier>
                        </findQualifiers>
                        <categoryBag>
                            <keyedReference
                                tModeKey="uddi:uddi.org:ubr:taxonomy:naics"
                                keyName="Motor Vehicle Parts"
                                keyValue="42112_"/>
                        </categoryBag>
                    </find_service>
                    </subscriptionFilter>
                    <bindingKey>
                        bindingKeyOfTheClientsNotifySubscriptionListenerService
                    </bindingKey>
                    <notificationInterval>P5D</notificationInterval>
                    <maxEntities>1000</maxEntities>
                    <expiresAfter>20030101T00:00:00</expiresAfter>
            </subscription>
            <keyBag>
                <deleted>false</deleted>
                <serviceKey>matchingKey1</serviceKey>
                <serviceKey>matchingKey2</serviceKey>
                <serviceKey>matchingKey3</serviceKey>
                <serviceKey>matchingKey4</serviceKey>
            </keyBag>
            <keyBag>
                <deleted>true</deleted>
                <serviceKey>matchingKey5</serviceKey>
                <serviceKey>matchingKey6</serviceKey>
            </keyBag>
        </subscriptionResultsList>
    </notify_subscriptionListener>
동기식 요청

API를 사용하여 동기식으로 subscription 결과를 가져올 수 있다. 동기식 요청을 위한 subscription의 저장은 subscription Listener를 위한 <bindingKey>를 필요로 하지 않는다는 것을 제외하면, 비동기식 공지 예제에 살펴본 subscription의 저장 방법과 동일하다.

다음은 전형적인 get_subscriptionResults API를 사용하는 예제이다. (출처: http://uddi.org/pubs/uddi-v3.0.2-20041019.htm)

<get_subscriptionResults>
    <authInfo>myAuthCode</authInfo>
    <subscriptionKey>mySubscriptionKey</subscriptionKey>
    <coveragePeriod>
        <startPoint>20020101T00:00:00</startPoint>
    </coveragePeriod>
</get_subscriptionResults>

위의 요청은 동기적으로 <subscriptionResultList> 형태로 응답된다. (출처: http://uddi.org/pubs/uddi-v3.0.2-20041019.htm)

<subscriptionResultsList>
    <chunkToken>"nodeGeneratedToken"</chunkToken>
    <coveragePeriod>
        <startPoint>20020101T00:00:00</startPoint>
    </coveragePeriod>
    <subscription  brief="true">
        <subscriptionFilter>
            <find_service xmlns="urn:uddi-org:api_v3">
                <findQualifiers>
                    <findQualifier>
                        uddi:uddi.org:findqualifier:sql99:like
                    </findQualifier>
                </findQualifiers>
                <categoryBag>
                    <keyedReference
                        tModeKey="uddi:uddi.org:ubr:taxonomy:naics"
                        keyName="Motor Vehicle Parts"
                        keyValue="42112_"/>
                </categoryBag>
            </find_service>
        </subscriptionFilter>
        <bindingKey>
            bindingKeyOfTheClientsNotifySubscriptionListenerService
        </bindingKey>
        <notificationInterval>P5D</notificationInterval>
        <maxEntities>1000</maxEntities>
        <expiresAfter>20030101T00:00:00</expiresAfter>
    </subscription>
    <keyBag>
        <deleted>false</deleted>
        <serviceKey>matchingKey1</serviceKey>
        <serviceKey>matchingKey2</serviceKey>
        <serviceKey>matchingKey3</serviceKey>
        <serviceKey>matchingKey4</serviceKey>
    </keyBag>
</subscriptionResultsList>

6.4. UDDI subscription 클라이언트 프로그래밍

JEUS UDDI 클라이언트는 subscription API를 지원하기 위해 jeus.uddi.v3.client.UDDIClient 클래스에 다음과 같은 메소드를 제공한다.

public subscriptions save_subscription(
    String authInfo, Subscription subscription)
public void delete_subscription(
    String authInfo, String subscriptionKey)
public Subscriptions get_subscriptions(String authInfo)
public SubscriptionResultsList get_subscriptionResults(
    String authInfo, String subscriptionKey,
    CoveragePeriod coveragePeriod, String chunkToken)

subscription 클라이언트 프로그래밍은 기본적으로 기존의 JEUS UDDI 클라이언트 프로그래밍 방법과 동일하다. 이때 subscription 필터 조건을 가능한 제한적으로 설정하는 것에 주의해야 한다.

다음은 간단한 JEUS UDDI subscription 클라이언트 프로그래밍의 예이다.

UDDIClient client;
. . .

AuthToken authToken = client.get_authToken(user, password);

// Make a subscription
Subscription subscription = new Subscription();

// Make a subscriptionFilter
FindBusiness findBusiness = new FindBusiness();
findBusiness.addName(new Name("biz"));
subscription.setSubscriptionFilter(
new SubscriptionFilter(findBusiness));

// execute save_subscription request
Subscriptions subscriptions = client.save_subscription(
    authToken.getAuthInfoString(), subscription);

Subscription savedSubscription = subscriptions.getSubscription(0);
String subscriptionKey =
    savedSubscription.getSubscriptionKeyString();
. . .

등록된 subscription으로부터 얻은 subscription 키는 이 subscription을 delete_subscription API를 사용하여 삭제하거나 get_subscriptionResults API를 사용하여 동기식 요청으로 결과를 얻어올 때 사용된다. get_subscriptions API는 가입자가 등록한 모든 subscription을 조회할 때 사용된다.

가입자가 subscription을 등록할 때 등록된 subscription의 결과가 단지 Entity key만을 사용하도록 제한되길 원한다면 다음과 같이 subscription에 'brief' 속성을 'true’로 설정한다.

. . .
// Make a Subscription
Subscription subscription = new Subscription();
Subscription.setBrief(true);
. . .

가입자가 비동기식 공지를 받기를 원하다면, subscription Listener를 위한 <bindingKey>를 subscription에 설정해야 하고 공지 간격을 설정해야 한다. 공지 간격은 XML 스키마에 정의된 xsd:duration 타입이며, 'PnYnMnDTnHnMnS’를 갖는다.

. . .
// Make a Subscription
Subscription subscription = new Subscription();
subscription.setBindingKey(
    bindingKeyOfTheClientsNotifySubscriptionListenerService);
subscription.setNotificationInterval("P5D");
. . .

6.5. 이메일 공지를 받기 위한 UDDI 서버 설정

JEUS UDDI 서버가 가입자에게 이메일를 통해 subscription 결과를 공지하기 위해서는 메일 서버에 대한 설정이 필요하다. 이 설정은 JEUS UDDI 서버의 설정 파일인 'uddi.properties’에 설정된다.

. . .
uddi.subscription.mail.smtp.host=...
uddi.subscription.mail.smtp.port=...
uddi.subscription.mail.smtp.from=...
. . .

7. UDDI WSDL Publishing 사용법

본 절에서는 UDDI WSDL Publishing의 사용 방법에 대해 설명한다.

7.1. UDDI WSDL Publishing

e-business 표준을 위한 기구인 OASIS에서는 UDDI v2.0, v3.0 스펙(specification) 외에 몇 가지 이에 관련된 Technical Note들에 대해 작업하고 있는데 그 중 하나가 바로 UDDI WSDL Publishing(Using WSDL in a UDDI Registry, Version 2.0.2)이다.

WSDL은 abstract한 인터페이스와 임의의 네트워크 서비스의 프로토콜 바인딩들을 제공함으로써 UDDI 표준을 보완할 수 있다. OASIS의 "Using WSDL in a UDDI Registry"는 바로 이러한 WSDL의 description들과 UDDI의 Data Structure와의 매핑에 관해 권고하는 접근 방식을 밝히고 있다. 자세한 사항은 OASIS TC Using WSDL in a UDDI Registry, Version 2.0.2를 참고한다.

figure image041
WSDL description과 UDDI Data Structure 매핑

7.2. wsdl2uddi 사용

본 절에서는 JEUS에서 제공하는 wsdl2uddi 툴에 대해 설명하고, wsdl2uddi를 사용해서 wsdl을 UDDI에 Publishing하는 방법을 설명한다.

wsdl2uddi

JEUS UDDI WSDL Publishing은 이러한 매핑을 자동화해주는 툴인 wsdl2uddi를 제공한다. 기본적인 동작 방법은 콘솔에서 다음과 같이 입력하여 명령어를 수행한다.

$ wsdl2uddi

사용 방법은 다음과 같다.

Usage: wsdl2uddi UDDIVersion WSDLURI [wsdl-options] -uddiInquiry
UDDIInquiryURI -uddiPublish UDDIPublish -uddiUsername UDDIUsername
-uddiPassword UDDIPassword [options]

* wsdl-options
    -wsdlUsername                username to access the WSDL-URI
    -wsdlPassword                password to access the WSDL-URI

* options
    -level LEVEL                 specify log level.
                                 LEVEL : SEVERE, WARNING, INFO, FINE, FINER, FINEST
    -verbose                     same as -level FINE

각 파라미터의 설명은 다음과 같다.

파라미터 설명

UDDIVersion

알맞은 값은 v2 또는 v3이다. (필수 항목)

WSDLURI

실제 WSDL이 존재하는 곳의 URI 값이다. (필수 항목)

wsdl-options

보안이 설정된 WSDL에 접근할 경우 username과 password를 설정할 때 사용한다.

UDDIInquiryURI

실제 UDDI의 Inquiry URI 값을 지정한다. (필수 항목)

UDDIPublishURI

실제 UDDI의 publish URI 값을 지정한다. (필수 항목)

UDDIUsername

UDDI에 접근할 때 필요한 username을 설정한다. (필수 항목)

UDDIPassword

UDDI에 접근할 때 필요한 password를 설정한다. (필수 항목)

options

로그 레벨을 지정할 경우 사용한다.

임의의 WSDL을 UDDI에 Publishing

wsdl2uddi 툴을 이용하여 하나의 WSDL을 UDDI에 Publishing한다.

$ wsdl2uddi v2 BasicAuthServiceTestService.wsdl -uddiInquiry
http://localhost:8088/uddi/inquiry -uddiPublish
http://localhost:8088/uddi/publish -uddiUsername jeus -uddiPassword jeus
[2006.12.12 17:22:47][2][] [client-10] [WSVC-5240] Analyzing WSDL :
BasicAuthServiceTestService.wsdl

위와 같이 입력하면 wsdl2uddi 툴은 자동으로 wsdl을 해석해서 알맞은 바인딩 규칙에 따라 UDDI에 Publishing한다.

Publishing된 wsdl을 UDDI에서 확인하면 다음과 같다.

figure image042
UDDI에 Publishing된 wsdl의 모습