ヘッダーをスキップ
Oracle® Complex Event Processing開発者ガイド
11g リリース1 (11.1.1.4.0) for Eclipse
B61654-02
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

14 カスタム・アダプタの構成

この章では、カスタム・アダプタをコーディングして登録する方法について説明します。内容は次のとおりです。

14.1 カスタム・アダプタの概要

アダプタの主な役割の1つには、マーケット・データ・フィードなどのチャネルからのデータをOracle CEPイベントに変換する作業があります。これらのイベントはその後、プロセッサなどのアプリケーションの他のコンポーネントに渡されます。通常、アダプタはOracle CEPアプリケーションへのエントリ・ポイントです。アダプタは中間コンポーネントからのイベントを受信し、外部アプリケーションで読取り可能な形式にデータを変換し、それらのデータを送信するためアプリケーションの出口ポイントになる場合もあります。

『Oracle Complex Event Processingスタート・ガイド』のFXサンプルの説明には、通貨データ・フィードからデータを読み込み、ネットワークの次のコンポーネントであるプロセッサに特定のイベント・タイプの形式でデータを渡す3つのアダプタが示されています。

着信データの形式およびアダプタ・コードで変換に使用される技術に応じて、さまざまなタイプのアダプタを作成できます。最も一般的なタイプのアダプタは、以下のとおりです。

アダプタは、特定のOracle CEPインタフェースを実装するJavaクラスです。アプリケーション全体を記述するEPNアセンブリ・ファイルでアダプタ・クラスを登録します。

オプションで、アダプタのデフォルト構成を変更できます。また、構成を拡張したり、新しい構成要素および属性を追加することもできます。

構成データをアダプタに渡す方法は2つあります。デプロイの後で構成を動的に変更するかどうかに応じて選択する方法が異なります。

この項では次について説明します:

14.1.1 カスタム・アダプタのイベント・ソースとイベント・シンク

アダプタは、イベント・ソース、イベント・シンク、またはその両方に使用できます。イベント・ソースはイベントを生成し、イベント・シンクはイベントを受信します。

14.1.1.1 イベント・ソースとしてのカスタム・アダプタ

com.bea.wlevs.ede.api.StreamSourceまたはRelationSource APIを実装して、EPN内のアダプタ・コンポーネントがイベント・ソースであることを指定します。

イベント・ソースであるカスタム・アダプタの実装クラスは、アプリケーションのプライベートとして指定するか、または他のアプリケーションによる再利用が可能な公開されたOSGIサービスとして指定できます。

wlevs:adapter要素を使用してEPNアセンブリ・ファイルにアダプタを登録します。例:

<wlevs:adapter id="myAdapterSource" class="com.acme.MySourceAdapter">
</wlevs:adapter>

この例では、JavaクラスMySourceAdapter.javacom.bea.wlevs.ede.api.StreamSourceまたはRelationSource APIを実装します。

詳細は、14.2.2.1項「カスタム・アダプタをイベント・ソースとして実装」を参照してください。

14.1.1.2 イベント・シンクとしてのカスタム・アダプタ

カスタム・アダプタのイベント・シンクはcom.bea.wlevs.ede.api.StreamSinkまたはRelationSink APIを実装する必要がある以外はイベント・シンクとしてのカスタム・アダプタの機能はイベント・ソースによく似ています。

イベント・シンクはアクティブではないため、Runnableインタフェースを実装している場合、Oracle CEPではこれらを個別のスレッドで実行しません。

wlevs:listener要素を使用してEPNアセンブリ・ファイルでイベント・シンクを参照します。

<wlevs:adapter id="myAdapterSink" class="com.acme.MySinkAdapter">
</wlevs:adapter>

<wlevs:channel id="myStream" >
    <wlevs:listener ref="myAdapterSink" />
</wlevs:channel>

この例では、JavaクラスMySinkAdapter.javacom.bea.wlevs.ede.api.StreamSinkまたはRelationSink APIを実装します。

詳細は、14.2.2.2項「カスタム・アダプタをイベント・シンクとして実装」を参照してください。

14.1.2 カスタム・アダプタ・ファクトリ

アダプタが単一のOracle CEPアプリケーションによってのみ使用される場合は、ファクトリを作成する必要はありません。ただし、同一のアダプタが複数のアプリケーションで使用される場合は、ファクトリもプログラミングする必要があります。この場合、それぞれのアプリケーションで固有のアダプタ・インスタンスが取得されます。

アダプタのファクトリはcom.bea.wlevs.ede.api.Factoryインタフェースを実装する必要があります。このインタフェースには、アダプタまたはイベントBeanのインスタンスを作成するために実装する単一のメソッドcreateが含まれています。

wlevs:factory要素を使用してEPNアセンブリ・ファイルにファクトリを登録します。

<wlevs:factory provider-name="myprovider" class="my.Implementation"/>

サービスのプロパティを指定する必要がある場合は、osgi:service要素を使用してファクトリを登録する必要があります。

14.1.3 シングルおよびマルチスレッド・アダプタ

デフォルトでは、アダプタはシングルスレッドです。つまり、アダプタは、シングルスレッドを使用してデータ・ソースからメッセージを読み取ります。

アダプタがシングルスレッドであると、イベント順序が保証されます。

スケーラビリティを向上させるために、アダプタでマルチスレッドを使用してデータ・ソースから読み取るように構成できます。このように構成する場合、最も簡単な方法はワーク・マネージャを使用してアダプタを構成することです。アダプタだけが使用する専用のワーク・マネージャを指定するか、他のアダプタやJettyなどのいくつかのコンポーネントでワーク・マネージャを共有できます。

アダプタがマルチスレッドであると、イベント順序は保証されません。

詳細については、次を参照してください。

14.2 カスタム・アダプタの実装

作成するJavaクラスにカスタム・アダプタを実装します。このJavaクラスを作成するには、次のどちらかの手順を実行します。

詳細は、14.1項「カスタム・アダプタの概要」を参照してください。

14.2.1 Antを使用したカスタム・アダプタの実装方法

次の手順は、Oracle CEP AntタスクTBDを使用して、完全に機能する空のアダプタを生成する方法について説明します。

Antを使用してカスタム・アダプタを実装するには、次の手順を実行します。

  1. オプションとして、ファクトリ・クラスをプログラミングします。

    多数のアプリケーションでカスタム・アダプタを使用する場合に限りこの処理が必要です。

    14.2.3項「カスタム・アダプタ・ファクトリの実装」を参照してください。

  2. オプションとして、デフォルトのコンポーネント構成が適切でない場合に、カスタム・アダプタのコンポーネント構成を拡張します。

    第19章「コンポーネント構成の拡張」を参照してください。

  3. カスタム・アダプタを構成します。

    詳細については、次を参照してください。

14.2.2 カスタム・アダプタを手動で実装する方法

次の手順は、カスタム・アダプタを手動で作成するための一般的なステップを示します。


注意:

次の手順では、プロセッサ、ストリーム、ビジネス・ロジックPOJOなどのイベント・ネットワークの他のコンポーネントが含まれている同一のアプリケーションJARファイルにカスタム・アダプタがバンドルされると想定しています。複数のアプリケーションで共有できるようにカスタム・アダプタを固有のJARファイルにバンドルする必要がある場合は、24.2.4.1項「カスタム・アダプタの固有のバンドルでのアセンブリ方法」を参照してください。

カスタム・アダプタを実装するには、次の手順を実行します。

  1. カスタム・アダプタJavaクラスをプログラミングします。

    カスタム・アダプタがイベント・ソースである場合は、14.2.2.1項「カスタム・アダプタをイベント・ソースとして実装」を参照してください。

    カスタム・アダプタがイベント・シンクである場合は、14.2.2.2項「カスタム・アダプタをイベント・シンクとして実装」を参照してください。

    カスタム・アダプタがイベント・ソースおよびイベント・シンクの両方である場合は、両方の項を参照してください。

    カスタム・アダプタがデータ・フィード・プロバイダを使用して自身を認証する必要がある場合は、14.3項「アダプタからデータ・フィード・プロバイダへのログイン資格証明の受け渡し」を参照してください。

  2. オプションとして、ファクトリ・クラスをプログラミングします。

    多数のアプリケーションでカスタム・アダプタを使用する場合に限りこの処理が必要です。

    14.2.3項「カスタム・アダプタ・ファクトリの実装」を参照してください。

  3. オプションとして、デフォルトのコンポーネント構成が適切でない場合に、カスタム・アダプタのコンポーネント構成を拡張します。

    第19章「コンポーネント構成の拡張」を参照してください。

  4. カスタム・アダプタを構成します。

    詳細については、次を参照してください。

14.2.2.1 カスタム・アダプタをイベント・ソースとして実装

この項では、イベント・ソースとして動作するカスタム・アダプタを作成する方法について説明します。このカスタム・アダプタは着信データを受け取り、それをEPNの次のコンポーネントに送信するイベントを生成します。

着信カスタム・アダプタ・クラスは、通常マーケット・データ・フィードなどからの着信データのストリームを読み込み、アプリケーションの残りの部分によって認識されるOracle CEPイベント・タイプに変換し、ネットワークの次のコンポーネントにイベントを送信します。

次の例は、空間サンプルのカスタム・アダプタ・クラスを示します。Javaコードの太字部分に対応するコーディングのガイドラインについては、例の後で説明しています。

package com.oracle.cep.sample.spatial;
 
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
 
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
 
import com.bea.wlevs.ede.api.EventProperty;
import com.bea.wlevs.ede.api.EventRejectedException;
import com.bea.wlevs.ede.api.EventType;
import com.bea.wlevs.ede.api.EventTypeRepository;
import com.bea.wlevs.ede.api.RunnableBean;
import com.bea.wlevs.ede.api.StreamSender;
import com.bea.wlevs.ede.api.StreamSink;
import com.bea.wlevs.ede.api.StreamSource;
import com.bea.wlevs.util.Service;
import java.lang.RuntimeException;
 
import oracle.spatial.geometry.JGeometry;
import com.oracle.cep.cartridge.spatial.Geometry;
 
public class BusStopAdapter implements RunnableBean, StreamSource, StreamSink
{
  private final static String APP_NAME              = "spatial_sample";
...
  private String              m_eventTypeName;
  private EventType           m_eventType;
  private StreamSender        m_eventSender;
...
  public BusStopAdapter()
  {
    super();
  }
 
...
  @Service(filter = EventTypeRepository.SERVICE_FILTER)
  public void setEventTypeRepository(EventTypeRepository etr)
  {
    m_etr = etr;
  }
 
  public void setShow(boolean b)
  {
    m_show = b;
  }
 
  public void run()
  {
    m_stopped = false;
 
    // Need to store running thread so that it can be interrrupted in case of
    // suspend.
    m_runningThread = Thread.currentThread();
 
    if (m_etr == null)
    {
      throw new RuntimeException("EventTypeRepoitory is not set");
    }
 
    m_eventType = m_etr.getEventType(m_eventTypeName);
    if (m_eventType == null)
    {
      throw new RuntimeException("EventType(" + m_eventType + ") is not found.");
    }

    s_logger.info("fileSource " + m_filePath);

    if (m_initialDelay > 0)
    {
      try
      {
        s_logger.info("Sleeping for : " + m_initialDelay);
        Thread.sleep(m_initialDelay);
      } catch (InterruptedException e)
      {
        e.printStackTrace();
      }
    }

    synchronized (this)
    {
      while (!m_start)
      {
        try
        {
          this.wait();
        } catch (InterruptedException e)
        {
        }
      }
    }
    BufferedReader reader = null;

    System.out.println("Sending " + m_eventType + " from " + m_filePath);
    while ((m_repeat != 0) && (!m_stopped))
    {
      try
      {
        s_logger.info("Starting fileSource " + m_filePath);
        m_lineno = 0;
        reader = new BufferedReader(new FileReader(m_filePath));
      } catch (Exception e)
      {
        s_logger.warn(e.toString());
        m_stopped = true;
        break;
      }
      while (!isStopped())
      {
        try
        {
          Object ev = null;
          ev = readLine(reader);
          if (ev == null)
          {
            reader.close();
            break;
          }
          m_eventSender.sendInsertEvent(ev);
          if (m_show)
          {
            System.out.println(ev.toString());
          }
        } catch (Exception e)
        {
          s_logger.fatal("Failed to get tuple from " + m_filePath + ":"
              + m_lineno + "\n" + e.toString() + "\n");
          m_stopped = true;
          break;
        }
        if (m_sleep > 0)
        {
          try
          {
            synchronized (this)
            {
              // We need to save thread so that it can be interrupted in case of
              // suspend.
              wait(m_sleep);
            }
          } catch (InterruptedException e)
          {
            s_logger.warn(e);
            break;
          }
        }
      } // while
      if (m_repeat > 0)
        m_repeat--;
    } // while
    s_logger.info("FileAdaptor  " + hashCode() + " stopped. " + m_filePath);
  }

  public void setEventSender(StreamSender sender)
  {
    m_eventSender = sender;
  }

...
}

アダプタJavaクラスのプログラミングでは、次のガイドラインに従います。上記の例でガイドラインのコード例は太字で示されています。

  • Oracle CEP APIのインタフェースおよびクラスをインポートします。

    import com.bea.wlevs.ede.api.StreamSender;
    import com.bea.wlevs.ede.api.StreamSource;
    import com.bea.wlevs.ede.api.RunnableBean;
    

    アダプタはイベント・ソースであるため、StreamSourceインタフェースを実装する必要があります。アダプタをスレッドで実行する必要がある場合は、RunnableBeanも実装します。StreamSenderインタフェースは、イベント・タイプをアプリケーション・ネットワークの次のコンポーネントに送信します。これらのAPIの完全な詳細は、Oracle Fusion Middleware Oracle Complex Event Processing Java APIリファレンスを参照してください。

  • アダプタ・クラスはイベント・ソースであり、固有のスレッドで実行されるため、StreamSourceおよびRunnableBeanインタフェースを実装する必要があります。

    public class BusStopAdapter implements RunnableBean, StreamSource, StreamSink
    

    StreamSourceインタフェースではイベントの送信に使用されるStreamSenderが提供されます。

  • RunnableBeanインタフェースが実装されるため、アダプタではrunメソッドを実装する必要があります。

    public void run() {...
    

    ここに、マーケット・フィードなどからの着信データを読み込み、Oracle CEPイベント・タイプに変換し、ネットワークの次のコンポーネントにイベントを送信するコードを配置する必要があります。着信データの読込み方法の詳細については、データ・フィード・プロバイダのドキュメントを参照してください。サード・パーティJARファイルにパッケージ化されているベンダーAPIに確実にアクセスできるための情報は、24.2.2.2項「サード・パーティJARファイルへのアクセス」を参照してください。

    空間サンプルでは、readLine保護メソッドを使用してアダプタ自体が着信データを生成します。これは説明のためであり、実際のシナリオではありません。

    詳細は、第2章「Oracle CEPイベント・タイプの作成」を参照してください。

  • アダプタではStreamSourceが実装されるため、イベントの送信に使用されるStreamSenderを渡すsetEventSenderメソッドを実装する必要があります。

    public void setEventSender(StreamSender sender) { ...
    
  • 通常のケースと同様、アダプタでSuspendableBeanが実装される場合は、たとえばアプリケーションがアンデプロイされた場合などにアダプタを停止するsuspendメソッドを実装する必要があります。

    public synchronized void suspend() throws Exception { ... 
    

14.2.2.2 カスタム・アダプタをイベント・シンクとして実装

次のコード例は、HelloWorldアプリケーションでイベント・シンクとして動作するSpring Beanです。太字部分のコードについては、例の後で説明しています。

次の例は、空間サンプルのカスタム・アダプタ・クラスを示します。Javaコードの太字部分に対応するコーディングのガイドラインについては、例の後で説明しています。

package com.oracle.cep.sample.spatial;
 
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
 
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
 
import com.bea.wlevs.ede.api.EventProperty;
import com.bea.wlevs.ede.api.EventRejectedException;
import com.bea.wlevs.ede.api.EventType;
import com.bea.wlevs.ede.api.EventTypeRepository;
import com.bea.wlevs.ede.api.RunnableBean;
import com.bea.wlevs.ede.api.StreamSender;
import com.bea.wlevs.ede.api.StreamSink;
import com.bea.wlevs.ede.api.StreamSource;
import com.bea.wlevs.util.Service;
import java.lang.RuntimeException;
 
import oracle.spatial.geometry.JGeometry;
import com.oracle.cep.cartridge.spatial.Geometry;
 
public class BusStopAdapter implements RunnableBean, StreamSource, StreamSink
{
  private final static String APP_NAME              = "spatial_sample";
...
  private String              m_eventTypeName;
  private EventType           m_eventType;
  private StreamSender        m_eventSender;
...
  public BusStopAdapter()
  {
    super();
  }
 
...
  @Service(filter = EventTypeRepository.SERVICE_FILTER)
  public void setEventTypeRepository(EventTypeRepository etr)
  {
    m_etr = etr;
  }
 
  public void setShow(boolean b)
  {
    m_show = b;
  }
 
  public void run()
  {
    m_stopped = false;
 
    // Need to store running thread so that it can be interrrupted in case of
    // suspend.
    m_runningThread = Thread.currentThread();
 
    if (m_etr == null)
    {
      throw new RuntimeException("EventTypeRepoitory is not set");
    }
 
    m_eventType = m_etr.getEventType(m_eventTypeName);
    if (m_eventType == null)
    {
      throw new RuntimeException("EventType(" + m_eventType + ") is not found.");
    }

    s_logger.info("fileSource " + m_filePath);

    if (m_initialDelay > 0)
    {
      try
      {
        s_logger.info("Sleeping for : " + m_initialDelay);
        Thread.sleep(m_initialDelay);
      } catch (InterruptedException e)
      {
        e.printStackTrace();
      }
    }

    synchronized (this)
    {
      while (!m_start)
      {
        try
        {
          this.wait();
        } catch (InterruptedException e)
        {
        }
      }
    }
    BufferedReader reader = null;

    System.out.println("Sending " + m_eventType + " from " + m_filePath);
    while ((m_repeat != 0) && (!m_stopped))
    {
      try
      {
        s_logger.info("Starting fileSource " + m_filePath);
        m_lineno = 0;
        reader = new BufferedReader(new FileReader(m_filePath));
      } catch (Exception e)
      {
        s_logger.warn(e.toString());
        m_stopped = true;
        break;
      }
      while (!isStopped())
      {
        try
        {
          Object ev = null;
          ev = readLine(reader);
          if (ev == null)
          {
            reader.close();
            break;
          }
          m_eventSender.sendInsertEvent(ev);
          if (m_show)
          {
            System.out.println(ev.toString());
          }
        } catch (Exception e)
        {
          s_logger.fatal("Failed to get tuple from " + m_filePath + ":"
              + m_lineno + "\n" + e.toString() + "\n");
          m_stopped = true;
          break;
        }
        if (m_sleep > 0)
        {
          try
          {
            synchronized (this)
            {
              // We need to save thread so that it can be interrupted in case of
              // suspend.
              wait(m_sleep);
            }
          } catch (InterruptedException e)
          {
            s_logger.warn(e);
            break;
          }
        }
      } // while
      if (m_repeat > 0)
        m_repeat--;
    } // while
    s_logger.info("FileAdaptor  " + hashCode() + " stopped. " + m_filePath);
  }

  @Override
  public void onInsertEvent(Object event) throws EventRejectedException  {
    if (!m_start)
    {
      m_start = true;
      synchronized (this)
      {
        notify();
      }
    }
  }
...
}

上記の例に示したプログラミングのガイドラインは、次のとおりです。

  • カスタム・アダプタはcom.bea.wlevs.ede.api.StreamSinkインタフェースを実装する必要があります。

    public class BusStopAdapter implements RunnableBean, StreamSource, StreamSink
    
  • StreamSinkインタフェースは、実装する必要のあるonInsertEvent (java.lang.Object)という単一のメソッドがあります。このメソッドは、イベントを受信するためのコールバック・メソッドです。メソッドパラメータはオブジェクトであり、イベントを送信したコンポーネントからBeanが受信した実際のイベントを表現します。

    public void onInsertEvent(Object event)
    

この項で説明しているOracle CEP APIの完全なAPIリファレンス情報については、Oracle Fusion Middleware Oracle Complex Event Processing Java APIリファレンスを参照してください。

14.2.3 カスタム・アダプタ・ファクトリの実装

アダプタ・ファクトリ・クラスはcom.bea.wlevs.ede.api.AdapterFactoryインタフェースを実装する必要があり、これには1つのメソッドcreateが含まれていますが、ここに特定のアダプタ・クラスを作成するコードを作成します。イベントBeanはFactoryを実装します。

次の例は、HelloWorldのサンプルで使用可能なアダプタ・ファクトリ・クラスです。

package com.bea.adapter.wlevs.example.helloworld;
import com.bea.wlevs.ede.api.Adapter;
import com.bea.wlevs.ede.api.AdapterFactory;
public class HelloWorldAdapterFactory implements Factory {
    public HelloWorldAdapterFactory() {
    }
    public synchronized Adapter create() throws IllegalArgumentException {
        return new HelloWorldAdapter();
    }
}

これらのAPIの詳細は、Oracle Fusion Middleware Oracle Complex Event Processing Java APIリファレンスを参照してください。

14.3 アダプタからデータ・フィード・プロバイダへのログイン資格証明の受け渡し

外部データ・フィードにアクセスする場合、アダプタはユーザー認証のためログイン資格証明(ユーザー名とパスワード)をデータ・フィードに渡す必要がある場合があります。

最も簡単で安全性の低い方法は、アダプタのJavaコード内に暗号化されていないログイン資格証明をハード・コード化することです。ただし、この方法ではパスワードを暗号化することができず、アダプタのJavaコードを再コンパイルせずに後からログイン資格証明を変更することもできません。

次の手順では、これらの問題が考慮された異なる方法について説明します。この手順では、データ・フィードにアクセスするユーザー名にjuliet、パスワードにsuperSecretを想定しています。

ログイン資格証明をEPNアセンブリ・ファイルで静的に構成するか、アダプタの構成を拡張して動的に構成するかを指定する必要があります。EPNアセンブリ・ファイルで資格証明を静的に構成する方が簡単ですが、後から資格証明が変更された場合は、EPNアセンブリ・ファイルへの更新が反映されるようにアプリケーションを再起動する必要があります。アダプタの構成を拡張する方法では、アプリケーションを再起動せずに資格証明を動的に変更できますが、構成の拡張には、XSDファイルの作成や、JAXBオブジェクトへのコンパイルなどの追加の手順が必要になります。

この項では次について説明します:

詳細は、第19章「コンポーネント構成の拡張」を参照してください。

14.3.1 データ・フィード・プロバイダへの静的ログイン資格証明の受け渡し

この手順では、EPNアセンブリ・ファイルで静的に構成したログイン資格証明を渡す方法について説明します。

データ・フィード・プロバイダへ静的ログイン資格証明を受け渡すには、次の手順を実行します。

  1. コマンド・ウィンドウを開き、『Oracle Complex Event Processingスタート・ガイド』の開発環境の設定に関する項の説明に従って、環境を設定します。

  2. アプリケーションのEPNアセンブリ・ファイルがあるディレクトリに移動します。

  3. 任意のXMLエディタを使用し、EPNアセンブリ・ファイルを編集して、アダプタを宣言しているwlevs:adapter要素を更新します。

    特に、ログイン資格証明のユーザー名とパスワードに対応する2つのインスタンス・プロパティを追加します。ここで、cleartextのパスワード値を指定します。後からこの値は暗号化されます。また、一時password要素を追加し、その値はcleartextパスワードにします。例:

    <wlevs:adapter id="myAdapter" provider="myProvider">
      <wlevs:instance-property name="user" value="juliet"/>
      <wlevs:instance-property name="password" value="superSecret"/>
      <password>superSecret</password>
    </wlevs:adapter>
    
  4. EPNアセンブリ・ファイルを保存します。

  5. EPNアセンブリ・ファイルのpassword要素の値を暗号化するためにencryptMSAConfigコマンドを実行します。

    prompt> ORACLE_CEP_HOME/ocep_11.1/bin/encryptMSAConfig . epn_assembly_file msainternal.dat_file
    

    ORACLE_CEP_HOMEは、d:\oracle_cepなどのOracle CEPのインストール先のメイン・ディレクトリです。2番目の引数はEPNアセンブリ・ファイルが含まれているディレクトリです。この手順では実際にそのディレクトリに移動しているため、例では「.」と示されています。epn_assembly_fileパラメータはEPNアセンブリ・ファイルの名前です。最後に、msainternal.dat_fileパラメータは、ドメインに関連付けられている.msainternal.datファイルの場所です。デフォルトでは、このファイルはDOMAIN_DIR/servernameディレクトリにあります。DOMAIN_DIRは、/oracle_cep/user_projects/domains/mydomainなどのドメイン・ディレクトリで、servernameはサーバー・インスタンスです。

    詳細は、『Oracle Complex Event Processing管理者ガイド』のencryptMSAConfigコマンドライン・ユーティリティに関する項を参照してください。

    コマンドを実行すると、EPNアセンブリ・ファイルのpassword要素の値が暗号化されます。

  6. EPNアセンブリ・ファイルを編集します。

    password要素の暗号化された値をpasswordインスタンス・プロパティのvalue属性にコピーします。

    password要素をXMLファイルから削除します。

    例:

    <wlevs:adapter id="myAdapter" provider="myProvider">
        <wlevs:instance-property name="user" value="juliet"/>
        <wlevs:instance-property name="password"
            value="{Salted-3DES}B7L6nehu7dgPtJJTnTJWRA=="/>
    </wlevs:adapter>
    
  7. 構成されたログイン資格証明のプロパティにアクセスしてパスワードを復号化するよう、アダプタのJavaコードを更新します。

    14.3.1項「データ・フィード・プロバイダへの静的ログイン資格証明の受け渡し」を参照してください。

  8. アプリケーションのMANIFEST.MFファイルを編集し、Import-Packageヘッダーにcom.bea.core.encryptionパッケージを追加します。24.2.2.1項「MANIFEST.MFファイルの作成」を参照してください。

  9. アプリケーションを通常通り再アセンブルしてデプロイします。第24章「Oracle CEPアプリケーションのアセンブルおよびデプロイ」を参照してください。

14.3.2 データ・フィード・プロバイダへの動的ログイン資格証明の受け渡し

この手順では、アダプタの構成を拡張して動的に構成したログイン資格証明を渡す方法について説明します。

データ・フィード・プロバイダへ動的ログイン資格証明を受け渡すには、次の手順を実行します。

  1. String型の2つの新しい要素userおよびpasswordを追加してアダプタの構成を拡張します。

    たとえば、HelloWorldのサンプルのアダプタを拡張した場合、XSDファイルは次のようになります。

    <xs:complexType name="HelloWorldAdapterConfig">
       <xs:complexContent>
         <xs:extension base="wlevs:AdapterConfig">
           <xs:sequence>
             <xs:element name="message" type="xs:string"/>
             <xs:element name="user" type="xs:string"/>
             <xs:element name="password" type="xs:string"/>
           </xs:sequence>
         </xs:extension>
       </xs:complexContent>
    </xs:complexType>
    

    詳細は、第19章「コンポーネント構成の拡張」を参照してください。

  2. コマンド・ウィンドウを開き、『Oracle Complex Event Processingスタート・ガイド』の開発環境の設定に関する項の説明に従って、環境を設定します。

  3. アダプタのコンポーネント構成XMLファイルがあるディレクトリに移動します。

  4. 任意のXMLエディタを使用してこのコンポーネント構成XMLファイルを編集し、<user>および<password>要素を使用して必要なログイン資格証明を追加します。ここでは、クリア・テキストのパスワード値を指定します。これは後から暗号化されます。例:

    <?xml version="1.0" encoding="UTF-8"?>
    <myExample:config
      xmlns:myExample="http://www.bea.com/xml/ns/wlevs/example/myExample">
      <adapter>
        <name>myAdapter</name>
        <user>juliet</user>
        <password>superSecret</password>
      </adapter>
    </myExample:config>
    
  5. アダプタの構成ファイルを保存します。

  6. アダプタ構成ファイルのpassword要素の値を暗号化するためにencryptMSAConfigコマンドを実行します。

    prompt> ORACLE_CEP_HOME/ocep_11.1/bin/encryptMSAConfig . adapter_config_file msainternal.dat_file
    

    ORACLE_CEP_HOMEは、d:\oracle_cepなどのOracle CEPのインストール先のメイン・ディレクトリです。2番目の引数はアダプタの構成ファイルが含まれているディレクトリです。この手順では実際にそのディレクトリに移動しているため、例では「.」と示されています。adapter_config_fileパラメータはアダプタ構成ファイルの名前です。最後に、msainternal.dat_fileパラメータは、ドメインに関連付けられている.msainternal.datファイルの場所です。デフォルトでは、このファイルはDOMAIN_DIR/servernameディレクトリにあります。DOMAIN_DIRは、/oracle_cep/user_projects/domains/mydomainなどのドメイン・ディレクトリで、servernameはサーバー・インスタンスです。

    詳細は、『Oracle Complex Event Processing管理者ガイド』のencryptMSAConfigコマンドライン・ユーティリティに関する項を参照してください。

    コマンドを実行すると、password要素の値が暗号化されます。

  7. 構成されたログイン資格証明のプロパティにアクセスしてパスワードを復号化するよう、アダプタのJavaコードを更新します。

    14.3.1項「データ・フィード・プロバイダへの静的ログイン資格証明の受け渡し」を参照してください。

  8. アプリケーションのMANIFEST.MFファイルを編集し、Import-Packageヘッダーにcom.bea.core.encryptionパッケージを追加します。24.2.2.1項「MANIFEST.MFファイルの作成」を参照してください。

  9. アプリケーションを通常通り再アセンブルしてデプロイします。第24章「Oracle CEPアプリケーションのアセンブルおよびデプロイ」を参照してください。

14.3.3 実行時のログイン資格証明へのアクセス方法

この項では、拡張されたアダプタ構成から動的にユーザーとパスワードの値を取得し、com.bea.core.encryption.EncryptionService APIを使用して暗号化されたパスワードを復号化するようにカスタム・アダプタのJavaコードを更新する方法について説明します。

次に示すコード・スニペットは、14.2.2.1項「カスタム・アダプタをイベント・ソースとして実装」に示したアダプタのJavaコードのHelloWorldを基に作成されます。

実行時にログイン資格証明プロパティにアクセスするには、次の手順を実行します。

  1. 暗号化されたパスワードの複合化に必要な追加のAPIをインポートします。

    import com.bea.core.encryption.EncryptionService;
    import com.bea.core.encryption.EncryptionServiceException;
    import com.bea.wlevs.util.Service;
    
  2. @Service注釈を使用してEncryptionServiceへの参照を取得します。

    private EncryptionService encryptionService;
    ...
    @Service
    public void setEncryptionService(EncryptionService encryptionService) {
        this.encryptionService = encryptionService;
    }
    
  3. @Prepareコールバック・メソッドで、拡張されたアダプタ構成のuserおよびpasswordプロパティの値を通常どおり取得します(password値のコードのみ示しています)。

    private String password;
    ...
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    ...
    @Prepare
    public void checkConfiguration(HelloWorldAdapterConfig adapterConfig) {
        if (adapterConfig.getMessage() == null
                || adapterConfig.getMessage().length() == 0) {
            throw new RuntimeException("invalid message: " + message);
        }
        this.password= adapterConfig.getPassword();
        ...
    }
    

    拡張されたアダプタ構成へのアクセスに関する情報は、19.3項「カスタム・アダプタまたはイベントBeanの構成へのプログラムからのアクセス」を参照してください。

  4. @Prepareコールバック・メソッドでEncryptionService.decryptStringAsCharArrayメソッドを使用して暗号化されたパスワードを複合化します。

    @Prepare
    public void checkConfiguration(HelloWorldAdapterConfig adapterConfig) {
        if (adapterConfig.getMessage() == null
                || adapterConfig.getMessage().length() == 0) {
            throw new RuntimeException("invalid message: " + message);
        }
        this.password= adapterConfig.getPassword();
        try {
            char[] decrypted = encryptionService.decryptStringAsCharArray(password);
            System.out.println("DECRYPTED PASSWORD is "+ new String(decrypted));
        } catch (EncryptionServiceException e) {
            throw new RuntimeException(e);
        }
    }
    

    decryptStringAsCharArrayメソッドのシグネチャは次のとおりです。

    char[] decryptStringAsCharArray(String encryptedString)
                                    throws EncryptionServiceException
    
  5. ベンダーAPIを使用してこれらの資格証明をデータ・フィード・プロバイダに渡します。

14.4 カスタム・アダプタのEPNアセンブリ・ファイルの構成

次の項で説明しているように、アダプタおよびアダプタ・ファクトリ(使用する場合)をEPNアセンブリ・ファイルに登録する必要があります。

アプリケーションの他のコンポーネントの登録を含む、構成ファイルの完全な説明は、4.3項「EPNアセンブリ・ファイルの作成」を参照してください。

14.4.1 カスタム・アダプタ・ファクトリの登録

wlevs:factory要素を使用してEPNアセンブリ・ファイルにファクトリを登録します。

<wlevs:factory provider-name="myprovider" class="my.Implementation"/>

サービスのプロパティを指定する必要がある場合は、osgi:service>要素を使用して、EPNアセンブリ・ファイルにOSGIサービスとしてファクトリを登録する必要があります。OSGIサービス・レジストリのスコープはOracle CEP全体です。このため、指定のサーバーにデプロイされた複数のアプリケーションが同じアダプタ・ファクトリを使用する場合は、アダプタ・ファクトリをOSGIサービスとして登録するのが必ず一度きりになるようにします。

エントリを追加して、サービスをcom.bea.wlevs.ede.api.AdapterFactoryインタフェースの実装として登録します。key属性のtype、およびこのアダプタ・プロバイダを参照する名前を使用して、プロパティを指定します。最後に、ネストされた標準のSpring bean要素を追加して、Springアプリケーション・コンテキストで特定のアダプタ・クラスを登録します。

たとえば、EPNアセンブリ・ファイルの次の部分では、HelloWorldAdapterFactoryをタイプhellomsgsのプロバイダとして登録します。

<osgi:service interface="com.bea.wlevs.ede.api.AdapterFactory">
    <osgi:service-properties>
        <entry key="type" value="hellomsgs"</entry>
    </osgi:service-properties>
    <bean  class="com.bea.adapter.wlevs.example.helloworld.HelloWorldAdapterFactory" />
</osgi:service>

typeでファクトリを参照する方法については、14.4.2項「アプリケーションのカスタム・アダプタ・コンポーネントの宣言」を参照してください。

14.4.2 アプリケーションのカスタム・アダプタ・コンポーネントの宣言

EPNアセンブリ・ファイルでは、wlevs:adapter要素を使用してアダプタをイベント・プロセッサ・ネットワークのコンポーネントとして宣言します。例:

<wlevs:adapter id="recplayEventSink"
                  class="com.bea.wlevs.example.recplayRecplayEventSink">
    <wlevs:listener ref="playbackHttpPublisher"/>
</wlevs:adapter>

オプションのファクトリをOSGIサービスとして登録した場合は、provider属性を使用して、osgi:serviceエントリでtypeとして指定した名前を参照します。例:

<wlevs:adapter id="helloworldAdapter" provider="hellomsgs"/>

これにより、アダプタはタイプhellomsgsで登録されたファクトリによってインスタンス化されます。

wlevs:adapterwlevs:instance-property子要素を使用して、アダプタBeanの静的プロパティを設定することもできます。静的プロパティはアダプタのデプロイ後に動的に変更されないプロパティです。

たとえば、アダプタ・クラスにsetPortメソッドが含まれている場合は、次のようにポート番号を渡すことができます。

<wlevs:adapter id="myAdapter" provider="myProvider">
    <wlevs:instance-property name="port" value="9001" />
</wlevs:adapter>

14.5 カスタム・アダプタのコンポーネント構成ファイルの構成

アプリケーションの各アダプタにはデフォルトの構成があり、オプションで拡張コンポーネント構成を持つものがあります。

アプリケーションに複数のアダプタが含まれている場合は、各アダプタごとに個別のコンポーネント構成XMLファイルを作成するか、すべてのアダプタのコンフィグレーションが含まれた単一のコンポーネント構成XMLファイルを作成するか、またはアプリケーションのすべてのコンポーネント(アダプタ、プロセッサ、およびストリーム)が含まれたファイルを作成できます。開発環境に最も適した方法を選択します。

次の手順では、アダプタの構成ファイルを作成する主なステップについて示します。簡略化のため、この手順ではアプリケーションのすべてのコンポーネントを1つのXMLファイルに構成することを想定しています。

詳細については、次を参照してください。

14.5.1 カスタム・アダプタを手動で構成する方法

次の手順では、カスタム・アダプタを手動で構成する方法について説明します。

カスタム・アダプタ・コンポーネント構成ファイルを構成するには、次の手順を実行します。

  1. お気に入りのXMLエディタを使用してXMLファイルを作成します。

    このXMLファイルの名前は自分で決定しますが、その拡張は.xmlで終了することが必要です。

    構成ファイルのルート要素はconfigであり、次のステップに示すネームスペース定義を使用します。

  2. アプリケーションの各アダプタは、configadapter子要素を追加します。

    name子要素で各アダプタを一意に識別します。この名前は、アプリケーションのイベント処理ネットワークを定義するEPNアセンブリ・ファイルのwlevs:adapter要素のid属性の値と一致している必要があります。このように指定することで、Oracle CEPでは、このアダプタ構成が適用されるEPNアセンブリ・ファイル内の特定のアダプタ・コンポーネントを認識します。詳細は、4.3項「EPNアセンブリ・ファイルの作成」を参照してください。

    たとえば、アプリケーションに2つのアダプタがある場合、構成ファイルは最初に次のようになります。

    <?xml version="1.0" encoding="UTF-8"?>
    <helloworld:config
      xmlns:helloworld="http://www.bea.com/xml/ns/wlevs/example/helloworld">
      <processor>
       ...
      </processor>
      <adapter>
        <name>firstAdapter</name>
        ...
      </adapter>
      <adapter>
        <name>secondAdapter</name>
        ...
      </adapter>
    </helloworld:config>
    

    この例では、構成ファイルにfirstAdaptersecondAdapterの2つのアダプタが含まれています。このため、EPNアセンブリ・ファイルには同じ識別子を持つアダプタが少なくとも2つ登録されている必要があります。

    <wlevs:adapter id="firstAdapter" ...>
      ...
    </wlevs:adapter>
    <wlevs:adapter id="secondAdapter" ...>
      ...
    </wlevs:adapter>
    

    注意:

    XMLファイルの識別子と名前は大/小文字が区別されるため、EPNアセンブリ・ファイルでコンポーネントの識別子を参照するときは、必ず大/小文字を同一にします。

14.5.1.1 カスタム・アダプタ構成ファイルの例

次のXMLファイルの例は、firstAdapterおよびsecondAdapterの2つのアダプタを構成する方法を示します。

<?xml version="1.0" encoding="UTF-8"?>
<sample:config
  xmlns:sample="http://www.bea.com/xml/ns/wlevs/example/sample">
  <adapter>
    <name>firstAdapter</name>
  </adapter>
  <adapter>
    <name>secondAdapter</name>
  </adapter>
</sample:config>