blob: e666eb7322ac8a7e95c26598f6249f4366b0a283 [file] [log] [blame]
Toshio Koide3738ee52014-02-12 14:57:39 -08001/*
2 * To change this template, choose Tools | Templates
3 * and open the template in the editor.
4 */
Jonathan Hart6df90172014-04-03 10:13:11 -07005package net.onrc.onos.core.datagrid.web;
Toshio Koide3738ee52014-02-12 14:57:39 -08006
7import java.io.IOException;
Nick Karanatsios8abe7172014-02-19 20:31:48 -08008import java.util.Collection;
Toshio Koide3738ee52014-02-12 14:57:39 -08009import java.util.Iterator;
Ray Milkey9c8a2132014-04-02 15:16:42 -070010
Jonathan Hartaa380972014-04-03 10:24:46 -070011import net.onrc.onos.core.intent.ConstrainedShortestPathIntent;
12import net.onrc.onos.core.intent.Intent;
13import net.onrc.onos.core.intent.IntentMap;
14import net.onrc.onos.core.intent.IntentOperation;
15import net.onrc.onos.core.intent.IntentOperationList;
16import net.onrc.onos.core.intent.ShortestPathIntent;
17import net.onrc.onos.core.intent.runtime.IPathCalcRuntimeService;
18
Toshio Koide3738ee52014-02-12 14:57:39 -080019import org.codehaus.jackson.JsonGenerationException;
20import org.codehaus.jackson.JsonNode;
21import org.codehaus.jackson.map.JsonMappingException;
22import org.restlet.resource.Post;
23import org.restlet.resource.ServerResource;
24import org.codehaus.jackson.map.ObjectMapper;
Jonathan Hartaa380972014-04-03 10:24:46 -070025
Nick Karanatsios1a4a2002014-02-14 04:35:39 -080026import net.floodlightcontroller.util.MACAddress;
Ray Milkey9c8a2132014-04-02 15:16:42 -070027
Nick Karanatsios5fcf93e2014-02-15 14:13:55 -080028import java.util.HashMap;
Nick Karanatsios87e8be72014-02-21 23:45:37 -080029import java.util.LinkedList;
Nick Karanatsios5fcf93e2014-02-15 14:13:55 -080030import java.util.Map;
Ray Milkey9c8a2132014-04-02 15:16:42 -070031
Nick Karanatsios5fcf93e2014-02-15 14:13:55 -080032import org.codehaus.jackson.node.ArrayNode;
Nick Karanatsios88948d32014-02-18 15:14:30 -080033import org.codehaus.jackson.node.ObjectNode;
Nick Karanatsios1f4defb2014-02-23 19:34:47 -080034import org.restlet.resource.Delete;
Nick Karanatsios88948d32014-02-18 15:14:30 -080035import org.restlet.resource.Get;
Nick Karanatsios5fcf93e2014-02-15 14:13:55 -080036import org.slf4j.Logger;
37import org.slf4j.LoggerFactory;
Toshio Koide3738ee52014-02-12 14:57:39 -080038
39/**
Toshio Koide3738ee52014-02-12 14:57:39 -080040 * @author nickkaranatsios
41 */
42public class IntentResource extends ServerResource {
Nick Karanatsios5fcf93e2014-02-15 14:13:55 -080043 private final static Logger log = LoggerFactory.getLogger(IntentResource.class);
Nick Karanatsiosda9f36f2014-02-21 01:27:02 -080044 // TODO need to assign proper application id.
45 private final String APPLN_ID = "1";
Ray Milkey9c8a2132014-04-02 15:16:42 -070046
Toshio Koide3738ee52014-02-12 14:57:39 -080047 @Post("json")
Nick Karanatsios88948d32014-02-18 15:14:30 -080048 public String store(String jsonIntent) throws IOException {
Ray Milkey9c8a2132014-04-02 15:16:42 -070049 IPathCalcRuntimeService pathRuntime = (IPathCalcRuntimeService) getContext()
Nick Karanatsios8abe7172014-02-19 20:31:48 -080050 .getAttributes().get(IPathCalcRuntimeService.class.getCanonicalName());
51 if (pathRuntime == null) {
Nick Karanatsiosda9f36f2014-02-21 01:27:02 -080052 log.warn("Failed to get path calc runtime");
Nick Karanatsios8abe7172014-02-19 20:31:48 -080053 return "";
54 }
Nick Karanatsios5fcf93e2014-02-15 14:13:55 -080055 String reply = "";
Ray Milkey9c8a2132014-04-02 15:16:42 -070056 ObjectMapper mapper = new ObjectMapper();
57 JsonNode jNode = null;
58 try {
59 jNode = mapper.readValue(jsonIntent, JsonNode.class);
60 } catch (JsonGenerationException ex) {
61 log.error("JsonGeneration exception ", ex);
62 } catch (JsonMappingException ex) {
63 log.error("JsonMappingException occurred", ex);
64 } catch (IOException ex) {
65 log.error("IOException occurred", ex);
66 }
Nick Karanatsios1a4a2002014-02-14 04:35:39 -080067
Ray Milkey9c8a2132014-04-02 15:16:42 -070068 if (jNode != null) {
69 reply = parseJsonNode(jNode.getElements(), pathRuntime);
70 }
Nick Karanatsios5fcf93e2014-02-15 14:13:55 -080071 return reply;
Toshio Koide3738ee52014-02-12 14:57:39 -080072 }
Ray Milkey9c8a2132014-04-02 15:16:42 -070073
Nick Karanatsios1f4defb2014-02-23 19:34:47 -080074 @Delete("json")
75 public String store() {
Ray Milkey9c8a2132014-04-02 15:16:42 -070076 IPathCalcRuntimeService pathRuntime = (IPathCalcRuntimeService) getContext().
Nick Karanatsios1f4defb2014-02-23 19:34:47 -080077 getAttributes().get(IPathCalcRuntimeService.class.getCanonicalName());
78 pathRuntime.purgeIntents();
79 // TODO no reply yet from the purge intents call
80 return "";
Ray Milkey9c8a2132014-04-02 15:16:42 -070081
Nick Karanatsios1f4defb2014-02-23 19:34:47 -080082 }
Toshio Koide3738ee52014-02-12 14:57:39 -080083
Nick Karanatsios88948d32014-02-18 15:14:30 -080084 @Get("json")
Nick Karanatsios8abe7172014-02-19 20:31:48 -080085 public String retrieve() throws IOException {
Ray Milkey9c8a2132014-04-02 15:16:42 -070086 IPathCalcRuntimeService pathRuntime = (IPathCalcRuntimeService) getContext().
Nick Karanatsios8abe7172014-02-19 20:31:48 -080087 getAttributes().get(IPathCalcRuntimeService.class.getCanonicalName());
Ray Milkey9c8a2132014-04-02 15:16:42 -070088
Nick Karanatsios87e8be72014-02-21 23:45:37 -080089 String intentCategory = (String) getRequestAttributes().get("category");
90 IntentMap intentMap = null;
91 if (intentCategory.equals("high")) {
92 intentMap = pathRuntime.getHighLevelIntents();
93 } else {
94 intentMap = pathRuntime.getPathIntents();
95 }
Nick Karanatsios8abe7172014-02-19 20:31:48 -080096 ObjectMapper mapper = new ObjectMapper();
97 String restStr = "";
Nick Karanatsiosed645df2014-02-20 23:22:29 -080098
99 String intentId = (String) getRequestAttributes().get("intent_id");
Nick Karanatsios8abe7172014-02-19 20:31:48 -0800100 ArrayNode arrayNode = mapper.createArrayNode();
Nick Karanatsios8abe7172014-02-19 20:31:48 -0800101 Collection<Intent> intents = intentMap.getAllIntents();
102 if (!intents.isEmpty()) {
Ray Milkey9c8a2132014-04-02 15:16:42 -0700103 if ((intentId != null)) {
Nick Karanatsiosda9f36f2014-02-21 01:27:02 -0800104 String applnIntentId = APPLN_ID + ":" + intentId;
105 Intent intent = intentMap.getIntent(applnIntentId);
Nick Karanatsiosed645df2014-02-20 23:22:29 -0800106 if (intent != null) {
107 ObjectNode node = mapper.createObjectNode();
Nick Karanatsios87e8be72014-02-21 23:45:37 -0800108 // TODO refactor/remove duplicate code.
Nick Karanatsiosda9f36f2014-02-21 01:27:02 -0800109 node.put("intent_id", intentId);
Nick Karanatsiosed645df2014-02-20 23:22:29 -0800110 node.put("status", intent.getState().toString());
Nick Karanatsios87e8be72014-02-21 23:45:37 -0800111 LinkedList<String> logs = intent.getLogs();
112 ArrayNode logNode = mapper.createArrayNode();
Ray Milkey9c8a2132014-04-02 15:16:42 -0700113 for (String intentLog : logs) {
Nick Karanatsios87e8be72014-02-21 23:45:37 -0800114 logNode.add(intentLog);
115 }
116 node.put("log", logNode);
Nick Karanatsiosed645df2014-02-20 23:22:29 -0800117 arrayNode.add(node);
118 }
119 } else {
120 for (Intent intent : intents) {
121 ObjectNode node = mapper.createObjectNode();
Nick Karanatsiosda9f36f2014-02-21 01:27:02 -0800122 String applnIntentId = intent.getId();
123 intentId = applnIntentId.split(":")[1];
124 node.put("intent_id", intentId);
Nick Karanatsiosed645df2014-02-20 23:22:29 -0800125 node.put("status", intent.getState().toString());
Nick Karanatsios87e8be72014-02-21 23:45:37 -0800126 LinkedList<String> logs = intent.getLogs();
127 ArrayNode logNode = mapper.createArrayNode();
Ray Milkey9c8a2132014-04-02 15:16:42 -0700128 for (String intentLog : logs) {
Nick Karanatsios87e8be72014-02-21 23:45:37 -0800129 logNode.add(intentLog);
130 }
131 node.put("log", logNode);
Nick Karanatsiosed645df2014-02-20 23:22:29 -0800132 arrayNode.add(node);
133 }
Nick Karanatsios8abe7172014-02-19 20:31:48 -0800134 }
Nick Karanatsiosed645df2014-02-20 23:22:29 -0800135 restStr = mapper.writeValueAsString(arrayNode);
Nick Karanatsios8abe7172014-02-19 20:31:48 -0800136 }
137 return restStr;
Nick Karanatsios88948d32014-02-18 15:14:30 -0800138 }
Ray Milkey9c8a2132014-04-02 15:16:42 -0700139
Nick Karanatsios8abe7172014-02-19 20:31:48 -0800140 private String parseJsonNode(Iterator<JsonNode> nodes,
Ray Milkey9c8a2132014-04-02 15:16:42 -0700141 IPathCalcRuntimeService pathRuntime) throws IOException {
Nick Karanatsios8abe7172014-02-19 20:31:48 -0800142 IntentOperationList operations = new IntentOperationList();
Nick Karanatsios5fcf93e2014-02-15 14:13:55 -0800143 ObjectMapper mapper = new ObjectMapper();
144 ArrayNode arrayNode = mapper.createArrayNode();
Ray Milkey9c8a2132014-04-02 15:16:42 -0700145 while (nodes.hasNext()) {
146 JsonNode node = nodes.next();
147 if (node.isObject()) {
148 JsonNode data;
149 Iterator<String> fieldNames = node.getFieldNames();
Nick Karanatsios5fcf93e2014-02-15 14:13:55 -0800150 Map<String, Object> fields = new HashMap<>();
Ray Milkey9c8a2132014-04-02 15:16:42 -0700151 while (fieldNames.hasNext()) {
152 String fieldName = fieldNames.next();
153 data = node.get(fieldName);
Nick Karanatsios5fcf93e2014-02-15 14:13:55 -0800154 parseFields(data, fieldName, fields);
Ray Milkey9c8a2132014-04-02 15:16:42 -0700155 }
Nick Karanatsios87e8be72014-02-21 23:45:37 -0800156 Intent intent = processIntent(fields, operations);
Ray Milkey9c8a2132014-04-02 15:16:42 -0700157 appendIntentStatus(intent, (String) fields.get("intent_id"), mapper, arrayNode);
158 }
159 }
Nick Karanatsios8abe7172014-02-19 20:31:48 -0800160 pathRuntime.executeIntentOperations(operations);
Nick Karanatsios5fcf93e2014-02-15 14:13:55 -0800161 return mapper.writeValueAsString(arrayNode);
Toshio Koide3738ee52014-02-12 14:57:39 -0800162 }
Nick Karanatsios1a4a2002014-02-14 04:35:39 -0800163
Ray Milkey9c8a2132014-04-02 15:16:42 -0700164 private void appendIntentStatus(Intent intent, final String intentId,
165 ObjectMapper mapper, ArrayNode arrayNode) throws IOException {
Nick Karanatsios88948d32014-02-18 15:14:30 -0800166 ObjectNode node = mapper.createObjectNode();
Nick Karanatsiosda9f36f2014-02-21 01:27:02 -0800167 node.put("intent_id", intentId);
Nick Karanatsios87e8be72014-02-21 23:45:37 -0800168 node.put("status", intent.getState().toString());
169 LinkedList<String> logs = intent.getLogs();
170 ArrayNode logNode = mapper.createArrayNode();
171 for (String intentLog : logs) {
172 logNode.add(intentLog);
173 }
174 node.put("log", logNode);
Nick Karanatsios88948d32014-02-18 15:14:30 -0800175 arrayNode.add(node);
Nick Karanatsios5fcf93e2014-02-15 14:13:55 -0800176 }
Ray Milkey9c8a2132014-04-02 15:16:42 -0700177
Nick Karanatsios87e8be72014-02-21 23:45:37 -0800178 private Intent processIntent(Map<String, Object> fields, IntentOperationList operations) {
Ray Milkey9c8a2132014-04-02 15:16:42 -0700179 String intentType = (String) fields.get("intent_type");
180 String intentOp = (String) fields.get("intent_op");
Nick Karanatsios87e8be72014-02-21 23:45:37 -0800181 Intent intent;
Ray Milkey9c8a2132014-04-02 15:16:42 -0700182 String intentId = (String) fields.get("intent_id");
Toshio Koide565d6dd2014-03-27 11:22:25 -0700183 boolean pathFrozen = false;
184 if (intentId.startsWith("F")) { // TODO define REST API for frozen intents
185 pathFrozen = true;
186 intentId = intentId.substring(1);
187 }
188 String applnIntentId = APPLN_ID + ":" + intentId;
Ray Milkey9c8a2132014-04-02 15:16:42 -0700189
Nick Karanatsios88948d32014-02-18 15:14:30 -0800190 IntentOperation.Operator operation = IntentOperation.Operator.ADD;
191 if ((intentOp.equals("remove"))) {
192 operation = IntentOperation.Operator.REMOVE;
193 }
Nick Karanatsios5fcf93e2014-02-15 14:13:55 -0800194 if (intentType.equals("shortest_intent_type")) {
Nick Karanatsiosda9f36f2014-02-21 01:27:02 -0800195 ShortestPathIntent spi = new ShortestPathIntent(applnIntentId,
Nick Karanatsios5fcf93e2014-02-15 14:13:55 -0800196 Long.decode((String) fields.get("srcSwitch")),
197 (long) fields.get("srcPort"),
198 MACAddress.valueOf((String) fields.get("srcMac")).toLong(),
199 Long.decode((String) fields.get("dstSwitch")),
200 (long) fields.get("dstPort"),
201 MACAddress.valueOf((String) fields.get("dstMac")).toLong());
Toshio Koide565d6dd2014-03-27 11:22:25 -0700202 spi.setPathFrozen(pathFrozen);
Nick Karanatsiosa1bad352014-02-22 14:16:34 -0800203 operations.add(operation, spi);
Nick Karanatsios87e8be72014-02-21 23:45:37 -0800204 intent = spi;
Nick Karanatsios5fcf93e2014-02-15 14:13:55 -0800205 } else {
Nick Karanatsiosda9f36f2014-02-21 01:27:02 -0800206 ConstrainedShortestPathIntent cspi = new ConstrainedShortestPathIntent(applnIntentId,
Nick Karanatsios5fcf93e2014-02-15 14:13:55 -0800207 Long.decode((String) fields.get("srcSwitch")),
208 (long) fields.get("srcPort"),
209 MACAddress.valueOf((String) fields.get("srcMac")).toLong(),
210 Long.decode((String) fields.get("dstSwitch")),
211 (long) fields.get("dstPort"),
212 MACAddress.valueOf((String) fields.get("dstMac")).toLong(),
213 (double) fields.get("bandwidth"));
Toshio Koide565d6dd2014-03-27 11:22:25 -0700214 cspi.setPathFrozen(pathFrozen);
Nick Karanatsiosa1bad352014-02-22 14:16:34 -0800215 operations.add(operation, cspi);
Nick Karanatsios87e8be72014-02-21 23:45:37 -0800216 intent = cspi;
Nick Karanatsios5fcf93e2014-02-15 14:13:55 -0800217 }
Nick Karanatsios87e8be72014-02-21 23:45:37 -0800218 return intent;
Nick Karanatsios5fcf93e2014-02-15 14:13:55 -0800219 }
220
221 private void parseFields(JsonNode node, String fieldName, Map<String, Object> fields) {
222 if ((node.isTextual())) {
Nick Karanatsios5fcf93e2014-02-15 14:13:55 -0800223 fields.put(fieldName, node.getTextValue());
224 } else if ((node.isInt())) {
Ray Milkey9c8a2132014-04-02 15:16:42 -0700225 fields.put(fieldName, (long) node.getIntValue());
Nick Karanatsios5fcf93e2014-02-15 14:13:55 -0800226 } else if (node.isDouble()) {
Nick Karanatsios5fcf93e2014-02-15 14:13:55 -0800227 fields.put(fieldName, node.getDoubleValue());
228 } else if ((node.isLong())) {
Nick Karanatsios5fcf93e2014-02-15 14:13:55 -0800229 fields.put(fieldName, node.getLongValue());
230 }
231 }
Toshio Koide3738ee52014-02-12 14:57:39 -0800232}