blob: 8229e38f9be8b96632701559036d3d16eaaaca4e [file] [log] [blame]
Pavlin Radoslavov13669052014-05-13 10:33:39 -07001package net.onrc.onos.core.intent.runtime.web;
2
3import java.io.IOException;
4import java.util.Collection;
5
6import net.floodlightcontroller.util.MACAddress;
7import net.onrc.onos.api.intent.ApplicationIntent;
Ray Milkeya8091b12014-05-16 14:42:47 -07008import net.onrc.onos.api.rest.RestError;
9import net.onrc.onos.api.rest.RestErrorCodes;
Pavlin Radoslavov13669052014-05-13 10:33:39 -070010import net.onrc.onos.core.intent.ConstrainedShortestPathIntent;
11import net.onrc.onos.core.intent.Intent;
12import net.onrc.onos.core.intent.IntentMap;
13import net.onrc.onos.core.intent.IntentOperation;
14import net.onrc.onos.core.intent.IntentOperationList;
15import net.onrc.onos.core.intent.ShortestPathIntent;
16import net.onrc.onos.core.intent.runtime.IPathCalcRuntimeService;
17import net.onrc.onos.core.util.Dpid;
18
Pavlin Radoslavov13669052014-05-13 10:33:39 -070019import org.codehaus.jackson.map.ObjectMapper;
Ray Milkeya8091b12014-05-16 14:42:47 -070020import org.restlet.data.Status;
Pavlin Radoslavov13669052014-05-13 10:33:39 -070021import org.restlet.resource.Delete;
22import org.restlet.resource.Get;
23import org.restlet.resource.Post;
24import org.restlet.resource.ServerResource;
25import org.slf4j.Logger;
26import org.slf4j.LoggerFactory;
27
28/**
29 * A class to access the high-level intents.
30 */
31public class IntentHighResource extends ServerResource {
32 private static final Logger log = LoggerFactory.getLogger(IntentHighResource.class);
33 // TODO need to assign proper application id.
34 private static final String APPLN_ID = "1";
35
36 /**
37 * Gets all high-level intents.
38 *
39 * @return a collection with all high-level intents.
40 */
41 @Get("json")
42 public Collection<Intent> retrieve() throws IOException {
43 IPathCalcRuntimeService pathRuntime = (IPathCalcRuntimeService) getContext().
44 getAttributes().get(IPathCalcRuntimeService.class.getCanonicalName());
45
46 IntentMap intentMap = pathRuntime.getHighLevelIntents();
47 Collection<Intent> intents = intentMap.getAllIntents();
48
49 return intents;
50 }
51
52 /**
53 * Adds a collection of high-level intents.
54 *
55 * @return the status of the operation (TBD).
56 */
57 @Post("json")
58 public String store(String jsonIntent) throws IOException {
59 IPathCalcRuntimeService pathRuntime = (IPathCalcRuntimeService) getContext()
60 .getAttributes().get(IPathCalcRuntimeService.class.getCanonicalName());
61 if (pathRuntime == null) {
62 log.warn("Failed to get path calc runtime");
63 return "";
64 }
65
66 String reply = "";
67 ObjectMapper mapper = new ObjectMapper();
68 ApplicationIntent[] addOperations = null;
69 try {
Ray Milkeya8091b12014-05-16 14:42:47 -070070 if (jsonIntent != null) {
71 addOperations = mapper.readValue(jsonIntent, ApplicationIntent[].class);
72 }
Pavlin Radoslavov13669052014-05-13 10:33:39 -070073 } catch (IOException ex) {
Ray Milkeya8091b12014-05-16 14:42:47 -070074 log.error("Exception occurred parsing inbound JSON", ex);
Pavlin Radoslavov13669052014-05-13 10:33:39 -070075 }
Ray Milkeya8091b12014-05-16 14:42:47 -070076
Pavlin Radoslavov13669052014-05-13 10:33:39 -070077 if (addOperations == null) {
Ray Milkeya8091b12014-05-16 14:42:47 -070078 setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
79 final RestError error =
80 RestError.createRestError(RestErrorCodes.RestErrorCode.INTENT_INVALID);
81 return mapper.writeValueAsString(error);
Pavlin Radoslavov13669052014-05-13 10:33:39 -070082 }
83
84 //
85 // Process all intents one-by-one
86 //
87 // TODO: The Intent Type should be enum instead of a string,
88 // and we should use a switch statement below to process the
89 // different type of intents.
90 //
91 IntentOperationList intentOperations = new IntentOperationList();
92 for (ApplicationIntent oper : addOperations) {
93 String applnIntentId = APPLN_ID + ":" + oper.intentId();
94
95 IntentOperation.Operator operator = IntentOperation.Operator.ADD;
96 Dpid srcSwitchDpid = new Dpid(oper.srcSwitchDpid());
97 Dpid dstSwitchDpid = new Dpid(oper.dstSwitchDpid());
98
99 if (oper.intentType().equals("SHORTEST_PATH")) {
100 //
101 // Process Shortest-Path Intent
102 //
103 ShortestPathIntent spi =
104 new ShortestPathIntent(applnIntentId,
105 srcSwitchDpid.value(),
106 oper.srcSwitchPort(),
107 MACAddress.valueOf(oper.matchSrcMac()).toLong(),
108 dstSwitchDpid.value(),
109 oper.dstSwitchPort(),
110 MACAddress.valueOf(oper.matchDstMac()).toLong());
111 spi.setPathFrozen(oper.isStaticPath());
112 intentOperations.add(operator, spi);
113 } else {
114 //
115 // Process Constrained Shortest-Path Intent
116 //
117 ConstrainedShortestPathIntent cspi =
118 new ConstrainedShortestPathIntent(applnIntentId,
119 srcSwitchDpid.value(),
120 oper.srcSwitchPort(),
121 MACAddress.valueOf(oper.matchSrcMac()).toLong(),
122 dstSwitchDpid.value(),
123 oper.dstSwitchPort(),
124 MACAddress.valueOf(oper.matchDstMac()).toLong(),
125 oper.bandwidth());
126 cspi.setPathFrozen(oper.isStaticPath());
127 intentOperations.add(operator, cspi);
128 }
129 }
130 // Apply the Intent Operations
131 pathRuntime.executeIntentOperations(intentOperations);
132
Ray Milkeya8091b12014-05-16 14:42:47 -0700133 setStatus(Status.SUCCESS_CREATED);
134
Pavlin Radoslavov13669052014-05-13 10:33:39 -0700135 return reply;
136 }
137
138 /**
139 * Deletes all high-level intents.
140 *
141 * @return the status of the operation (TBD).
142 */
143 @Delete("json")
144 public String store() {
145 IPathCalcRuntimeService pathRuntime = (IPathCalcRuntimeService) getContext().
146 getAttributes().get(IPathCalcRuntimeService.class.getCanonicalName());
147
148 // Delete all intents
149 // TODO: The implementation below is broken - waiting for the Java API
150 // TODO: The deletion should use synchronous Java API?
151 pathRuntime.purgeIntents();
Ray Milkeya8091b12014-05-16 14:42:47 -0700152 setStatus(Status.SUCCESS_NO_CONTENT);
Pavlin Radoslavov13669052014-05-13 10:33:39 -0700153 return ""; // TODO no reply yet from the purge intents call
154 }
155}