add more functionality into rest intent
Change-Id: I0c3c89da15c9b48bbe40ef8004db59e33bfdaf12
diff --git a/src/main/java/net/onrc/onos/datagrid/web/DatagridWebRoutable.java b/src/main/java/net/onrc/onos/datagrid/web/DatagridWebRoutable.java
old mode 100644
new mode 100755
index e0e1666..90c7a18
--- a/src/main/java/net/onrc/onos/datagrid/web/DatagridWebRoutable.java
+++ b/src/main/java/net/onrc/onos/datagrid/web/DatagridWebRoutable.java
@@ -18,6 +18,7 @@
Router router = new Router(context);
router.attach("/get/map/{map-name}/json", GetMapResource.class);
router.attach("/add/intent/json", IntentResource.class);
+ router.attach("/get/intents/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 0d50865..0f552d3 100755
--- a/src/main/java/net/onrc/onos/datagrid/web/IntentResource.java
+++ b/src/main/java/net/onrc/onos/datagrid/web/IntentResource.java
@@ -11,6 +11,7 @@
import net.onrc.onos.intent.ShortestPathIntent;
import net.onrc.onos.intent.IntentOperation;
import net.onrc.onos.intent.IntentMap;
+//import net.onrc.onos.intent.Intent.IntentState;
import net.onrc.onos.ofcontroller.networkgraph.INetworkGraphService;
import net.onrc.onos.ofcontroller.networkgraph.NetworkGraph;
import net.onrc.onos.registry.controller.IControllerRegistryService;
@@ -28,6 +29,8 @@
import java.util.LinkedList;
import java.util.Map;
import org.codehaus.jackson.node.ArrayNode;
+import org.codehaus.jackson.node.ObjectNode;
+import org.restlet.resource.Get;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -43,11 +46,11 @@
private class IntentStatus {
String intentId;
- boolean status;
+ String status;
public IntentStatus() {}
- public IntentStatus(String intentId, boolean status) {
+ public IntentStatus(String intentId, String status) {
this.intentId = intentId;
this.status = status;
}
@@ -60,33 +63,28 @@
this.intentId = intentId;
}
- public boolean getStatus() {
+ public String getStatus() {
return status;
}
- public void setStatus(boolean status) {
+ public void setStatus(String status) {
this.status = status;
}
}
@Post("json")
- public String store(String jsonFlowIntent) throws IOException {
+ public String store(String jsonIntent) throws IOException {
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();
String reply = "";
ObjectMapper mapper = new ObjectMapper();
JsonNode jNode = null;
try {
- System.out.println("json string " + jsonFlowIntent);
- jNode = mapper.readValue(jsonFlowIntent, JsonNode.class);
+ jNode = mapper.readValue(jsonIntent, JsonNode.class);
} catch (JsonGenerationException ex) {
log.error("JsonGeneration exception ", ex);
} catch (JsonMappingException ex) {
@@ -98,11 +96,15 @@
if (jNode != null) {
Kryo kryo = new Kryo();
reply = parseJsonNode(kryo, jNode.getElements(), datagridService);
- // datagridService.registerIntent(intents);
}
return reply;
}
+ @Get("json")
+ public String retrieve() {
+ return "123";
+ }
+
private String parseJsonNode(Kryo kryo, Iterator<JsonNode> nodes,
IDatagridService datagridService) throws IOException {
LinkedList<IntentOperation> operations = new LinkedList<>();
@@ -119,8 +121,7 @@
data = node.get(fieldName);
parseFields(data, fieldName, fields);
}
- System.out.println("recv fields " + fields);
- boolean status = processIntent(fields, operations);
+ String status = processIntent(fields, operations);
appendIntentStatus(status, (String)fields.get("intent_id"), mapper, arrayNode);
// datagridService.registerIntent(Long.toString(uuid),
// sb.toString().getBytes());
@@ -132,22 +133,25 @@
}
- private void appendIntentStatus(boolean status, final String applnIntentId,
+ private void appendIntentStatus(String status, final String applnIntentId,
ObjectMapper mapper, ArrayNode arrayNode) throws IOException {
+ System.out.println("status " + status);
String intentId = applnIntentId.split(":")[1];
- String boolStr = Boolean.TRUE.toString();
- if (status == false) {
- boolStr = Boolean.FALSE.toString();
- }
- String jsonString = "{\"intent_id\":" + intentId + "," + "\"status\":" + boolStr + "}";
- JsonNode parsedNode = mapper.readValue(jsonString, JsonNode.class);
- arrayNode.add(parsedNode);
+ ObjectNode node = mapper.createObjectNode();
+ node.put("intent_id", intentId);
+ node.put("status", status);
+ arrayNode.add(node);
}
- private boolean processIntent(Map<String, Object> fields, LinkedList<IntentOperation> operations) {
+ private String processIntent(Map<String, Object> fields, LinkedList<IntentOperation> operations) {
String intentType = (String)fields.get("intent_type");
- boolean status = false;
+ String intentOp = (String)fields.get("intent_op");
+ String status = null;
+ IntentOperation.Operator operation = IntentOperation.Operator.ADD;
+ if ((intentOp.equals("remove"))) {
+ operation = IntentOperation.Operator.REMOVE;
+ }
if (intentType.equals("shortest_intent_type")) {
ShortestPathIntent spi = new ShortestPathIntent((String) fields.get("intent_id"),
Long.decode((String) fields.get("srcSwitch")),
@@ -156,8 +160,9 @@
Long.decode((String) fields.get("dstSwitch")),
(long) fields.get("dstPort"),
MACAddress.valueOf((String) fields.get("dstMac")).toLong());
- operations.add(new IntentOperation(IntentOperation.Operator.ADD, spi));
- status = true;
+ operations.add(new IntentOperation(operation, spi));
+ System.out.println("intent operation " + operation.toString());
+ status = (spi.getState()).toString();
} else {
ConstrainedShortestPathIntent cspi = new ConstrainedShortestPathIntent((String) fields.get("intent_id"),
Long.decode((String) fields.get("srcSwitch")),
@@ -167,24 +172,20 @@
(long) fields.get("dstPort"),
MACAddress.valueOf((String) fields.get("dstMac")).toLong(),
(double) fields.get("bandwidth"));
- operations.add(new IntentOperation(IntentOperation.Operator.ADD, cspi));
- status = true;
+ operations.add(new IntentOperation(operation, cspi));
+ status = (cspi.getState()).toString();
}
return status;
}
private void parseFields(JsonNode node, String fieldName, Map<String, Object> fields) {
if ((node.isTextual())) {
- System.out.println("textual fieldname = " + fieldName);
fields.put(fieldName, node.getTextValue());
} else if ((node.isInt())) {
- System.out.println("int fieldname = " + fieldName);
fields.put(fieldName, (long)node.getIntValue());
} else if (node.isDouble()) {
- System.out.println("double fieldname = " + fieldName);
fields.put(fieldName, node.getDoubleValue());
} else if ((node.isLong())) {
- System.out.println("long fieldname = " + fieldName);
fields.put(fieldName, node.getLongValue());
}
}
diff --git a/src/main/java/net/onrc/onos/intent/Intent.java b/src/main/java/net/onrc/onos/intent/Intent.java
index de960f0..3429d1f 100644
--- a/src/main/java/net/onrc/onos/intent/Intent.java
+++ b/src/main/java/net/onrc/onos/intent/Intent.java
@@ -4,7 +4,7 @@
* @author Toshio Koide (t-koide@onlab.us)
*/
public class Intent {
- enum IntentState {
+ public enum IntentState {
CREATED,
INST_REQ,
INST_NACK,
diff --git a/web/add-intent.rb b/web/add-intent.rb
deleted file mode 100644
index b1d8dfd..0000000
--- a/web/add-intent.rb
+++ /dev/null
@@ -1,122 +0,0 @@
-require "rest-client"
-require "optparse"
-
-options = { :intent_id => 123, :intent_type => "shortest_intent_type", :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.to_i
- end
- opts.on('-i', '--intent_id intent_id', 'global intent id') do |id|
- options[:intent_id] = id.to_i
- end
- opts.on('-s', '--shortest', 'create a shortest path intent') do
- options[:intent_type] = "shortest_intent_type"
- end
- opts.on('-c', '--constrained', 'create a constrained shortest path intent') do
- options[:intent_type] = "constrained_shortest_intent_type"
- end
- opts.on('-m', '--max_switches max_switches', 'max. number of switches') do |max_switches|
- options[:max_switches] = max_switches.to_i
- end
- opts.on('-h', '--help', 'Display help') do
- puts opts
- exit
- end
-end
-parser.parse!
-
-puts options.inspect
-server = options[:server]
-server ||= "127.0.0.1"
-port = options[:port]
-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
- attr_reader :ports
- attr_reader :intent_id
- attr_reader :application_id
- attr_reader :intent_type
-
- 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
- json_intents
- 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]
- @intent_id ||= 1
- @application_id = options[:application_id]
- @application_id ||= 1
- @intent_type = options[:intent_type]
- end
-
-
- def _create_intent src_switch, iterable_switches, json_intents
- network_id = 1
- 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 = {
- :intent_id => "#{@application_id}:#{@intent_id}",
- :intent_type => @intent_type,
- :srcSwitch => src_switch.to_s,
- :srcPort => @ports[sw_i],
- :srcMac => "00:00:c0:a8:#{mac_format(src_switch)}",
- :dstSwitch => iterable_switches[sw_i].to_s,
- :dstPort => dst_port,
- :dstMac => "00:00:c0:a8:#{mac_format(iterable_switches[sw_i].to_i)}"
- }
-puts intent
- @intent_id = @intent_id + 1
- json_intents << intent
-puts
- end
- #sha256 = Digest::SHA256.new
- #sha256.update intent_hash.to_s
- #puts sha256.hexdigest
- #puts "intent hash = #{intent_hash}"
- json_intents
- end
-
- def mac_format number
- if number > 255
- divisor = number / 256
- remainder = number % 256
- return sprintf("%02x:%02x",divisor ,remainder)
- end
- "00:%02x" % number
- end
-end
-
-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
diff --git a/web/rest-intent/add-get-intent.rb b/web/rest-intent/add-get-intent.rb
new file mode 100644
index 0000000..1627aea
--- /dev/null
+++ b/web/rest-intent/add-get-intent.rb
@@ -0,0 +1,207 @@
+require "rest-client"
+require "optparse"
+
+options = {
+ :rest_op => "add",
+ :intent_id => 123,
+ :intent_type => "shortest_intent_type",
+ :max_switches => 4,
+ :intent_op => "add"
+}
+
+parser = OptionParser.new do |opts|
+ opts.banner = "Usage add-get-intent [options]"
+ opts.on('-g', '--get_intents', 'get intents state') do
+ options[:rest_op] = "get"
+ end
+ opts.on('-t', '--max_intents max_intents', 'max. number of intents') do |max_intents|
+ options[:max_intents] = max_intents
+ end
+ opts.on('-l', '--application application_id', 'set application id') do |appl_id|
+ options[:application_id] = appl_id.to_i
+ end
+ opts.on('-i', '--intent_id intent_id', 'global intent id') do |id|
+ options[:intent_id] = id.to_i
+ end
+ # optional argument
+ opts.on('-s', '--shortest', 'create a shortest path intent') do
+ options[:intent_type] = "shortest_intent_type"
+ end
+ # optional argument
+ opts.on('-c', '--constrained', 'create a constrained shortest path intent') do
+ options[:intent_type] = "constrained_shortest_intent_type"
+ end
+ # optional argument
+ opts.on('-r', '--random_intent', 'create minimum no. of random intents') do
+ options[:random_intent] = true
+ end
+ opts.on('-m', '--max_switches max_switches', 'max. number of switches') do |max_switches|
+ options[:max_switches] = max_switches.to_i
+ end
+ opts.on('-o', '--intent_op add|remove', 'an operation to post an intent') do |operation|
+ options[:intent_op] = operation
+ end
+ opts.on('-w', '--server server', 'server to post intents') do |server|
+ options[:server] = server
+ end
+ opts.on('-p','--port port', 'server port') do |port|
+ options[:port] = port
+ end
+ opts.on('b', '--bulk_limit bulk_limit', 'bulk request upto this limit') do |bulk_limit|
+ options[:bulk_limit] = bulk_limit
+ end
+ opts.on('-h', '--help', 'Display help') do
+ puts opts
+ exit
+ end
+end
+parser.parse!
+
+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
+ attr_reader :application_id, :intent_type, :intent_op
+ attr_reader :random_intent, :server, :port
+ attr_reader :bulk_limit
+
+ def initialize options
+ parse_options options
+ end
+
+ def post_intent
+ create_specific_intent
+ end
+
+ def get_intent
+ request = RestClient.get "http://#{@server}:#{@port}/wm/onos/datagrid/get/intents/json"
+ puts request
+ end
+
+ private
+
+ def create_specific_intent
+ if @random_intent == true
+ create_random_intent
+ else
+ create_many_intents
+ end
+ end
+
+ # create as many intents as the number of switches
+ def create_many_intents
+ intents = []
+ @switches.each do |sw|
+ rest = @switches - [sw]
+ intents = _create_intent sw, rest, intents
+puts intents.size
+ post_slice intents
+ end
+ post_slice intents, true
+ end
+
+ # pick a random src switch and create intents to all other switches
+ def create_random_intent
+ intents = []
+ sw = @switches.shuffle[0]
+ rest = @switches - [sw]
+ intents = _create_intent sw, rest, intents
+ post_slice intents, true
+ end
+
+ def post_slice intents, last=false
+ @bulk_limit = @bulk_limit.to_i
+ if intents.size >= @bulk_limit
+ post intents.slice!(0..(@bulk_limit - 1))
+ end
+ if last == true
+ loop do
+ new_bulk_limit = intents.size > @bulk_limit ? @bulk_limit : intents.size
+ post intents.slice!(0..(new_bulk_limit - 1))
+ break if new_bulk_limit < @bulk_limit
+ end
+ end
+ end
+
+ def post intents
+ json_data = intents.to_json
+ response = RestClient.post "http://#{@server}:#{@port}/wm/onos/datagrid/#{intent_op}/intent/json", json_data, :content_type => :json, :accept => :json
+ puts response
+ 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]
+ @intent_id ||= 1
+ @application_id = options[:application_id]
+ @application_id ||= 1
+ @intent_type = options[:intent_type]
+ @intent_op = options[:intent_op]
+ @intent_op ||= "add"
+ @random_intent = options[:random_intent]
+ @random_intent ||= false
+ @server = options[:server]
+ @server ||= "127.0.0.1"
+ @port = options[:port]
+ @port ||= 8080
+ @bulk_limit = options[:bulk_limit]
+ @bulk_limit ||= 10000
+ end
+
+
+ def _create_intent src_switch, iterable_switches, json_intents
+ network_id = 1
+ 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 = {
+ :intent_id => "#{@application_id}:#{@intent_id}",
+ :intent_type => @intent_type,
+ :intent_op => @intent_op,
+ :srcSwitch => src_switch.to_s,
+ :srcPort => @ports[sw_i],
+ :srcMac => "00:00:c0:a8:#{mac_format(src_switch)}",
+ :dstSwitch => iterable_switches[sw_i].to_s,
+ :dstPort => dst_port,
+ :dstMac => "00:00:c0:a8:#{mac_format(iterable_switches[sw_i].to_i)}"
+ }
+puts intent.inspect
+ @intent_id = @intent_id + 1
+ json_intents << intent
+puts
+ end
+ #sha256 = Digest::SHA256.new
+ #sha256.update intent_hash.to_s
+ #puts sha256.hexdigest
+ #puts "intent hash = #{intent_hash}"
+ json_intents
+ end
+
+ def mac_format number
+ if number > 255
+ divisor = number / 256
+ remainder = number % 256
+ return sprintf("%02x:%02x",divisor ,remainder)
+ end
+ "00:%02x" % number
+ end
+end
+
+intent = Intent.new options
+if options[:rest_op] == "get"
+ intent.get_intent
+else
+ json_data = intent.post_intent
+end
+