Tuesday, November 05, 2013

Self Monitoring Processor Design for a State Machine Implementation

Self Monitoring Processor Design for a FSM

Using the Runnable and Callable interface as well as the Java 6 ThreadPool classes to create a class design that not only executes a task, but can monitor the execution progress periodically Here is how the interface looks like. Note that each processor has an associated ‘State’ and each state has a status - like ex scheduled, started, awaiting_async, success , fail ,timeout etc. This is because the IProcessor class is also used to implement a state machine.I won't be going through this part in more detail here.
 
public interface IProcessor extends Runnable,
  Callable {

  ProcessingStatus getCurrentStatus();
ProcessingState getCurrentState();

ProcessingStatus execute();
Future getTask();

void setScheduledFutureHandle(ScheduledFuture handle);

Now we define an Abstract class that does the basic work
 

public abstract class Processor implements IProcessor,
  Comparable {

@Override
//Method which does the actual work
public ProcessingStatus call() throws InterruptedException {
..
//Actual execution is delegated to the subclass
currentStatus = execute();
...
}
//Method which is called from the Scheduled Thread Pool , and which  //monitors the state of the task; ex if it is running beyond timeout, //putting it to timeout etc , basically Task Status Monitoring
@Override
public void run() {
}
All other different Processor classes will just have to inherit and implement the execute method
 
public class ProcessorStateX extends Processor {


       /**
  * execute method will be called as part of the processor execution
  */
 public ProcessingStatus execute() {
               //do some StateX related work
 }
Now these tasks will be created and pushed to a Input queue and from there a controlling class will take this and add this to a Thread Pool; Let us see how it is done
 
public class StateController{


private ExecutorService fxdpool = null;
private ScheduledExecutorService pool = null;


//Create the ThreadPools
public void startStateController(){


this.fxdpool = Executors.newFixedThreadPool(FIXED_THREADPOOL_COUNT_2);
this.pool = Executors.newScheduledThreadPool(SCHEDULED_THREADPOOL_COUNT_4);
}


//The method that takes from the input queue and adds it to the ThreadPool
//@processor is what is present in the Task Completed queue
private void pollTaskQueueAndExecute(IProcessor processor) throws InterruptedException {


//This passes in the current completed (success or failed ) processor and looks up a state flow xml to create a next processor that represents the next state in the State Machine
taskProcessor = getNextProcessor(processor);


  //send it for execution
  //Will call Processor::call method
Future unusedFuture = fxdpool.
              submit((Runnable) taskProcessor.getTask());


 if (unusedFuture.isCancelled()) {
       log.info("Task has been cancelled :"
       + taskProcessor.getTask());
 }
  //Create a scheduled checker for the task- Task Self monitoring
  // Will call Processor::run method
  final ScheduledFuture handle = pool.scheduleAtFixedRate(
      taskProcessor, 0,      taskProcessor.getPeriodicExecutionInterval(),
      TimeUnit.MILLISECONDS);
}


}
Thats about it. And here is the method in the SiteController that causes the transition between different states, which basically implements the FSM.

Wednesday, April 10, 2013

OpenLayers Advanced Clustering and Setting dynamic images for OpenLayer Styles via Ajax


OpenLayers Advanced Clustering and Setting dynamic images  for OpenLayer Styles via Ajax


JSFiddle Source for this Tutorial
Let us start with a simple OpenLayer map In the JSP or the HTML we have


<head>
<script src="http://openlayers.org/api/OpenLayers.js"></script>
<script type="text/javascript"
 src="<%=request.getContextPath()%>/js/maplister.js"></script>
<script type="text/javascript"
 src="<%=request.getContextPath()%>/js/jquery-1.7.2.min.js"></script>
<script src="http://maps.google.com/maps/api/js?v=3&amp;sensor=false"></script>
</head>

<body>
<div id="map-id" style="height:100%;width=100%"></div>
</body>
And on document load AUI().ready(function(X) { resize("scMapListerportlet", "#map-id"); var iconpath ="<%=request.getContextPath()%>/images"; LayerCreationModule.initOpenLayerMap(24.938622,60.170421,iconpath,OpenLayers); var url = '<%=ajaxCallResourceURL.toString()%>'; LayerCreationModule.setUrlForDynamicImage(url);
var initOpenLayerMap = function(lat,long,path,openLayerP){
  
  openLayerObj=openLayerP;
  _projection = new openLayerObj.Projection("EPSG:4326");
  _bounds = new openLayerObj.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34);


  var mapControls = [ new openLayerObj.Control.Navigation(),
                      new openLayerObj.Control.PanZoomBar(),
                      new openLayerObj.Control.ScaleLine(),
                      new openLayerObj.Control.LayerSwitcher(),
                      new openLayerObj.Control.MousePosition(),
                      new openLayerObj.Control.Attribution() ];
  iconpath=path;
  map = new openLayerObj.Map({
   div:"map-id",
   allOverlays: true,
   //projection : 'EPSG:3857', //Spherical Mercator, but no need to specify heree
   displayProjection: _projection,
   maxResolution:'auto',
   units: "degrees",
   controls : mapControls,
   eventListeners : {
    'zoomend' : adjustMarkerStyle
   }
  });

                //Add the OpenSteetMap and GoogleMap Baselayers
  var osm = new openLayerObj.Layer.OSM("OpenStreeMap");
 
  var gmap =  new openLayerObj.Layer.Google("Google Streets", 
    {type: google.maps.MapTypeId.ROADMAP, 
   sphericalMercator:true, 
   'maxExtent': _bounds,visibility:false});


  map.addLayers([osm,gmap]);

This will give you the open layers map with two base layers - Google Maps and OpenStreet Map selected. This is straight enough except for the fact that you need to understand a little about Map Projections 

OpenStreetMap, Google Maps, Yahoo Map etc use a projection called the Spherical Mercator projection. This treats the globe as a perfect sphere. Spherical Mercator has an official designation of EPSG:3857. You can convert a given longitude,latitude to the map projection using the OpenLayers method as shown below. For more details regarding projections kindly read http://docs.openlayers.org/library/spherical_mercator.html

_projection = new openLayerObj.Projection("EPSG:4326");

    var covertlatitudelong = function (lat, long) {

        var lonlatObject = new OpenLayer.LonLat(lat, long).transform(
        _projection, map.getProjectionObject() //Speherical Meracao
        );
        return lonlatObject;

    };

Layers and Style - Relationship

  Let us create a layer and find out how layer and Style are related

 summary_layer = new openLayerObj.Layer.Vector("SummaryLayer", {
            styleMap: smapCluster,
            renderers: ['Canvas', 'SVG'],
            strategies: [new openLayerObj.Strategy.Cluster({
                "distance": 20
            })]

Now the million dollar insight about manipulating layer is via the StyleMap. It is easy enough once you know that it is important; If you thought initially that it is something to do with Style and ignore it, then you are going to miss the bus;


      var smapCluster = new openLayerObj.StyleMap({
            'default': pointStyleforCluster,
                'select': new openLayerObj.Style({
                pointRadius: "${radius}",
                fillColor: "yellow"

            })
        });
What we do here is to create a Style map and tell that for 'default' rendering use the pointStyleforCluster and in-case someone selects the feature apply the style listed for 'select' So let us see the full gamut of Style (take a peek below). There are two ways of specifying 'Style'. One via Static attributes and one via Dynamic attributes. Take the case of pointRadius. One can set a static value to it say 50 , and set the fillColor attribute to 'blue'. Then any feature ( for the time being think about a feature as a point in the map) added to this layer will have a blue circle seen in the map; Now what if we want to change the color of the feature based on a Custom Attribute for a feature we need to specify it as a dynamic attribute like "${fcolor}" and then in the context section add a function that takes a feature as an argument and based on some logic or attribute in the feature returns a specific color

 //styling for drawing
        var pointStyleforCluster = new openLayerObj.Style({
            fill: false,
            pointRadius: "${radius}", //default shape that is drawn is a circle with this radisu
            externalGraphic: "${chartUrl}", //this could be any url that returns an image
           // strokeColor: "red",
            fillColor: "${fcolor}", //fill color of the circle
            strokeOpacity: 0,
            fillOpacity: 0.5,
            strokeWidth: "${strokeWidth}",
            label: "${label}",// Text that will be visible for the feature
            labelOutlineWidth:1,
            //fontWeight: "bold",
            //fontColor:  "#ffffff",
            fontColor:  "black",
            fontOpacity: "0.8",
            fontSize: "10px"
            // ...
        }, {
            context: {

               label: function(feature) {

     if(feature.cluster){

      var clustercount = getClusterCount(feature);
      return  clustercount.planningCount +"/" +
      clustercount.inerrorCount+ "/" + clustercount.onairCount;
     }
     else{
      return "";
     };

    },
                radius: function (feature) {
                    //var pix = 2;
                    if (feature.cluster) {
                        return adjustMarkerStyle();
                    } else {
                        return 100;
                    };

                },
                fcolor: function (feature) {

                    if (feature.cluster) {
                        var cc = getClusterCount(feature);
                        if (cc.attributeCount != 1) {//This means it is clustered
                            return "blue";
                        }
                        if (cc.planningCount === 1) {
                            return "#cf33e1";
                        }
                        if (cc.inerrorCount === 1) {
                            return "#ff0000";
                        }
                        if (cc.onairCount === 1) {
                            return "#2da725";
                        }

                    } else {
                        return "grey";
                    };
                },
                strokeWidth: function (feature) {

                    if (feature.cluster) {
                        return adjustMarkerStyle() * 2;
                    };
                },

                chartUrl: function (feature) {

                    //..Draw a dynamic chart
        });

Adding Feature to a Layer with a Custom Attribute

We can add either a simple point or a geometric shape to a Feature and then add set of Features to the Layer (to which the style map is associated). For example if we add a Point to a feature,then the radius of the style map associated with the Layer will be taken to draw a circle with the Point as the Center. Similarly if we create a Polygon and add it to the Feature and add the feature to the Layer , the fillColor of the Polygon will be the one associated in the Style

 var features = layer.features;//If the layer has features already store it temporarily.

 var polygon = OpenLayer.Geometry.Polygon.createRegularPolygon(point, 50, 22, 0);
        var feature = new openLayerObj.Feature.Vector(polygon, {
            fcolor: color,// this is a custom attribute of this feature
            name: "Polygon"
        });

        features.push(feature);
        layer.removeAllFeatures();// A Quirk in the OpenLayer, remove all and push all features at one go for clustering especially to work)
        layer.addFeatures(features);

//OR Adding a Point and Custom Attribute

var lonlatObject = covertlatitudelong(lat, long);
        var point = new OpenLayer.Geometry.Point(lonlatObject.lon, lonlatObject.lat);


var  customAttr = "plan";

 var feature2 = new openLayerObj.Feature.Vector(point, {
            customAttr: customAttr// this is a Custom Attribute of the Feature
       
        });

        var summaryfeatures = summary_layer.features;
        summary_layer.removeAllFeatures();
        summaryfeatures.push(feature2);

Where to access and use the Custom Attributes added to the Feature

Okay now since we have the custom attributes and features in place let us see how to use them. Before that let us take a look at Clustering because the example I have given is heavily based on that and the custom attributes are added to the Layer with Clustering. So it would be better to explain if first. A cluster strategy is added to the Layer. Below we have a distance based simple Cluster ; If two features in the Map are within 20 pixels of each other , at any given Zoom level then it will create one new feature to represent both the separate points

 summary_layer = new openLayerObj.Layer.Vector("SummaryLayer", {
            styleMap: smapCluster,
            renderers: ['Canvas', 'SVG'],
            strategies: [new openLayerObj.Strategy.Cluster({
                "distance": 20
            })]
Once clustering is active, every time the bound of the map gets invalidated by the user zooming or panning the features get redrawn and the functions in the context associated with the Style Map gets called. So suppose we have only one layer which is clustered- say the SummaryLayer, and we want to print a text which has the count of the number of types of custom attribute are present in a clustered layer. Let us see how we do it.

//Code snippet from the Context part of the StyleMap

  context: {

               label: function(feature) {

     if(feature.cluster){

      var clustercount = getClusterCount(feature);
      return  clustercount.planningCount +"/" +
      clustercount.inerrorCount+ "/" + clustercount.onairCount;
      
     }
     else{
      return "";
     };

    },

Here we see that we are calling a function and passing in the feature. Let us take a look at the the getClusterCount function. The feature.cluster[i].attributes.. will give the list of feature attributes that are going to be replaced. So if we have added any custom attribute it should be added to the feature.attributes . Otherwise the next time clustering is called your Custom attribute may not be there in the clustered feature. Next as we can see we are just accessing the value of the customAttr and incrementing a number to count it. This is returned back and printed in the label. This same information can be send to the server via the externalGraphics url, a graph created on the fly and a png image of the graph generated and send as response to GET request of the externalGraphics URL

 var getClusterCount = function (feature) {

        var clustercount = {};
        var planningcount = 0;
        var onaircount = 0;
        var inerrorcount = 0;

        for (var i = 0; i < feature.cluster.length; i++) {

            if (feature.cluster[i].attributes.cluster) {
            //THE MOST IMPORTANT LINE IS THE ONE BELOW, While clustering open layers removes the orginial feature layer with its own. So to get the attributes of the feature you have added add it to the openlayer created feature layer
                feature.attributes.customAttr = feature.cluster[i].attributes.customAttr;
                switch (feature.cluster[i].attributes.customAttr) {

                    case "plan":
                        // plan
                        planningcount = planningcount + 1;
                        break;
                    case "error":
                        // error
                        inerrorcount = inerrorcount + 1;
                        break;
                    case "air":
                        // onair
                        onaircount = onaircount + 1;
                        break;
                }
            };

        }
        clustercount.planningCount = planningcount;
        clustercount.inerrorCount = inerrorcount;
        clustercount.onairCount = onaircount;
        clustercount.attributeCount = feature.attributes.count;
        // console.log(clustercount);
        return clustercount;
    };

Code snippet for generating the Pie Graph image from data in the URL .

 public void serveResource(ResourceRequest resourceRequest,
   ResourceResponse resourceResponse) throws IOException,
   PortletException {

  try {

   System.out.println("server function called");

   System.out.println("MapLister AJAX - image request");

   String onair = resourceRequest.getParameter("onair");
   String inerror = resourceRequest.getParameter("inerror");
   String inplanning = resourceRequest.getParameter("inplanning");

   System.out.println("onair="+onair+" inerror="+inerror+" inplanning="+inplanning);

   int width = 155;
   int height = 155;
   resourceResponse.setContentType("image/png");
   JFreeChart chart=createChart(new Integer(onair),new Integer(inerror),new Integer(inplanning));
   OutputStream out=resourceResponse.getPortletOutputStream();
   ChartUtilities.writeChartAsPNG(out, chart, width, height,true,0);
  

  } catch (Exception e) {
   System.out.println("Exception caused "+ e);
  }

 }

Install/Upgrade NVIDI Driver in Ubuntu for CUDA SDK

Most linux distribution comes with the Nouveau https://nouveau.freedesktop.org/wiki/ display driver configured. If you need to use NVIDIA...