The HelloWorld Sample: Lessons for Agent Developers

The HelloWorld sample is a minimum viable agent program. It illustrates a lower bound on code complexity, API support and operating environment. Careful examination of its code can yield valuable information for novice agent developers.

The HelloWorld sample is a stand-alone agent process, which runs in a Jetty server.

We have coded the sample's top-level object in the interface style. That is, we define the class HelloWorldAgent to implement the TopLevelTeaObject interface. (For background information, see Object Type Definition: Overview and Interface Style.)

We begin by defining the five required methods of that interface—getName, getDescription, getMembers, getTypeName, getTypeDescription. For the purposes of this sample, all five methods do the minimum work—getMembers returns an empty list, while the others each return a constant string.

public class HelloWorldAgent implements TopLevelTeaObject{
    private static final String NAME = "hw";
    private static final String DESC = "Hello World";
    
    @Override
    public String getDescription() {
        return DESC;
    }
    
    @Override
    public String getName() {
        return NAME;
    }
    
    @Override
    public Collection<BaseTeaObject> getMembers() {
        return Collections.EMPTY_LIST;
    }
    
    @Override
    public String getTypeDescription() {
        return "Top level type for HelloWorld";
    }
    
    @Override
    public String getTypeName() {
        return "HelloWorldTopLevelType";
    }

We also define a method named helloworld, and annotate it as a @TeaOperation. This method implements the one operation that this agent offers to users. If you ignore the annotations, you can see that the method itself is simple; it concatenates two strings (one of which is the method's argument) and returns the resulting string. The @TeaOperation annotation makes this method available in the TIBCO Enterprise Administrator server as an operation of the agent. Java introspection of the annotation gives the server the operation's name and description. The @TeaParam annotation tells the server to prompt the user for the operation's argument.

    @TeaOperation(name = NAME, description = "Send greetings")
    public String helloworld(
            @TeaParam(name = "greetings", description = "Greetings parameter") final String greetings) throws IOException {
        return "Hello " + greetings;
    }
The main method initializes the agent process:
    public static void main(final String[] args) throws Exception {
        TeaAgentServer server = new TeaAgentServer("HelloWorldAgent", "1.0", "Hello World Agent", 1234, "/helloworldagent", true);
        server.registerInstance(new HelloWorldAgent());
        server.start();
    }
  1. It instantiates a TeaAgentServer—an object that wraps a Jetty instance. This instance, server, represents the dedicated Jetty server within which the agent runs.

    (Notice that we must distinguish between two distinct servers—the Jetty web server instance, and the TIBCO Enterprise Administrator server.)

    The fourth and fifth arguments to the constructor—port and contextPath—together specify the URL where agent listens for requests from the TIBCO Enterprise Administrator server.

  2. It creates a singleton instance of the agent's top-level object, HelloWorldAgent.
  3. server.registerInstance introspects that instance, gathering metadata from the annotations (@TeaOperation and @TeaParam, above).

    The TIBCO Enterprise Administrator server later requests this metadata from the Jetty server, and uses it to implement its user interface for the agent.

  4. server.start starts the Jetty server and deploys the agent code within it.