×

Please give details of the problem

Docs

Find

Creating a Custom Adapter for the SEC

In this guide we will create a simple SEC Adapter. Our objective is to create a "HelloWorld" adapter that will return a message with a certain structure when posting the resource.

For this guide the following is assumed :

  • The SEC manager is running on the server and a tunnel is open and configured. You can find instructions on how to install and configure the SEC here
  • The server has Java installed.
  • The ping port on the manager is 4444 (this can be configured in the adapter and the manager).
  • The manager is running on the same server as the adapter (127.0.0.1).

The Adapter will be coded in JAVA and we will use the "Generic Protocol Handler". This means that the classes we create must include the SEC-SDK project, which contains the Generic Protocol Handler classes.

Adapter Classes

We will create 2 classes : the Handler and the Adapter.

Handler

The Handler will create a new instance of the Generic Protocol Handler with the configuration information. For this example, we will create a class called HelloWorldHandler. The code for the Handler looks as following :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
package com.runmyprocess.sec;

import java.io.File;
import java.util.logging.Level;

public class HelloWorldHandler {
    public static void main(String [] args)throws java.io.IOException{  
        try{
            GenericHandler genericHandler = new GenericHandler();//Creates a new instance of generic handler
            System.out.println("Searching for config file...");
            Config conf = new Config("configFiles"+File.separator+"handler.config",true);//sets the congif info
            System.out.println("Handler config file found for manager ping port "+
                                conf.getProperty("managerPort"));
            genericHandler.run(conf);//Runs the handler
        }catch( Exception e ){
                SECErrorManager errorManager = new SECErrorManager();//creates a new instance of the SDK error manager
                errorManager.logError(e.getMessage(), Level.SEVERE);//logs the error
                e.printStackTrace();//prints the error stack trace
            }
        }
}

This is the starting point of our Adapter. We are importing :

  • com.runmyprocess.sec - To have access to the SDK classes and the Generic Protocol Handler. Basically, the Adapter part of the same package as the SDK.
  • java.io.File - To get the OS's file separator so that the adapter can be run in different OSs.
  • java.util.logging.Level - To log any error.

The main method is run when starting the adapter. It will first create a new instance of the Generic Protocol Handler and then load the config files. For this example we are loading the handler config file from a folder named "configFiles". The handler config file should look like this:

1
2
3
4
5
6
7
8
#Generic Protocol Configuration
protocol = HelloWorld
protocolClass = com.runmyprocess.sec.HelloWorld
handlerHost = 127.0.0.1
connectionPort = 5832
managerHost = 127.0.0.1
managerPort = 4444
pingFrequency = 300

Where :

  • protocol is the name to identify our Adapter.
  • protocolClass is the class of the Adapter.
  • handlerHost is where the Adapter is running.
  • connectionPort is the port of the adapter where data will be received and returned.
  • managerHost is where the SEC is running.
  • managerPort is the port where the SEC is listening for ping registrations.
  • pingFrequency is the frequency in which the manager will be pinged (at least three times shorter than what's configured in the manager).

Adapter

If the handler is configured correctly, it will ping the manager and will be automatically registered with the first ping. The handler must implement the ProtocolInterface. This interface structures the data transfer. It contains two methods to be overridden :

  • accept - where the data is received and processed.
  • getResponse - gets the response object.

The Adapter code should look as following :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package com.runmyprocess.sec;

import java.util.logging.Level;
import org.runmyprocess.json.JSONObject;

public class HelloWorld implements ProtocolInterface{

    private Response response = new Response();

    public HelloWorld() {
        // TODO Auto-generated constructor stub
    }

    private JSONObject HelloWorldError(String error){
        response.setStatus(500);//sets the return status to internal server error
        JSONObject errorObject = new JSONObject();
        errorObject.put("error", error.toString());
        return errorObject;
    }

      @Override
    public void accept(JSONObject jsonObject,String configPath) {
        try {
            String message = jsonObject.getString("message");//Gets the message sent 
            response.setStatus(200);//sets the return status to 200
            JSONObject resp = new JSONObject();
            resp.put("Message", "Hello World! "+message);//sends the info inside an object
            response.setData(resp);

        } catch (Exception e) {
            response.setData(this.HelloWorldError(e.getMessage()));
            SECErrorManager errorManager = new SECErrorManager();
            errorManager.logError(e.getMessage(), Level.SEVERE);
            e.printStackTrace();
        }
    }

    @Override
    public Response getResponse() {
        return response;
    }   
}

By looking at the code we can see that in the accept method, the received JSON object expects a message parameter which will be parsed as a String and concatenated to our hardcoded "Hello World! " string. We will then create a JSONObject and add this string as a property and finally run the setData method of the response object. The Generic Protocol Handler will take care of calling the getReponse method and sending back the information to the manager on the configured port.

It is important to mention that the accept method receives another parameter (configPath). This string is the configuration path.

Configuring and testing the Adapter

Configuration

In order to test the adapter we recommend you generate a runnable jar file with the classes mentioned above. You must import the rmp-sec-sdk library as well as RunMyProcess' JSON libraries.

We also recommend that you use maven2 to build the adapter with the following pom:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.runmyprocess.sec</groupId>
    <artifactId>rmp-sec-helloWorld</artifactId>
    <version>1.0</version>
    <packaging>jar</packaging>

    <properties>
    <!-- Explicitly declaring the source encoding eliminates the following message: -->
    <!-- [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! -->
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>commons-codec</groupId>
        <artifactId>commons-codec</artifactId>
        <version>1.4</version>
    </dependency>
    <dependency>
        <groupId>org.runmyprocess</groupId>
        <artifactId>json</artifactId>
        <version>1.6.4</version>
    </dependency>
    <dependency>
        <groupId>com.runmyprocess.sec</groupId>
        <artifactId>rmp-sec-sdk</artifactId>
        <version>1.0</version>
    </dependency>
    </dependencies>

    <build>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.3.2</version>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
                <encoding>utf8</encoding>
            </configuration>
        </plugin>
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>org.runmyprocess.sec.HelloWorldHandler</mainClass>
                    </manifest>
                </archive>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
            <executions>
                <execution>
                    <id>make-assembly</id> <!-- this is used for inheritance merges -->
                    <phase>package</phase> <!-- bind to the packaging phase -->
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
    </build>
</project>

Make sure that the required libraries are in your local mvn repository.

Local tests

We recommend you first test that the adapter is running and that the SEC is registering it correctly. To accomplish this make sure that the Protocol Manager and the Adapter are running. When started, the Adapter will look into the "configFiles" folder and get the config file for the handler.

Your Protocol Manager and HelloWorld Adapter consoles should show the following information:

config_domain

You can see that the Protocol Manager is running on port 8080 and that the Adapter is pinging the manager on port 4444.

NB : If you are getting an error message on the Adapter make sure that the ping port is the same in the Adapter config file and the Protocol Manager config file.

You can now open a browser window and navigate to your localhost and the port on which the Protocol Manager is running (8080 by default). The browser will return the list of registered Adapters.

config_domain

This test assures that the Protocol Manager is running correctly and that the Hello World adapter was registered. Then, you can test the adapter by sending a Post request to the Protocol Manager. There are several ways to locally post a socket, you can use the Firefox Poster add-on. To obtain a JSONObject response with a message property containing "Hello World! we are online!" the body of the POST should look like this :

1
2
3
4
5
6
{
"protocol":"HelloWorld",
"data":{
        "message":"we are online!"
    } 
}

Use Poster to post this JSON. The reply should look like this:

config_domain

NB : To use your Adapter from RunMyProcess, simply run the connector agent and create a connector in RunMyProcess. For more information on how to configure RunMyProcess connectors for the SEC, check out the "How to call a local resource from my RunMyProcess account?" on the SEC Installation Guide. You may also send a "GET" request to retrieve a list of registered adapters.