Extend the Runtime Manager Agent for Hybrid | MuleSoft Documentation
# Extend the Runtime Manager Agent for Hybrid
Private Cloud Edition 
Where possible, we changed noninclusive terms to align with our company value of Equality. We maintained certain terms to avoid any effect on customer implementations.  
---  
You can extend the Anypoint Runtime Manager agent, including implementing a complete service, external message handler, and internal message hander using a method to revert a string.
## Runtime Manager Agent Extensible Component
The Runtime Manager agent contains the following extensible components:
  * Services
  * External message handlers
  * Internal message handlers


## Runtime Manager Agent Custom Component Structure
A Runtime Manager agent custom component should comply with the following structure:
  * `/lib` contains component dependencies
  * `/classes` contain compiled classes


A custom component should also be compiled with Java 1.7, components compiled with higher versions will not be loaded by the agent.
For this example, in order to acquire the libraries necessary to extend the agent, add the following dependencies to your `pom.xml`:
```
<properties>
  <maven.compiler.source>1.7</maven.compiler.source>
  <maven.compiler.target>1.7</maven.compiler.target>
  <mule.agent.version>1.6.4-mule-3.x</mule.agent.version>
  <jersey.core.version>2.11</jersey.core.version>
  <commons.lang.version>2.4</commons.lang.version>
</properties>
<dependencies>
    <dependency>
      <groupId>com.mulesoft.agent</groupId>
      <artifactId>mule-agent-api</artifactId>
      <version>${mule.agent.version}</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.glassfish.jersey.core</groupId>
      <artifactId>jersey-client</artifactId>
      <version>${jersey.core.version}</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>commons-lang</groupId>
      <artifactId>commons-lang</artifactId>
      <scope>provided</scope>
      <version>${commons.lang.version}</version>
    </dependency>
</dependencies>
<repositories>
  <repository>
    <id>mulesoft-ci-releases</id>
    <name>ci releases</name>
    <url>https://repository-master.mulesoft.org/nexus/content/repositories/releases-ee/<url>
  </repository>
</repositories>
<build>
  <plugins>
    <plugin>
      <artifactId>maven-assembly-plugin</artifactId>
      <executions>
        <execution>
          <phase>package</phase>
          <goals>
            <goal>single</goal>
          </goals>
        </execution>
      </executions>
      <configuration>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
      </configuration>
    </plugin>
  </plugins>
</build>
```

Contact MuleSoft Support for access to this repository: ```
https://repository-master.mulesoft.org/nexus/content/repositories/releases-ee/
```
  
---  
The corresponding JAR should be added under the `lib` folder within the `mule-agent` plugin, which is contained in the `plugins` folder of the Mule instance. For example, `$MULE_HOME/plugins/mule-agent/lib/<component name>.jar`.
## Add a New Service
To add a new service, implement the `MuleAgentService` interface.
Considerations for custom services:
  * The service can execute any internal handler registered in the Runtime Manager agent environment, by using the `@Inject` annotation.
  * You don’t have to follow the Runtime Manager agent architecture in order to create a new service.


### Write Your Service
#### Implement MuleAgentService
```
@Named("my.company.service")
@Singleton
public class MyService implements MuleAgentService
{
  @Inject
  private Map<String, InternalMessageHandler<List<T>>> handlers;
  @Override
  public java.util.List<com.mulesoft.agent.handlers.InternalMessageHandler> getInternalHandlers()
  {
    // TODO: return List of Internal Handlers
  }
  @Override
  public void enable(boolean state) throws AgentEnableOperationException {
    // TODO: enable the Service
  }
  @Override
  public boolean isEnabled() {
    // TODO: return Service status
  }
}
```

To add your new service, just drop the JAR containing your classes in the `lib` folder within the `mule-agent` plugin folder (for example, in `$MULE_HOME/mule-agent/lib`).
### Revert String Service Example
As explained above, this document uses a simple example to explain how to write a full extension to revert a string. The first step is to add a service for this purpose.
```
@Named("com.company.service.reverse")
@Singleton
public class ReverseService implements MuleAgentService
{
  @Inject
  List<InternalMessageHandler<String>> messageHandlerList;
  @Override
  public List<InternalMessageHandler> getInternalHandlers()
  {
    return new ArrayList<InternalMessageHandler>(messageHandlerList);
  }
  @Override
  public void enable(boolean b) throws AgentEnableOperationException
  {
  }
  @Override
  public boolean isEnabled()
  {
    return true;
  }
  public String getConvertedString(String origString)
  {
    String reverted = StringUtils.reverse(origString);
    for (InternalMessageHandler<String> internalMessageHandler : messageHandlerList)
    {
      internalMessageHandler.handle(reverted);
    }
    return reverted;
  }
}
```

## Add a New External Message Handler
To add a new external message handler, you have to implement the Runtime Manager agent Reverse String External Message Handler interface.
Considerations for custom external message handlers:
  * The external message handler will be injected into a transport
  * The external message handler must be thread-safe
  * An external message handler is executed by a transport and cannot interact with Mule. **Only Services can interact with Mule**


### Write Your External Message Handler
```
@Named("my.external.handler")
@Path("somePath")
@Singleton
public class MyRequestHandler implements ExternalMessageHandler
{
  @Inject
  private MuleService muleServiceInTheAPIModule;
  @Override
  public void enable(boolean state) throws AgentEnableOperationException {
    // TODO: enable the Handler
  }
  @Override
  public boolean isEnabled() {
    // TODO: return Handler status
  }
  @GET
  @Produces(MediaType.APPLICATION_JSON)
  public List<Component> someRequest()
  {
  }
}
```

#### WebSockets
```
@Named("TYPE_OF_MESSAGE_THAT_MUST_DISPATCH")
@Singleton
public class MyRequestHandler implements ExternalMessageHandler
{
  @Inject
  private MuleService muleServiceInTheAPIModule;
  @Override
  public void enable(boolean state) throws AgentEnableOperationException {
    // TODO: enable the Handler
  }
  @Override
  public boolean isEnabled() {
    // TODO: return Handler status
  }
}
```

To add your new external message handler, just drop the JAR containing your classes under the `lib` folder within the `mule-agent` plugin folder (for example, in `$MULE_HOME/mule-agent/lib`).
### Reverse String External Message Handler
Following the Reverse String example, the External Handler is shown below.
```
@Named("com.company.externalhandler.reverse")
@Path("revert")
@Singleton
public class ReverseExternalHandler implements ExternalMessageHandler
{
  @Inject
  private ReverseService reverseService;
  @Override
  public void enable(boolean b) throws AgentEnableOperationException
  {
  }
  @Override
  public boolean isEnabled()
  {
    return true;
  }
  @GET
  public String getReversedString(@QueryParam("string") String string)
  {
    return reverseService.getConvertedString(string);
  }
}
```

The above code exposes a resource under `<your REST transport host>/mule/revert`.
## Add a New Internal Message Handler
To add a new internal message handler, you have to implement the Internal Message Handler interface.
Considerations for custom internal message handlers:
  * The internal message handler will be injected into a service based on the message types it handles
  * The internal message handler must be thread-safe
  * An internal message handler is executed by a service and cannot interact with Mule. **Only Services can interact with Mule**


### Write Your Internal Message Handler
```
@Named("my.company.internal.handler")
@Singleton
public class MyInternalMessageHandler<T> implements InternalMessageHandler<T>{
  boolean handle(T t){
     // TODO handle message
  }
  @Override
  public void enable(boolean state) throws AgentEnableOperationException {
    // TODO: enable the Handler
  }
  @Override
  public boolean isEnabled() {
    // TODO: return Handler status
  }
}
```
The above code exposes a resource under `<your REST transport host>/mule/revert`.
## Add a New Internal Message Handler
To add a new internal message handler, you have to implement the Internal Message Handler interface.
Considerations for custom internal message handlers:
  * The internal message handler will be injected into a service based on the message types it handles
  * The internal message handler must be thread-safe
  * An internal message handler is executed by a service and cannot interact with Mule. **Only Services can interact with Mule**


### Write Your Internal Message Handler
```
@Named("my.company.internal.handler")
@Singleton
public class MyInternalMessageHandler<T> implements InternalMessageHandler<T>{
  boolean handle(T t){
     // TODO handle message
  }
  @Override
  public void enable(boolean state) throws AgentEnableOperationException {
    // TODO: enable the Handler
  }
  @Override
  public boolean isEnabled() {
    // TODO: return Handler status
  }
}
```

To add your new internal message handler, just drop the jar containing your classes under the `lib` folder within the `mule-agent` plugin folder (for example, in `$MULE_HOME/mule-agent/lib`).
#### Reverse String Internal Message Handler
The code below shows an internal message handler for the reverse string example.
```
@Named("com.mulesoft.agent.test.extension.internalHandler")
@Singleton
public class ReverseInternalHandler extends BufferedHandler<String>
{
  @Configurable("true")
  protected boolean enabled;
  @Configurable
  public String host;
  @Configurable
  public String port;
  @Inject
  public ReverseInternalHandler()
  {
    super();
  }
  @Override
  protected boolean canHandle(String t)
  {
    return true;
  }
  @Override
protected boolean flush(Collection<String> ts)
  {
    String tempDir = System.getProperty("java.io.tmpdir");
    File revertedStringFile = new File(tempDir, "revertedString.txt");
    FileOutputStream fos = null;
    BufferedWriter bw = null;
    try
    {
      fos = new FileOutputStream(revertedStringFile);
      bw = new BufferedWriter(new OutputStreamWriter(fos));
      for (String string : ts)
      {
        bw.write(string);
        bw.newLine();
      }
    }
    catch (IOException e)
    {
      System.out.println("Error writing reversed string");
      return false;
    } finally {
     if (bw != null){
      try {
        bw.close();
      } catch(IOException x) {
      }
     }
     if (fos != null){
      try{
        fos.close();
      } catch(IOException x) {
      }
     }
    }
    return true;
  }
  @PostConfigure
  public void postConfigure()
  {
  }
  @Override
  public void enable(boolean b) throws AgentEnableOperationException
  {
   enabled = b;
  }
  @Override
  public boolean isEnabled()
  {
    return enabled;
  }
}
```

This internal message handler writes the message processed by the service to a file called `revertedString.txt`.
## Runtime Manager Agent API Interfaces
### Mule Service
```
**
 * <p>
 * Implementations of this interface provides new functionality to the Runtime Manager agent. These services handle data from
 * Mule and interact with Mule.
 * </p>
 *
 * @see com.mulesoft.agent.handlers.ExternalMessageHandler , InternalMessageHandler
 * @since 1.0
 */
public interface MuleAgentService extends Switcher
{
  public List<InternalMessageHandler> getInternalHandlers();
}
```

### External Message Handler
```
/**
 * <p>
 * Gets messages coming from an external system and executes {@link com.mulesoft.agent.services.MuleAgentService} based
 * the request.
 * </p>
 * <p>
 * This is just a marker interface for the communication layer to recognize the interface as a External message receiver
 * </p>
 *
 * @since 1.0
 */
public interface ExternalMessageHandler extends Switcher
{
}
```

### Internal Message Handler
```
/**
 * <p>
 * Internal messages come generally from mule side. {@link InternalMessageHandler} are use to handle those messages depending on,
 * for example, the transport.
 * </p>
 *
 * @param <Rq> is the type of the message it must handle
 * @since 1.0
 */
public interface InternalMessageHandler<Rq> extends Switcher
{
  /**
   * <p>
   * Process an internal message
   * </p>
   *
   * @param message The message to be processed
   * @return true if the message could be processed
   */
  boolean handle(@NotNull Rq message);
}
```

### Switcher
```
/**
 * <p>
 * All the classes implementing this interface will be able to enable/disable themselves
 * </p>
 *
 * @since 1.0
 */
public interface Switcher
{
  /**
   * <p>
   * Turn the feature on, the class will be behave as expected
   * <br/>
   * If the feature is being disabled, any resources it has allocated should be freed and taken again when it is reenabled
   * </p>
   * @param state true if enabled, false otherwise
   * @throws AgentEnableOperationException if the end state is not the requested one
   */
  void enable(boolean state) throws AgentEnableOperationException;
  /**
   * <p>
   * Check the state of the class
   * </p>
   *
   * @return true if it is on, false otherwise
   */
  boolean isEnabled();
}
```