blob: 712ccae5ad3e850940e18c1a580877d0cc3adc5e [file] [log] [blame]
Jian Lie9ac2c52016-01-13 17:42:05 -08001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Jian Lie9ac2c52016-01-13 17:42:05 -08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.rest.resources;
17
18import com.fasterxml.jackson.databind.JsonNode;
19import com.fasterxml.jackson.databind.node.ObjectNode;
20import org.onosproject.net.DeviceId;
21import org.onosproject.net.flowobjective.FilteringObjective;
22import org.onosproject.net.flowobjective.FlowObjectiveService;
23import org.onosproject.net.flowobjective.ForwardingObjective;
24import org.onosproject.net.flowobjective.NextObjective;
25import org.onosproject.rest.AbstractWebResource;
26
27import javax.ws.rs.Consumes;
28import javax.ws.rs.GET;
29import javax.ws.rs.POST;
30import javax.ws.rs.Path;
31import javax.ws.rs.PathParam;
32import javax.ws.rs.Produces;
Jian Lia424a052016-05-30 21:02:33 +090033import javax.ws.rs.QueryParam;
Jian Li9d616492016-03-09 10:52:49 -080034import javax.ws.rs.core.Context;
Jian Lie9ac2c52016-01-13 17:42:05 -080035import javax.ws.rs.core.MediaType;
36import javax.ws.rs.core.Response;
Jian Li9d616492016-03-09 10:52:49 -080037import javax.ws.rs.core.UriBuilder;
38import javax.ws.rs.core.UriInfo;
Jian Lie9ac2c52016-01-13 17:42:05 -080039import java.io.IOException;
40import java.io.InputStream;
Jian Lie9ac2c52016-01-13 17:42:05 -080041
42/**
43 * Manage flow objectives.
44 */
45@Path("flowobjectives")
46public class FlowObjectiveWebResource extends AbstractWebResource {
47
Jian Li9d616492016-03-09 10:52:49 -080048 @Context
Jian Licc730a62016-05-10 16:36:16 -070049 private UriInfo uriInfo;
Jian Li9d616492016-03-09 10:52:49 -080050
Jian Licc730a62016-05-10 16:36:16 -070051 private static final String DEVICE_INVALID =
Jian Lie9ac2c52016-01-13 17:42:05 -080052 "Invalid deviceId in objective creation request";
Jian Licc730a62016-05-10 16:36:16 -070053 private static final String POLICY_INVALID = "Invalid policy";
Jian Lie9ac2c52016-01-13 17:42:05 -080054
Jian Licc730a62016-05-10 16:36:16 -070055 private final FlowObjectiveService flowObjectiveService = get(FlowObjectiveService.class);
56 private final ObjectNode root = mapper().createObjectNode();
Jian Lie9ac2c52016-01-13 17:42:05 -080057
58 /**
59 * Creates and installs a new filtering objective for the specified device.
60 *
Jian Lia424a052016-05-30 21:02:33 +090061 * @param appId application identifier
Jian Lie9ac2c52016-01-13 17:42:05 -080062 * @param deviceId device identifier
63 * @param stream filtering objective JSON
64 * @return status of the request - CREATED if the JSON is correct,
65 * BAD_REQUEST if the JSON is invalid
66 * @onos.rsModel FilteringObjective
67 */
68 @POST
69 @Path("{deviceId}/filter")
70 @Consumes(MediaType.APPLICATION_JSON)
71 @Produces(MediaType.APPLICATION_JSON)
Jian Lia424a052016-05-30 21:02:33 +090072 public Response createFilteringObjective(@QueryParam("appId") String appId,
73 @PathParam("deviceId") String deviceId,
Jian Lie9ac2c52016-01-13 17:42:05 -080074 InputStream stream) {
Jian Lie9ac2c52016-01-13 17:42:05 -080075 try {
Jian Li9d616492016-03-09 10:52:49 -080076 UriBuilder locationBuilder = null;
Jian Lie9ac2c52016-01-13 17:42:05 -080077 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
78 if (validateDeviceId(deviceId, jsonTree)) {
Jian Lia424a052016-05-30 21:02:33 +090079
80 if (appId != null) {
81 jsonTree.put("appId", appId);
82 }
83
Jian Lie9ac2c52016-01-13 17:42:05 -080084 DeviceId did = DeviceId.deviceId(deviceId);
85 FilteringObjective filteringObjective =
86 codec(FilteringObjective.class).decode(jsonTree, this);
87 flowObjectiveService.filter(did, filteringObjective);
Jian Li9d616492016-03-09 10:52:49 -080088 locationBuilder = uriInfo.getBaseUriBuilder()
89 .path("flowobjectives")
90 .path(did.toString())
91 .path("filter")
92 .path(Integer.toString(filteringObjective.id()));
Jian Lie9ac2c52016-01-13 17:42:05 -080093 }
Jian Li9d616492016-03-09 10:52:49 -080094 return Response
95 .created(locationBuilder.build())
96 .build();
97 } catch (IOException e) {
Jian Lie9ac2c52016-01-13 17:42:05 -080098 throw new IllegalArgumentException(e);
99 }
Jian Lie9ac2c52016-01-13 17:42:05 -0800100 }
101
102 /**
103 * Creates and installs a new forwarding objective for the specified device.
104 *
Jian Lia424a052016-05-30 21:02:33 +0900105 * @param appId application identifier
Jian Lie9ac2c52016-01-13 17:42:05 -0800106 * @param deviceId device identifier
107 * @param stream forwarding objective JSON
108 * @return status of the request - CREATED if the JSON is correct,
109 * BAD_REQUEST if the JSON is invalid
110 * @onos.rsModel ForwardingObjective
111 */
112 @POST
113 @Path("{deviceId}/forward")
114 @Consumes(MediaType.APPLICATION_JSON)
115 @Produces(MediaType.APPLICATION_JSON)
Jian Lia424a052016-05-30 21:02:33 +0900116 public Response createForwardingObjective(@QueryParam("appId") String appId,
117 @PathParam("deviceId") String deviceId,
Jian Lie9ac2c52016-01-13 17:42:05 -0800118 InputStream stream) {
Jian Lie9ac2c52016-01-13 17:42:05 -0800119 try {
Jian Li9d616492016-03-09 10:52:49 -0800120 UriBuilder locationBuilder = null;
Jian Lie9ac2c52016-01-13 17:42:05 -0800121 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
122 if (validateDeviceId(deviceId, jsonTree)) {
Jian Lia424a052016-05-30 21:02:33 +0900123
124 if (appId != null) {
125 jsonTree.put("appId", appId);
126 }
127
Jian Lie9ac2c52016-01-13 17:42:05 -0800128 DeviceId did = DeviceId.deviceId(deviceId);
129 ForwardingObjective forwardingObjective =
130 codec(ForwardingObjective.class).decode(jsonTree, this);
131 flowObjectiveService.forward(did, forwardingObjective);
Jian Li9d616492016-03-09 10:52:49 -0800132 locationBuilder = uriInfo.getBaseUriBuilder()
133 .path("flowobjectives")
134 .path(did.toString())
135 .path("forward")
136 .path(Integer.toString(forwardingObjective.id()));
Jian Lie9ac2c52016-01-13 17:42:05 -0800137 }
Jian Li9d616492016-03-09 10:52:49 -0800138 return Response
139 .created(locationBuilder.build())
140 .build();
141 } catch (IOException e) {
Jian Lie9ac2c52016-01-13 17:42:05 -0800142 throw new IllegalArgumentException(e);
143 }
Jian Lie9ac2c52016-01-13 17:42:05 -0800144 }
145
146 /**
147 * Creates and installs a new next objective for the specified device.
148 *
Jian Lia424a052016-05-30 21:02:33 +0900149 * @param appId application identifier
Jian Lie9ac2c52016-01-13 17:42:05 -0800150 * @param deviceId device identifier
151 * @param stream next objective JSON
152 * @return status of the request - CREATED if the JSON is correct,
153 * BAD_REQUEST if the JSON is invalid
154 * @onos.rsModel NextObjective
155 */
156 @POST
157 @Path("{deviceId}/next")
158 @Consumes(MediaType.APPLICATION_JSON)
159 @Produces(MediaType.APPLICATION_JSON)
Jian Lia424a052016-05-30 21:02:33 +0900160 public Response createNextObjective(@QueryParam("appId") String appId,
161 @PathParam("deviceId") String deviceId,
Jian Lie9ac2c52016-01-13 17:42:05 -0800162 InputStream stream) {
Jian Lie9ac2c52016-01-13 17:42:05 -0800163 try {
Jian Li9d616492016-03-09 10:52:49 -0800164 UriBuilder locationBuilder = null;
Jian Lie9ac2c52016-01-13 17:42:05 -0800165 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
166 if (validateDeviceId(deviceId, jsonTree)) {
Jian Lia424a052016-05-30 21:02:33 +0900167
168 if (appId != null) {
169 jsonTree.put("appId", appId);
170 }
171
Jian Lie9ac2c52016-01-13 17:42:05 -0800172 DeviceId did = DeviceId.deviceId(deviceId);
173 NextObjective nextObjective =
174 codec(NextObjective.class).decode(jsonTree, this);
175 flowObjectiveService.next(did, nextObjective);
Jian Li9d616492016-03-09 10:52:49 -0800176 locationBuilder = uriInfo.getBaseUriBuilder()
177 .path("flowobjectives")
178 .path(did.toString())
179 .path("next")
180 .path(Integer.toString(nextObjective.id()));
Jian Lie9ac2c52016-01-13 17:42:05 -0800181 }
Jian Li9d616492016-03-09 10:52:49 -0800182 return Response
183 .created(locationBuilder.build())
184 .build();
185 } catch (IOException e) {
Jian Lie9ac2c52016-01-13 17:42:05 -0800186 throw new IllegalArgumentException(e);
187 }
Jian Lie9ac2c52016-01-13 17:42:05 -0800188 }
189
190 /**
191 * Returns the globally unique nextId.
192 *
Jian Licc730a62016-05-10 16:36:16 -0700193 * @return 200 OK with next identifier
Jian Lid79d39e2016-02-01 12:53:47 -0800194 * @onos.rsModel NextId
Jian Lie9ac2c52016-01-13 17:42:05 -0800195 */
196 @GET
197 @Path("next")
198 @Produces(MediaType.APPLICATION_JSON)
199 public Response getNextId() {
200 root.put("nextId", flowObjectiveService.allocateNextId());
201 return ok(root).build();
202 }
203
204 /**
205 * Installs the filtering rules onto the specified device.
206 *
207 * @param stream filtering rule JSON
Jian Licc730a62016-05-10 16:36:16 -0700208 * @return 200 OK
Jian Lie9ac2c52016-01-13 17:42:05 -0800209 * @onos.rsModel ObjectivePolicy
210 */
211 @POST
212 @Path("policy")
213 @Consumes(MediaType.APPLICATION_JSON)
Jian Licc730a62016-05-10 16:36:16 -0700214 public Response initPolicy(InputStream stream) {
Jian Lie9ac2c52016-01-13 17:42:05 -0800215
216 try {
217 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
218 JsonNode policyJson = jsonTree.get("policy");
219
220 if (policyJson == null || policyJson.asText().isEmpty()) {
221 throw new IllegalArgumentException(POLICY_INVALID);
222 }
223
224 flowObjectiveService.initPolicy(policyJson.asText());
Jian Licc730a62016-05-10 16:36:16 -0700225 return Response.ok().build();
Jian Lie9ac2c52016-01-13 17:42:05 -0800226 } catch (IOException e) {
227 throw new IllegalArgumentException(e);
228 }
229 }
230
231 /**
Jian Licc730a62016-05-10 16:36:16 -0700232 * Validates the deviceId that is contained in json string against the
Jian Lie9ac2c52016-01-13 17:42:05 -0800233 * input deviceId.
234 *
235 * @param deviceId device identifier
236 * @param node object node
237 * @return validity
238 */
239 private boolean validateDeviceId(String deviceId, ObjectNode node) {
240 JsonNode specifiedDeviceId = node.get("deviceId");
241
242 if (specifiedDeviceId != null &&
243 !specifiedDeviceId.asText().equals(deviceId)) {
244 throw new IllegalArgumentException(DEVICE_INVALID);
245 }
246 return true;
247 }
248}