WS-Notification 範例輕鬆演練

事件來源範例 (EventSource.java) 是簡式事件來源,它會將單一且寫在程式中的事件傳送給「Web 服務」。它會示範事件來源必須遵循的下列步驟:

  1. 取得事件 Factory
  2. 建立事件及移入事件的必要資料
  3. 使用產生的「Web 服務」用戶端說明性常式來傳送事件

可在 SDK 的 <sdk_install_dir>/samples/wsnt-was/src/com/wtci/samples/was/source 目錄中取得 EventSource.java 的程式碼。

此範例使用 Hyades 記載類別以及從 wsdl 檔案產生的類別。請使用下列 import 陳述式來存取必要的套件:

import com.ibm.wtci.samples.waswsn10.emitter.NotificationConsumerService;
import com.ibm.wtci.samples.waswsn10.emitter.NotificationConsumerServiceLocator;
import com.ibm.wtci.samples.waswsn10.wsn.NotificationConsumer;
import com.ibm.wtci.samples.waswsn10.wsn.NotificationMessageHolderType;

import com.ibm.ws.webservices.engine.xmlsoap.SOAPElement;
import com.ibm.ws.webservices.engine.xmlsoap.SOAPFactory;

import org.eclipse.hyades.logging.events.cbe.CommonBaseEvent;
import org.eclipse.hyades.logging.events.cbe.EventFactory;
import org.eclipse.hyades.logging.events.cbe.EventFactoryFactory;
import org.eclipse.hyades.logging.events.cbe.Situation;
import org.eclipse.hyades.logging.events.cbe.util.EventFormatter;

import java.net.URL;

EventSource.java 的 main 方法會使用預設建構子來建立 EventSource 的新實例。然後, 它會呼叫專用 sendEvent 方法,而此方法包含主程式邏輯。傳回 sendEvent 方法之後,main() 方法會將「已送出通知」訊息列印至標準輸出。

    /**
     * Main method for the event source.
     * 
     * @param args
     *            arguments passed from the command line
     */
    public static void main(String args[]) {
        EventSourceWsn10 source = new EventSourceWsn10();
        try {
            source.sendEvent();
            System.out.println("Notification sent");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

建立事件並將資料移入事件

EventSource.java 的 createEvent() 方法是 helper 方法,可使用它來建立事件, 並將最小一組的內容資料移入該事件。sendEvent 方法會呼叫此方法, 以建立將傳送給「Web 服務」的事件。

    public static CommonBaseEvent[] createEvents() throws Exception {
        CommonBaseEvent[] events = null;

        String cbeFile = System.getProperty("cbe.file");
        if (cbeFile != null) {
            events = EventFormatter.eventsFromCanonicalXMLDoc(cbeFile);
        } else {
            // The first step is accessing the event factory
            EventFactory eventFactory = EventFactoryFactory.createEventFactory();

            // Creating an event with an extension name.
            CommonBaseEvent event = eventFactory.createCommonBaseEvent("EVENT");
            event.setCreationTimeAsLong(System.currentTimeMillis());

            // Setting the mandatory situation description for the event.
            Situation situation = eventFactory.createSituation();
            situation.setCategoryName(Situation.REPORT_SITUATION_CATEGORY);
            situation.setReportSituation("INTERNAL", "Succeeded");
            event.setSituation(situation);

            // Setting the mandatory component identification for the
            // event source
            event.setSourceComponentId("Event Source",
                "source.EventSource",
                "createEvent()",
                "http://www.ibm.com/namespaces/autonomic/Tivoli/Samples",
                "Sample",
                "unknown",
                "hostname");

            // Setting Common Base Event version
            event.setVersion("1.0.1");
            // Setting optional fields
            event.setSeverity((short) 10);
            event.setMsg("Common Event Infrastructure Tutorial");

            events = new CommonBaseEvent[] { event };
        }

        return events;
    }

createEvent 方法會執行下列步驟:

  1. 使用 EventFactoryFactory 的 createEventFactory() 方法來建立新的 EventFactory 物件
  2. 使用事件 Factory 的 createCommonBaseEvent(String) 方法來建立新的事件物件 (CommonBaseEvent 的實例)。指定的字串 ("EVENT") 是用來設定事件的 extensionName 內容,而現行系統時間是用來設定 creationTime 內容。
  3. 設定事件的 situation 內容值。因為 situation 是複式內容, 所以是以特殊 Java 類別來呈現。因此,設定 situation 內容需要數個個別的步驟:
    1. 建立新的 Situation 物件
    2. 使用 setter 方法,將必要的內容資料移入 Situation 物件
    3. 呼叫 Event.setSituation() 方法來設定事件的 situation 內容,並指定資料要移入的 Situation 物件
  4. 設定其他數個事件內容 (部份必要的事件內容及部份選用的事件內容) 的值。這些內容包括 severitymsgversion sourceComponentId
    附註:situation 相似,sourceComponentId 也是複式屬性。然而,它的子內容全部都是以字串來呈現的簡式屬性, 所以您可以使用 setSourceComponentId() helper 方法,而不是個別實例化特殊 Java 物件。

    範例所設定的其他屬性內容 (versionseveritymsg) 全部都是以字串或整數來呈現的簡式內容屬性。

  5. 最後,createEvent() 方法會傳回現在已移入內容資料的事件。

建立通知訊息

事件來源範例的下一個方法 createNotificationMessage(event) 是 helper 方法, 可使用它來建立會將傳入的事件封裝為方法之參數的通知訊息。sendEvent 方法會呼叫此方法,以建立將傳送給「Web 服務」的通知訊息。

    public static NotificationMessageHolderType[] createNotificationMessage(
            CommonBaseEvent events[]) throws Exception {
        NotificationMessageHolderType[] notificationArray = 
            new NotificationMessageHolderType[events.length];
        for (int i = 0; i < events.length; i++) {

            //Creating an instance of NotificationMessageHolderType
            notificationArray[i] = new NotificationMessageHolderType();

            //Creating a Topic element with the name 'Topic'
            SOAPFactory soapFactory = new SOAPFactory();
            SOAPElement topicSE = (SOAPElement) 
                soapFactory.createElement("Topic");
            SOAPElement topicSEChild = (SOAPElement)
                topicSE.addChildElement("Topic");
            topicSEChild.setAttribute("dialect","none");
            notificationArray[i].setTopic(topicSE);

            //Setting the event to be the message of the notification
            SOAPElement messageSE = (SOAPElement) 
                soapFactory.createElement("Message");
            messageSE.addNamespaceDeclaration("ns2",
                "http://www.ibm.com/AC/commonbaseevent1_0_1");
            messageSE.addAttribute("http://www.w3.org/2001/XMLSchema-instance",
                "type",
                "ns2:CommonBaseEvent");
            String cbeStr = EventFormatter.toCanonicalXMLString(events[i]);
            SOAPElement cbeSE = (SOAPElement) 
                soapFactory.createElementFromXMLString(cbeStr);
            messageSE.addChildElement(cbeSE);
            notificationArray[i].setMessage(messageSE);

            //Setting information about the producer of the event in
            //the notification
            SOAPElement producerSE = (SOAPElement) 
                soapFactory.createElement("ProducerReference");
            SOAPElement producerSEChild = (SOAPElement) 
                soapFactory.createElement("Address",
                "ns1",
                "http://schemas.xmlsoap.org/ws/2003/03/addressing");
            producerSEChild.addTextNode("protocol://your.event.source.address");
            producerSE.addChildElement(producerSEChild);
            notificationArray[i].setProducerReference(producerSE);
        }
        return notificationArray;
    }

createNotificationMessage(event) 會執行下列步驟:

  1. 建立 NotificationMessageHolderType 物件,以保留要傳送的通知資訊。
  2. 使用 'Topic' 名稱來建立通知的 Topic 元素。會新增巢狀子元素,以顯示在接收到通知時將略過之 Topic 元素內的所有項目。
  3. 將通知訊息設定成傳送給方法的事件。
  4. 在通知中設定事件產生器的相關資訊。
  5. 將因此而建立及移入資訊的通知訊息傳回給呼叫端。

傳送事件

事件來源範例的最後一個方法 sendEvent() 包含主程式邏輯。此方法會處理所有與 NotificationConsumer 用戶端的互動 (包括傳送事件)。

    private void sendEvent() throws Exception {
        //The first step is creating an event
        CommonBaseEvent[] events = createEvents();

        //Creating the Notification message encapsulating the event
        NotificationMessageHolderType[] notification = 
            createNotificationMessage(events);

        //Obtaining the address of the NotificationConsumerService webservice
        String endpoint = System.getProperty("service.address");
        if (endpoint == null) {
            // If no address was specified, the webservice is assumed to be
            // runnning in the localhost at port 9080 for was
            endpoint = "http://localhost:9080/wsnt-was/services/NotificationConsumer10Soap";
        }

        //Creating an URL object for the address obtained
        java.net.URL serviceURL = new URL(endpoint);

        //Creating an instance of NotificationConsumerServiceLocator
        NotificationConsumerService notifierSvc = 
            new NotificationConsumerServiceLocator();
        NotificationConsumer notifier = 
            notifierSvc.getNotificationConsumer10Soap(serviceURL);

        //Sending the notification
        notifier.notify(notification);

    }

sendEvent() 方法會執行下列步驟:

  1. 呼叫 createEvent() helper 方法,以建立新事件並將資料移入該事件。
  2. 呼叫 createNotificationMessage(event) helper 方法,以建立會封裝所建立之事件的通知訊息。
  3. 從系統內容中,取得「NotificationConsumer Web 服務」的位址 (服務通知要求)。
  4. 實例化 NotificationConsumerServiceLocator,然後使用它來取得 NotificationConsumer 物件。
  5. 呼叫 NotificationConsumer 的 notify() 方法來傳送事件。這會產生封裝該事件的 SOAP 訊息


相關主題
建置範例
執行範例


相關概念
將「共用基本事件」格式的事件轉換成 Enterprise Console 事件格式