                          How to Use the Java EIF
                          -----------------------

Contents
--------

I.   A Java Implementation of Postemsg
II.  Sample Program Using the Java EIF
III. Postemsg Reference
IV.  Sample Configuration File
V.   Known Bugs
VI.  Main Program from TECAgent

I. A Java Implementation of Postemsg
   ---------------------------------

   The main() function of the class com.tivoli.tec.eif.TECAgent is a Java
implementation of the C program postemsg, and you can use it as a replacement
for postemsg.  A copy of the entry for postemsg from the TEC references manual
is given in section III below and sample configuration file specifications
are given in section IV.
 
   Suppose you have a TEC server running on an AIX machine named 'artemis'.
Because the TEC server is running on a UNIX box it has registered itself with
the portmapper and you don't need to know the port the TEC server is listening
on in order to send events.  Suppose you are running the Java EIF on an NT
machine and eif.jar is in the directory c:\tmp.  Here are the steps you need to
take to send an event to the TEC server on artemis.

   1. Add the EIF JAR file to your the Java CLASSPATH environment variable.
      For example:

         bash$ export "CLASSPATH=c:/jdk1.1.6/lib;c:/tmp/eif.jar"

   2. Create a configuration file with 'ServerLocation' set to 'artemis' and
      'BufEvtPath' set to file where you want events saved in case the TEC
      server could not be contacted.

         bash$ echo "ServerLocation=artemis" > c:/tmp/cfg.txt
         bash$ echo "BufEvtPath=c:/tmp/cache" >> c:/tmp/cfg.txt

   3. Send an event just specifying the event class and source.

         bash$ java com.tivoli.tec.eif.TECAgent NONTME -f c:/tmp/cfg.txt
               TEC_DB TEC

   4. Send an event specifying a message, hostname, and severity.
   
         bash$ java com.tivoli.tec.eif.TECAgent NONTME -f c:/tmp/cfg.txt
               -m "The Message" -r HARMLESS hostname=myhost TEC_DB TEC

   5. Send event without using a configuration file.

         bash$ java com.tivoli.tec.eif.TECAgent NONTME -S artemis TEC_DB TEC

      The file used to save events in case the server couldn't be connected
      in this example is '/tmp/event_cache'.

   You may have noted that in each example the first argument to the main()
function of com.tivoli.tec.eif.TECAgent is 'NONTME'.  This means that the
EIF will contact the TEC server over a socket in order to send the event rather
than making a CORBA call to the TEC server object.  The other choice, 'TME',
tells the EIF to make the CORBA call instead.  Unfortunately, that choice is
not currently implemented.

II. Sample Program Using the Java EIF
    ---------------------------------

   import java.io.StringReader;
   import com.tivoli.tec.eif.TECAgent;
   import com.tivoli.tec.eif.TECEvent;
   import com.tivoli.tec.eif.EIFException;

   public class EIFSample
   {
      public static void main(String[] argv)
      {
         TECAgent agent = null;
         try {
            agent = new TECAgent(
               new StringReader(
                  "ServerLocation=artemis\n" +
                  "BufEvtPath=c:/tmp/cache\n"),
               TECAgent.COMM_NONTME);
         }
         catch (EIFException e) {
            // Huh? Only happens w/ bad configuration files, but we know this
            // isn't the case because the config file was hard-coded as a
            // string.
            System.exit(1);
         }

         TECEvent event = new TECEvent();
         event.setClassName("TEC_DB");
         event.setSlot("msg", "The Message");
         event.setSlot("source", "TEC");

         int rc = agent.sendEvent(event.toString(true));
         agent.disconnect();

         System.exit(rc == TECAgent.SEND_SUCCESS ? 0 : 1);
      }
   }

III. Postemsg Reference
     ------------------

NAME
   postemsg

PURPOSE
   Posts an event to the event server.

SYNOPSIS
   postemsg [-S server] [-f configuration file] [-m message] [-r
   severity] [slot=value...] class source

DESCRIPTION
   The postemsg command sends an event to an event server. This
   command does not require the use of Tivoli Management
   Environment 10 services. Posting events is a good way to test the
   server after you have created new event groups, created event group
   assignments, edited rules, or otherwise changed the method a server
   processes events.

   If your message contains an embedded single quote ('), you must
   preface the embedded quote with another single quote.

   Note: If the Tivoli Management Environment 10 is installed on
         your system, you can use the wpostemsg command.

Authorization
   none

Arguments
   -S server   Specifies the host name or the Internet Protocol (IP)
               address of the server. You must specify either the -S
               argument or the -f argument.

   -f configuration file
               Specifies the name of the adapter configuration file.
               The default adapter configuration file is
               /etc/Tivoli/tecad_eif/tecad.conf. You must specify
               either the -S argument or the -f argument.

   -m message  Specifies the text of the event. If there are any blank
               spaces in the message text, enclose the text in double
               quotes.

   -r severity Specifies a severity, one of FATAL, CRITICAL,
               MINOR, WARNING, HARMLESS, and UNKNOWN.

   slot=value  Assigns a value to any valid attribute. The attribute
               must be one defined for the event class.

   class       Specifies the class of the event. It must match a class
               that is configured at the server. Classes are defined
               by the event adapter and are listed in the adapter's
               .baroc file. If there are any blank spaces in the class
               name, enclose the class name in double quotes.

   source      Specifies the source of the event. It must match a
               source that is configured at the server. If there are any
               blank spaces in the source name, enclose the source
               name in double quotes.

EXAMPLES
   The following example sends a test message that displays a
   Su_Failure event on the event consoles:

   postemsg -r WARNING -m "su login failure." Su_Failure LOGFILE

IV. Sample Configuration File
    -------------------------

  Note - Good references for what can go in a configuration file and what
    the key/value pairs mean are the "Enterprise Console Adapters Guide" or
    the "Event Integration Facility User's Guide".  You can find PDF versions
    of these guides at "http://www.tivoli.com/support/documents/" if you
    have a password for that site.

  Example:
    ----------------------------------------------------------------------
    # ServerLocation - What server to talk to.
    ServerLocation=artemis.dev.tivoli.com

    # ServerPort - What port is the TEC server listening on for events.  The
    #   UNIX TEC servers register themselves w/ the portmapper and you don't
    #   have to provide this info, but for NT you do.  5529 is the default port
    #   that the NT TEC server listens on.
    ServerPort=5529

    # BufEvtPath - This is where events are saved to disk if the TEC server
    #    can't be contacted.  If the server can be contacted and this file
    #    is non-empty, then the events saved in the file are flushed to the
    #    server before sending the "current" event.
    BufEvtPath=c:/tmp/cache

    # BufferEvents - This controls whether or not the EIF saves events to the
    #    file named by BufEvtPath when the server could not be contacted. If
    #    value is something besides "YES" then events are not saved.  The 
    #    default value is "YES".
    BufferEvents=YES

    # BufEvtMaxSize - The maximum size of the buffer file of saved events.
    #    You specify the value in kilobytes.  The default is 64.
    BufEvtMaxSize=64
    ----------------------------------------------------------------------

V. Known Bugs
   ----------

1. Event filtering does not work properly with events that specify a slot
   with a list value.

2. The notion of event syntax used to parse events into slot/value pairs
   for the purposes of filtering turns out to be a too restrictive.
   However, the problem is not accepting things like "SNMP Trap Event"
   as class names and "User Name" as slot names; i.e., names w/ spaces
   in them which no one does anyway.

3. There is no default value for 'BufEvtPath' like there is with the C EIF.
   The reason this is true is because the default value is platform dependent,
   and in particular it requires accessing the "SystemRoot" environment variable
   on NT.  Since access to environment variables has been removed from current
   versions of the JVM, this bug will probably never be fixed.

VI. Main Program from TECAgent
    --------------------------

   This is the main program from com.tivoli.tec.eif.TECAgent implementing
   a command-line utility that can be used like the C program postemsg.

   public static void main(String[] argv)
   {
      int tmeMode = 0;
      String server = null;
      String cfgFile = null;
      TECEvent tEv = new TECEvent();

      if (argv.length < 3)
         usage();

      if (argv[0].equals("TME"))
         tmeMode = COMM_TME;
      else if (argv[0].equals("NONTME"))
         tmeMode = COMM_NONTME;
      else
         usage();
      
      for (int i = 1; i < argv.length - 2; ++i)
      {
         if      (argv[i].equals("-S"))
         {
            if (server != null || i + 3 == argv.length) usage();
            server = argv[++i];
         }
         else if (argv[i].equals("-f"))
         {
            if (cfgFile != null || i + 3 == argv.length) usage();
            cfgFile = argv[++i];
         }
         else if (argv[i].equals("-r"))
         {
            if (tEv.getSlot("severity") != null || i + 3 == argv.length)
               usage();
            if (!tEv.setSlot("severity", argv[i + 1]))
            {
               System.err.println(
                  MD.g(MD.PostemsgBadSev, new String[]{argv[i + 1]}));
               System.exit(1);
            }
            ++i;
         }
         else if (argv[i].equals("-m"))
         {
            if (tEv.getSlot("msg") != null || i + 3 == argv.length) usage();
            if (!tEv.setSlot("msg", argv[i + 1]))
            {
               System.err.println(
                  MD.g(MD.PostemsgBadMsg, new String[]{argv[i + 1]}));
               System.exit(1);
            }
            ++i;
         }
         else
         {
            String slot, value;
            int eNdx = argv[i].indexOf('=');
            if (eNdx == -1 || eNdx == 0 || eNdx == (argv[i].length() - 1))
               usage();
            slot = argv[i].substring(0, eNdx);
            value = argv[i].substring(eNdx + 1);
            if (tEv.getSlot(slot) != null)
            {
               System.err.println(
                  MD.g(MD.PostemsgMultDefSlot, new String[]{slot}));
               System.exit(1);
            }
            if (!tEv.setSlot(slot, value))
            {
               System.err.println(
                  MD.g(MD.PostemsgBadSlotValPair, new String[]{slot, value}));
               System.exit(1);
            }
         }
      }

      if (server != null && cfgFile != null)
         usage();

      if (!tEv.setClassName(argv[argv.length - 2]))
      {
         System.err.println(
            MD.g(MD.PostemsgBadClsName, new String[]{argv[argv.length - 2]}));
         System.exit(1);
      }
      if (!tEv.setSlot("source", argv[argv.length - 1]))
      {
         System.err.println(
            MD.g(MD.PostemsgBadSrcVal, new String[]{argv[argv.length - 1]}));
         System.exit(1);
      }
      
      if (tEv.getSlot("origin") == null)
      {
         try { 
            tEv.setSlot("origin", InetAddress.getLocalHost().getHostAddress());
         }
         catch (UnknownHostException e) {
            EIFDbg.err(MD.g(MD.PostemsgUnkwnOrigin));
            tEv.setSlot("origin", "?.?.?.?");
         }
      }

      Reader cfgIn = null;
      if (cfgFile != null)
      {
         File f = new File(cfgFile);
         if (!f.exists())
         {
            System.err.println(
               MD.g(MD.PostemsgCfgNoExist, new String[]{cfgFile}));
            System.exit(1);
         }
         if (!f.canRead())
         {
            System.err.println(
               MD.g(MD.PostemsgCfgNoRead, new String[]{cfgFile}));
            System.exit(1);
         }
         try { cfgIn = new FileReader(cfgFile); }
         catch (FileNotFoundException e) {
            System.err.println(
               MD.g(MD.PostemsgCfgNoRead, new String[]{cfgFile}));
            System.exit(1);
         }
      }
      else
         cfgIn = new StringReader(
            "ServerLocation=" + server + "\n" +
            "BufEvtPath=/tmp/event_cache\n");

      TECAgent agent = null;
      try { agent = new TECAgent(cfgIn, tmeMode); }
      catch (EIFException e) {
         System.err.println(
            MD.g(MD.PostemsgCfgBad, new String[]{e.getMessage()}));
         System.exit(1);
      }

      int rv = agent.sendEvent(tEv.toString(true));
      if (rv != SEND_SUCCESS && rv != SEND_BUFFERED)
      {
         System.err.println(
            MD.g(MD.PostemsgBadSend, new String[]{agent.config.BufEvtPath}));
         rv = 1;
      }
      else
         rv = 0;
      agent.disconnect();

      System.exit(rv);
   }
