blob: db1f0251a7ec23f246edd1a1851e5abe2c478aa8 [file] [log] [blame]
Ray Milkey4f5de002014-12-17 19:26:11 -08001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Ray Milkey4f5de002014-12-17 19:26:11 -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 */
Jonathan Hart9bb32ab2015-05-05 18:17:31 -070016package org.onosproject.rest.resources;
Ray Milkey4f5de002014-12-17 19:26:11 -080017
Jian Li9d616492016-03-09 10:52:49 -080018import com.fasterxml.jackson.databind.JsonNode;
19import com.fasterxml.jackson.databind.node.ArrayNode;
20import com.fasterxml.jackson.databind.node.ObjectNode;
Ray Milkeyd43fe452015-05-29 09:35:12 -070021import org.onlab.util.ItemNotFoundException;
22import org.onosproject.net.Device;
23import org.onosproject.net.DeviceId;
24import org.onosproject.net.device.DeviceService;
25import org.onosproject.net.flow.FlowEntry;
26import org.onosproject.net.flow.FlowRule;
27import org.onosproject.net.flow.FlowRuleService;
28import org.onosproject.rest.AbstractWebResource;
29
Jian Li9d616492016-03-09 10:52:49 -080030import javax.ws.rs.Consumes;
31import javax.ws.rs.DELETE;
32import javax.ws.rs.GET;
33import javax.ws.rs.POST;
34import javax.ws.rs.Path;
35import javax.ws.rs.PathParam;
36import javax.ws.rs.Produces;
37import javax.ws.rs.core.Context;
38import javax.ws.rs.core.MediaType;
39import javax.ws.rs.core.Response;
40import javax.ws.rs.core.UriBuilder;
41import javax.ws.rs.core.UriInfo;
42import java.io.IOException;
43import java.io.InputStream;
Thomas Vachuskaa1ae5e12016-03-28 10:36:30 -070044import java.util.List;
Jian Li9d616492016-03-09 10:52:49 -080045import java.util.stream.StreamSupport;
Ray Milkeyd43fe452015-05-29 09:35:12 -070046
Ray Milkey4f5de002014-12-17 19:26:11 -080047/**
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -070048 * Query and program flow rules.
Ray Milkey4f5de002014-12-17 19:26:11 -080049 */
50
51@Path("flows")
52public class FlowsWebResource extends AbstractWebResource {
Jian Li9d616492016-03-09 10:52:49 -080053
54 @Context
55 UriInfo uriInfo;
56
Ray Milkey4f5de002014-12-17 19:26:11 -080057 public static final String DEVICE_NOT_FOUND = "Device is not found";
Thomas Vachuskaa1ae5e12016-03-28 10:36:30 -070058 public static final String FLOWS = "flows";
Ray Milkey4f5de002014-12-17 19:26:11 -080059
60 final FlowRuleService service = get(FlowRuleService.class);
61 final ObjectNode root = mapper().createObjectNode();
Thomas Vachuskaa1ae5e12016-03-28 10:36:30 -070062 final ArrayNode flowsNode = root.putArray(FLOWS);
Ray Milkey4f5de002014-12-17 19:26:11 -080063
64 /**
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -070065 * Get all flow entries. Returns array of all flow rules in the system.
Andrea Campanella10c4adc2015-12-03 15:27:54 -080066 * @onos.rsModel Flows
Ray Milkey4f5de002014-12-17 19:26:11 -080067 * @return array of all the intents in the system
68 */
69 @GET
70 @Produces(MediaType.APPLICATION_JSON)
71 public Response getFlows() {
Ray Milkey4f5de002014-12-17 19:26:11 -080072 final Iterable<Device> devices = get(DeviceService.class).getDevices();
73 for (final Device device : devices) {
Phaneendra Mandaaec654c2015-09-23 19:02:23 +053074 final Iterable<FlowEntry> flowEntries = service.getFlowEntries(device.id());
75 if (flowEntries != null) {
76 for (final FlowEntry entry : flowEntries) {
Thomas Vachuska8683e012015-03-18 18:03:33 -070077 flowsNode.add(codec(FlowEntry.class).encode(entry, this));
Ray Milkey4f5de002014-12-17 19:26:11 -080078 }
79 }
80 }
81
Ray Milkey3f025692015-01-26 11:15:41 -080082 return ok(root).build();
Ray Milkey4f5de002014-12-17 19:26:11 -080083 }
84
85 /**
Thomas Vachuskaa1ae5e12016-03-28 10:36:30 -070086 * Create new flow rules. Creates and installs a new flow rules.<br>
87 * Instructions description:
88 * https://wiki.onosproject.org/display/ONOS/Flow+Rule+Instructions
89 * <br>
90 * Criteria description:
91 * https://wiki.onosproject.org/display/ONOS/Flow+Rule+Criteria
92 *
93 * @onos.rsModel FlowsBatchPost
94 * @param stream flow rules JSON
95 * @return status of the request - CREATED if the JSON is correct,
96 * BAD_REQUEST if the JSON is invalid
97 */
98 @POST
99 @Consumes(MediaType.APPLICATION_JSON)
100 @Produces(MediaType.APPLICATION_JSON)
101 public Response createFlows(InputStream stream) {
102 try {
103 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
104 ArrayNode flowsArray = (ArrayNode) jsonTree.get(FLOWS);
105 List<FlowRule> rules = codec(FlowRule.class).decode(flowsArray, this);
106 service.applyFlowRules(rules.toArray(new FlowRule[rules.size()]));
107 } catch (IOException ex) {
108 throw new IllegalArgumentException(ex);
109 }
110 return Response.ok().build();
111 }
112
113 /**
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700114 * Get flow entries of a device. Returns array of all flow rules for the
115 * specified device.
Andrea Campanella10c4adc2015-12-03 15:27:54 -0800116 * @onos.rsModel Flows
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700117 * @param deviceId device identifier
Ray Milkey4f5de002014-12-17 19:26:11 -0800118 * @return flow data as an array
119 */
120 @GET
121 @Produces(MediaType.APPLICATION_JSON)
122 @Path("{deviceId}")
123 public Response getFlowByDeviceId(@PathParam("deviceId") String deviceId) {
Phaneendra Mandaaec654c2015-09-23 19:02:23 +0530124 final Iterable<FlowEntry> flowEntries =
Ray Milkey4f5de002014-12-17 19:26:11 -0800125 service.getFlowEntries(DeviceId.deviceId(deviceId));
126
Jian Li9d616492016-03-09 10:52:49 -0800127 if (flowEntries == null || !flowEntries.iterator().hasNext()) {
Ray Milkey4f5de002014-12-17 19:26:11 -0800128 throw new ItemNotFoundException(DEVICE_NOT_FOUND);
129 }
Phaneendra Mandaaec654c2015-09-23 19:02:23 +0530130 for (final FlowEntry entry : flowEntries) {
Thomas Vachuska8683e012015-03-18 18:03:33 -0700131 flowsNode.add(codec(FlowEntry.class).encode(entry, this));
Ray Milkey4f5de002014-12-17 19:26:11 -0800132 }
Ray Milkey3f025692015-01-26 11:15:41 -0800133 return ok(root).build();
Ray Milkey4f5de002014-12-17 19:26:11 -0800134 }
135
136 /**
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700137 * Get flow rule. Returns the flow entry specified by the device id and
138 * flow rule id.
Andrea Campanella10c4adc2015-12-03 15:27:54 -0800139 * @onos.rsModel Flows
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700140 * @param deviceId device identifier
141 * @param flowId flow rule identifier
Ray Milkey4f5de002014-12-17 19:26:11 -0800142 * @return flow data as an array
143 */
144 @GET
145 @Produces(MediaType.APPLICATION_JSON)
146 @Path("{deviceId}/{flowId}")
147 public Response getFlowByDeviceIdAndFlowId(@PathParam("deviceId") String deviceId,
148 @PathParam("flowId") long flowId) {
Phaneendra Mandaaec654c2015-09-23 19:02:23 +0530149 final Iterable<FlowEntry> flowEntries =
Ray Milkey4f5de002014-12-17 19:26:11 -0800150 service.getFlowEntries(DeviceId.deviceId(deviceId));
151
Jian Li9d616492016-03-09 10:52:49 -0800152 if (flowEntries == null || !flowEntries.iterator().hasNext()) {
Ray Milkey4f5de002014-12-17 19:26:11 -0800153 throw new ItemNotFoundException(DEVICE_NOT_FOUND);
154 }
Phaneendra Mandaaec654c2015-09-23 19:02:23 +0530155 for (final FlowEntry entry : flowEntries) {
Ray Milkey4f5de002014-12-17 19:26:11 -0800156 if (entry.id().value() == flowId) {
Thomas Vachuska8683e012015-03-18 18:03:33 -0700157 flowsNode.add(codec(FlowEntry.class).encode(entry, this));
Ray Milkey4f5de002014-12-17 19:26:11 -0800158 }
159 }
Ray Milkey3f025692015-01-26 11:15:41 -0800160 return ok(root).build();
Ray Milkey4f5de002014-12-17 19:26:11 -0800161 }
Ray Milkeyd43fe452015-05-29 09:35:12 -0700162
163 /**
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700164 * Create new flow rule. Creates and installs a new flow rule for the
Andrea Campanella881f29f2016-03-03 19:18:42 -0800165 * specified device. <br>
166 * Instructions description:
167 * https://wiki.onosproject.org/display/ONOS/Flow+Rule+Instructions
168 * <br>
169 * Criteria description:
170 * https://wiki.onosproject.org/display/ONOS/Flow+Rule+Criteria
171 *
Andrea Campanella10c4adc2015-12-03 15:27:54 -0800172 * @onos.rsModel FlowsPost
Madan Jampani0dbac7a2015-06-25 10:37:45 -0700173 * @param deviceId device identifier
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700174 * @param stream flow rule JSON
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700175 * @return status of the request - CREATED if the JSON is correct,
Ray Milkeyd43fe452015-05-29 09:35:12 -0700176 * BAD_REQUEST if the JSON is invalid
177 */
178 @POST
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700179 @Path("{deviceId}")
Ray Milkeyd43fe452015-05-29 09:35:12 -0700180 @Consumes(MediaType.APPLICATION_JSON)
181 @Produces(MediaType.APPLICATION_JSON)
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700182 public Response createFlow(@PathParam("deviceId") String deviceId,
183 InputStream stream) {
Ray Milkeyd43fe452015-05-29 09:35:12 -0700184 try {
Ray Milkey5d915f42015-08-13 10:27:53 -0700185 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
186 JsonNode specifiedDeviceId = jsonTree.get("deviceId");
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700187 if (specifiedDeviceId != null &&
188 !specifiedDeviceId.asText().equals(deviceId)) {
189 throw new IllegalArgumentException(
190 "Invalid deviceId in flow creation request");
191 }
Ray Milkey5d915f42015-08-13 10:27:53 -0700192 jsonTree.put("deviceId", deviceId);
193 FlowRule rule = codec(FlowRule.class).decode(jsonTree, this);
Ray Milkeyd43fe452015-05-29 09:35:12 -0700194 service.applyFlowRules(rule);
Jian Li9d616492016-03-09 10:52:49 -0800195 UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
196 .path("flows")
197 .path(deviceId)
Ray Milkey90289b02016-03-31 15:23:28 -0700198 .path(Long.toString(rule.id().value()));
Jian Li9d616492016-03-09 10:52:49 -0800199
200 return Response
201 .created(locationBuilder.build())
202 .build();
203 } catch (IOException ex) {
Ray Milkey5d915f42015-08-13 10:27:53 -0700204 throw new IllegalArgumentException(ex);
Ray Milkeyd43fe452015-05-29 09:35:12 -0700205 }
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700206 }
207
208 /**
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700209 * Remove flow rule. Removes the specified flow rule.
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700210 *
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700211 * @param deviceId device identifier
212 * @param flowId flow rule identifier
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700213 */
214 @DELETE
215 @Produces(MediaType.APPLICATION_JSON)
216 @Path("{deviceId}/{flowId}")
217 public void deleteFlowByDeviceIdAndFlowId(@PathParam("deviceId") String deviceId,
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700218 @PathParam("flowId") long flowId) {
Phaneendra Mandaaec654c2015-09-23 19:02:23 +0530219 final Iterable<FlowEntry> flowEntries =
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700220 service.getFlowEntries(DeviceId.deviceId(deviceId));
221
Phaneendra Mandaaec654c2015-09-23 19:02:23 +0530222 if (!flowEntries.iterator().hasNext()) {
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700223 throw new ItemNotFoundException(DEVICE_NOT_FOUND);
224 }
225
Phaneendra Mandaaec654c2015-09-23 19:02:23 +0530226 StreamSupport.stream(flowEntries.spliterator(), false)
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700227 .filter(entry -> entry.id().value() == flowId)
228 .forEach(service::removeFlowRules);
Ray Milkeyd43fe452015-05-29 09:35:12 -0700229 }
230
Ray Milkey4f5de002014-12-17 19:26:11 -0800231}