Java로 입력 노드 작성

시작하기 전에

Java 사용자 정의 노드는 .jar 파일로 분배됩니다. 본 주제에서는 Java를 사용하여 입력 노드를 작성하기 위해 수행할 단계를 설명합니다. 다음 단계에 대한 개요가 제공됩니다.
  1. 새 Java 프로젝트 작성
  2. 입력 노드 클래스 선언
  3. 노드 구성자 정의
  4. 버퍼로 외부 데이터 수신
  5. 메시지 전달
  6. 스레드 및 트랜잭션성 제어
  7. 노드 이름 선언
  8. 속성 선언
  9. 노드 기능 구현
  10. 디폴트 메시지 구문 분석기 속성 대체(선택사항)
  11. 노드의 인스턴스 삭제

새 Java 프로젝트 작성

Workbench 내에서 Java 노드를 작성할 수 있습니다. 이를 수행하려면 다음과 같이 새 Java 프로젝트를 작성해야 합니다.
  1. Java Perspective로 전환하십시오.
  2. 파일 > 새로 작성 > 프로젝트를 누르십시오. 왼쪽 메뉴에서 Java를 선택한 다음 오른쪽 메뉴에서 Java 프로젝트를 선택하십시오.
  3. 프로젝트에 이름을 제공하십시오.

    Java 설정 패널이 표시됩니다.

  4. 라이브러리 탭을 선택하고 외부 JAR 추가를 누르십시오.
  5. install_dir\classes\jplugin2.jar을 선택하십시오.
  6. 다른 빌드 설정값을 정의하려면 다른 탭의 프롬프트를 따르십시오.
  7. 완료를 누르십시오.
그 다음 이 프로젝트 내에서 Java 노드의 소스를 개발할 수 있습니다.

입력 노드 클래스 선언

MbInputNodeInterface를 구현하며 브로커의 LIL 경로에 들어 있는 모든 클래스는 브로커에 입력 노드로 등록됩니다. MbInputNodeInterface를 구현할 때는 이 클래스의 run 메소드 또한 구현해야 합니다. run 메소드는 메시지 플로우의 시작을 나타내고, 메시지를 구성하는 데이터를 포함하여, 플로우를 따라 메시지를 전달합니다. 지정된 스레드 모델에 따라 스레드가 사용 가능해지면 브로커는 run 메소드를 호출합니다.

예를 들면, 입력 노드 클래스를 선언하는 코드는 다음과 같습니다.

package com.ibm.jplugins;

import com.ibm.broker.plugin.*;

public class BasicInputNode extends MbInputNode implements MbInputNodeInterface
{
...
다음과 같이 Workbench에서 이를 수행할 수 있습니다.
  1. 파일 > 새로 작성 > 클래스를 누르십시오.
  2. 패키지 및 클래스 이름 필드를 적절한 값으로 설정하십시오.
  3. Superclass 텍스트 필드에서 텍스트를 삭제하고 찾아보기 단추를 누르십시오.
  4. MbInputNode를 선택하십시오.
  5. 인터페이스 텍스트 필드 옆의 추가 단추를 누르고 MbInputNodeInterface를 선택하십시오.
  6. 완료를 누르십시오.

노드 구성자 정의

노드가 인스턴스화될 때, 사용자 노드 클래스의 구성자가 호출됩니다. 이때 노드의 터미널을 작성하고, 속성의 디폴트 값을 초기화해야 합니다.

한 입력 노드에는 여러 출력 터미널이 연관되어 있지만 일반적으로 입력 터미널은 없습니다. 노드를 인스턴스화할 때 노드에 출력 터미널을 추가하려면 createOutputTerminal 메소드를 사용하십시오. 예를 들면, 세 가지 출력 터미널로 노드를 작성하는 코드는 다음과 같습니다.

public BasicInputNode() throws MbException
{
	createOutputTerminal ("out");
	createOutputTerminal ("failure");
	createOutputTerminal ("catch");
   setAttribute ("firstParserClassName","myParser");
attributeVariable = "none"; 
}

버퍼로 외부 데이터 수신

노드 출력이 올바른 형식으로 되어 있다면, 입력 노드는 파일 시스템, 큐 또는 데이터베이스와 같은 모든 유형의 외부 소스로부터 다른 Java 프로그램과 같은 방식으로 데이터를 수신할 수 있습니다.

입력 데이터를 포함할 입력 버퍼(또는 비트스트림)를 제공하고 이를 메시지 오브젝트와 연관시키십시오. MbInputNode 클래스의 createMessage 메소드를 사용하여 바이트 배열로부터 메시지를 작성하고 이 메시지로부터 올바른 메시지 어셈블리를 새성하십시오. 이러한 메소드에 대한 자세한 내용은 Java API를 참조하십시오. 예를 들면, 파일에서 입력을 읽으려면 다음을 수행하십시오.

  1. 파일에서 읽을 입력 스트림을 작성하십시오.
    FileInputStream inputStream = new FileInputStream("myfile.msg");
  2. 입력 파일의 크기 바이트 배열을 작성하십시오.
    byte[] buffer = new byte[inputStream.available()];
  3. 파일에서 바이트 배열로 읽으십시오.
    inputStream.read(buffer);
  4. 입력 스트림을 닫으십시오.
    inputStream.close();
  5. 큐에 넣을 메시지를 작성하십시오.
    MbMessage msg = createMessage(buffer);
  6. 이 메시지를 보유할 새 메시지 어셈블리를 작성하십시오.
    msg.finalizeMessage(MbMessage.FINALIZE_VALIDATE);
    MbMessageAssembly newAssembly =
                new MbMessageAssembly( assembly, msg );

메시지 전달

메시지 어셈블리를 작성한 경우, 이를 노드 터미널 중 하나로 전달할 수 있습니다.

예를 들면, 메시지 어셈블리를 "out" 터미널로 전달하는 코드는 다음과 같습니다.
    MbOutputTerminal out = getOutputTerminal("out");
        out.propagate(newAssembly);
메시지를 삭제하려면 다음을 수행하십시오.
msg.clearMessage();

메시지 트리에 할당된 메모리를 지우려면 최종 try/catch 블록에서 clearMessage() 함수를 호출하십시오.

스레드 및 트랜잭션성 제어

브로커 인프라스트럭처는 메시지 처리가 완료되었을 때 WebSphere MQ 또는 데이터베이스 작업 단위의 확약 제어와 같은 트랜잭션 문제를 핸들링합니다. 그러나 사용자 정의 노드 내에서 수정된 자원의 경우 반드시 브로커의 트랜잭션 제어를 받을 필요는 없습니다.

각 메시지 플로우 스레드는 각 메시지 플로우에 유지보수되는 스레드 풀로부터 할당되며, run 메소드에서 실행을 시작합니다.

사용자 정의 노드는 리턴 값을 사용하여 트랜잭션이 성공했는지 여부를 표시하고, 트랜잭션이 확약되었는지 또는 롤백되었는지 여부를 제어하며, 스레드가 풀로 리턴되는 시기를 제어합니다. 핸들링되지 않은 예외는 브로커 인프라스트럭처에서 포착되며, 트랜잭션이 롤백됩니다.

다음의 적절한 리턴 값을 통해 트랜잭션 및 스레드의 작동을 판별할 수 있습니다.

MbInputNode.SUCCESS_CONTINUE
트랜잭션이 확약되고 브로커는 같은 스레드를 사용하여 run 메소드를 다시 호출합니다.
MbInputNode.SUCCESS_RETURN
트랜잭션이 확약되고, 스레드는 해당 메시지 플로우의 유일한 스레드가 아닌 것으로 간주되어 스레드 풀로 리턴됩니다.
MbInputNode.FAILURE_CONTINUE
트랜잭션이 롤백되고 브로커는 같은 스레드를 사용하여 run 메소드를 다시 호출합니다.
MbInputNode.FAILURE_RETURN
트랜잭션이 롤백되고, 스레드는 해당 메시지 플로우의 유일한 스레드가 아닌 것으로 간주되어 스레드 풀로 리턴됩니다.
MbInputNode.TIMEOUT
run 메소드는 입력 데이터가 도착할 때까지 기다리는 동안 무한정 블록 상태로 있어서는 안 됩니다. 사용자 코드가 플로우를 블록킹하는 동안 브로커를 종료하거나 재구성할 수 없습니다. run 메소드는 run 메소드로부터 리턴하여 정기적으로 브로커로 제어를 보내야 합니다. 특정 기간(예: 5초) 후에 입력 데이터가 수신되지 않으면, TIMEOUT 리턴 코드가 표시되면서 메소드가 리턴됩니다. 브로커를 재구성하거나 종료할 필요가 없다고 간주하고, 입력 노드의 run 메소드가 즉시 다시 호출됩니다.
멀티스레드 메시지 플로우를 작성하려면 메시지가 작성된 후 그 메시지가 출력 터미널로 전달되기 전에 dispatchThread 메소드를 호출하십시오. 그러면 다른 스레드가 메시지를 처리하는 동안 단 하나의 스레드만이 데이터를 기다리게 됩니다. 메시지 플로우의 additionalInstances 속성이 지정하는 최대 한계까지 스레드 풀로부터 새 스레드가 취득됩니다. 예를 들면 다음과 같습니다.
public int run( MbMessageAssembly assembly ) throws MbException
{
    byte[] data = getDataWithTimeout();  // user supplied method
                                                                              // returns null if timeout
    if( data == null )
        return TIMEOUT;

    MbMessage msg = createMessage( data );
    msg.finalizeMessage( MbMessage.FINALIZE_VALIDATE );
  MbMessageAssembly newAssembly =
              new MbMessageAssembly( assembly, msg );

    dispatchThread();

    getOutputTerminal( "out" ).propagate( newAssembly );

    return SUCCESS_RETURN;
}

노드 이름 선언

노드 이름은 Workbench에 의해 식별되기 때문에 노드 이름을 선언해야 합니다. 모든 노드 이름은 "Node"로 끝나야 합니다. 노드 이름을 선언하는 메소드는 다음과 같습니다.

public static String getNodeName()
{
      return "BasicInputNode";
}
이 메소드가 선언되지 않을 경우, Java API 프레임워크는 다음 규칙을 사용하여 디폴트 노드 이름을 작성합니다.
  • 클래스 이름이 패키지 이름에 추가됩니다.
  • 점이 제거되고, 각 패키지 및 클래스 이름 부분의 첫 번째 글자가 대문자로 바뀝니다.
예를 들면, 디폴트 값으로 다음 클래스에 노드 이름 "ComIbmPluginsamplesBasicInputNode"가 할당됩니다.
package com.ibm.pluginsamples;
public class BasicInputNode extends MbInputNode implements MbInputNodeInterface
{
   ...

속성 선언

Java Bean 등록 정보와 같은 방식으로 노드 속성을 선언하면 됩니다. 속성의 getter 및 setter 메소드를 작성해야 하며, API 프레임워크는 Java Bean 검토 규칙을 사용하여 속성 이름을 예상합니다. 예를 들면, 다음의 두 메소드를 선언할 경우,

private String attributeVariable;

public String getFirstAttribute()
{
    return attributeVariable;
}

publc void setFirstAttribute(String value)
{
    attributeVariable = value;
}

브로커는 노드가 firstAttribute라는 속성을 가진다고 예상합니다. 이 이름은 내부 클래스 구성원 변수 이름이 아닌 get 또는 set 메소드 이름으로부터 도출됩니다. 속성은 문자열로만 표현될 수 있으므로, get 또는 set 메소드에서 모든 숫자 유형을 문자열로(부터) 변환해야 합니다. 예를 들면, 다음 메소드는 timeInSeconds라는 속성을 정의합니다.

int seconds;

public String getTimeInSeconds()
{
    return Integer.toString(seconds);
}

public void setTimeInSeconds(String value)
{
    seconds = Integer.parseInt(value);
}

노드 기능 구현

앞에서 설명한 대로, 브로커는 run 메소드를 호출하여 입력 메시지를 작성합니다. 이 메소드는 입력 노드의 모든 처리 기능을 제공합니다.

디폴트 메시지 구문 분석기 속성 대체(선택사항)

일반적으로 입력 노드 구현은 초기에 입력 메시지를 구문 분석하는 메시지 구문 분석기가 어떤 것인지 판별합니다. 예를 들면, 기본 MQInput 노드는 MQMD 구문 분석기가 MQMD 헤더를 구문 분석하도록 지시합니다. 사용자 정의 입력 노드는 디폴트로 포함된 다음 속성을 사용하여 적절한 헤더나 메시지 구문 분석기, 구문 분석이 제어되는 모드를 선택할 수 있습니다. 이 속성을 대체할 수 있습니다.

rootParserClassName
사용자 정의 입력 노드가 지원하는 메시지 형식을 구문 분석하는 루트 구문 분석기의 이름을 정의합니다. 디폴트 값은 제공된 루트 구문 분석기인 GenericRoot로서, 브로커가 구분 분석기를 할당하고 서로 체인으로 연결하도록 합니다. 노드가 이 속성 값을 수정할 필요는 없습니다.
firstParserClassName
비트스트림 구문 분석을 담당하는 구문 분석기 체인이 될 위치에서 첫 번째 구문 분석기 이름을 정의합니다. 디폴트 값은 XML입니다.
messageDomainProperty
입력 메시지를 구문 분석하는 데 필요한 메시지 구문 분석기의 이름을 정의하는 선택적 속성입니다. 지원되는 값은 MQInput 노드가 지원하는 값과 같습니다. (MQInput 노드에 대한 자세한 정보는 MQInput 노드를 참조하십시오.)
messageSetProperty
messageDomainProperty 속성으로 MRM 구문 분석기가 지정된 경우에만 메시지 세트 필드에 메시지 세트 ID 또는 메시지 세트 이름을 정의하는 선택적 속성입니다.
messageTypeProperty
messageDomainProperty 속성으로 MRM 구문 분석기가 지정된 경우에만 메시지 유형 필드에 메시지의 ID를 정의하는 선택적 속성입니다.
messageFormatProperty
messageDomainProperty 속성으로 MRM 구문 분석기가 지정된 경우에만 메시지 형식 필드에 메시지 형식을 정의하는 선택적 속성입니다.

노드의 인스턴스 삭제

다음과 같은 경우 노드 인스턴스가 삭제됩니다.
  • 브로커를 종료할 때
  • 노드 또는 노드가 포함된 메시지 플로우를 제거하고 구성을 재전개할 때
노드 삭제 중에는 소켓 닫기와 같은 삭제 조작을 수행할 수 있도록 노드에 알리는 것이 좋습니다. 노드가 선택적 onDelete 메소드를 구현할 경우, 노드가 삭제되기 바로 전에 브로커에서 이 메소드를 호출합니다.

onDelete 메소드는 다음과 같이 구현할 수 있습니다.

public void onDelete()
{
    // perform node cleanup if necessary
}
관련 정보
Java API
주의사항 | 등록상표 | 다운로드 | 라이브러리 | 지원 | 피드백
Copyright IBM Corporation 1999, 2006 마지막 갱신 날짜: 2006/08/21
as09950_