Java 메시지 처리 또는 출력 노드의 성능 확장

시작하기 전에

다음 주제를 읽고 이해했는지 확인하십시오.
사용자 정의 노드를 작성한 후에는 다음 기능을 사용할 수 있습니다.
  1. 메시지 데이터 액세스
  2. 메시지 오브젝트 변환
  3. ESQL 액세스
  4. 예외 핸들링
  5. 메시지 전달
  6. 출력 디바이스에 쓰기

메시지 데이터 액세스

많은 경우, 사용자 정의 노드는 해당 입력 터미널에서 수신된 메시지의 컨텐츠에 액세스해야 합니다. 메시지는 구문 요소의 트리로 표현됩니다. 메시지 관리, 메시지 버퍼 액세스, 구문 요소 탐색, 구문 요소 액세스를 위한 유틸리티 함수 그룹이 제공됩니다.

MbElement 클래스는 구문 요소로의 인터페이스를 제공합니다. Java API에 대한 자세한 내용은 Javadoc을 참조하십시오.

예를 들면 다음과 같습니다.

  1. XML 메시지의 관련 구문 요소로 이동하는 코드는 다음과 같습니다.
            MbElement rootElement = assembly.getMessage().getRootElement();
            MbElement switchElement = 
    			rootElement.getLastChild().getFirstChild().getFirstChild();
  2. 이 요소의 값이 나타내는 터미널을 선택하는 코드는 다음과 같습니다.
            String terminalName;
          String elementValue = (String)switchElement.getValue();
            if(elementValue.equals("add"))
                terminalName = "add";
            else if(elementValue.equals("change"))
                terminalName = "change";
            else if(elementValue.equals("delete"))
                terminalName = "delete";
            else if(elementValue.equals("hold"))
                terminalName = "hold";
            else
                terminalName = "failure";
        
            MbOutputTerminal out = getOutputTerminal(terminalName);

메시지 오브젝트 변환

수신된 입력 메시지는 읽기 전용이므로, 메시지를 변환하려면 해당 메시지를 새 출력 메시지에 써야 합니다. 입력 메시지로부터 요소를 복사하거나, 새 요소를 작성하여 메시지에 첨부할 수 있습니다. 일반적으로 새 요소는 구문 분석기 도메인에 있습니다.

MbMessage 클래스는 복사 구성자, 메시지의 루트 요소를 가져오는 메소드를 제공합니다. MbElement 클래스는 구문 요소로의 인터페이스를 제공합니다.

예를 들어, 임베드된 메시지가 있는 메시지 어셈블리가 수신될 때 다음을 수행하십시오.
  1. 새 메시지 어셈블리 및 해당 임베드된 메시지 사본을 작성하십시오.
            MbMessage newMsg = new MbMessage(assembly.getMessage());
            MbMessageAssembly newAssembly = new MbMessageAssembly(assembly, newMsg);
  2. XML 메시지의 관련 구문 요소로 이동하십시오.
            MbElement rootElement = newAssembly.getMessage().getRootElement();
            MbElement switchElement = 
    			rootElement.getFirstElementByPath("/XML/data/action");
  3. 기존 요소 값을 변경하십시오.
        String elementValue = (String)switchElement.getValue();
            if(elementValue.equals("add"))
                switchElement.setValue("change");
            else if(elementValue.equals("change"))
                switchElement.setValue("delete");
            else if(elementValue.equals("delete"))
                switchElement.setValue("hold");
            else
                switchElement.setValue("failure");
  4. 스위치 태그의 하위 태그로서 새 태그를 추가하십시오.
            MbElement tag = switchElement.createElementAsLastChild(MbElement.TYPE_NAME,
                                                                                                                          "PreviousValue",
                                                                                                                          elementValue);
  5. 이 새 태그에 속성을 추가하십시오.
            tag.createElementAsFirstChild(MbElement.TYPE_NAME_VALUE,
                                                                        "NewValue",
                                                                        switchElement.getValue());
    
            MbOutputTerminal out = getOutputTerminal("out");
변환의 일부로 새 메시지 본문를 작성해야 할 수도 있습니다. 새 메시지 본문를 작성하기 위해 다음 메소드를 사용할 수 있습니다.
createElementAfter
createElementAsFirstChild
createElementAsLastChild
createElementBefore
createElementAsLastChildFromBitstream
메시지 트리 폴더에 구문 분석기를 지정하는 데 특정하므로 이런 메소드를 사용해야 합니다.
다음 메소드는 소유하고 있는 구문 분석기를 폴더와 연관시키지 않으므로 메시지 본문을 작성할 때 사용하지 마십시오.
createElementAfter
createElementAfter
createElementAsFirstChild
createElementAsFirstChild
createElementAsLastChild
createElementAsLastChild
createElementBefore
createElementBefore 

ESQL 액세스

노드는 Compute 노드 ESQL 구문을 사용하여 ESQL 표현식을 호출할 수 있습니다. ESQL 표현식을 사용하여 메시지 구성요소를 작성하고 수정할 수 있으며, 외부 데이터베이스의 입력 메시지 및 데이터 요소를 참조할 수 있습니다.

다음 프로시저는 ESQL을 사용하여 사용자 정의 노드에서 트랜잭션을 제어하는 법을 보여줍니다.
  1. 사용할 ODBC 데이터 소스의 이름을 설정하십시오. 예를 들면,
    String dataSourceName = "myDataSource";
  2. 실행할 ESQL문을 설정하십시오.
    String statement = 
          "SET OutputRoot.XML.data = 
                        (SELECT Field2 FROM Database.Table1 WHERE Field1 = 1);";
    또는 결과를 리턴하지 않는 명령문을 실행하는 코드는 다음과 같습니다.
    String statement = "PASSTHRU(
                                                    'INSERT INTO Database.Table1 VALUES(
                                                              InputRoot.XML.DataField1,
                                                              InputRoot.XML.DataField2)');";
  3. 다음 중 원하는 트랜잭션 유형을 선택하십시오.
    MbSQLStatement.SQL_TRANSACTION_COMMIT
    ESQL문이 실행될 때 즉시 트랜잭션을 확약합니다.
    MbSQLStatement.SQL_TRANSACTION_AUTO
    메시지 플로우가 완료될 때 트랜잭션을 확약합니다. (필요한 경우 롤백이 수행됩니다.)
    예를 들면,
    int transactionType = MbSQLStatement.SQL_TRANSACTION_AUTO;
  4. ESQL문을 가져옵니다. 예를 들면,
    MbSQLStatement sql = 
                  createSQLStatement(dataSourceName, statement, transactionType);
    createSQLStatement(dataSource, statement) 메소드를 사용하여 트랜잭션 유형의 디폴트 값을 MbSQLStatement.SQL_TRANSACTION_AUTO로 설정할 수 있습니다.
  5. 전달할 새 메시지 어셈블리를 작성합니다.
    MbMessageAssembly newAssembly = 
                  new MbMessageAssembly(assembly, assembly.getMessage());
  6. ESQL문을 실행합니다.
    sql.select(assembly, newAssembly);
    또는 결과를 리턴하지 않는 SQL문을 실행하는 코드는 다음과 같습니다.
    sql.execute(assembly);

ESQL에 대한 자세한 정보는 ESQL 개요를 참조하십시오.

예외 핸들링

예외를 포착하고 액세스하기 위해 mbException 클래스를 사용합니다. mbException 클래스는 브로커 예외 목록에서 예외의 하위를 표시하는 예외 오브젝트 배열을 리턴합니다. 리턴되는 각 요소는 예외 유형을 지정합니다. 예외에 하위가 없는 경우 빈 배열이 리턴됩니다. 다음 코드 샘플에서는 MbException 클래스의 사용법 예를 보여줍니다.

public void evaluate(MbMessageAssembly assembly, MbInputTerminal inTerm) throws MbException
  {
    try
      {

                // plug-in functionality

      }
        catch(MbException ex)
      {
                traverse(ex, 0);

                throw ex; // if re-throwing, it must be the original exception that was caught
      }
  }

    void traverse(MbException ex, int level)
  {
        if(ex != null)
      {
                // Do whatever action here
                System.out.println("Level: " + level);
                System.out.println(ex.toString());
                System.out.println("traceText:  " + ex.getTraceText());

                // traverse the hierarchy
                MbException e[] = ex.getNestedExceptions();
                int size = e.length;
                for(int i = 0; i < size; i++)
          {
                        traverse(e[i], level + 1);
          }
      }
  }

mbException 클래스의 사용에 대한 자세한 정보는 javadoc를 참조하십시오.

모든 현재 예외에 액세스할 수 있도록 사용자 정의 메시지 처리 또는 출력 노드를 개발할 수 있습니다. 예를 들어, 데이터베이스 예외를 포착하기 위해 MbSQLStatement 클래스를 사용할 수 있습니다. 이 클래스는 데이터베이스 오류 발생 시 브로커 작동을 판별하는 'throwExceptionOnDatabaseError' 속성 값을 설정합니다. 참으로 설정되면 예외가 발생할 경우 사용자 정의 확장으로 예외를 포착하여 처리할 수 있습니다.

다음 코드 샘플에서는 MbSQLStatement 클래스의 사용 방법 예를 보여줍니다.

public void evaluate(MbMessageAssembly assembly, MbInputTerminal inTerm) throws MbException
  {
        MbMessage newMsg = new MbMessage(assembly.getMessage());
        MbMessageAssembly newAssembly = new MbMessageAssembly(assembly, newMsg);

        String table = assembly.getMessage().getRootElement().getLastChild().getFirstChild().getName();

        MbSQLStatement state = createSQLStatement( "dbName", 
                                                      "SET OutputRoot.XML.integer[] = PASSTHRU('SELECT * FROM " + table + "');" );

        state.setThrowExceptionOnDatabaseError(false);
        state.setTreatWarningsAsErrors(true);

        state.select( assembly, newAssembly );

        int sqlCode = state.getSQLCode();
        if(sqlCode != 0)
      {
                // Do error handling here

                System.out.println("sqlCode = " + sqlCode);
                System.out.println("sqlNativeError = " + state.getSQLNativeError());
                System.out.println("sqlState = " + state.getSQLState());
                System.out.println("sqlErrorText = " + state.getSQLErrorText());
      }

        getOutputTerminal("out").propagate(assembly);
  }

메시지 전달

메시지를 전달하기 전에 전달할 메시지 플로우 데이터, 데이터를 수신할 노드 터미널을 결정해야 합니다. 메시지를 전달하기 전에 종료해야 합니다. 메시지를 전달한 후에는 출력 메시지를 삭제해야 합니다.

예를 들면,
  1. 메시지를 출력 터미널 "out"으로 전달하는 코드는 다음과 같습니다.
    MbOutputTerminal out = getOutputTerminal("out");
                    out.propagate(newAssembly);
  2. 출력 메시지를 삭제하는 코드는 다음과 같습니다.
      newMsg.clearMessage();	

출력 디바이스에 쓰기

출력 디바이스에 쓰려면 논리적(계층 구조) 메시지를 비트스트림으로 다시 변환해야 합니다. 이때 다음과 같이MbMessagegetBuffer 메소드를 사용하면 됩니다.

public void evaluate( MbMessageAssembly assembly, MbInputTerminal in)
                                                                                                          throws MbException
{
    MbMessage msg = assembly.getMessage();
    byte[] bitstream = msg.getBuffer();

    // write the bitstream out somewhere
    writeBitstream( bitstream );   // user method

 }

일반적으로 출력 노드의 경우 메시지가 출력 터미널로 전달되지 않으므로 지금 리턴할 수 있습니다.

주: WebSphere MQ 큐에 쓸 때는 제공된 MQOutput 노드를 사용해야 합니다. 브로커는 내부적으로 WebSphere MQ 연결을 유지하고, 스레드별로 큐 핸들을 열며, 성능 최적화를 위해 캐시되기 때문입니다. 또한, 브로커는 특정 WebSphere MQ 이벤트가 발생할 때 복구 시나리오를 처리하는데, 사용자 정의 출력 노드에 WebSphere MQ MQI 호출이 사용된 경우 좋지 않은 영향을 미칠 수 있습니다.
관련 참조
ExceptionList 구조
주의사항 | 등록상표 | 다운로드 | 라이브러리 | 지원 | 피드백
Copyright IBM Corporation 1999, 2005 마지막 갱신 날짜: 11/08/2005
as24990_