wip:fix destination port problem

Change-Id: If8ec9e2d43ea2c7b68e78380e0de9f67634d2b7e
diff --git a/src/main/java/net/onrc/onos/datagrid/web/IntentResource.java b/src/main/java/net/onrc/onos/datagrid/web/IntentResource.java
index db2c38a..416ab76 100755
--- a/src/main/java/net/onrc/onos/datagrid/web/IntentResource.java
+++ b/src/main/java/net/onrc/onos/datagrid/web/IntentResource.java
@@ -5,13 +5,10 @@
 package net.onrc.onos.datagrid.web;
 
 import java.io.IOException;
-import java.util.ArrayList;
+import java.util.Collection;
 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;
@@ -24,115 +21,170 @@
 import org.restlet.resource.ServerResource;
 import org.codehaus.jackson.map.ObjectMapper;
 import org.slf4j.LoggerFactory;
+import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.ofcontroller.networkgraph.Port;
+import net.onrc.onos.ofcontroller.networkgraph.Switch;
+import com.esotericsoftware.kryo.Kryo;
+import com.esotericsoftware.kryo.io.Input;
+import com.esotericsoftware.kryo.io.Output;
 
 /**
- *
+ * 
  * @author nickkaranatsios
  */
 public class IntentResource extends ServerResource {
 
-    private final static org.slf4j.Logger log = LoggerFactory.getLogger(IntentResource.class);
+    private final static org.slf4j.Logger log = LoggerFactory
+	    .getLogger(IntentResource.class);
+    private final String sep = ":";
     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);
-        }
+	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();
 
-        List<Intent> intents = new ArrayList<>();
-        if (jNode != null) {
-            parseJsonNode(graph, jNode.getElements(), intents);
-            // datagridService.registerIntent(intents);
-        }
+	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);
+	}
+
+	if (jNode != null) {
+	    Kryo kryo = new Kryo();
+	    parseJsonNode(kryo, jNode.getElements(), datagridService);
+	    // 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(sb.toString().getBytes());
-                Intent intent = intentDesializer.getIntent();
-                intents.add(intent);
-            }
-        }
+    private void parseJsonNode(Kryo kryo, Iterator<JsonNode> nodes,
+	    IDatagridService datagridService) {
+	StringBuilder sb = new StringBuilder();
+	sb.ensureCapacity(256);
 
+	while (nodes.hasNext()) {
+	    JsonNode node = nodes.next();
+	    if (node.isObject()) {
+		JsonNode data = null;
+		Iterator<String> fieldNames = node.getFieldNames();
+		String intentId = null;
+		String pathTypeName = null;
+		long srcSwitch = 0, dstSwitch = 0;
+		String srcMac = null, dstMac = null;
+		long srcPort = 0, dstPort = 0;
+		Double bandwidth = null;
+		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());
+			    // uuid = setPathIntentId();
+			    pathTypeName = data.getTextValue();
+			    setPathIntentType(pathTypeName, sb);
+			}
+		    } else if (fieldName.equals("intentId")) {
+			intentId = data.getTextValue();
+		    } else if (fieldName.equals("srcSwitch")) {
+			srcSwitch = Long.decode(data.getTextValue());
+		    } else if (fieldName.equals("dstSwitch")) {
+			dstSwitch = Long.decode(data.getTextValue());
+		    } else if (fieldName.equals("srcMac")) {
+			srcMac = data.getTextValue();
+		    } else if (fieldName.equals("dstMac")) {
+			dstMac = data.getTextValue();
+		    } else if (fieldName.equals("srcPort")) {
+			srcPort = data.getLongValue();
+		    } else if (fieldName.equals("dstPort")) {
+			dstPort = data.getLongValue();
+		    } else if (fieldName.equals("bandwidth")) {
+			bandwidth = data.getDoubleValue();
+		    }
+		}
+		if (pathTypeName.equals("shortest-path")) {
+		    ShortestPathIntent spi = new ShortestPathIntent(intentId, 
+                            srcSwitch, 
+                            srcPort, 
+                            MACAddress.valueOf(srcMac).toLong(), 
+                            dstSwitch, 
+                            dstPort,
+			    MACAddress.valueOf(dstMac).toLong());
+		    sb.append(toBytes(kryo, spi));
+
+		} else {
+		    ConstrainedShortestPathIntent cspi = new ConstrainedShortestPathIntent(intentId, 
+                            srcSwitch, 
+                            srcPort, 
+                            MACAddress.valueOf(srcMac).toLong(), dstSwitch,
+			    dstPort, MACAddress.valueOf(dstMac).toLong(),
+			    bandwidth);
+		    sb.append(toBytes(kryo, cspi));
+
+		}
+		System.out.println("constructed node " + sb.toString());
+		// datagridService.registerIntent(Long.toString(uuid),
+		// sb.toString().getBytes());
+		sb.delete(0, sb.length());
+	    }
+	}
     }
-    
-    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 long setPathIntentId() {
+	long uuid = 0;
+	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) {
+	    uuid = nextIdBlock;
+	    nextIdBlock++;
+	}
+	return uuid;
     }
-    
+
     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());
-        }
+	String canonicalName = null;
+	if (pathIntentType.equals("shortest-path")) {
+	    canonicalName = ShortestPathIntent.class.getCanonicalName();
+	    sb.append(ShortestPathIntent.class.getCanonicalName());
+	} else if (pathIntentType.equals("constrained-shortest-path")) {
+	    canonicalName = ShortestPathIntent.class.getCanonicalName();
+	}
+	sb.append(canonicalName);
+	sb.append(sep);
     }
-    
+
     private IControllerRegistryService getControllerRegistry() {
-        return (IControllerRegistryService) getContext().getAttributes().get(IControllerRegistryService.class.getCanonicalName());
+	return (IControllerRegistryService) getContext().getAttributes().get(
+		IControllerRegistryService.class.getCanonicalName());
+    }
+
+    private byte[] toBytes(Kryo kryo, Object value) {
+	Output output = new Output(1024);
+        kryo.writeObject(output, value);
+        output.close();
+        return output.toBytes();
     }
 }
diff --git a/web/add-intent.rb b/web/add-intent.rb
new file mode 100644
index 0000000..1b480b3
--- /dev/null
+++ b/web/add-intent.rb
@@ -0,0 +1,126 @@
+require "rest-client"
+require "optparse"
+
+
+options = { :intent_id => 123, :path_intent => "shortest_path_intent", :max_switches => 4 }
+
+parser = OptionParser.new do |opts|
+  opts.banner = "Usage add-intent [options]"
+  opts.on('-t', '--max_intents max_intents', 'max. number of intents') do |max_intents|
+    options[:max_intents] = max_intents
+  end
+  opts.on('-a', '--application application_id', 'set application id') do |appl_id|
+    options[:application_id] = appl_id
+  end
+  opts.on('-i', '--intent_id intent_id', 'global intent id') do |id|
+    options[:intent_id] = id
+  end
+  opts.on('-s', '--shortest path intent', 'create a shortest path intent') do
+    options[:path_intent] = "shortest_path_intent"
+  end
+  opts.on('-c', '--constrained shortest path intent', 'create a constrained shortest path intent') do |cspi|
+    options[:path_intent] = "constrained_shortest_path_intent"
+  end
+  opts.on('-m', '--max_switches max_switches', 'max. number of switches') do |max_switches|
+    options[:max_switches] = max_switches;
+  end
+  opts.on('-h', '--help', 'Display help') do
+    puts opts
+    exit
+  end
+end
+parser.parse!
+
+puts options.inspect
+server = options[:server] || "127.0.0.1"
+port = options[:port] || 8080
+
+def rand_mac
+  mac = `openssl rand -hex 6`
+  mac.scan(/(..)/).join(":")
+end
+
+def rand_switch
+  switch = `openssl rand -hex 5`.chomp
+end
+
+class Intent
+  attr_reader :switches, :ports, :intent_id, :application_id
+
+  def initialize options
+    parse_options options
+  end
+
+  def create_intent 
+    json_intents = []
+    @switches.each do |sw|
+      rest = switches - [sw]
+      json_intents = _create_intent sw, rest, json_intents
+    end
+puts json_intents.inspect
+  end
+
+  def parse_options options
+    max_switches = options[:max_switches].to_i || 4
+    @switches = (1..max_switches).to_a
+    @ports = (1..(max_switches - 1)).to_a
+    @intent_id = options[:intent_id].to_i || 1
+    @application_id = options[:application_id].to_i || 1
+  end
+
+
+  def _create_intent src_switch, iterable_switches, json_intents
+    iterable_switches.each_index do |sw_i|
+      dst_switch = iterable_switches[sw_i]
+      sw_set = @switches - [dst_switch]
+      dst_port = sw_set.index(src_switch)
+      dst_port = dst_port + 1
+      intent = {
+        :applicationId => @application_id,
+        :intentId => @intent_id,
+        :srcSwitch => src_switch.to_s,
+        :srcPort => @ports[sw_i],
+        :srcMac => "00:00:00:c0:a8:01:#{@ports[sw_i]}",
+        :dstSwitch => iterable_switches[sw_i],
+        :dstPort => dst_port,
+        :dstMac => "00:00:00:c0:a8:01:#{dst_port}"
+      }
+      @intent_id = @intent_id + 1
+      json_intents << intent
+    end
+    #sha256 = Digest::SHA256.new
+    #sha256.update intent_hash.to_s
+    #puts sha256.hexdigest
+    #puts "intent hash = #{intent_hash}"
+    json_intents
+  end
+end
+
+# the program accepts the number of switches and ports and outputs a number of intents
+json_data = [{
+  :intentId => 12345,
+  :type => "shortest-path", 
+  :srcSwitch => "0x0000000000000001", 
+  :srcPort => 1, 
+  :srcMac =>"#{rand_mac}", 
+  :dstSwitch => "0x0000000000000002",
+  :dstPort => 4, 
+  :dstMac => "00:00:00:00:00:02"} 
+#  {:type => "constrained-shortest-path", 
+#  :srcSwitch => "0x#{rand_switch}",
+#  :srcPort => 2, 
+#  :srcMac => "00:00:00:00:00:11", 
+#  :dstSwitch => "0x#{rand_switch}",
+#  :dstPort => 3, 
+#  :dstMac => "00:00:00:00:00:22", 
+#  :bandwidth => 5.0 }
+]
+#puts json_data.to_json
+
+
+ports = [1,2,3]
+switches = [1,2,3,4]
+intent = Intent.new options
+json_data = intent.create_intent
+#response = RestClient.post 'http://#{server}:#{port}/wm/onos/datagrid/add/intent/json', json_data.to_json, :content_type => :json, :accept => :json
+#puts response.inspect