wip - add rest intent handling

Change-Id: I6a127c2aaebfcb4915b80625a03d48a12102db77
diff --git a/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java b/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java
old mode 100644
new mode 100755
index 13a0157..e80ef56
--- a/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java
+++ b/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java
@@ -18,7 +18,6 @@
 import net.floodlightcontroller.restserver.IRestApiService;
 import net.onrc.onos.datagrid.web.DatagridWebRoutable;
 import net.onrc.onos.ofcontroller.flowmanager.IFlowEventHandlerService;
-import net.onrc.onos.ofcontroller.flowmanager.PerformanceMonitor.Measurement;
 import net.onrc.onos.ofcontroller.proxyarp.ArpReplyNotification;
 import net.onrc.onos.ofcontroller.proxyarp.IArpReplyEventHandler;
 import net.onrc.onos.ofcontroller.proxyarp.IPacketOutEventHandler;
@@ -44,8 +43,10 @@
 import com.hazelcast.core.EntryListener;
 import com.hazelcast.core.Hazelcast;
 import com.hazelcast.core.HazelcastInstance;
+import com.hazelcast.core.IList;
 import com.hazelcast.core.IMap;
 import com.hazelcast.instance.GroupProperties;
+import net.onrc.onos.intent.Intent;
 
 import net.onrc.onos.ofcontroller.flowmanager.PerformanceMonitor;
 
@@ -109,6 +110,16 @@
     protected static final String arpReplyMapName = "arpReplyMap";
     private IMap<ArpReplyNotification, byte[]> arpReplyMap = null;
     private List<IArpReplyEventHandler> arpReplyEventHandlers = new ArrayList<IArpReplyEventHandler>();
+    
+    
+    protected static final String intentListName = "intentList";
+    private IList<Intent> intentList = null;
+
+    @Override
+    public void registerIntent(Collection<Intent> intents) {
+        intentList.addAll(intents);
+    }
+    
 
     /**
      * Class for receiving notifications for Flow state.
@@ -710,6 +721,9 @@
 
 	arpReplyMap = hazelcastInstance.getMap(arpReplyMapName);
 	arpReplyMap.addEntryListener(new ArpReplyMapListener(), true);
+        intentList = hazelcastInstance.getList(intentListName);
+        
+        
     }
 
     /**
diff --git a/src/main/java/net/onrc/onos/datagrid/IDatagridService.java b/src/main/java/net/onrc/onos/datagrid/IDatagridService.java
old mode 100644
new mode 100755
index 80d1781..d3cf98e
--- a/src/main/java/net/onrc/onos/datagrid/IDatagridService.java
+++ b/src/main/java/net/onrc/onos/datagrid/IDatagridService.java
@@ -3,6 +3,7 @@
 import java.util.Collection;
 
 import net.floodlightcontroller.core.module.IFloodlightService;
+import net.onrc.onos.intent.Intent;
 import net.onrc.onos.ofcontroller.flowmanager.IFlowEventHandlerService;
 import net.onrc.onos.ofcontroller.proxyarp.ArpReplyNotification;
 import net.onrc.onos.ofcontroller.proxyarp.IArpReplyEventHandler;
@@ -20,6 +21,10 @@
  * Interface for providing Datagrid Service to other modules.
  */
 public interface IDatagridService extends IFloodlightService {
+    /*
+     * register all the intents as one batch
+     */
+    void registerIntent(Collection<Intent> intents);
     /**
      * Register Flow Event Handler Service for receiving Flow-related
      * notifications.
diff --git a/src/main/java/net/onrc/onos/datagrid/web/DatagridWebRoutable.java b/src/main/java/net/onrc/onos/datagrid/web/DatagridWebRoutable.java
index 1d3afe7..e0e1666 100644
--- a/src/main/java/net/onrc/onos/datagrid/web/DatagridWebRoutable.java
+++ b/src/main/java/net/onrc/onos/datagrid/web/DatagridWebRoutable.java
@@ -17,6 +17,7 @@
     public Restlet getRestlet(Context context) {
         Router router = new Router(context);
         router.attach("/get/map/{map-name}/json", GetMapResource.class);
+        router.attach("/add/intent/json", IntentResource.class);
         return router;
     }
 
diff --git a/src/main/java/net/onrc/onos/datagrid/web/IntentResource.java b/src/main/java/net/onrc/onos/datagrid/web/IntentResource.java
new file mode 100755
index 0000000..ee1c704
--- /dev/null
+++ b/src/main/java/net/onrc/onos/datagrid/web/IntentResource.java
@@ -0,0 +1,138 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package net.onrc.onos.datagrid.web;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import net.onrc.onos.datagrid.IDatagridService;
+import net.onrc.onos.intent.ConstrainedShortestPathIntent;
+import net.onrc.onos.intent.Intent;
+import net.onrc.onos.intent.IntentDeserializer;
+import net.onrc.onos.intent.ShortestPathIntent;
+import net.onrc.onos.ofcontroller.networkgraph.INetworkGraphService;
+import net.onrc.onos.ofcontroller.networkgraph.NetworkGraph;
+import net.onrc.onos.registry.controller.IControllerRegistryService;
+import net.onrc.onos.registry.controller.IdBlock;
+import org.codehaus.jackson.JsonGenerationException;
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.map.JsonMappingException;
+import org.restlet.resource.Post;
+import org.restlet.resource.ServerResource;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author nickkaranatsios
+ */
+public class IntentResource extends ServerResource {
+
+    private final static org.slf4j.Logger log = LoggerFactory.getLogger(IntentResource.class);
+    private IdBlock idBlock = null;
+    private long nextIdBlock = 0;
+
+    @Post("json")
+    public void store(String jsonFlowIntent) {
+        IDatagridService datagridService =
+                (IDatagridService) getContext().getAttributes().
+                get(IDatagridService.class.getCanonicalName());
+        if (datagridService == null) {
+            log.debug("FlowIntentResource ONOS Datagrid Service not found");
+            return;
+        }
+        INetworkGraphService networkGraphService = (INetworkGraphService)getContext().getAttributes().
+                get(INetworkGraphService.class.getCanonicalName());
+        NetworkGraph graph = networkGraphService.getNetworkGraph();
+        
+        ObjectMapper mapper = new ObjectMapper();
+        JsonNode jNode = null;
+        try {
+            System.out.println("json string " + jsonFlowIntent);
+            jNode = mapper.readValue(jsonFlowIntent, JsonNode.class);
+        } catch (JsonGenerationException ex) {
+            log.error("JsonGeneration exception ", ex);
+        } catch (JsonMappingException ex) {
+            log.error("JsonMappingException occurred", ex);
+        } catch (IOException ex) {
+            log.error("IOException occurred", ex);
+        }
+
+        List<Intent> intents = new ArrayList<>();
+        if (jNode != null) {
+            parseJsonNode(graph, jNode.getElements(), intents);
+            // datagridService.registerIntent(intents);
+        }
+    }
+
+    private void parseJsonNode(NetworkGraph graph, Iterator<JsonNode> nodes, List<Intent> intents) {
+        StringBuilder sb = new StringBuilder();
+        sb.ensureCapacity(256);
+        IntentDeserializer intentDesializer = null;
+        
+        while (nodes.hasNext()) {
+            JsonNode node = nodes.next();
+            if (node.isObject()) {
+                JsonNode data = null;
+                Iterator<String> fieldNames = node.getFieldNames();
+                while (fieldNames.hasNext()) {
+                    String fieldName = fieldNames.next();
+                    data = node.get(fieldName);
+                    if (fieldName.equals("type")) {
+                        if (data != null) {
+                            System.out.println("type is not null " + data.getTextValue());
+                            setPathIntentId(sb);
+                            setPathIntentType(data.getTextValue(), sb);
+                        }
+                    } else {
+                        if (data.isTextual()) {
+                            sb.append(data.getTextValue());
+                        } else if (data.isDouble()) {
+                            Double bandwidth = data.getDoubleValue();
+                            sb.append(bandwidth);
+                        } else if (data.isNumber()) {
+                            Integer number = data.getIntValue();
+                            sb.append(number);
+                        }
+                    }
+                }
+                System.out.println("constructed node " + sb.toString());
+                sb.delete(0, sb.length());
+                intentDesializer = new IntentDeserializer(graph, sb.toString().getBytes());
+                Intent intent = intentDesializer.getIntent();
+                intents.add(intent);
+            }
+        }
+
+    }
+    
+    private void setPathIntentId(StringBuilder sb) {
+        if (idBlock == null || nextIdBlock + 1 == idBlock.getSize()) {
+            IControllerRegistryService controllerRegistry = getControllerRegistry();
+            if (controllerRegistry != null) {
+                idBlock = controllerRegistry.allocateUniqueIdBlock();
+                nextIdBlock = idBlock.getStart();
+                System.out.println("start block " + nextIdBlock + " end block " + idBlock.getEnd() + " size " + idBlock.getSize());
+            }
+        }
+        if (idBlock != null) {
+            sb.append(nextIdBlock);
+            nextIdBlock++;
+        }
+    }
+    
+    private void setPathIntentType(final String pathIntentType, StringBuilder sb) {
+        if (pathIntentType.equals("shortest-path")) {
+            sb.append(ShortestPathIntent.class.getCanonicalName());
+        } else if (pathIntentType.equals("constrainted-shortest-path")) {
+            sb.append(ConstrainedShortestPathIntent.class.getCanonicalName());
+        }
+    }
+    
+    private IControllerRegistryService getControllerRegistry() {
+        return (IControllerRegistryService) getContext().getAttributes().get(IControllerRegistryService.class.getCanonicalName());
+    }
+}