How to use Call Trace gadget of RTGov in FSW 6.0.0 ?
Environment
- Red Hat JBoss Fuse Service Works (FSW)
- 6.0.0
Issue
- While trying to show governance information about SOA services using
RTGovand after changing the property to true onoverlord-rtgov.properties, metrics start showing up on the UI ofhttp://localhost:8080/gadget-web. But the problem is that it does not show any information onCall Tracegadget. 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 Tracegadget is used. As per the documentation available inOverlordforum [0] , theCall Traceservice is used to return a tree structure, tracing the path of a business transaction (as a call/invocation stack) through aService Oriented Architecture. - The
Call Tracegadget needs an input calledValue(which is a globally unique identifier value for the business transaction) from user to displayActivitydetails (which the documentation refers aspath of a business transaction) fetching fromRTGovdatabase tables from the back-end. Users can enter the value to theValueparameter only after clicking the settings icon , seen at the top right corner (middle icon) of the gadget to seek the database records ofActivityfrom the back-end tableRTGOV_ACTIVITY_CONTEXT. Behind the scenes (as ofFSW 6.0.0release) the gadget makes a call to a REST endpoint with the Valuehtp://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.RESTCallTraceServerserver code'sinstance(...)method. Interestingly, although this method takes two parameters (aContext typeandvalue) , but since currently theCall Tracegadget UI only supplies theValue, that is why it only defaults to useConversationas the default acceptedContext typefor filtering activity records from back end database tables. This is a limitation in the currently shippedCall tracegadget UI and aFeature Request[1] has been raised to provide a feature to accepttypeas well from users throughCall Tracegadget 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
Valueoftestfrom theCall Tracegadget UI to show a demo trace of the business transactions on the gadget window. These details are hard-coded on the sameRESTCallTraceServercode as shown above. The attached screenshotCallTrace_Value=test.pngshows how it is demonstrated. -
Although, the
FSW 6.0.0installation ships a sample quickstart at the locationjboss-eap-6.1/quickstarts/overlord/rtgov/activityclient/which demonstrates how they can insert Activity insideRTGovdatabase by the help ofActivityCollectorAPI . But, unfortunately, currently it only inserts transactions with theContext typeofMessage, and as per current limitation of theCall Tracewidget these transaction calls won't be shown in the screen UI. Hence, this quickstart has been modified in it's Master branch inOverlord Community GitHubrepository [2] , where users can see sample business transactions, containing theContext typeofConversationin action. The attached screenshotData_Conversation_CONTEXT.pngshows how does the database table records forConversationtype look like after running the modified quickstart. Users can select anyVALUEcolumn's data from the database and use it to run theCall Tracegadget by providing the value in theValueparameter in the UI. The screenshotCallTrace_Tree.pngdemonstrates how a sample call trace look like in the UI ofCall Tracegadget 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
ActivityCollectorAPI to do therecord(...)operation of the transaction (ActivityType) inside the database tables. There is anidinteger data type being used in the code during the creation of theActivityType. Thisidwould be a unique random value and it is saved as the value to theVALUEcolumn (which is going to be used as searchedValuethroughCall Tracegadget to show the trace of the business transaction) insideRTGOV_ACTIVITY_CONTEXTtable. Hence, users need to keep thisidhandy while trying to run theCall Tracegadget after executing the quickstart. Attached is the quickstart (updated one) for reference. Just extract the attached archivesamples_updated.zip, go insidesamples/jbossas/activityclientdirectory and run the commandmvn clean install -Dcount=1000to 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-webURL. AFeature Request[4] also has been raised so that the current quickstart can also be updated to show the usage of other types ofContext 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.
Welcome! Check out the Getting Started with Red Hat page for quick tours and guides for common tasks.
