Rest-intent
- add get intent by id
- fix problem of not returning the correct intent id at creation to UI.
- create script for mesh mininet topology
Change-Id: I5fc4f008ab2d31a63d222f3e42502408dc25fe6b
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 99f79fc..28399c8 100755
--- a/src/main/java/net/onrc/onos/datagrid/web/DatagridWebRoutable.java
+++ b/src/main/java/net/onrc/onos/datagrid/web/DatagridWebRoutable.java
@@ -19,6 +19,7 @@
router.attach("/get/map/{map-name}/json", GetMapResource.class);
router.attach("/add/intents/json", IntentResource.class);
router.attach("/get/intents/json", IntentResource.class);
+ router.attach("/get/intent/{intent_id}/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
index daf786f..7a2cdd9 100755
--- a/src/main/java/net/onrc/onos/datagrid/web/IntentResource.java
+++ b/src/main/java/net/onrc/onos/datagrid/web/IntentResource.java
@@ -105,17 +105,29 @@
getAttributes().get(IPathCalcRuntimeService.class.getCanonicalName());
ObjectMapper mapper = new ObjectMapper();
String restStr = "";
+
+ String intentId = (String) getRequestAttributes().get("intent_id");
ArrayNode arrayNode = mapper.createArrayNode();
IntentMap intentMap = pathRuntime.getHighLevelIntents();
Collection<Intent> intents = intentMap.getAllIntents();
if (!intents.isEmpty()) {
- for (Intent intent : intents) {
- ObjectNode node = mapper.createObjectNode();
- node.put("intent_id", intent.getId());
- node.put("status", intent.getState().toString());
- arrayNode.add(node);
- restStr = mapper.writeValueAsString(arrayNode);
+ if ((intentId != null )) {
+ Intent intent = intentMap.getIntent(intentId);
+ if (intent != null) {
+ ObjectNode node = mapper.createObjectNode();
+ node.put("intent_id", intent.getId());
+ node.put("status", intent.getState().toString());
+ arrayNode.add(node);
+ }
+ } else {
+ for (Intent intent : intents) {
+ ObjectNode node = mapper.createObjectNode();
+ node.put("intent_id", intent.getId());
+ node.put("status", intent.getState().toString());
+ arrayNode.add(node);
+ }
}
+ restStr = mapper.writeValueAsString(arrayNode);
}
return restStr;
}
@@ -146,9 +158,8 @@
private void appendIntentStatus(String status, final String applnIntentId,
ObjectMapper mapper, ArrayNode arrayNode) throws IOException {
- String intentId = applnIntentId.split(":")[1];
ObjectNode node = mapper.createObjectNode();
- node.put("intent_id", intentId);
+ node.put("intent_id", applnIntentId);
node.put("status", status);
arrayNode.add(node);
}
diff --git a/src/main/java/net/onrc/onos/intent/persist/PersistIntent.java b/src/main/java/net/onrc/onos/intent/persist/PersistIntent.java
index 860b6dd..691a656 100755
--- a/src/main/java/net/onrc/onos/intent/persist/PersistIntent.java
+++ b/src/main/java/net/onrc/onos/intent/persist/PersistIntent.java
@@ -5,21 +5,19 @@
package net.onrc.onos.intent.persist;
import com.esotericsoftware.kryo.Kryo;
-import com.esotericsoftware.kryo.Serializer;
-import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import edu.stanford.ramcloud.JRamCloud;
import java.io.ByteArrayOutputStream;
import java.util.concurrent.atomic.AtomicLong;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import net.onrc.onos.datagrid.web.IntentResource;
import net.onrc.onos.datastore.RCTable;
import net.onrc.onos.intent.IntentOperationList;
import net.onrc.onos.ofcontroller.networkgraph.INetworkGraphService;
import net.onrc.onos.ofcontroller.networkgraph.NetworkGraph;
+import net.onrc.onos.ofcontroller.util.serializers.KryoFactory;
import net.onrc.onos.registry.controller.IControllerRegistryService;
import net.onrc.onos.registry.controller.IdBlock;
+import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
@@ -27,7 +25,7 @@
* @author nickkaranatsios
*/
public class PersistIntent {
- private final static org.slf4j.Logger log = LoggerFactory.getLogger(IntentResource.class);
+ private final static Logger log = LoggerFactory.getLogger(IntentResource.class);
private final static long range = 10000;
private final IControllerRegistryService controllerRegistry;
NetworkGraph graph = null;
@@ -45,7 +43,7 @@
this.controllerRegistry = controllerRegistry;
this.graph = ng.getNetworkGraph();
table = RCTable.getTable(intentJournal);
- stream = new ByteArrayOutputStream();
+ stream = new ByteArrayOutputStream(1024);
output = new Output(stream);
}
@@ -75,12 +73,12 @@
// TODO call controllerRegistry.isClusterLeader()
if (leader) {
try {
- System.out.println("persist operations to ramcloud");
+ System.out.println("persist operations to ramcloud size of operations: " + operations.size());
kryo.writeObject(output, operations);
output.close();
byte[] buffer = stream.toByteArray();
table.create(String.valueOf(key).getBytes(), buffer);
- System.out.println("key is " + key);
+ System.out.println("key is " + key + " value length is " + buffer.length);
ret = true;
} catch (JRamCloud.ObjectExistsException ex) {
log.warn("Failed to store intent journal with key " + key);
diff --git a/test-network/mininet/mesh_topology.py b/test-network/mininet/mesh_topology.py
new file mode 100755
index 0000000..5cd8091
--- /dev/null
+++ b/test-network/mininet/mesh_topology.py
@@ -0,0 +1,118 @@
+#!/usr/bin/python
+"""Custom topology example
+
+Two directly connected switches plus a host for each switch:
+
+ host --- switch --- switch --- host
+
+Adding the 'topos' dict with a key/value pair to generate our newly defined
+topology enables one to pass in '--topo=mytopo' from the command line.
+"""
+
+import sys, getopt
+from mininet.net import Mininet
+from mininet.node import Controller, RemoteController
+from mininet.log import setLogLevel, info, error, warn, debug
+from mininet.topo import Topo
+from mininet.link import Link, TCLink
+from mininet.util import dumpNodeConnections
+
+class MyController( Controller ):
+ def __init__( self, name, ip='127.0.0.1', port=6633, **kwargs):
+ """Init.
+ name: name to give controller
+ ip: the IP address where the remote controller is
+ listening
+ port: the port where the remote controller is listening"""
+ Controller.__init__( self, name, ip=ip, port=port, **kwargs )
+
+ def start( self ):
+ "Overridden to do nothing."
+ return
+
+ def stop( self ):
+ "Overridden to do nothing."
+ return
+
+ def checkListening( self ):
+ "Warn if remote controller is not accessible"
+ listening = self.cmd( "echo A | telnet -e A %s %d" %
+ ( self.ip, self.port ) )
+ if 'Unable' in listening:
+ warn( "Unable to contact the remote controller"
+ " at %s:%d\n" % ( self.ip, self.port ) )
+
+
+class MyTopo( Topo ):
+ "Simple topology example."
+
+ def __init__( self, max_switches ):
+ "Create custom topo."
+
+ # Initialize topology
+ Topo.__init__( self )
+
+ installed_switches = {}
+ # add switches first
+ for sw in range( max_switches ):
+ sw_str = "sw" + `sw + 1`
+ msw = self.addSwitch( sw_str )
+ installed_switches[sw_str] = msw
+
+ # create links between switches
+ for sw in range( max_switches ):
+ next_sw = sw + 1
+ for link in range( next_sw, max_switches ):
+ link_from = "sw" + `next_sw`
+ link_to = "sw" + `link + 1`
+ print "link_from ", link_from, " link to ", link_to
+ self.addLink( link_from, link_to )
+
+ # finally add links to hosts
+ for sw in range( max_switches ):
+ sw_str = "sw" + `sw + 1`
+ host_str = "h" + `sw + 1`
+ mhost = self.addHost( host_str )
+ msw = installed_switches[sw_str]
+ self.addLink( msw, mhost)
+
+def main(argv):
+ max_switches = ""
+ try:
+ opts,args = getopt.getopt(argv, "hs:", ["help", "switches="])
+ except getopt.GetoptError:
+ print "Usage mesh_topology.py [options]"
+ print "-s, --switches number of switches to set"
+ sys.exit(2)
+ for opt, arg in opts:
+ if opt == '-h':
+ print "Usage mesh_topology.py [options]"
+ print "-s, --switches number of switches to set"
+ sys.exit()
+ elif opt in ("-s", "--switches"):
+ max_switches = arg
+
+ switches = 4
+ if max_switches != "":
+ switches = int(max_switches)
+ topos = { 'mytopo': ( lambda: MyTopo(switches) ) }
+ net = Mininet(topo=MyTopo(switches), controller=MyController, link=TCLink)
+ print dumpNodeConnections(net.switches)
+
+ for sw in range(switches):
+ next_sw = sw + 1
+ mhost = "h" + `next_sw`
+ host = net.get( mhost )
+ if next_sw > 255:
+ divisor = next_sw / 256
+ remainder = next_sw % 256
+ host.setMAC('00:00:%02x:%02x:%02x:%02x' % (192, 168, divisor, remainder))
+ print "Host", host.name, "has IP address", host.IP(), "and MAC address", host.MAC()
+ else:
+ host.setMAC('00:00:%02x:%02x:%02x:%02x' % (192, 168, 0, next_sw))
+ print "Host", host.name, "has IP address", host.IP(), "and MAC address", host.MAC()
+
+ net.start()
+
+if __name__ == "__main__":
+ main(sys.argv[1:])
diff --git a/web/rest-intent/add-get-intent.rb b/web/rest-intent/add-get-intent.rb
index 55c8f94..6b88447 100644
--- a/web/rest-intent/add-get-intent.rb
+++ b/web/rest-intent/add-get-intent.rb
@@ -10,10 +10,23 @@
}
parser = OptionParser.new do |opts|
- opts.banner = "Usage add-get-intent [options]"
- opts.on('-g', '--get_intents', 'get intents state') do
+ opts.banner = "Usage [get-options] [post-options]"
+
+ opts.separator ""
+ opts.separator "Get options:"
+
+ opts.on('-G', '--get_intents', 'get intents state') do
+ options[:get_intents] = true
options[:rest_op] = "get"
end
+ opts.on('-g', '--get_intent intent_id', 'get intent state') do |intent_id|
+ options[:rest_op] = "get"
+ options[:get_intent] = intent_id
+ end
+
+ opts.separator ""
+ opts.separator "Post options:"
+
opts.on('-t', '--max_intents max_intents', 'max. number of intents') do |max_intents|
options[:max_intents] = max_intents
end
@@ -57,7 +70,6 @@
end
parser.parse!
-
class Intent
attr_reader :switches, :ports, :intent_id
attr_reader :application_id, :intent_type, :intent_op
@@ -72,8 +84,14 @@
create_specific_intent
end
- def get_intent
- request = RestClient.get "http://#{@server}:#{@port}/wm/onos/datagrid/get/intents/json"
+ def get_intent options
+ if options[:get_intents] == true
+ request = RestClient.get "http://#{@server}:#{@port}/wm/onos/datagrid/get/intents/json"
+ else
+ url = "http://#{@server}:#{@port}/wm/onos/datagrid/get/intent/#{options[:get_intent]}/json"
+ request = RestClient.get url
+ #request = RestClient.get "http://#{@server}:#{@port}/wm/onos/datagrid/get/intent/json",{:intent_id => options[:get_intent]}
+ end
puts request
end
@@ -124,7 +142,7 @@
def post intents
json_data = intents.to_json
- response = RestClient.post "http://#{@server}:#{@port}/wm/onos/datagrid/#{intent_op}/intents/json", json_data, :content_type => :json, :accept => :json
+ #response = RestClient.post "http://#{@server}:#{@port}/wm/onos/datagrid/#{intent_op}/intents/json", json_data, :content_type => :json, :accept => :json
puts response
end
@@ -188,7 +206,7 @@
intent = Intent.new options
if options[:rest_op] == "get"
- intent.get_intent
+ intent.get_intent options
else
json_data = intent.post_intent
end