External Resource

본 장에서는 JEUS와 연동하여 하나의 시스템을 구축할 수 있는 다양한 외부 리소스(External Resource)에 대한 소개와 설정 방법에 대해 설명한다. 외부 리소스에 대한 설정이나 사용법에 관한 자세한 내용들은 각 외부 리소스의 안내서를 참고한다.

1. 리소스 종류

External Resource는 애플리케이션이 JEUS를 통해서 접근할 수 있는 JEUS 외부에 존재하는 리소스로 DB가 대표적인 예이다. 이러한 리소스들은 JEUS에 관련 설정을 추가함으로써 연결이 가능하다.

만약 External Resource에서 JCA 표준 호환의 리소스 어댑터를 제공하는 경우에는 리소스 어댑터를 deploy해서 사용하길 권장한다.

다음은 JEUS에 설정할 수 있는 리소스이다.

  • 데이터소스

    데이터소스(Datasource)는 JDBC 호환 DB를 의미한다. 데이터소스는 클라이언트에서 직접적으로 접근할 수 있는데 이런 경우에는 특별히 JEUS에 설정하지 않아도 된다. 그러나 데이터소스를 설정하면 JNDI를 이용해서 JDBC Connection Pool을 사용할 수 있으므로 애플리케이션이 더욱 편리하게 DB에 접근할 수 있다. 데이터소스의 설정은 DB Connection Pool과 JDBC를 참고한다.

  • Mail Resource

    메일 리소스(Mail Resource)는 SMTP와 같은 메일 프로토콜을 이용하여 클라이언트 애플리케이션으로부터 이메일(e-mail)을 전송할 때 사용한다. JEUS에서는 JNDI Export name에 이메일 호스트의 정보를 bind하고, 클라이언트에서 간접적으로 접근하여 호스트를 사용하도록 한다. JNDI를 Lookup하면 jakarta.mail.Session 타입의 메일 소스를 가져온다.

  • URL Resource

    URL 리소스는 애플리케이션에서 외부 URL 객체를 JNDI를 통해 접근할 수 있도록 한다. URL이 변경되는 경우 해당 URL 설정을 수정함으로써 애플리케이션의 소스 수정 없이 그대로 사용할 수 있도록 한다. JNDI를 Lookup하면 java.net.URL 타입의 URL 객체를 가져온다.

  • Message Bridge

    Message Bridge는 여러 JMS 벤더의 Destination 사이에 연결을 위해 사용된다. Jakarta Messaging 2.0 스펙을 충족하는 MQ라면 무엇이든 설정 가능하며 자세한 내용은 JEUS MQ 안내서의 JEUS MQ Message Bridge를 참고한다.

  • Custom Resource

    Custom Resource는 Java Bean 형태의 리소스를 JNDI repository에 bind시킬 수 있다. lookup할 때 JNDI ObjectFactory를 통해 등록한 서비스를 사용할 수 있도록 하는 일반적인 리소스이다.

  • External Source - IBM MQ, Sonic MQ 등

    JEUS와 연결할 수 있는 비정규화된 소스들을 말한다. 일반적으로 JEUS에 설정할 수 있는 것으로는 IBM MQ, Sonic MQ 등의 Jakarta Messaging 제품들과 Tmax TP Monitor 등이 있다. 이 리소스들은 JEUS에 설정하지 않아도 Java API를 통해서 직접적으로 액세스할 수도 있다. 그러나 트랜잭션 매니저에서 이 소스들을 관리하려면 설정을 해야 한다(트랜잭션 매니저 참조).

  • External Resource

    JEUS위에서 동작하는 리소스들을 말한다. 주로 JEUS와 연동되는 WebT나 jTmax, 또는 InifiniteCache에서 사용한다. JEUS에서 이런 External Resource를 사용하려면 jeus.external.ResourceBootstrapper를 구현한 class를 등록해야 한다.

  • Concurrency Utilities Resource

    Jakarta Concurrency와 관련한 리소스를 정의한다. 이를 통해 애플리케이션 서버 상에서 관리 가능한 작업들을 정의하고, 작업이 실행될 때 컨텍스트를 유지하며 동작할 수 있다. 자세한 설명은 JEUS Jakarta Concurrency 안내서를 참고한다.

2. 리소스 설정

본 절에서는 각각의 리소스를 설정하는 방법에 대해 설명한다.

리소스는 도메인 범위에 설정하고, 서버가 부팅할 때 이 정보를 읽어 자신의 서버에 리소스를 등록한다.

2.1. 데이터소스 설정

데이터소스는 DB 관련 설정을 다루게 된다. 이 내용은 DB Connection Pool과 JDBC에 기술되어 있으므로 해당 절을 참고한다.

2.2. 메일 소스 설정

JEUS에 클라이언트 애플리케이션에서 메일을 보낼 때 사용될 SMTP 호스트를 설정할 수 있다. 이메일 호스트에 대한 정보는 Jakarta Mail 사양을 참고한다.

domain.xml을 다음과 같이 편집하여 메일 소스를 설정할 수 있다.

<servers>
    <server>
        <name>server1</name>
        ...
        <resources>
            <mail-source>
                <mail-entry>
                    <export-name>mailSource</export-name>
                    <mail-property>
                        <name>mail.smtp.auth</name>
                        <value>true</value>
                    </mail-property>
                </mail-entry>
            </mail-source>
        </resource>
    </server>
</servers>

'Main Property'에 설정하는 속성명은 Jakarta Mail 사양을 따르므로 해당 사양을 참고해서 지정한다.

2.3. URL 소스 설정

다음은 JNDI 이름은 PRIMARY_URL과 SECONDARY_URL이고 각각에 bind되는 URL이다.

http://www.foo.com
http://www.bar.com

URL 소스 설정을 위해 domainl.xml을 다음과 같이 편집한다.

<resources>
    <url-source>
        <url-entry>
            <export-name>PRIMARY_URL</export-name>
            <url>http://www.foo.com</url>
        </url-entry>
        <url-entry>
            <export-name>SECONDARY_URL</export-name>
            <url>http://www.bar.com</url>
        </url-entry>
    </url-source>
</resources>

2.4. Custom Resource 설정

Custom Resource는 Java Bean 형태의 리소스를 JNDI ObjectFactory를 통해 Lookup하여 사용할 수 있도록 하는 일반적인 리소스이다. 본 절에서는 Custom Resource 구현 방법과 등록 방법에 대해서 설명한다.

다음은 Java Bean 형태의 리소스 클래스와 리소스 인스턴스를 생성할 ObjectFactory 클래스에 대한 예제이다. 이 클래스는 SERVER_HOME/lib/application 또는 DOMAIN_HOME/lib/application에 있어야 한다.

Custom Resource를 생성할 팩토리 클래스의 예제
package dog;

import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.spi.ObjectFactory;

public class DogFactory implements ObjectFactory {
    public DogFactory() {}

    public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment)
        throws Exception {
        Dog dog = Dog.getInstance();
        System.out.println("Creating a dog whose name is " + dog.getName() + ",
and age is " + dog.getAge());
        return dog;
    }
}
Custom Resource 예제 클래스
package dog;

public class Dog implements java.io.Serializable {
    public static final String DOG_NAME = "wangwang";
    public static final int DOG_AGE = 1;

    private static Dog instance = new Dog();

    private int age = DOG_AGE;
    private String name = DOG_NAME;

    public Dog() {}

    public static Dog getInstance() {
        return instance;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean equals(Object anObject) {
        if (this == anObject) {
           return true;
        }
        if (anObject instanceof Dog) {
           Dog anotherDog = (Dog) anObject;
           return (this.age == anotherDog.age && this.name.equals(anotherDog.name));
        }
        return false;
    }

}

Custom Resource를 동적으로 추가하기 위해서는 이미 해당 클래스들이 서버의 클래스 로더에 클래스 패스로 잡혀있어야 가능하다. 만약 서버의 클래스 로더에서 이 클래스를 로딩할 수 없으면 동적 추가 명령은 pending 처리된다. 이럴 경우 Custom Resource 클래스를 SERVER_HOME/lib/application 또는 DOMAIN_HOME/lib/application에 추가하고 서버를 재기동해야 한다.

Custom Resource를 삭제하는 동작은 Graceful하게 수행되지 않는다. 즉, 진행 중인 요청이 있더라도 이를 완료하지 않기 때문에 사용자 애플리케이션에서는 에러가 발생할 수 있음을 유의한다.

콘솔 툴 사용

Custom Resource는 콘솔 툴을 통해서 서버에 등록된 리소스에 대한 조회 명령이 가능하다. 또한 새로운 Custom Resource를 동적으로 추가, 삭제하는 것이 가능하다.

[MASTER]domain1.adminServer>add-custom-resource custom/dog -resource dog.Dog -factory dog.DogFactory
Successfully performed the ADD operation for A custom resource.
Check the results using "list-custom-resources or add-custom-resource"

[MASTER]domain1.adminServer>list-custom-resources
List of Custom Resources
================================================================================
+-------------+--------------------+--------------------------+----------------+
| Export Name |   Resource Class   |       Factory Class      |   Properties   |
+-------------+--------------------+--------------------------+----------------+
| custom/dog  | dog.Dog            | dog.DogFactory           | [test=1,       |
|             |                    |                          |test1=2]        |
+-------------+--------------------+--------------------------+----------------+
================================================================================

[MASTER]domain1.adminServer>add-custom-resource-to-servers custom/dog -servers server1
Successfully performed the ADD operation for A custom resource.
Check the results using "list-custom-resources"

[MASTER]domain1.adminServer>remove-custom-resource custom/dog
Successfully performed the REMOVE operation for A custom resource.
Check the results using "list-custom-resources or remove-custom-resource"

[MASTER]domain1.adminServer>list-custom-resources
List of Custom Resources
================================================================================
+-------------+--------------------+--------------------------+----------------+
| Export Name |   Resource Class   |       Factory Class      |   Properties   |
+-------------+--------------------+--------------------------+----------------+
(No data available)
================================================================================

2.5. External Source 설정

외부 소스는 크게 JMS 소스와 Connector로 나뉜다.

JMS Source

JMS 소스를 추가하기 위해서는 다음과 같이 domain.xml의 편집이 필요하다.

<resources>
    <external-source>
        <jms-source>
            <vendor>ibmmq</vendor>
            <factory-class-name>FirstClassName</factory-class-name>
            <resource-type>QCF</resource-type>
            <export-name>exportName</export-name>
            <queue>MQ</queue>
            <queueManager>MQManager</queueManager>
        </jms-source>
    </external-source>
</resources>

다음은 JMS 소스 설정 항목에 대한 설명이다.

항목 설명

Vendor

JMS 벤더를 설정한다. 다음의 값 중 하나를 설정한다.

  • ibmmq : IBM사의 제품이다.

  • sonicmq : Sonic MQ이다.

  • others : 그 외의 제품들이다.

Factory Class Name

해당 JMS 리소스의 Factory Class의 이름을 지정한다.

Resource Type

해당하는 JMS의 타입을 결정한다.

다음의 8가지 값 중에 하나를 설정한다.

  • QCF

  • TCF

  • Q

  • T

  • XAQCF

  • XATCF

  • LOCALXAQCF

  • LOCALXATCF

Export Name

JNDI에 바인딩될 이름을 지정한다. 사용자는 이 이름을 이용하여 JMS의 ConnectionFactory, Destination 등을 이용할 수 있다.

Queue

'Rresource Type'이 'Q’일 때만 사용한다.

Queue Manager

'Rresource Type'이 'Q’일 때만 사용한다.

Topic

'Rresource Type'이 'T’일 때만 사용한다.

Property

JMS 리소스에 필요한 속성들을 기록한다. 이 설정은 name, type, value로 구성된다.

각 태그에 대한 자세한 내용은 자세한 것은 IBM MQ나 Sonic MQ의 매뉴얼을 참조한다.

Connector 추가

domain.xml을 다음과 같이 편집하여 Connector를 추가할 수 있다.

<resources>
    <external-source>
        <connector>
            <resource-adapter-module-id>connectorModuleId</resource-adapter-module-id>
            <worker-pool>
                <min>0</min>
                <max>5</max>
                <keep-alive-time>60000</keep-alive-time>
                <queue-size>4096</queue-size>
                <shutdown-timeout>-1</shutdown-timeout>
            </worker-pool>
        </connector>
    </external-source>
</resources>

Connector에 대한 자세한 설명은 JEUS Jakarta Connectors 안내서를 참고한다.

2.6. External Resource 설정

JEUS에서는 Tmax나 InfiniCache와 같이 타 제품을 JEUS에서 연동하기 위해서 External Resource를 설정할 수 있다. Tmax와의 연동을 위해서는 JEUS에서 Tmax로 연결해서 Tmax의 트랜잭션 서비스를 사용하는 아웃바운드(Outbound)인 WebT와 Tmax에서 JEUS로 온 서비스 요청을 받아주는 인바운드(Inbound)인 JTmax를 설정할 수 있다. 자세한 내용은 관련된 Tmax 매뉴얼의 "JTmax Server Guide"를 참고한다.

본 절에서는 External Resource 구현 방법과 등록 방법에 대해서 설명한다.

다음은 jeus.external.ResourceBootstrapper 인터페이스이다. 이 인터페이스를 구현한 클래스는 SERVER_HOME/lib/application 또는 DOMAIN_HOME/lib/application에 있어야 한다.

jeus.external.ResourceBootstrapper
package jeus.external;

import javax.naming.Context;
import java.util.Map;

/**
 * 외부 resource를 JEUS에서 사용할 수 있도록 하는 bootstrapper이다.
 */
public interface ResourceBootstrapper {
    /**
     *
     * @param propertyMap resource의 설정을 가진 Map
     */
    void setProperties(Map propertyMap) throws InvalidPropertyException;

    /**
     * resource를 bind한다.
     * @param context
     */
    void initResources(Context context);

    /**
     * 사용할 수 있는 property의 정보를 return한다.
     * @return
     */
    ResourcePropertyInfo[] getPropertyInfo();

    /**
     *
     * @param propertyMap 변경되는 property가 있는 Map
     */
    void modifyProperties(Map propertyMap) throws InvalidPropertyException;

    /**
     * resource를 다시 bind할때 호출된다.
     * @param context
     */
    void reconfigResources(Context context);

    /**
     * resource를 제거할때 사용한다.
     * @param context
     */
    void destroyResources(Context context);
}

External Resource를 동적으로 추가하기 위해서는 이미 해당 클래스들이 서버의 클래스 로더에 클래스 패스로 잡혀있어야 가능하다. 만약 서버의 클래스 로더에서 이 클래스를 로딩할 수 없으면 동적 추가 명령은 pending 처리된다. 이럴 경우 External Resource 클래스를 SERVER_HOME/lib/application 또는 DOMAIN_HOME/lib/application에 추가하고 서버를 재기동해야 한다.

External Resource를 삭제하는 동작은 Graceful하게 수행되지 않는다. 즉, 진행 중인 요청이 있더라도 이를 완료하지 않기 때문에 사용자 애플리케이션에서는 에러가 발생할 수 있음을 유의한다.

콘솔 툴 사용

External Resource는 콘솔 툴을 통해서 서버에 등록된 리소스에 대한 조회 명령이 가능하다. 또한 새로운 External Resource를 동적으로 추가, 삭제하는 것이 가능하다.

[MASTER]domain1.adminServer>add-external-resource test/ext -resource test.ext.TestResourceBootstrapper
Successfully performed the ADD operation for A external resource.
Check the results using "list-external-resources or add-external-resource"

[MASTER]domain1.adminServer>list-external-resources
List of External Resources
=============================================================================
+----------+---------------------------------------------------+------------+
| Name     |                   Resource Class                  | Properties |
+----------+---------------------------------------------------+------------+
| test/ext | test.ext.TestResourceBootstrapper                 | []         |
+----------+---------------------------------------------------+------------+
=============================================================================

[MASTER]domain1.adminServer>add-external-resource-to-servers test/ext -servers server1
Successfully performed the ADD operation for A external resource.
Check the results using "list-external-resources"

[MASTER]domain1.adminServer>remove-external-resource test/ext
Successfully performed the REMOVE operation for A external resource.
Check the results using "list-external-resources or remove-external-resource"

[MASTER]domain1.adminServer>list-external-resources
List of External Resources
=========================================================================
+------+---------------------------------------------------+------------+
| Name |                   Resource Class                  | Properties |
+------+---------------------------------------------------+------------+
(No data available)
=========================================================================