Previous Topic: Adding Tags to Transaction FramesNext Topic: Extending Java VSE


Extending the Broker

Broker extensions are loaded and invoked by the broker after a transaction fragment is received from an agent.

Broker extensions let you perform the following tasks:

To extend the broker, implement the com.itko.lisa.remote.plumbing.IAssemblyExtension interface. This interface defines the onTransactionReceived() method. For more information, see the JavaDocs in the doc folder of your installation directory.

public interface IAssemblyExtension {
     /**
      * The method invoked prior to assembly
      * @param frame the partial transaction root received from an agent
      * @return true to bypass normal assembly (i.e. if the extension wants to take care of it itself)
      */
     public boolean onTransactionReceived(TransactionFrame frame);
 }

To deploy a broker extension, compile the extension and package it in a JAR file with a manifest that contains the following entry:

Broker-Extension: extension class name 

When you drop this JAR in the broker (registry) directory, the broker automatically picks it up. If you add the file after the broker (registry) has started, a hot load mechanism helps to ensure that the file is applied. If you update the extension JAR as the broker (registry) is running, the JAR classes are reloaded dynamically. Dynamic reloading makes it easy and fast to test your extension code without restarting the broker (registry).

 

Example

A typical usage example is when the normal stitching algorithm that uses TCP/IPs and ports is confused by a load balancer sitting between agents and is assigned a virtual IP, or when agents use a native library to do IO and we do not have direct access to the IPs and ports in use. In that case, the address and port fields of frames are either left blank or incorrect and we must assemble the frames in an extension:

import com.itko.lisa.remote.plumbing.IAssemblyExtension;
import com.itko.lisa.remote.transactions.TransactionFrame;
import com.itko.lisa.remote.utils.Log;
import com.itko.lisa.remote.utils.UUID;
 
public class LoadBalancerExtension implements IAssemblyExtension {
 
    private TransactionFrame m_lastAgent1Frame;
    private TransactionFrame m_lastAgent2Frame;
 
    public boolean onTransactionReceived(TransactionFrame frame) {
 
    if (frame.getClassName().equals("Class1") && frame.getMethod().equals("method1")) {
        m_lastAgent2Frame = frame;
        if (m_lastAgent1Frame.getFrameId() == m_lastAgent2Frame.getParentId()) {
            stitch(m_lastAgent1Frame, m_lastAgent2Frame);
        }
    }
 
    if (frame.getClassName().equals("Class2") && frame.getMethod().equals("method2")) {
        m_lastAgent1Frame = frame;
        if (m_lastAgent1Frame.getFrameId() == m_lastAgent2Frame.getParentId()) {
            stitch(m_lastAgent1Frame, m_lastAgent2Frame);
        }
    }
 
        return false;
    }
 
    private void stitch(TransactionFrame parent, TransactionFrame child) {
    String newFrameId = UUID.newUUID();
    parent.setFrameId(newFrameId);
    child.setParent(parent);
    parent.getChildren().add(child);
}
}