Enterprise Integration Zone is brought to you in partnership with:

Senior consultant at Apogado, living in Antwerpen, married, playing GO (13k EGF), exercising martial arts (4D) Gabriel has posted 1 posts at DZone. You can read more from them at their website. View Full User Profile

Trip to the client side - HTML5 client for the Talend ESB Activity Monitor

12.31.2013
| 1045 views |
  • submit to reddit

Introduction

Talend ESB includes the SAM (Service Activity Monitoring) – a feature gathering and storing web service messages along some metadata. To display the stored event data the Talend offers a monitoring UI as a part of their commercial offering (subscription).

The SAM bundles include a REST service enabling simple access to the stored events. To have a real production monitoring one needs much more (search, filters, views, ..). Therefore for heavy-duty usage the clients should use the Talend Administration or a full blown monitoring solutions (Hyperic HQ, Nagios, LEK (LogStash/ElasticSearch/Kibana), etc). I found these SAM basic services particularly useful for simple logging and monitoring during development or production in its early phase.

I consider myself a server-side expert. Very competent in the system integration domain and as well in the server side development. When creating a user interface, I rely mostly on the JSF (Icefaces). So as a part of our integration solution I built a nice JSF web application with paginated table and views displaying event details.

And I got an idea. There’s a lot of buzz about HTML5 and client side applications, however – I’ve got proven distrust to anything based on JavaScript. Few years back one needed to test any JS functionality on all browsers with no warranty it will still work in a few weeks. But – maybe it’s time I give it another chance.
Let’s try to build a simple client over the services providing the logged data. It will be a nice exercise and as well an opportunity to learn something new. Another advantage would be, that a lighter application could run from the ESB itself without need of an external web server (in the real-life scenarios, there’s a web/app server present anyway).

Client application

Lets start simple. My idea was to have a table with server-side pagination.

Apparently – many people start learning new UI technologies with such an example, as it seems very practical and useful. However – it is not as simple as it seems. To have a paginated table, we need multiple components playing together. This exercise is far from a good step-by-step exercise. And I assume the reader know many things, so I skip things I consider granted and clear. As I can be pretty stubborn sometimes, I will go on with this idea.

So – we will

  • create a table
  • load data from an external service
  • paginate the data on the server-side

Another point – I am really no expert in the JS / HTML5 / CSS domain. If you find any way to improve it, give a constructive advice, you are really welcome. I took this task as an opportunity to learn and if you are willing to share too, it would be very appreciated.

Client services

This blog is not about the Talend ESB, nor the SAM itself, but if you want to start use it, I’ll give you a small hint:
- download and install the Talend ESB
- install the tesb-sam-* features

What I particularly like on this solution is, that the monitoring agent is implemented as a CXF feature. It means that it takes almost no effort to enable monitoring on existing services and it doesn’t touch framework libraries.

To get the SAM data, user can call the list REST service:
http://server:port/services/sam/list with optional parameters offset and limit.

For simplified testing, I’ve stored a sample output from the service
https://bitbucket.org/gusto2_/sam-ui2/src/15074b814e0a2b904b463daf959696e60f3281b0/src/main/webapp/data.json?at=master so we can play locally too.

YUI Library

YUI is a free, open source JavaScript and CSS library for building rich interactive web applications. http://yuilibrary.com/
Now – many of you may ask why did I choose the YUI Library. People use other frameworks too (jQuery, AngularJS, ..). Well, there is no apparent reason. Simply – I like the default skin design. Now it reminds me how I felt, when my mother chose her car based on its color. Simply – I chose one of many options. But the principles stay more or less the same.

Resources:
http://yuilibrary.com/
http://stlsmiths.github.io/blunderalong/index.html

Client application

YUI implementation

for start we will do only the main activity table, we won’t go to master / detail views, etc.
This is the whole implementation with comments

<html>
  <head>
  <title>YUI test</title>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <script type="text/javascript" src="http://yui.yahooapis.com/3.14.0/build/yui/yui-min.js"></script>
  <link rel="stylesheet" href="apogado-css.css" />
  </head>
  <body>
  <div>
  <div id="messages"></div>   
  <div id="mainTable"></div>
  <div id="mainTablePaginator"></div>
  <script type="text/javascript">
  YUI().use(
  // modules to work with datatable,
  // data source and json datasource
  'datatable-base', 'datatype-date',
  'datasource-io', 'datasource-jsonschema',
  'datatable-datasource',
  // gallery paginator
  'gallery-datatable-paginator', 'gallery-paginator-view',
  // node for displaying messages
  'node',
  function(Y) {
  // function to display response status messages
  function displayMessage(msg)
  {
  var msgElement = Y.one('#messages');
  msgElement.setHTML(msg);
  }

  var mainTable = new Y.DataTable(
  {
  columns: [
  {
  key: "flowID",
  formatter: function(o) {
  return '<img src="./arrow-next.gif"/>'
  },
  allowHTML: true
  },
  {  // convert long to readable
  // datetime format
  key: "timestamp",
  formatter: function(o) {
  return Y.Date.format(new Date(o.value), {format: '%Y-%m-%d %H:%M:%S'});
  }
  },
  'operation', 'port', 'elapsed', 'types',
  'providerIP', 'providerHost'],
  paginator: new Y.PaginatorView({
  model: new Y.PaginatorModel(
  {page: 1, itemsPerPage: 10}),
  container: '#mainTablePaginator',
  // display only reasonable amount 
  // of links
  maxPageLinks: 5
  }),
  // use server side pagination
  paginationSource: 'remote',
  // request template for each page
  requestStringTemplate: '?page={page}&limit={itemsPerPage}',
  }
  );
  // define datasource
  var dataSource = new Y.DataSource.IO({
  source: './camel/sam/list',
  });
  // event handler, in this case we display 
  // status code and status message
  dataSource.on('response', function(e) {
  displayMessage(e.data.status + ' '+e.data.statusText);
  });   
  // datasource produces JSON data
  // we need to map the result to columns
  dataSource.plug(Y.Plugin.DataSourceJSONSchema,
  {
  schema: {
  resultListLocator: 'aggregated',
  resultFields: [
  'timestamp', 'operation', 'port',
  'elapsed', 'types', 'flowID',
  'providerIP', 'providerHost'
  ],
  // necessary the server-side
  // pagination to work
// NOTE: It is ESSENTIAL that your response includes meta data 
// for totalItems, otherwise the paginator won't render.
//http://yuilibrary.com/gallery/show/datatable-paginator

  metaFields: {
  // the ‘count’ parameter reflects the count element in the 
  // returned data   
  totalItems: 'count'
  }
  }
  });

  // tell the table to use the datasource
  mainTable.plug(Y.Plugin.DataTableDataSource,
  {
  datasource: dataSource,
  // if initialRequest defined, 
  // a request is issued as soon
  // as the TableDataSource is initialized
  initialRequest: ''
  });
  mainTable.render('#mainTable');
  });
  </script>
  </div>
  </body>
</html>

sam-ui2

Parameter consideration

The SAM resource REST service URL looks as follows

http://server:port/services/sam/list?offset=...&[limit=...]]

and the paginated DataTable sends request in the format

http://server:port/…?page=…&limit=..

so we need to create means to transform page to the offset. [offset=(page-1)*limit]

I didn’t find a reasonable way to do it at the UI level. When I consider back, the paginator works on pages, not offsets, so we won’t force the tool where not appropriate. As a result I created a Camel route transforming the page parameter to the offset. There are two advantages of this approach. first – I can do it quickly. Second – we can treat (secure) the service endpoint as a part of the application.

Follow up

I’ve created a client application with detail views, see

https://bitbucket.org/gusto2_/sam-ui2

there are two build profiles – run-on-karaf and run-on-tomcat. I hope they are self-explanatory. To run on karaf, one must install camel-cxf and spring-web features too.

Conclusion

We have a light and quick client application, which even looks nice. It didn’t take a lot of time to learn it and mainly – it didn’t hurt.. much :)
Published at DZone with permission of its author, Gabriel Vince.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)