Sei sulla pagina 1di 5

Hyperic HQ Agent/Server Communication

This document describes the setup and operation of the communication channels
used within the Hyperic HQ product. This includes setup of the server and agent,
as well as description of how data is passed between the various HQ
components. For readability, the classes referenced in this document that are
part of the HQ package are highlighted in bold italics. References to
<subsystem> should be replaced with one of the subsystems within HQ. (control,
measurement, rt, etc)

Server Configuration

By default the HQ server listens on the following ports:

Port Purpose
7080 HTTP
7443 HTTPS
9009 AJP Connector
2098 RMI
2099 JNP
7444 RMI Object Port
7445 ServerBindPort
9093 ServerBindPort

These ports are configurable at installation time, or by modifying hq-server.conf


in the server installation conf directory. Modification of hq-server.conf will require
a restart.

All inbound communication to the HQ server from agents is done through the
web container listening on either 7080 for HTTP or 7443 for HTTPS. The port
that is used is determined when the agent setup is run. All requests from the
agents are processed by the jboss-lather web application.

The JNP and RMI ports are used by the HQ shell to execute methods on the
server using the server’s remote EJB interfaces.

Agent Configuration

By default the HQ agent listens on port 2144. To change this, the


agent.ListenPort property must be changed in the agent.properties. If the agent
had already been setup to talk with an HQ server, the setup process must be re-
run to re-establish communication with the HQ server.

Hyperic Confidential
All communication to the agent through port 2144 is encrypted using SSL, and
connections are authenticated using a shared secret that is established when the
agent is first setup.

To aid in setups where firewalls are an issue, the HQ agent setup process will
ask for the IP address for the server to contact the agent at, in case this is a
different IP address than the agent is binding to.

Server/Agent Communication

Within HQ there are 2 types of communication between the agent and server.

 Server initiated communication


 Agent initiated communication

In both cases an object is passed as an argument and a separate object is


returned as a return value. These are described in detail below.

Server Initiated Communication

Server initiated communication are the agent commands, and are usually
initiated through the UI or through the HQ Shell. These commands include
running control actions and scheduling metrics among others. The protocol for
sending the commands is fairly primitive. The command is sent in raw TCP/IP
over SSL to the agent daemon.

The table below describes the protocol:

Type Purpose
Integer API Version
Integer Command Version
String Command Name
String Key1
String Value1
String Key2
String Value2
… …

A class that extends AgentRemoteValue is used for argument passing and


return values. The underlying data structure for the AgentRemoteValue only
allows for storage of String types, but has convenience methods for storing
Integer, Long and Double types. For any other Java object, it must be serialized
and converted to a String for transport.

Within HQ many of the types we send over the wire have their own serialization
methods. Examples of this are the ConfigReponse and ConfigSchema
classes. For other objects standard Java serialization can be used to obtain a

Hyperic Confidential
byte representation of the object, which can then be converted to a String using
Hyperic’s Base64 encoder. Base64 is used for conversion to String mainly for
speed, but it’s symmetric properties make it a good choice for encoding and
decoding Strings.

An example of passing a java.util.Properties object follows:

// Key for storing Properties objects


private static final String PROP_PROPERTIES = "properties";

public void setProperties(Properties properties) {


ObjectOutputStream os;
try {
String propStr;
ByteArrayOutputStream bs = new ByteArrayOutputStream();
os = new ObjectOutputStream(bs);
String propStr;

os.writeObject(properties);
propStr = Base64.encode(bs.toByteArray());

super.setValue(PROP_PROPERTIES, propStr);
} catch (IOException e) {
} catch (EncodingException e) {
} finally {
try {os.close();}
catch (Exception ex) {}
}
}

public Properties getProperties() {

String propStr = this.getValue(PROP_PROPERTIES);


Properties res;
try {
byte[] data = Base64.decode(propStr);
ByteArrayInputStream bs = new ByteArrayInputStream(data);
ObjectInputStream os = new ObjectInputStream(bs);

res = (Properties)os.readObject();
return res;
} catch (IOException e) {
} catch (EncodingException e) {
}
}

This example illustrates sending Java types using ByteArrayOutputStream and


ObjectOutputStream to serialize the data, and ByteArrayInputStream and
ObjectInputStream to de-serialize the data.

All the subclasses of AgentRemoteValue within HQ follow a JavaBean pattern


of having a get() and set() method for each argument. In HQ you can find

Hyperic Confidential
subclasses of AgentRemoteValue in the
net.hyperic.hq.<subsystem>.agent.commands package.

Now that argument and result object processing is understood, the next topic is
the client classes that are used to invoke the methods on the agent. In HQ these
classes are named <Subsystem>CommandsClient, and are found in the
net.hyperic.hq.<subsystem>.client package. The client classes have methods for
each command that is available for that subsystem within the agent. These
methods simply wrap up the arguments into a AgentRemoteValue and call the
agent using the sendCommand() method in the AgentConnection class.

In addition to passing types it is also possible to stream data out to an agent.


This is done by calling sendCommandHeaders() in the AgentConnection class
which will return an AgentStreamPair which contains an InputStream and
OutputStream to the agent. A good example of how this works can be found in
the ControlCommandsClient.

This document is meant to illustrate the sending data to and from the server. For
more information on extending the HQ agent see the document Hyperic HQ
Agent.doc.

Important: Note that the HQ agent uses a single accept model. This means that
the command is sent to the agent using the client class, then blocks waiting for
the return object. For methods that may take a considerable time on the agent,
it’s advisable to return a NullLatherValue and report the results back to the
server asynchronously using an agent call back into the server. This method is
described below.

Agent Initiated Communication

Agent initiated commands are used by the agent to send data back to the server.
The most common case in HQ is the sending of measurement data back to the
server. Another use of agent initiated commands is to send back the result of an
agent command that may take a while to complete. An example of this is a
control action, or an auto-discovery scan.

Agent initiated communication to the server is similar to server initiated


communication in many respects. The main difference is the argument and
result objects are LatherValue objects, which are able to store data in a more
sophisticated fashion. Unlike AgentRemoteValue, all major Java types are
supported, including String, Integer, Double, Long, byte[] and Object. Sending
lists of any of these types is also supported. One example of this is sending a list
of MeasurementReport objects back to the server.

Hyperic Confidential
Commands sent to the server are sent to the jboss-lather servlet running inside
the HQ server using a POST over HTTP or HTTPS. Within HQ all subclasses of
LatherValue can be found in the net.hyperic.hq.bizapp.shared.lather package.

The use of these classes to pass and return values is similar to that of the
AgentRemoteValue class. Like AgentRemoteValue, each parameter should
have a get() and set() method to abstract out the storage implementation.

Just like server to agent communication, the agent to server communication also
involves a set of client classes to send the command to the server. These
classes follow the naming pattern <Subsystem>CallbackClient. They can be
found in the net.hyperic.hq.bizapp.client package.

Each CallbackClient extends the AgentCallbackClient class, which implements


the sending of commands back to the server. Each method in the callback class
represents a command that can be invoked on the server. Just like in the
CommandsClient classes, these methods simply create the LatherValue objects
based on the parameters passed into the method. This is done to abstract out
the communication layer (in this case Lather) from the caller of the client classes.

Hyperic Confidential

Potrebbero piacerti anche