head	1.2;
access;
symbols;
locks; strict;
comment	@# @;


1.2
date	2001.08.21.22.16.11;	author leonardr;	state Exp;
branches;
next	1.1;

1.1
date	2001.08.10.14.30.26;	author leonardr;	state Exp;
branches;
next	;


desc
@@


1.2
log
@Brought doc in line with what was actually implemented.
@
text
@<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>

<head>
 <title>The Helm Event Propagation Architecture</title>
</head>

<body>

<h1>The Helm Event Propagation Architecture</h1>
Leonard Richardson &lt;leonardr at collab dot net&gt;<br>
<small>$Id: event.html,v 1.1 2001/08/10 14:30:26 leonardr Exp $</small>

<h2>Introduction</h2>

 <p>Tigris versions 1.2 and previous supported a hub-and-spoke
 architecture in which Helm (the hub) could propagate events to a
 static set of software tools (such as Anzu, Issuezilla, and
 CVS). Adding a new component required changing Helm to be aware of
 the new tool. In 1.3, however, new tools can be integrated into Helm
 without changing any Helm code. This is accomplished, in part, by the
 definition of a dynamic event propagation architecture.

 <p>Since Tigris 1.3 is still built around a hub-and-spoke
 architecture, the event propagation will be initially used only by
 Helm to notify integrated tools of events. However, nothing in the
 architecture prevents tools from sending events to Helm (apart from
 the fact that Helm will not respond to any such events), nor does it
 prevent tools from communicating with each other, defining their own
 event vocabularies of which Helm need know nothing. Tool-to-Helm and
 tool-to-tool communication are planned for later versions of Tigris.

 <p>Tool event propagation is built on top of Spread and Fulcrum. The
 three pieces of Helm event propagation are the <code>ToolEvent</code>
 class, the <code>ToolEventPropagationService</code> service, and the
 listeners (which do not need to have any particular superclass or
 implement any particular interface),

<h2><code>ToolEvent</code></h2>

 <p><code>ToolEvent</code> contains code for building a tool event and
 injecting it into the Spread message stream. You must associate a
 name and a (possibly empty) list of Helm business objects with an
 event, and you may choose to associate a component name (the default
 component is '*', meaning all components) with the event.

 <p><code>ToolEvent</code> has a static method for each tool event
 used by Helm, used for sending off events. Helm code calls these
 methods at the appropriate times. In Tigris 1.3, these methods are
 the only originators of events.

<h2><code>ToolEventPropagationService</code></h2>

 <p><code>ToolEventPropagationService</code> is a Fulcrum service
 which is found in Helm. Its purpose is to receive
 <code>ToolEvent</code>s over Spread and propagate them to the
 components integrated into Helm.

 <p>One or more machines in the cluster need to have an
 <code>ToolEventPropagationService</code> service running. Each
 <code>ToolEventPropagationService</code> machine also needs to have
 every tool adaptor installed, since it might be called upon to
 propagate an event to any tool.

 <p>One <code>ToolEventPropagationService</code>s designated as the
 singleton for the cluster. The singleton is reponsible for handling
 all events. However, all members of the group keep track of such
 events in case they should become the singleton. When the singleton
 <code>ToolEventPropagationService</code> completes processing an
 event, it broadcasts success to the group using a
 <code>CompletionEvent</code>, and everyone forgets about that event.

<h2>Listeners</h2>

 <p>Events are handled by listeners. A listener may implement the
 <code>HelmListener</code> interface or subclass the
 <code>NullHelmListener</code> subclass (which implements every method
 of <code>HelmListener</code> as a method which does nothing), but it
 can implement whatever methods it wants; it's just that the only
 listener methods that will ever be called in 1.3 will be the ones
 defined by the HelmListener interface.

 <p>To define a listener for your component, put a line like the
 following in your component's
 <code>conf/[0-9][0-9][component].TurbineResources.properties</code>
 file:

 <p><code>
  component.listener.[component name]=[fully-qualified classpath to listener]
 </code>

 <p>[Note that you may have to add to the <code>Makefile</code> and
 <code>Makefile.config</code> files in your component's
 <code>conf/</code> directory to get them to copy over the
 <code>TurbineResources.properties</code> fragment. This will only
 neccessary if your component did not previously provide a
 <code>TurbineResources.properties</code> fragment.]

 <p>When the singleton <code>ToolEventPropagationService</code>
 instance receives a <code>ToolEvent</code>, it decodes the event into
 a method name and a list of Helm OM classes (or Torque key classes)
 which correspond to the method signature. It then looks for a method
 of that component's listener which implements that name and
 signature. If one is found, the
 <code>ToolEventPropagationService</code> instantiates objects of the
 given classes (using information found in the event) and calls the
 listener method using the business objects as arguments. If no
 corresponding method is found, then nothing happens.

<h3>Dealing with Failures</h3>

 If all goes well, the listener method will do its thing and return
 properly. However, if not all goes well, the listener method will
 throw a <code>PropagationFailed</code> exception. The
 <code>ToolEventPropagationService</code> then sends out a
 <code>PropagationFailedEvent</code> so that every member of the
 cluster will know about the failure. If the original event had a
 destination component of '*', it will be rebroadcast to the specific
 component which had the failure. One '*' event may spawn multiple,
 more specific events if more than one component suffers a failure.

 <p>The first time an event fails, it will cause an email to be sent
 to the site administrator(s). An event will be retried until it
 succeeds (but a failed event will not block subsequent events from
 running).

 <p>The TaskList servlet will show you the queued events at any given
 moment. Events which have failed will display the date and message
 associated with the first failure and of the most recent failure.

<h2>Conclusion</h2>

 If you want to make your tool respond to Helm events, just implement
 a class with static methods corresponding to the
 <code>HelmListener</code> methods you're interested in responding
 to. Have the methods call whatever functionality you'd like to
 associate with the Helm event (or run scripts, which you'd also have
 to write, if your application isn't written in Java). Declare the
 class as your component's listener in your component's
 TurbineResources file, and the appropriate methods will be called
 anytime something happens in Helm that you'd like to be aware of.

</body>

</html>@


1.1
log
@Integration documents now have their own directory. Also added a new event propagation architecture document to the new directory.
@
text
@d12 1
a12 1
<small>$Id: integration.html,v 1.24 2001/08/07 22:40:45 leonardr Exp $</small>
d28 1
a28 1
 the fact that Helm will respond to no such events), nor does it
d33 5
a37 5
 <p>Event propagation is built on top of Spread and Fulcrum. The three
 pieces of Helm event propagation are the <code>Event</code> class,
 the <code>EventPropagator</code> class, and the listeners (which do
 not need to have any particular superclass or implement any
 particular interface),
d39 1
a39 1
<h2><code>Event</code></h2>
d41 1
a41 1
 <p><code>Event</code> contains code for building a tool event and
d45 1
a45 2
 component is '*', meaning all components) with the event. All events
 start out with a failure count of 0.
d47 11
a57 10
 <p>Helm contains a utility class which sends off
 <code>Event</code>s. It has one method for each event type used by
 Helm. Helm code calls these methods at the appropriate times. In
 Tigris 1.3 these methods are the only originators of events.

<h2><code>EventPropagator</code></h2>

 <p><code>EventPropagator</code> is a Fulcrum service which is found
 in Helm. Its purpose is to receive <code>Event</code>s over Spread
 and propagate them to the components integrated into Helm.
d60 12
a71 16
 <code>EventPropagator</code> service running. Every component has a
 corresponding Spread group called "event-propagation-[component]",
 and an <code>EventPropagator</code> service needs to subscribe to the
 event propagation group for each of that machine's components. Each
 component needs at least one associated <code>EventPropagator</code>
 (else it will not be informed of Helm goings-on), but one
 <code>EventPropagator</code> may serve many components.

 <p>A component's event propagation group always has one of its member
 <code>EventPropagator</code>s designated as the singleton for that
 group. The singleton is reponsible for handling any events which
 interest that component. However, all members of the group keep track
 of such events in case they should become the singleton. When the
 singleton <code>EventPropagator</code> completes processing an event,
 it broadcasts success to the group, and everyone forgets about that
 event.
d83 26
a108 14
 <p>The fully-qualified classpath of a component's listener is defined
 as "[component].listener" in the component's
 conf/[0-9][0-9][component].components file. <i>[TODO: Allow multiple
 listeners for the same component?]</i>

 <p>When an <code>EventPropagator</code> receives an event for a
 component for which it is the singleton, it decodes the event into a
 method name and a list of Helm OM classes which correspond to the
 method signature. It then looks for a method of that component's
 listener which implements that name and signature. If one is found,
 the <code>EventPropagator</code> instantiates objects of the given
 classes (using information found in the event) and calls the listener
 method using the business objects as arguments. If no corresponding
 method is found, then nothing happens.
d114 16
a129 10
 throw a NestableException. The <code>EventPropagator</code> needs to
 note the exception and then resend the original message with its
 failure count incremented. [The only exception to this rule is when
 the original message had a destination component of '*'; in that
 case, the destination is changed to be the component which had the
 failure. One '*' event may spawn multiple, more specific events if
 more than one component suffers a failure.] Once the failure count
 reaches a certain number, the site administrator will be notified of
 the problem, but the message will keep cycling through the system
 until it either succeeds or is removed.
d139 3
a141 3
 class as your component's listener in your components file, and the
 appropriate methods will be called anytime something happens in Helm
 that you'd like to be aware of. 
@

