action.skip

Guidelines for Developing Event Handlers

Use this information on the structure and behavior of event handlers to develop event handlers for objects in a model. You should also consult the event handler examples (located in RocketSoftware\Verastream\HostIntegrator\examples\EventHandlers\java\documentation\index.html) that are available as part of the Host Integrator Development Kit.

Defining an Event Handler

Use the New Event Handler dialog box in the Design Tool to generate Java source code that is a template for the new event handler class. Each handler is a class that is associated with a specific type of model object (attribute, operation, procedure, etc.) and can be attached to one or more components of that type.

By definition, the event handler class extends a base class specific to the type of model object. This base class is defined as part of Host Integrator.

For each object type, the base class defines a method signature for each supported event. For example, a model event handler has these defined events:

  • Client Connected
  • Client Disconnected
  • Error Reported
  • Execute Login
  • Execute Logout
  • Format Error
  • Move Cursor
  • Move Cursor Forward
  • Move Cursor Backward
  • Process String
  • Unrecognized Screen

In the user derived class, the declaration of an override for an adapter method signals that the corresponding event is enabled. Otherwise, that event is considered disabled, which means any object that has its events mapped to the user class will not fire the event.

For example, the AttributeEventHandler base class defines two methods for events:

Java

void readAttribute(AttributeEvent e) throws ApptrieveException; void writeAttribute(AttributeEvent e) throws ApptrieveException;

.NET

public override string ReadAttribute(IReadAttributeEvent vsEvent) public override void WriteAttribute(IWriteAttributeEvent vsEvent)

If a user class overrides the writeAttribute method of the AttributeEventHandler base class, then the write event is considered enabled and the read event is considered to be disabled. You can also extend the event handler definition.

Setting Timeouts

A model's default event handler timeout setting applies to all events. See information on general timeout processing for more information.

  • Java - If a particular event requires a different value, a value can be assigned per event by declaring a static final member of the user's handler class. For example, to set the timeout for the Write Attribute event on a handler to 30 seconds, use this statement:

    static final int writeAttributeTimeout = 30;

  • .NET - If a particular event requires a different value, a value can be assigned per event by using the Timeout attribute. For example, to set the timeout for the Write Attribute event on a handler to 30 seconds, use this statement:

    [Timeout(30)]

    public override void WriteAttribute(IWriteAttributeEvent vsEvent)

Event Handler Interfaces

The event handler user class has access to all relevant interfaces by calling get<MethodType> methods on the <EventType>Event interface passed into the method. These interfaces include:

  • ModelContext— information about the model, its environment (system name), and its state (handler-populated hash table visible to all model sessions).
  • ClientSession— data about the connected client, such as the user name and ID passed to Host Integrator, and its state (handler-populated hash table visible only to this client).
  • ScriptHostSession— access to the terminal and the model objects. This is an expanded version of the Host Integrator connector interface available to the client in prior versions of Host Integrator.
  • Handler-specific methods— access to metadata information on the object being scripted and to any default model behavior defined for it.

Java Classpaths

A handler is permitted to use any available Java library to assist in meeting the requirements of its script. All libraries placed in the model's scripts\lib directory are included in the classpath for that model, and are introspected for event handler classes. In addition, you can specify a classpath that applies to the local Host Integrator installation with a [properties file]#event-handler-properties-files).

The script manager uses the class loader scheme shown below. The libraries in each model are isolated from each other, and the user class path will take precedence in loading classes. The model's class loader does not use manifest files to find nested JAR files; only class files included directly in the JAR are available.

java classpath

Processing Java Code into an Event Handler

After the source code is constructed, it is compiled into a Java class (.class file) and the class is placed in a Java Archive (.jar file). It is then available for use as an event handler. Host Integrator provides an Ant script that compiles all Java source files in the model's \scripts\src folder into Java classes in the \scripts\classes folder, and then stores the class files in a single Java Archive in the\scripts\lib folder. Once incorporated in the JAR file, all classes that extend handler adapters for a given object type can be mapped (attached) to any object in that model.

An available event handler can then be assigned to a model object. Most object types have an Advanced Properties option that allows you to attach the handler; the Attach Event Handlers dialog box provides access to all model object types and all available event handlers.

For a given model, all JAR files in the scripts\lib directory will be introspected using the Java reflection API for available event handlers. It is recommended that you use this folder only for event handlers.

Modifying the Java Event Handler Build Environment

You can modify the ant script (build.xml), located in the models\<modelname>\scripts folder, but remember that the Design Tool uses the following ant targets:

  • buildfile—used to build a single source file and add it to vhi_model.jar. The file is specified by the src.files ant property.
  • cleanbuild—used to rebuild all source files and create vhi_model.jar.

In both cases, the Design Tool defines the following ant properties:

  • vhi.jar.dir—the location of the Host Integrator JAR files for event handling.
  • vhi.script.classpath—the user classpath as defined in script.properties.

.NET Assemblies

A handler is permitted to use any available .NET Application Extension (DLL) to assist in meeting the requirements of its script. All .NET Application Extensions placed in the model's scripts\lib directory are included in the assembly for that model, and are introspected for event handler classes.

Processing .NET Code into an Event Handler

After the source code is constructed, it is compiled into a .NET Application Extension (DLL). It is then available for use as an event handler. Host Integrator provides a project file that msbuild uses to compile all .NET source files in the model's \scripts\src folder and subfolders into a .NET Application Extension in the \scripts\lib folder. Once msbuild has completed, all classes that extend handler adapters for a given object type can be mapped (attached) to any object in that model.

An available event handler can then be assigned to a model object. Most object types have an Advanced Properties option that allows you to attach the handler; the Attach Event Handlers dialog box provides access to all model object types and all available event handlers.

Modifying the .NET Event Handler Build Environment

You can modify the project build.proj, located in the models\<modelname>\scripts folder. The Design Tool will invoke msbuild so that the default target is built.

ScriptHostSession API

The Event Handler ScriptHostSession API, in combination with other event handler guidelines, will help you develop event handlers that override or extend standard model behavior.

An event handler performs a mix of custom logic and callbacks to Host Integrator to get information about or modify the state of the model or terminal.

An invocation takes place any time an event handler invokes a method on one of the ScriptHostSession interfaces. This may just be asking for information, or it may be a request to modify the model or terminal state.

Note the following properties of the ScriptHostSession API:

  • No specific timeout. The governing timeout is that of the event itself. The time allowed per callback extends to the remaining time allotted to the event.

  • The event can return the expected data, "normal errors" such as a bad parameter name or a runtime failure in the model, or an event timeout error if the event timeout expires during execution.

The ScriptHostSession API

The ScriptHostSession API is documented in the Javadocs for the Event Handler API and the .NET Event Handler API (available in a Windows help file). You can use this interface to get information about the host session and to manipulate the terminal (whether at the terminal, model, or table level).

ScriptHostSession Limitations

  • For events that rely on a specific terminal state, callbacks that could change terminal state are disabled within that event. If you attempt this sort of callback, you'll see an error message similar to the following:

    Event handler callback not allowed in current state. An event callback method was invoked at an inappropriate time.

    Click Details in the error message dialog box to see the sequence that preceded this error. The method immediately preceding the error can often tell you the offending ScriptHostSession method. Many events within recordset event handlers (for example, Apply Filter, Parse Screen) and recordset field event handlers (Read Field) disable most callbacks:

  • The ScriptHostSession interface cannot be used outside of the event from which it was obtained. In the following events, this interface is not available:

  • Entity Departure (entity event handler)
  • Format Error (model event handler)
  • Most events with life cycle event handlers

  • In addition to the limitations within the immediate event handler, ScriptHostSession restrictions apply when event handlers are nested. If an event with restrictions is currently open, this limitation will also be enforced for a nested event.

Nested Events

Event handler nested events, in combination with other event handler guidelines, will help you develop event handlers that override or extend standard model behavior.

Host Integrator's event handler architecture permits an event handler callback to invoke another event handler.

Example

A procedure event handler can issue a request to execute an operation. If the model happens to map the operation to an event handler, then a nested event handler invocation takes place. In this runtime situation, the operation event is considered to be the child or descendant of the procedure event, while the procedure event is defined as the parent or ancestor of the operation event. This is a transitory relationship that exists only as long as both event handlers are in progress.

Further, the operation event handler can request to read data from an attribute, where the attribute has a handler with the Read Attribute event defined. This process of nesting can continue to whatever level is dictated by the callback and event handler constructs of the user model.

Limitations

Host Integrator imposes one limitation on nested events: the same event on the same object cannot be signaled more than once in the same nesting structure. A nested request to invoke the same event on a given object results in an error being reported to the event handler that issued the callback request.

Errors

Errors returned from a nested event are propagated to the parent event handler in the form of an ApptrieveException result on the parent event handler callback. Host Integrator may add one or more additional messages to the stack when formulating its callback response.

When a nested event returns an exception, that error is propagated to the immediate ancestor event. If the exception is not an EventTimeoutException, the ancestor event is permitted to catch the resulting Java exception and proceed with the logic in the "catch" portion of the try-catch block surrounding the callback request. If the event handler completes its task within the time allotted and does not return an exception, then the event is considered a success and normal processing continues.

Timeouts

With nested events, the event with the smallest amount of remaining time governs the interval before a timeout notification takes place.

In the case discussed here, a procedure includes an operation that includes a request to read from an attribute. If a procedure with a 30-second timeout has been running for 15, an operation with a 10-second timeout has been running for 7, and the attribute has a 5-second timeout, the attribute event times out in 3 seconds (when the operation timer expires).

When a timeout occurs in a nested situation, some special processing rules apply.

At any given time, only one hierarchy of events can be in progress. The first event in the hierarchy is the primary event. All the errors reported from primary event handlers result in failure of the client request, but this is not the case for nested events.

If the operation times out in the example used here, both the nested attribute and operation event handlers receive and return EventTimeoutException results. For the procedure event handler containing the primary event, the operation timeout represents a simple failure. The procedure event handler receives an ApptrieveException result reporting the timeout. The procedure event can attempt recovery or otherwise continue processing to completion.

Session Startup/Shutdown

The initialization and shutdown sequence information below, in combination with other event handler guidelines, will help you develop event handlers that override or extend standard model behavior.

Model Loading and Unloading

The behavior for model loading and unloading within the Design Tool differs slightly from the same sequence in the Session Server.

Model Loading

When a model is loaded in either the Design Tool or the Session Server, the following sequence occurs:

Java

  1. The Design Tool copies all JAR files in the model's \\scripts\\lib directory to a temporary working area. On the Session Server, the deployment directory is the working area.
  2. Host Integrator notifies the script manager of the new model configuration, passing the model name, model directory, and the location of the working area. The Session Server also passes a copy of all model metadata to be cached in the script manager.
  3. An infrastructure, consisting of the created data accessible through the ModelContext interface and a class loader for the JARs in each model's working area, is built.
  4. Each JAR file in the event handler working area is inspected for classes that extend an event handler. For any class that is found, the methods and applicable timeout overrides are catalogued for return to Host Integrator.
  5. Upon return, if the model implements the Model Loaded event, that event is fired.
    • All errors returned by this event are reported and then ignored in the Design Tool.
    • In the Session Server, errors can cause the model load to fail. The model is then unavailable for pools or dedicated sessions.

.NET

  1. The Design Tool copies all assemblies (.DLL files) in the model's \\scripts\\lib directory to a \\scripts\\tmp. On the Session Server, the deployment directory is the working area.
  2. Host Integrator notifies the script manager of the new model configuration, passing the model name, model directory, and the location of the working area. The Session Server also passes a copy of all model metadata to be cached in the script manager.
  3. An infrastructure, consisting of the created data accessible through the IModelContext interface and a .NET AppDomain for the assemblies in each model's working area, is built.
  4. Each assembly in the event handler working area is inspected for classes that extend an event handler. For any class that is found, the methods and applicable timeout attributes are catalogued for return to Host Integrator. To be able to inspect the classes, the location from which they are loaded must be fully trusted. If you load classes from a network share, make sure this share is trusted.
  5. Upon return, if the model implements the Model Loaded event, that event is fired.
    • All errors returned by this event are reported and then ignored in the Design Tool.
    • In the Session Server, errors can cause the model load to fail. The model is then unavailable for pools or dedicated sessions.

Model Unloading

  • Design Tool - You unload a model when you close the Design Tool or open a new model. The act of opening a new model over an existing model causes the existing model to be unloaded. Reloading event handlers (for example, after a rebuild) also causes a model unload.

  • Session Server - The Session Server unloads a model during shutdown and when it is removed from or updated in the server configuration. The following steps take place:

  • Each host session is instructed to log out when the current client finishes. The host session is then destroyed.

  • Once all sessions have been destroyed, the Model Unloaded event is fired.
  • The command to remove the model is sent to the script manager. Among other actions, this includes destroying the Java class loader that was used to access the model's script manager work area.
  • The deployment directory is made available for clean up.

A change in the version of a model deployed to a Session Server results in a model unload/load sequence. This means that model versions can be changed and new versions of event handlers loaded without restarting the server.

Creating and Destroying Host Sessions

Whenever a host session is created by Host Integrator, the Host Session Created event is fired. Similarly, when a session is destroyed, the Host Session Destroyed event is fired.

  • Design Tool - You create a host session when you load a new model. Whenever you unload a model, the existing host session is destroyed.

  • Session Server - On the Session Server, all of the existing rules about configuration changes to models and session pools still apply. Host sessions are created at startup and destroyed on shutdown for session pools. When a new model version is loaded, any existing host sessions with that model are destroyed and recreated. Changing pool sizes up or down can also result in sessions being created or destroyed. Most other changes do not result in host sessions being created or destroyed.

Sessions are created when a client connects using the connectToModel API. The Host Session Destroyed event never fires when a client is actually connected to the host session.

Client Sessions and Authentication

The client session represents a client program accessing Host Integrator.

  • Design Tool - As long as there is a model loaded, there is always a single simulated client session. The Authenticate User and Client Session Created events are fired when you load the model, and the Client Session Destroyed event is fired when you unload the model. You are informed of any errors generated by the Authenticate User event via the Java console, but this does not prevent the client session from being created.

    In the Design Tool, the Client Connected event and the Client Disconnected event are attached to login and logout buttons to approximate the behavior of a client connecting to and disconnecting from a session. In this setting, a login process may be executed twice without an intervening logout process. However, after an initial login and associated Client Connected event fires, no additional Client Connected event will fire until a logout occurs.

  • Session Server - Each session spans one client connection. The Authenticate User event fires when a host session is allocated to an incoming client. If the Authenticate User event returns an error, the client session is not created. Otherwise, the client session is created and the Client Session Created event is fired. The Client Session Destroyed event is fired after the client has disconnected. If the Client Session Created event or Client Session Destroyed event fails, the client connection fails.

Error Processing

Event handler error processing, in combination with other event handler guidelines, will help you develop event handlers that override or extend standard model behavior.

In event handlers, errors are created when a Java exception is thrown. Here are a few examples:

  • The user code creates an exception to communicate an error to Host Integrator.
  • A runtime error returned from a Host Integrator callback is reformulated into an ApptrieveException.
  • A timeout condition communicated to the script manager causes any callback request to return a locally generated EventTimeoutException.

The user code has the ability to trap all exceptions thrown. The following rules apply to the user code for event handler errors:

  • To communicate standard application errors, an event handler should create and throw an ApptrieveException. This exception can contain multiple messages, each of which is converted into an error message on Host Integrator's internal stack.

  • Any exception thrown from an event handler that is not an ApptrieveException or a subclass results in a single error message being placed on the Host Integrator stack showing the exception class and the string returned from getMessage().

  • An event handler may trap and ignore any ApptrieveException it receives from a callback. In this case, however, no error is logged or returned to the client application. If informational logging is turned on, the only evidence of the error condition is an informational log message saying an error was returned to an event handler. Otherwise, Host Integrator does not generate any persistent record of the error.

  • As an extension of bullet 3, an event handler may trap one exception and then throw an entirely new exception with one or more custom messages. This operates as if the event handler initiated the error report.

  • An event handler may trap an ApptrieveException, append its own message, and re-throw the exception. The appended message appears with others generated during the client request.

  • An event handler is obligated either to not catch or to re-throw an EventTimeoutException. This exception indicates a system state that requires the event handler to terminate and control to be returned to Host Integrator. In any case, any return from the event handler other than the EventTimeoutException is ignored in favor of creating a new EventTimeoutException.

    In addition to the standard Host Integrator error stack reporting, any exception caught from user code that is not an ApptrieveException, a subclass of ApptrieveException, or an EventTimeoutException results in the Java stack dump being printed to the [Event Handler Console] (need link) or the [designated output file] (need link) (by default, this is the traps.out file in the <VHI>\etc\output subdirectory).

Timeout Processing

Event handler timeout processing, in combination with other event handler guidelines, to develop event handlers that override or extend standard model behavior. You can check timeout status using checkForTimeout or IEvent. CheckForTimeout for .NET.

When an event timeout expires, there are several possible processing states. The most common states are:

  • Event handler is executing

    This means that the script manager process has control of the client session to execute the logic in the user's event handler. Host Integrator sends a timeout notification that identifies the host session that has entered timeout processing. The event handler code can also periodically check for this state by invoking checkTimeout() on the callback interface.

    In this state, most callback invocations result in an immediate return of an EventTimeoutException. The callbacks that do not result in this exception are:

    Java

    ScriptHostSession Interface: getCursorPosition, getRectangularTerminalRegion, getLinearTerminalRegion, getTerminalScreenSize, getTerminalScreen, getStringAtCursor, getStringAtOffset, getStringAtLocation, getPatternRegion, getPatternRegions, getAttributeRegion, getAttributeRegions, getRecordSetRegion, getRecordRegion, getFieldRegion, getFieldRegions

    Event Interface: getLogger method for log level manipulation on the Logger interface (isLogInfoEnabled, isLogWarningEnabled, logInfoMessage, logWarningMessage).

    .NET

    IScriptHostSession: CursorPosition, GetRectangularTerminalRegion, GetLinearTerminalRegion, TerminalScreenSize, TerminalScreen, GetStringAtCursor, GetStringAtOffset, GetStringAtLocation, GetPatternRegion, GetPatternRegions, GetAttributeRegion, GetAttributeRegions, GetRecordSetRegion, GetRecordRegion, GetFieldRegion, GetFieldRegions

    Event Interface: Logger method for log level manipulation on the ILogger interface (LogInfoEnabled, LogWarningEnabled, LogInfoMessage, LogWarningMessage)

  • Callback is executing

    This occurs when the event handler makes a request to Host Integrator, and that request is being processed when the timeout expires. In this case, the same processing applies except that the callback return is a timeout error that is converted into an EventTimeoutException in the script manager.

Additional error states

Once the timeout status has been communicated to the script manager, Host Integrator begins another timer that governs how long the event handler is given to complete and return control:

  • If the event handler returns control within the time allotted, the errors are reported to the client and the session remains intact.

  • Abort mode: Should this new timer also expire, Host Integrator enters into abort mode. Host Integrator returns an event handler failure message to the invoking object (attribute, operation, etc.) and communicates this new state to the script manager. The script manager "quarantines" the event handler and its script manager session in a processing space separate from normally functioning sessions and handlers. If this expired handler returns, the response is ignored in favor of an AbortedSessionException in the standard unhandled exception locations. Once the client has been notified of these fatal errors, the host session is terminated and restarted. The Design Tool always leaves the terminal intact and creates a single new session; the Session Server will destroy the entire host session, including the virtual terminal, and will only recreate it if a session pool minimum would not otherwise be met.

    Abort mode may have some unpredictable side effects. Each abort results in at least one quarantined thread in the script manager that could theoretically exist for the life of the process. If the host session requires access to the script manager to log out of the host properly, this can also fail with unpredictable results for the host (for example, the host could lock the account for a period time). It is strongly recommended, therefore, that event handlers be written to conform to the timeout processing rules and that the handlers check the timeout status periodically during tasks that could take significant time to complete.

Importing Events Handlers

You can use an event handler in more than one model. To import existing event handlers created in one model into another model, you can do either of the following:

Java

  • Copy the .java files into the \scripts\src folder within your model folder. You must then rebuild event handlers in order to incorporate them into the .jar file for the model.

  • Copy the .jar file into the \scripts\lib folder within your model folder. Since the default .jar file for all models is vhi_model.jar, you may need to rename the .jar file that you are importing. By default, you do not have to rebuild event handlers. Host Integrator automatically loads the .jar file as soon as it is detected.

Note

The build process will attempt to rebuild all event handlers. You must manually delete any event handler .java files from the \scripts\src folder if you do not want them included in the .jar file.

.NET

  • Copy the source (.cs) files into the \scripts\src folder within your model folder. You must then rebuild event handlers in order to incorporate them into the .NET Assembly file for the model.

  • Copy the vhi_model.dll file into the \scripts\lib folder within your model folder. Since the default Application Extension file for all models is vhi_model.dll, you will probably need to rename the .dll file that you are importing. By default, you do not have to rebuild event handlers. Host Integrator automatically loads the .NET Assembly Extension file as soon as it is detected.

Note

The default rebuild process will attempt to rebuild all event handler C# source files. You must manually delete any event handler C# source files from the \scripts\src folder if you do not want them included in the .NET assembly, or explicitly exclude them in the project file, build.proj.

Extending Event Handlers

The general guidelines for developing event handlers provide basic information on defining an event handler by defining a Java class that directly extends the Host Integrator-defined event handler base class. However, it is permissible to use more complex class hierarchies that extend the base class through multiple subclasses.

Java

`class A extends AttributeEventHandler
{
   public static final int readAttributeTimeout = 50;
   void readAttribute(ReadAttributeEvent e) throws ApptrieveException;
   public String myRandomExampleMethod();
}
class B extends class A
{
   void readAttribute(ReadAttributeEvent e) throws ApptrieveException;
   void writeAttribute(WriteAttributeEvent e) throws ApptrieveException;
}
class C extends class B
{
   public static final int readAttributeTimeout = 100;
}`

All three of the above classes are valid attribute event handlers that can be mapped into a model.

  • Class A implements only the Read Attribute event and uses a 50 second timeout.
  • Class B implements its own version of both attribute events. It will inherit the 50 second timeout for Read Attribute from class A and use the model's default timeout for Write Attribute. Following standard Java inheritance rules, it inherits the method myRandomExampleMethod() from class A and can invoke it.
  • Class C also implements both attribute events—it inherits those defined in class B. In addition, class C defines a timeout override for the Read Attribute event of 100 seconds. For class C, this new definition supercedes the override from class A.

.NET

`public class A : AttributeEventHandler
{
    [Timeout(50)]
 public override string ReadAttribute(IReadAttributeEvent vsEvent)
 {
     return vsEvent.DefaultReadAttribute();
 }
 public String MyRandomExampleMethod()
 {
 }
}
class B : A
{
    public override string ReadAttribute(IReadAttributeEvent vsEvent)
 {
 }
  public override void WriteAttribute(IWriteAttributeEvent vsEvent)
 {
 }
}
class C : B
{
    [Timeout(100)]
 public override string ReadAttribute(IReadAttributeEvent vsEvent)
 {
 }
}`

All three of the above classes are valid attribute event handlers that can be mapped into a model.

  • Class A implements only the Read Attribute event and uses a 50 second timeout. Note that the .NET event handlers use a Timeout attribute to set the timeout period. The Timeout attribute has inheritance enabled.
  • Class B implements its own version of both attribute events.This example will inherit the 50 second timeout for Read Attribute from Class A and inherit the model's default timeout (EventHandlerConstant.DefaultTimeout) for Write Attribute. Following standard .NET inheritance rules, it inherits the method MyRandomExampleMethod() from class A and can invoke it.
  • Class C also implements both attribute events—it inherits those defined in class B. In addition, class C overrides the value of the Timeout attribute for the Read Attribute event, setting it to 100 seconds.

Example: Attaching and Testing an Event Handler

Examples are available for Java and .NET event handlers.

Example models are located at Program Files\\RocketSoftware\\Verastream\\HostIntegrator\\models\\CCSDemo

This Java example attaches and tests a sample event handler for reformatting currency amounts in recordset fields. Before you begin, you should review the basic steps for creating an event handler.

This example uses two Java files:

  • CurrencyFormatter.java - performs the reformatting job of prepending a dollar sign. This file is in the RocketSoftware\\Verastream\\HostIntegrator\\examples\\EventHandlers\\java\\shared\\src\\shared\\formatting folder. The CurrencyFormatter can be reused to reformat currencies in other model elements, such as attributes (such as CurrencyAttributeFormatter.java, also included in the examples folder).

  • CurrencyFieldHandler.java - reformats currencies in recordset fields. This file is in the RocketSoftware\Verastream\HostIntegrator\examples\EventHandlers\java\FieldEvents\FieldFormatting\scripts\src\fieldformatting folder.

Follow these steps to implement the currency formatting event handler:

  1. From the Design Tool, open the CCSDemo model.
  2. Save the model.
  3. Click Connect on the toolbar.
  4. Create a folder named fieldformatting under <Documents>\\RocketSoftware\\Verastream\\HostIntegrator\\models\\CCSDemo\\scripts\\src\\ and copy CurrencyFormatter.java and CurrencyFieldHandler.java to the folder.
  5. From the Settings menu, click Event Handlers. On the Technology tab, verify that Java is selected, and then click OK.
  6. On the Events menu, click Rebuild. The Build Output window indicates when the build is complete.
  7. In the Entity window, select the AcctTransactions entity.
  8. Click the Recordset tab, and then click the Fields subtab.
  9. Select the Amount Field, then click the Advanced Properties button.
  10. In the Advanced Recordset Field Properties dialog box, select fieldformatting.CurrencyFieldHandler from the Event Handler list. This dialog box also has options for reviewing the properties of the event handler or inspecting the code in your default Java editor.
  11. Click Close to attach the event handler to the Amount Field. When you return to the Fields tab, the Amount field now has a lightning bolt displayed to the left, indicating that an event handler has been attached.
  12. Click Apply to activate your changes.
  13. To test the event handler, select Recordset Test from the Debug menu. Confirm that AcctTransData is listed as the Recordset and Fetch Records is listed as the Action.
  14. Click Execute. After the test is complete, the returned values in the Amount column have a dollar sign and negative amounts are surrounded by parentheses, as they will be when returned to a client application.

.NET

This .NET example uses two C# files:

  • CurrencyFormatter.cs - Performs the reformatting job of prepending a dollar sign. This file is in the RocketSoftware\Verastream\HostIntegrator\examples\EventHandlers\dotnet\shared\formatting folder. The CurrencyFormatter can be reused to reformat currencies in other model elements, such as attributes.
  • fieldformatting.CurrencyFieldHandler.cs - Reformats currencies in recordset fields. This file is in the RocketSoftware\Verastream\HostIntegrator\examples\EventHandlers\dotnet\FieldEvents\FieldFormatting\scripts\src folder.

Follow these steps to implement the currency formatting event handler:

  1. Start the Design Tool and open the CCSDemo model.
  2. Save the model.
  3. Click Connect on the toolbar.
  4. Create a folder named fieldformatting under <Documents>\\RocketSoftware\\Verastream\\HostIntegrator\\models\\CCSDemo\\scripts\\src\\ and copy CurrencyFormatter.cs and fieldformatting.CurrencyFieldHandler.cs to the folder.
  5. From the Settings menu, click Event Handlers. On the Technology tab, verify that .NET is selected, and then click OK.
  6. On the Events menu, click Rebuild. The Build Output window indicates when the build is complete.
  7. In the Entity window, select the AcctTransactions entity.
  8. Click the Recordset tab, and then click the Fields subtab.
  9. Select the Amount Field, then click the Advanced Properties button.
  10. In the Advanced Recordset Field Properties dialog box, from the Event Handler drop down list, select fieldformatting.CurrencyFieldHandler. This dialog box also has options for reviewing the properties of the event handler or inspecting the code in your default C# editor.
  11. Click Close to attach the event handler to the Amount Field. When you return to the Fields tab, the Amount field now has a lightning bolt displayed to the left, indicating that an event handler has been attached.
  12. Click Apply to activate your changes.
  13. To test the event handler, select Recordset Test from the Debug menu. Confirm that AcctTransData is listed as the Recordset and Fetch Records is listed as the Action.
  14. Click Execute. After the test is complete, the returned values in the Amount column have a dollar sign and negative amounts are surrounded by parentheses, as they will be when returned to a client application.

Removing an Event Handler

You can use options within the Design Tool to detach event handlers from Host Integrator components. If you also want to remove associated files, additional steps are required.

  1. Click Events > Attach to open the Attach Event Handlers dialog box.
  2. Navigate to the object that has the event handler you want to detach.
  3. In the right panel, the Event Handlers column lists the event handler attached to an object. This option is available whether you view event handlers sorted by Structure or by Type.
  4. When you click the event handler, a list is available. Select <None> from the list and click OK.

Before you delete an event handler, check whether any other component is using it. You can review components that may be still be using the event handler from the Type tab on the Attach Event Handler dialog box.

If you delete the .java file (Java) or the .cs file (.NET) when an event handler is still attached to a component, the event handler will be displayed in red in the Attach Event Handlers dialog box, and you will be warned when you try to save the model that it cannot be deployed in its current state.

  1. The Java or .NET files associated with an event handler are located in <your_model_folder>\\<model name>\\scripts\\src.
  2. Delete the .java or .cs file for the event handler and then click Events > Rebuild to rebuild the model JAR or assembly (NET) file.

Event Handler Properties Files

Configure the default behavior for event handlers with settings available from the Event Handler Settings dialog box.

  • Java Event Handlers

    You can create other Java properties files for event handler settings. These settings are shared by all models in an installation and control aspects of runtime behavior. Those properties and their values are made available to event handlers via the callback interface method getHandlerProperty(String name) on the event interface passed as the event's parameter.

    There are two separate properties files for event handlers: one contains properties for event handlers as they execute within the Design Tool, and the other contains properties for event handlers as they execute with the Host Integrator Session Server.

    In the <VHI_install_dir>/HostIntegrator/etc folder, locate dt_script.properties.sample and script.properties.sample. Copy and rename these files as dt_script.properties and script.properties and modify them to your needs. There is additional documentation in the files.

  • .NET Event Handlers

    In the HostIntegrator\lib\dotnet\clrscriptserver.exe.config file you can modify properties used by the .NET script server. You cannot add arbitrary properties. You cannot use the .NET method IEvent.GetHandlerProperty() in this environment. Instead, consider reading properties from the environment or the registry.

Design Tool Properties

Create a script.properties file in the <VHI_install_dir>\HostIntegrator\etc folder. It can contain settings for the properties described below. This file has the form of a Java properties file. Entries have the form name=value, one per line. Backslashes ( \ ) must be doubled ( \\ ) to be interpreted literally. Open <VHI_install_dir>/HostIntegrator/etc/script.properties.sample for details.

Classpath: vhi.script.classpath=<semicolon-separated list of JAR file names>

Design Tool uses the vhi.script.classpath setting to locate Java classes that do not contain event handlers, but which must be available for use with the event handlers used by all models executing on the Server. This file is read at script manager startup. The script manager must be reset (by stopping and restarting it or by closing the Design Tool) before changes made to this file will take effect.

If this file is not present, or if the file does not contain a classpath definition, the classpath is assumed to be empty. No external Java libraries will be available to event handlers unless they are defined here.

Any other Java properties contained in this file are made available to event handlers via the Event.getHandlerProperty() API.

Server Properties

The script.properties file defines properties used by the session server to control the script manager. It must be located in the <VHI>\etc folder, and is in the form of a Java properties file. Entries have the form name=value, one per line. Backslashes ( \ ) must be doubled ( \\ ) to be interpreted literally. Open <VHI_install_dir>\HostIntegrator\etc\script.properties.sample for more details.

Classpath: vhi.script.classpath=<list of JAR file names>

The value is a string. On Linux, it consists of a colon-separated list of JAR file names to be searched. On Windows, it is a semicolon-separated list of JAR file names.

You can define the Java classpath that the session server uses for locating Java classes that do not contain event handlers, but that must be available for use with event handlers. This file is read-only when the server starts. The script manager must be reset (using the Reload Event Handlers option on the Events menu in the Design Tool, or by restarting the session server) before changes made to this file take effect.

If this property is not present, the default classpath is assumed to be empty (no external libraries used).

  • Script Output

    Two properties control how event handler data written to the System output (System.out and System.err) is sent.

  • vhi.script.output.file= true | false

    Boolean property that enables or disables script output. The default is false (output disabled).

  • vhi.script.output.filename=pathname

    String that specifies a file in the <VHI_install_dir>/HostIntegrator/etc/output directory where System.out and System.err are written. The default filename is handlers.out.

    No management is provided for any of the output generated by these properties. Any output recorded is simply appended to whatever content already exists in the output file.

  • Trap Output

    Two properties control how unhandled exceptions caught by the event handler environment will be written to a file.

  • vhi.script.output.traps= true | false

    Enables or disables trap output, recording information about unhandled exceptions. By default, Host Integrator writes stack dumps for unhandled exceptions caught from user classes.

  • vhi.script.output.trapfile= pathname

    String that specifies a file in the vhi/etc/output directory that holds the trap information. The default is traps.out.

    No management is provided for any output generated by these properties. Any output recorded is simply appended to whatever content already exists in the output file

Other Properties

Any other Java properties contained in this file are made available to event handlers via the getHandlerProperty API.