Implementing a Notification Server


This appendix describes how to modify the example servlet to customize for your own application, and contains the following sections:

Event Notification Overview

Running the Example Servlet

Customizing the Example Servlet

Events for Collection

Event Notification Overview

Event notification allows an Prime Fulfillment API user to collect events of interest from the Prime Fulfillment system. The events of interest are triggered by changes to objects managed by Prime Fulfillment. An event is registered and a notification is sent any time a database object is created, modified, or deleted, when a scheduled task begins or ends its execution, or when a watchdog event signals a change in execution status for any Prime Fulfillment service.

The Prime Fulfillment properties that manage the notification server are:

notification.clientEnabled—Used to turn notification forwarding on and off.

notification.clientHost—The machine running the event notification receiving program.

notification.clientPort—The listener port to open on the receiving machine. This property is defined in the Tomcat web.xml file.

notification.clientMethod—The method, or program, to contact on the receiving machine.

notification.clientRegFile—Contains the events of interest to be forwarded.


Note clientHost, clientMethod, and clientPort are used to construct a URL.


Figure B-1 illustrates the notification mechanisms implemented by Prime Fulfillment.

Figure B-1 Event Notification Mechanisms

The EventReceivingServlet can be customized and used for your own application.

The notification web.xml file (located in $PRIMEF_HOME/resources/webserver/tomcat/webapps/notification/WEB-INF) in Prime Fulfillment identifies two servlets:

notificationServlet

eventListener (EventReceivingServlet program)

Use this file as a template for implementing a notification servlet.

In the following web.xml file, the notificationServlet section and eventListener section are indicated in bold.

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-app
  PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
  "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
  <servlet>
    <servlet-name>notificationServlet</servlet-name>
    <display-name>Notification Servlet</display-name>
    <servlet-class>com.cisco.vpnsc.nbi.notification.NotificationServlet</servlet-class>
    <init-param>
      <param-name>log</param-name>
      <param-value>2</param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
  </servlet>
  <servlet>
    <servlet-name>eventListener</servlet-name>
    <display-name>Event Listener</display-name>
    <servlet-class>com.cisco.vpnsc.nbi.client.EventReceivingServlet</servlet-class>
    <init-param>
      <param-name>log</param-name>
      <param-value>2</param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>eventListener</servlet-name>
    <url-pattern>/notification/servlet/eventListener</url-pattern>
  </servlet-mapping>
</web-app>

The Prime Fulfillment installation contains an example servlet which can be activated to demonstrate the collection of notification events. The event notification receiving servlet (eventListener) calls a program com.cisco.vpnsc.nbi.client.EventReceivingServlet. This program is included in the Prime Fulfillment installation ($PRIMEF_HOME/resources/nbi/client/EventReceivingServlet.java) and shows a simple piece of code which receives an event and prints it to a log file.


Note For more information on example clients, see Appendix C, "Scripts".


Running the Example Servlet

Prime Fulfillment includes an example event-notification client servlet. This servlet can be activated on a standard Prime Fulfillment installation.

The example effectively creates a loopback scenerario whereby an Prime Fulfillment event generates a SOAP/XML message that is sent back to the Prime Fulfillment server's HTTP port. Upon arriving at the port (8030 is the default), the Tomcat server loads and executes the EventReceivingServlet client code.

You can observe the outbound event message and the inbound notification message by inspecting $PRIMEF_HOME/tmp/httpd_out.0 and $PRIMEF_HOME/notification.0 respectively. If the event notification succeeds, you will see the SOAP/XML event notification at the bottom of the notification.0 file.

To run a demonstration of the example servlet:


Step 1 Add an event to the cilentReg.txt file. This file is located $PRIMEF_HOME/resources/nbi/notification/clientReg.txt

Step 2 Enable dynamic loading of servlets on the Prime Fulfillment server with the following actions:

A) edit $PRIMEF_HOME/resources/webserver/tomcat/conf/web.xml

B) Make sure the mapping for the invoker servlet-mapping is uncommented. The following is the XML text for the invoker servlet-mapping:

<!-- The mapping for the invoker servlet -->

<servlet-mapping>

<servlet-name>invoker</servlet-name>

<url-pattern>/servlet/*</url-pattern>

</servlet-mapping>

For this example, add com.cisco.vpnsc.repository.devices.CiscoRouter.> to specify events involving a CiscoRouter.

Step 3 Change the property notification.clientEnabled to true. This file is located in $PRIMEF_HOME/etc/vpnsc.properties.

From the GUI:

Go to Administration->Control Center.

Choose your host and click Config.

Locate the notification server and select the clientEnabled property. Set to true and click Set Property.

Step 4 Restart Prime Fulfillment.

Step 5 Add a CiscoRouter device.

From the GUI:

Go to Service Inventory > Inventory and Connection Manager > Devices.

Click Create and select Cisco IOS Device.

Enter a host name.

Click Save.

Step 6 Go to $PRIMEF_HOME/tmp and cat the file httpd_out.0. The XML at the end should look like the following example:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:ns0="http://www.cisco.com/cim-cx/2.0" xmlns:ns1="urn:CIM">
  <soapenv:Header>
    <ns0:message />
  </soapenv:Header>
  <soapenv:Body>
    <ns1:deliverEvent>
      <returns xsi:type="ns1:CIMReturnList" soapenc:arrayType="ns1:CIMReturn[]">
        <record>
          <objectPath xsi:type="ns1:CIMObjectPath">
            <className xsi:type="xsd:string">InstIndication</className>
            <properties xsi:type="ns1:CIMPropertyList" 
soapenc:arrayType="ns1:CIMProperty[]">
              <item xsi:type="ns1:CIMProperty">
                <name xsi:type="xsd:string">IndicationType</name>
                <value xsi:type="xsd:string">create</value>
              </item>
              <item xsi:type="ns1:CIMProperty">
                <name xsi:type="xsd:string">IndicationTime</name>
                <value xsi:type="xsd:string">2003-12-03 13:15:26</value>
              </item>
              <item xsi:type="ns1:CIMProperty">
                <name xsi:type="xsd:string">InstClassName</name>
                <value xsi:type="xsd:string">CiscoRouter</value>
              </item>
              <item xsi:type="ns1:CIMProperty">
                <name xsi:type="xsd:string">InstName</name>
                <value xsi:type="xsd:string">xyz</value>
              </item>
              <item xsi:type="ns1:CIMProperty">
                <name xsi:type="xsd:string">LocatorId</name>
                <value xsi:type="xsd:string">40</value>
              </item>
            </properties>
          </objectPath>
        </record>
      </returns>
    </ns1:deliverEvent>
  </soapenv:Body>
</soapenv:Envelope>


Customizing the Example Servlet

Use the following procedure to implement a custom notification receiving servlet.


Step 1 Copy the web.xml file, located in $PRIMEF_HOME/resources/webserver/tomcat/webapps/notification/WEB-INF, to your own Tomcat structure.

Step 2 Remove the notification servlet xml section. This section is specific to Prime Fulfillment.

Step 3 Change the eventListener program from com.cisco.vpnsc.nbi.client.EventReceivingServlet to your own program.

Step 4 Specify the events to receive by editing the contents of the file $PRIMEF_HOME/resources/nbi/notification/clientReg.txt. The default contents of this file are:

com.cisco.vpnsc.repository.task.PersistentTask.>
com.cisco.vpnsc.repository.devices.PIX.>

This means that events involving PIX devices or PersistentTask will be forwarded to the EventListener servlet.

For example, add com.cisco.vpnsc.repository.devices.CiscoRouter.> to specify events involving a CiscoRouter.

See the "Events for Collection" section for a complete list of events that can be collected and forwarded.

Step 5 Change the property notification.clientEnabled to true. This file is located in $PRIMEF_HOME/etc/vpnsc.properties.

From the GUI:

Go to Administration >Control Center.

Choose your host and click Config.

Locate the notification server and select the clientEnabled property. Set to true and click Set Property.

Step 6 Restart Prime Fulfillment.


Events for Collection

The following events can be collected for the Prime Fulfillment notifications server:

'com.cisco.vpnsc.repository.task.Argument'

'com.cisco.vpnsc.repository.task.Action'

'com.cisco.vpnsc.repository.task.ActionDependency'

'com.cisco.vpnsc.repository.task.ActionTarget'

'com.cisco.vpnsc.repository.task.PersistentTask'

'com.cisco.vpnsc.repository.task.RuntimeAction'

'com.cisco.vpnsc.repository.task.RuntimeTask'

'com.cisco.vpnsc.repository.task.ScheduledTask'

'com.cisco.vpnsc.repository.devices.Device'

'com.cisco.vpnsc.repository.devices.CiscoDevice'

'com.cisco.vpnsc.repository.devices.CiscoRouter'

'com.cisco.vpnsc.repository.devices.PIX'

'com.cisco.vpnsc.repository.devices.TerminalServer'

'com.cisco.vpnsc.repository.devices.CatOs'

'com.cisco.vpnsc.repository.devices.NonCiscoDevice'

'com.cisco.vpnsc.repository.devices.IE2100'

'com.cisco.vpnsc.repository.devices.GenericDeviceInterface'

'com.cisco.vpnsc.repository.devices.CiscoDeviceInterface'

'com.cisco.vpnsc.repository.devices.NonCiscoDeviceInterface'

'com.cisco.vpnsc.repository.devices.PIXDeviceInterface'

'com.cisco.vpnsc.repository.devices.DeviceGroup'

'com.cisco.vpnsc.repository.devices.RepDev_DevGp_Mpng'

'com.cisco.vpnsc.repository.devices.CollectionZone'

'com.cisco.vpnsc.repository.devices.VPNSCHost'

'com.cisco.vpnsc.repository.devices.VPNSCHostProperties'

'com.cisco.vpnsc.repository.devices.VirtualCircuit'

'com.cisco.vpnsc.repository.devices.AtmVC'

'com.cisco.vpnsc.repository.device.FrameRelayVC'

'com.cisco.vpnsc.repository.devices.VlanVC'

'com.cisco.vpnsc.repository.devices.PEDevice'

'com.cisco.vpnsc.repository.devices.CPEDevice'

'com.cisco.vpnsc.repository.common.Customer'

'com.cisco.vpnsc.repository.common.Site'

'com.cisco.vpnsc.repository.common.LogicalDevice'

'com.cisco.vpnsc.repository.common.Cpe'

'com.cisco.vpnsc.repository.common.CustomerNetworkPrefix'

'com.cisco.vpnsc.repository.common.VPN'

'com.cisco.vpnsc.repository.common.Interface'

'com.cisco.vpnsc.repository.common.Vc'

'com.cisco.vpnsc.repository.common.PE'

'com.cisco.vpnsc.repository.common.Provider'

'com.cisco.vpnsc.repository.common.Region'

'com.cisco.vpnsc.repository.mpls.VRF'

'com.cisco.vpnsc.repository.common.GenericSR'

'com.cisco.vpnsc.repository.mlshare.AccessDomain'

'com.cisco.vpnsc.repository.common.AttributeValue'

'com.cisco.vpnsc.repository.common.ConfigletClob'

'com.cisco.vpnsc.repository.common.Configlet'

'com.cisco.vpnsc.repository.common.Policy'

'com.cisco.vpnsc.repository.common.SRAssociatedTemplate'

'com.cisco.vpnsc.repository.common.RepCableIpAddress'

'com.cisco.vpnsc.repository.common.RepSRReport'

'com.cisco.vpnsc.repository.common.SRHistoryReport'

'com.cisco.vpnsc.repository.common.StagedConfiglet'

'com.cisco.vpnsc.repository.common.StagedSR'

'com.cisco.vpnsc.repository.common.GenericSRToVpn'

'com.cisco.vpnsc.repository.mlshare.PhysicalLink'

'com.cisco.vpnsc.repository.mlshare.Ring'

'com.cisco.vpnsc.repository.mlshare.PhysicalLinkSeq'

'com.cisco.vpnsc.repository.mlshare.NamedPhysicalCircuit'

'com.cisco.vpnsc.repository.mlshare.MLSharePolicy'

'com.cisco.vpnsc.repository.mlshare.MlConnPolicy'

'com.cisco.vpnsc.repository.mlshare.LogicalLink'

'com.cisco.vpnsc.repository.mlshare.LogicalLinkSet'

'com.cisco.vpnsc.repository.mlshare.EndPoint'

'com.cisco.vpnsc.repository.mlshare.DevEndPoint'

'com.cisco.vpnsc.repository.mlshare.RepNotEditable'

'com.cisco.vpnsc.repository.mlshare.LinkTemplate'

'com.cisco.vpnsc.repository.mlshare.ReservedVlanPool'

'com.cisco.vpnsc.repository.mlshare.RingMembership'

'com.cisco.vpnsc.repository.mlshare.RingSeq'

'com.cisco.vpnsc.repository.mpls.MplsSR'

'com.cisco.vpnsc.repository.mpls.CERC'

'com.cisco.vpnsc.repository.mpls.CERCMembership'

'com.cisco.vpnsc.repository.mpls.VRFRole'

'com.cisco.vpnsc.repository.mpls.MplsVpnLink'

'com.cisco.vpnsc.repository.mpls.MplsLogicalLink'

'com.cisco.vpnsc.repository.mpls.MplsPolicyAttributeMap'

'com.cisco.vpnsc.repository.mpls.MplsPolicy'

'com.cisco.vpnsc.repository.mpls.MplsPolicyInterface'

'com.cisco.vpnsc.repository.mpls.MplsPolicyRoutingProtocol'

'com.cisco.vpnsc.repository.mpls.MplsPolicyOSPFRouting'

'com.cisco.vpnsc.repository.mpls.MplsPolicyBGPRouting'

'com.cisco.vpnsc.repository.mpls.MplsPolicyEIGRPRouting'

'com.cisco.vpnsc.repository.mpls.MplsPolicyIGRPRouting'

'com.cisco.vpnsc.repository.l2vpn.AC'

'com.cisco.vpnsc.repository.mpls.MplsPolicyISISRouting'

'com.cisco.vpnsc.repository.mpls.MplsPolicyRIPRouting'

'com.cisco.vpnsc.repository.mpls.MplsPolicyStaticRouting'

'com.cisco.vpnsc.repository.mpls.MplsPolicyNoneRouting'

'com.cisco.vpnsc.repository.mpls.MplsPolicyRedistributedRoutingProtocol'

'com.cisco.vpnsc.repository.mpls.MplsPolicyCercMembership'

'com.cisco.vpnsc.repository.mpls.RepStaticRoutes'

'com.cisco.vpnsc.repository.mpls.LinkAttrs'

'com.cisco.vpnsc.repository.mpls.LinkAttrsAttrMap'

'com.cisco.vpnsc.repository.mpls.LinkAttrsRedistributedRoutingProtocol'

'com.cisco.vpnsc.repository.mpls.LinkAttrsRoutingProtocol'

'com.cisco.vpnsc.repository.mpls.LinkAttrsOSPFRouting'

'com.cisco.vpnsc.repository.mpls.LinkAttrsBGPRouting'

'com.cisco.vpnsc.repository.mpls.LinkAttrsEIGRPRouting'

'com.cisco.vpnsc.repository.mpls.LinkAttrsIGRPRouting'

'com.cisco.vpnsc.repository.mpls.LinkAttrsISISRouting'

'com.cisco.vpnsc.repository.mpls.LinkAttrsRIPRouting'

'com.cisco.vpnsc.repository.mpls.LinkAttrsStaticRouting'

'com.cisco.vpnsc.repository.mpls.LinkAttrsNoneRouting'

'com.cisco.vpnsc.repository.mpls.RoutingProtocolAccessor'

'com.cisco.vpnsc.repository.mpls.LinkRoutingProtocolAccessor'

'com.cisco.vpnsc.repository.mpls.RepCableIpAddr'

'com.cisco.vpnsc.repository.mpls.RepOldTemplate'

'com.cisco.vpnsc.repository.mpls.MplsUniEtth'

'com.cisco.vpnsc.repository.mpls.LinkMulticastIPAddr'

'com.cisco.vpnsc.repository.l2vpn.L2VpnPolicyAttributeMap'

'com.cisco.vpnsc.repository.l2vpn.L2VpnPolicy'

'com.cisco.vpnsc.repository.l2vpn.L2VpnPolicyInterface'

'com.cisco.vpnsc.repository.l2vpn.EndToEndWireAttributeMap'

'com.cisco.vpnsc.repository.l2vpn.ACAttributeMap'

'com.cisco.vpnsc.repository.l2vpn.EndToEndWire'

'com.cisco.vpnsc.repository.l2vpn.EndToEndWireAttrs'

'com.cisco.vpnsc.repository.l2vpn.ACAttrs'

'com.cisco.vpnsc.repository.l2vpn.L2VpnSR'

'com.cisco.vpnsc.repository.l2vpn.L2VpnLogicalLink'

'com.cisco.vpnsc.repository.l2vpn.UniInterface'

'com.cisco.vpnsc.repository.l2vpn.UniProtocolTunnel'

'com.cisco.vpnsc.repository.l2vpn.UniMacAccessList'

'com.cisco.vpnsc.repository.l2vpn.UniSecureMacAddress'

'com.cisco.vpnsc.repository.protocol.Protocol'

'com.cisco.vpnsc.repository.protocol.ProtocolBundle'

'com.cisco.vpnsc.repository.protocol.RepPro_Bdl_Mpng'

'com.cisco.vpnsc.nbi.vpnsc.PLHelper'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.DataBlock'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.AgeDataBlock'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.RdAllocDataBlock'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.RdAvailDataBlock'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.RdAgeDataBlock'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.RtAllocDataBlock'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.RtAvailDataBlock'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.RtAgeDataBlock'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.SooAllocDataBlock'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.SooAvailDataBlock'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.SooAgeDataBlock'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.RdNameSeed'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.RtNameSeed'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.SooNameSeed'

'com.cisco.vpnsc.repository.resourcePool.externallyManaged.PoolType'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.IPDataBlock'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.RdDataBlock'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.RtDataBlock'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.SooDataBlock'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.VcIdDataBlock'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.VlanDataBlock'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.IPAllocDataBlock'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.IPAvailDataBlock'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.IPAgeDataBlock'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.MCASTDataBlock'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.MCASTAllocDataBlock'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.MCASTAvailDataBlock'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.MCASTAgeDataBlock'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.VlanAllocDataBlock'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.VlanAvailDataBlock'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.VcIdAllocDataBlock'

'com.cisco.vpnsc.repository.resourcePool.vpnscManaged.VcIdAvailDataBlock'

'com.cisco.vpnsc.repository.collection.Data'

'com.cisco.vpnsc.repository.collection.DevOwner'

'com.cisco.vpnsc.repository.sla.SAAProbe'

'com.cisco.vpnsc.repository.sla.SAADNSProbe'

'com.cisco.vpnsc.repository.sla.SAAEchoProbe'

'com.cisco.vpnsc.repository.sla.SAAHTTPProbe'

'com.cisco.vpnsc.repository.sla.SAAJitterProbe'

'com.cisco.vpnsc.repository.sla.SAATCPConnectProbe'

'com.cisco.vpnsc.repository.sla.SAAUDPEchoProbe'

'com.cisco.vpnsc.repository.sla.SAADHCPProbe'

'com.cisco.vpnsc.repository.sla.SAAFTPProbe'

'com.cisco.vpnsc.repository.vpls.MacAddress'

'com.cisco.vpnsc.repository.vpls.VplsServiceAttributeMap'

'com.cisco.vpnsc.repository.vpls.VplsPolicyInterface'

'com.cisco.vpnsc.repository.vpls.VplsUniProtocolTunnel'

'com.cisco.vpnsc.repository.vpls.VplsUniInterface'

'com.cisco.vpnsc.repository.vpls.VplsPolicy'

'com.cisco.vpnsc.repository.vpls.VplsLinkAttributeMap'

'com.cisco.vpnsc.repository.vpls.VplsServiceAttributes'

'com.cisco.vpnsc.repository.vpls.VplsLink'

'com.cisco.vpnsc.repository.vpls.VplsSR'

'com.cisco.vpnsc.repository.common.HubGroup'

'com.cisco.vpnsc.repository.vpls.VplsLogicalLink'

'com.cisco.vpnsc.repository.common.MultipointHub'

'com.cisco.vpnsc.repository.deploymentflow.Service'

'com.cisco.vpnsc.repository.deploymentflow.DfProcess'

'com.cisco.vpnsc.repository.deploymentflow.Step'

'com.cisco.vpnsc.repository.deploymentflow.StepArg'

'com.cisco.vpnsc.repository.deploymentflow.NotifyUserId'

'com.cisco.vpnsc.repository.deploymentflow.GlobalData'

'com.cisco.vpnsc.repository.deploymentflow.StepData'

'com.cisco.vpnsc.repository.deploymentflow.DFProfileEntry'

'com.cisco.vpnsc.repository.ual.UALog'

'com.cisco.vpnsc.repository.ual.UALPolicy'

'com.cisco.vpnsc.repository.ual.ObjectLogEntry'

'com.cisco.vpnsc.repository.license.SoftwareLicense'

'com.cisco.insmbu.templatemgr.repository.TemplateGroup'

'com.cisco.insmbu.templatemgr.repository.Template'

'com.cisco.insmbu.templatemgr.repository.DataFile'

'com.cisco.insmbu.templatemgr.repository.Keyword'

'com.cisco.insmbu.templatemgr.repository.TemplateAssociationOnRole'

'com.cisco.insmbu.templatemgr.repository.BusinessClassAssociation'

'com.cisco.vpnsc.repository.nbi.ServiceOrder'

'com.cisco.vpnsc.repository.nbi.SOSRAssociation'