Thursday, January 21, 2016

Hawkular Command Gateway Clients

This document is to briefly explain how clients can use the command gateway to send requests to the Hawkular Server and receive responses. The typical use case (though certainly not the only way to use this feature) is for a browser to send requests to Hawkular WildFly Agents routed through the Hawkular Server, with the agent’s responses routed back to the browser (back through the server intermediary) that sent the request.

Brief Summary

The typical workflow is the following:
  1. Client makes a websocket connection to the server.
  2. Client immediately receives a WelcomeResponse JSON message from the server notifying the client what its session ID is.
  3. Client can send JSON requests over the Web Socket connection.
  4. Client can receive JSON responses over the Web Socket connection. These messages are received asynchronous from its requests and may not even be tied to a specific request.
  5. Client can keep the connection open as long as it wants, and can disconnect when it wants.

Make the Connection

Clients first need to make a WebSocket connection to the Hawkular Server. That is done by connecting to the URL: "ws://:8080/ui/ws".

Note that a secure connection via SSL can be made by connecting to “wss://:8443” but this requires the server to be configured properly with a certificate and a security realm defined. Such details are out of scope for this document. For more, see http://www.hawkular.org/docs/user/secure-comm.html

Receiving the Welcome Message

For each client websocket connection that is made, the server sends an initial WelcomeResponse message immediately to it. This message contains the client’s session ID. This is the session ID that the server will use to identify that client. This session ID is actually not needed by the client today, but it is available for future functionality. For now, clients can actually ignore this session ID.

An example WelcomeResponse message that a client could receive is:

WelcomeResponse={“sessionId”:”abc:123:xyz:789”}

The WelcomeResponse JSON schema is defined here.

Sending a Request Message

Once connected, clients can immediately begin sending any valid request over the web socket connection. Because clients are able to send in different kinds of requests, the client must ensure the request message’s JSON content is prefixed with the JSON schema name followed by “=” . Valid JSON schemas can be found here.

Within the JSON content, there must be an authentication node containing the credentials of the client. The authentication node’s JSON schema is defined here.

So, for example, if you want to execute the “Undeploy” operation on a web deployment resource, the request sent over the web socket connection will look something like this:

ExecuteOperationRequest={“authentication”:{“username”:”joe”,”password”:”pw”},“operationName”:”Undeploy”,”resourcePath”:”/t;tenant-id/e;env-id/r;resource-id-of-the-deployment-resource”}

Note that in order for a client to request something related to a specific resource in inventory, that client must know the resource’s “resource path” as defined in Hawkular Inventory. See the Hawkular Inventory REST API documentation for more details on how to obtain inventory data such as these resource paths.

Receiving a Response Message

The clients can receive messages in the same format as it sent them. In other words, the JSON content received by the client will be prefixed with the JSON schema name that is to be used to properly parse the JSON content received.

For example, when a client sends a request message destined to an agent, the server will immediately send a GenericSuccessResponse back to the client. This means the request was received by the server and has been successfully forward to the agent (note: it does not mean the request was successfully processed by the agent - the agent will send its own success or failure response message back once it processes the original request). Such a response message received by the client would look like this:

GenericSuccessResponse={“message”:”The request has been forwarded to the feed [foo]”}

Sending Binary Content

Sometimes a client needs to send raw binary data as part of a request (e.g. when a client wants to deploy a web application, it sends a DeployApplicationRequest along with the application’s .war file). To do this, the client sends the JSON message as usual (i.e. in the form “json-schema={json content}”) but immediately following the final curly brace of the JSON content, the client should stream the binary content.

Friday, January 1, 2016

Hawkular WildFly Agent API For Your Own Inventory and Metrics

The Hawkular WildFly Agent is well into development and is coming along nicely. It provides a way to monitor one or more WildFly or EAP application servers (including the one it is deployed into). It communicates with a Hawkular Server where the agent stores its inventory and metric data via the Hawkular Inventory and Hawkular Metrics components. You can use the Hawkular GUI to interact with your managed application servers: view historical graphs of metric data, deploy and undeploy applications, etc.

But the Hawkular WildFly Agent provides a hidden gem that might be useful to those developers that want to store metrics in a metric storage facility for later reporting and graphing but don't want to take the time to implement that storage facility. This hidden gem also provides a way for developers to store their own managed resource definitions in an inventory storage facility but, again, don't want to implement all of the backend required for such a thing.

The Hawkular WildFly Agent already integrates with Hawkular Inventory and Hawkular Metrics - this is to enable the agent to be able to store its own inventory and metrics. It makes sense to open that up for applications to use so they, too, can store inventory and metrics. To allow for this, Hawkular WildFly Agent stores a helpful object in JNDI called HawkularWildFlyAgentContext under the name "java:global/hawkular/agent/api" (side note: the agent can be told to bind this object to a different JNDI name if you want; it can also be told to not bind this hidden gem in JNDI at all if you do not wish to expose this feature).

The API this exposes is very simple - you can store or remove resources from inventory, and you can store metric data and availability data (availability data is just a "special" kind of metric that allows you to store "UP", "DOWN" or "UNKNOWN" availability states).

Any application that is deployed in the same WildFly or EAP application server as the agent can use this API by obtaining the agent context object via JNDI. A simple example of how you can obtain this agent context object from JNDI can be seen in a test war that is used in the agent integration tests - its a singleton EJB that gets this context object injected via @Resource. See the HawkularWildFlyAgentProvider class.

Once that HawkularWildFlyAgentContext object is obtained, your application can use it to store inventory, metric, and availability data. Note that you do not have to use all of these. For example, if you just want to store metrics in a historical time-based data store, just use the Metric Storage API that you get from the agent context object. This will send your data for storage to Hawkular Metrics. You could then do whatever you want with your data later - Hawkular Metrics provides a REST interface and some clients that you can use to query and report on your metric data.

The example test war can show you how the API is used to do these things - see the test MyAppServlet.java. This is just for integration testing, so it doesn't do anything earth-shattering, but it does show you how the API is used to create and remove managed resources from inventory, store metric data, and store availability data.

This feature of the Hawkular WildFly Agent is a relatively minor feature considering all the other main requirements that the agent must fulfill, but since it is rather hidden I decided to talk about it here.