How to use Call Trace gadget of RTGov in FSW 6.0.0 ?

Solution Verified - Updated -

Environment

  • Red Hat JBoss Fuse Service Works (FSW)
    • 6.0.0

Issue

  • While trying to show governance information about SOA services using RTGov and after changing the property to true on overlord-rtgov.properties, metrics start showing up on the UI of http://localhost:8080/gadget-web. But the problem is that it does not show any information on Call Trace gadget. Is there any settings or configuration or any code change which needs to be done to show some data on this gadget?
  • Is there any sample demo which users could use as a reference?

Resolution

  • First, try to understand why Call Trace gadget is used. As per the documentation available in Overlord forum [0] , the Call Trace service is used to return a tree structure, tracing the path of a business transaction (as a call/invocation stack) through a Service Oriented Architecture.
  • The Call Trace gadget needs an input called Value (which is a globally unique identifier value for the business transaction) from user to display Activity details (which the documentation refers as path of a business transaction) fetching from RTGov database tables from the back-end. Users can enter the value to the Value parameter only after clicking the settings icon , seen at the top right corner (middle icon) of the gadget to seek the database records of Activity from the back-end table RTGOV_ACTIVITY_CONTEXT . Behind the scenes (as of FSW 6.0.0 release) the gadget makes a call to a REST endpoint with the Value htp://localhost:8080/overlord-rtgov/call/trace/instance?value=xxxx .

jboss-eap-6.1/standalone/deployments/overlord-rtgov/gadgets.war/calltrace-gadget/gadget.xml

...
    function makeJSONRequest(){
        var prefs = new gadgets.Prefs();
        //hack for now.
        var protocol = parent.window.location.protocol;
        var host = parent.window.location.host;
        var ident = getUserPreferenceValue("value");
        ...
    var restUrl = protocol + "//" + host + "/overlord-rtgov/call/trace/instance?value=" + ident;

        var params = {};
        params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON;
        params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.GET;
                params[gadgets.io.RequestParameters.REFRESH_INTERVAL] = 5;

        gadgets.io.makeRequest(restUrl, updateResponse, params);
    }
...
  • This REST call is handled by the org.overlord.rtgov.internal.call.trace.rest.RESTCallTraceServer server code's instance(...) method. Interestingly, although this method takes two parameters (a Context type and value) , but since currently the Call Trace gadget UI only supplies the Value , that is why it only defaults to use Conversation as the default accepted Context type for filtering activity records from back end database tables. This is a limitation in the currently shipped Call trace gadget UI and a Feature Request [1] has been raised to provide a feature to accept type as well from users through Call Trace gadget UI.

org.overlord.rtgov.internal.call.trace.rest.RESTCallTraceServer

@Path("/call/trace")
@ApplicationScoped
public class RESTCallTraceServer {

    private static final Logger LOG=Logger.getLogger(RESTCallTraceServer.class.getName());

    private CallTraceService _callTraceService=null;

    private ActivityServer _activityServer=null;
...
    @GET
    @Path("/instance")
    @Produces("image/svg+xml")
    public String instance(@DefaultValue("Conversation") @QueryParam("type") String type,
                    @QueryParam("value") String value) throws Exception {
        String ret="";

        CallTrace ct=getCallTrace(type, value);

        if (ct != null) {
            byte[] b=CallTraceUtil.serializeCallTrace(ct);

            if (b != null) {
                ret = new String(b);
            }
        }

        if (LOG.isLoggable(Level.FINEST)) {
            LOG.finest("Instance="+ret);        
        }

        return (ret);
    }

    /**
     * This method returns the call trace associated with the supplied
     * context.
     * 
     * @param type The context type
     * @param value The context value
     * @return The call trace, or null if not found
     * @throws Exception Failed to get call trace
     */
    protected CallTrace getCallTrace(String type, String value) throws Exception {
        CallTrace ret=null;

        if (value.equals("test")) {
            ret = createTestCallTrace();
        } else {
            Context query=new Context();

            if (type != null) {
                query.setType(Context.Type.valueOf(type));
            }

            query.setValue(value);

            ret = _callTraceService.createCallTrace(query);
        }

        return (ret);
    }
...
    /**
     * This method returns a test call trace that can be returned
     * from the REST service.
     * 
     * @return The test call trace
     */
    protected CallTrace createTestCallTrace() {
        CallTrace ret=new CallTrace();

        Call c0=new Call();
        c0.setComponent("TestService1");
        c0.setInterface("intf1");
        c0.setOperation("op1");
        c0.setRequest("<op1></op1>");
        c0.setResponse("<op1></op1>");
        c0.setDuration(2000);
        c0.setStatus(Status.Warning);
        c0.getProperties().put("customer", "Acme Inc");
        c0.getProperties().put("trader", "Fred Bloggs");
        ret.getTasks().add(c0);

        Task t1=new Task();
        t1.setDescription("Assign var1");
        t1.setDuration(100);
        t1.setPercentage(5);
        t1.getProperties().put("name", "var1");
        c0.getTasks().add(t1);

        Task t2=new Task();
        t2.setDescription("Evaluate expr1");
        t2.setDuration(100);
        t2.setPercentage(5);
        t2.getProperties().put("expression", "a + b");
        c0.getTasks().add(t2);

        Call c3=new Call();
        c3.setComponent("TestService2");
        c3.setInterface("intf2");
        c3.setOperation("op2");
        c3.setRequest("<op2></op2>");
        c3.setResponse("<op2></op2>");
        c3.setDuration(700);
        c3.setPercentage(35);
        c3.setRequestLatency(10);
        c3.setResponseLatency(10);
        c3.getProperties().put("customer", "Acme Inc");
        c0.getTasks().add(c3);

        Call c4=new Call();
        c4.setComponent("TestService3");
        c4.setInterface("intf3");
        c4.setOperation("op3");
        c4.setRequest("<op3></op3>");
        c4.setResponse("<op3></op3>");
        c4.setDuration(700);
        c4.setPercentage(35);
        c4.setRequestLatency(10);
        c4.setResponseLatency(10);
        c4.setFault("TestFault");
        c4.setStatus(Status.Fail);
        c4.getProperties().put("trader", "Fred Bloggs");
        c0.getTasks().add(c4);

        Task t5=new Task();
        t5.setDescription("Store var1");
        t5.setDuration(100);
        t5.setPercentage(5);
        c0.getTasks().add(t5);

        Task t31=new Task();
        t31.setDescription("Store var31");
        t31.setDuration(680);
        t31.setPercentage(100);
        t31.getProperties().put("name", "var31");
        t31.getProperties().put("value", "xyz");
        c3.getTasks().add(t31);

        Task t41=new Task();
        t41.setDescription("Store var41");
        t41.setDuration(340);
        t41.setPercentage(50);
        t41.getProperties().put("name", "var41");
        t41.getProperties().put("value", "abc");
        c4.getTasks().add(t41);

        Task t42=new Task();
        t42.setDescription("Store var42");
        t42.setDuration(340);
        t42.setPercentage(50);
        t42.getProperties().put("name", "var42");
        t42.getProperties().put("value", "ghj");
        c4.getTasks().add(t42);

        return (ret);
    }
...

Currently available Types of Context are the following.

org.overlord.rtgov.activity.model.Context

package org.overlord.rtgov.activity.model;
...

/**
 * This class represents context information that can be used to
 * correlate this (set of) activity with other activities related
 * to the same business/service transaction.
 *
 */
@Embeddable
public class Context implements .Externalizable {

...
    /**
     * This enumerated type represents the type of the context.
     *
     */
    public enum Type {

        /**
         * A 'conversation id' represents a value that can be used to correlate
         * activities across distributed services. These context types
         * will be globally unique, and may refer to values that are
         * carried in the application message contents.
         */
        Conversation,

        /**
         * The 'endpoint id' type represents an id that may be associated
         * with the executable unit enacting the service/process being monitored,
         * and can therefore be used to correlate local activities as being
         * part of the same executable unit.
         */
        Endpoint,

        /**
         * This context type represents an id associated with a particular message
         * being exchanged between distributed participants.
         */
        Message,

        /**
         * This context type represents an association between two or more activities
         * that will usually be constrained to a specified timeframe.
         */
        Link

    }
...
  • But, just for demonstration purpose, user can use the Value of test from the Call Trace gadget UI to show a demo trace of the business transactions on the gadget window. These details are hard-coded on the same RESTCallTraceServer code as shown above. The attached screenshot CallTrace_Value=test.png shows how it is demonstrated.

  • Although, the FSW 6.0.0 installation ships a sample quickstart at the location jboss-eap-6.1/quickstarts/overlord/rtgov/activityclient/ which demonstrates how they can insert Activity inside RTGov database by the help of ActivityCollector API . But, unfortunately, currently it only inserts transactions with the Context type of Message , and as per current limitation of the Call Trace widget these transaction calls won't be shown in the screen UI. Hence, this quickstart has been modified in it's Master branch in Overlord Community GitHub repository [2] , where users can see sample business transactions, containing the Context type of Conversation in action. The attached screenshot Data_Conversation_CONTEXT.png shows how does the database table records for Conversation type look like after running the modified quickstart. Users can select any VALUE column's data from the database and use it to run the Call Trace gadget by providing the value in the Value parameter in the UI. The screenshot CallTrace_Tree.png demonstrates how a sample call trace look like in the UI of Call Trace gadget for a business transaction.

...
"context":[{
"value":"{ID}-1",
"type":"Message"
},{
"value":"{ID}",
"type": "Conversation"
}]
...
  • Users can also review the client code for reference [3] which uses the ActivityCollector API to do the record(...) operation of the transaction (ActivityType) inside the database tables. There is an id integer data type being used in the code during the creation of the ActivityType. This id would be a unique random value and it is saved as the value to the VALUE column (which is going to be used as searched Value through Call Trace gadget to show the trace of the business transaction) inside RTGOV_ACTIVITY_CONTEXT table. Hence, users need to keep this id handy while trying to run the Call Trace gadget after executing the quickstart. Attached is the quickstart (updated one) for reference. Just extract the attached archive samples_updated.zip , go inside samples/jbossas/activityclient directory and run the command mvn clean install -Dcount=1000 to execute the quickstart. Please note, that while running the quickstart it might ask for credentials, which would be the credentials used to log-in inside /gadget-web URL. A Feature Request [4] also has been raised so that the current quickstart can also be updated to show the usage of other types of Context type , e.g. Conversation .

[0] Call Trace
[1] Call Trace gadget should provide a feature for specifying "type" through the UI
[2] OrderButter.json
[3] ActivityClient.java
[4] RTGov "quickstarts/overlord/rtgov/activityclient/" quickstart only demonstrates insertion of transaction with Context type as "Message"

Attachments

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.

Close

Welcome! Check out the Getting Started with Red Hat page for quick tours and guides for common tasks.