blob: befb60ed3507a5c3e4e5e7356c0c83905e45d0f1 [file] [log] [blame]
Ray Milkey4f5de002014-12-17 19:26:11 -08001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 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
Ray Milkeyd43fe452015-05-29 09:35:12 -070018import java.io.IOException;
19import java.io.InputStream;
Ray Milkeyeb5c7172015-06-23 14:59:27 -070020import java.net.URI;
21import java.net.URISyntaxException;
Thomas Vachuska57a30992016-03-28 10:36:30 -070022import java.util.List;
Ray Milkeyeb5c7172015-06-23 14:59:27 -070023import java.util.stream.StreamSupport;
Ray Milkey4f5de002014-12-17 19:26:11 -080024
Ray Milkeyd43fe452015-05-29 09:35:12 -070025import javax.ws.rs.Consumes;
Ray Milkeyeb5c7172015-06-23 14:59:27 -070026import javax.ws.rs.DELETE;
Thomas Vachuska8683e012015-03-18 18:03:33 -070027import javax.ws.rs.GET;
Ray Milkeyd43fe452015-05-29 09:35:12 -070028import javax.ws.rs.POST;
Thomas Vachuska8683e012015-03-18 18:03:33 -070029import javax.ws.rs.Path;
30import javax.ws.rs.PathParam;
31import javax.ws.rs.Produces;
32import javax.ws.rs.core.MediaType;
33import javax.ws.rs.core.Response;
Ray Milkey4f5de002014-12-17 19:26:11 -080034
Ray Milkeyd43fe452015-05-29 09:35:12 -070035import org.onlab.util.ItemNotFoundException;
36import org.onosproject.net.Device;
37import org.onosproject.net.DeviceId;
38import org.onosproject.net.device.DeviceService;
39import org.onosproject.net.flow.FlowEntry;
40import org.onosproject.net.flow.FlowRule;
41import org.onosproject.net.flow.FlowRuleService;
42import org.onosproject.rest.AbstractWebResource;
43
Ray Milkeyeb5c7172015-06-23 14:59:27 -070044import com.fasterxml.jackson.databind.JsonNode;
Ray Milkeyd43fe452015-05-29 09:35:12 -070045import com.fasterxml.jackson.databind.node.ArrayNode;
46import com.fasterxml.jackson.databind.node.ObjectNode;
47
Ray Milkey4f5de002014-12-17 19:26:11 -080048/**
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -070049 * Query and program flow rules.
Ray Milkey4f5de002014-12-17 19:26:11 -080050 */
51
52@Path("flows")
53public class FlowsWebResource extends AbstractWebResource {
Thomas Vachuska57a30992016-03-28 10:36:30 -070054
Ray Milkey4f5de002014-12-17 19:26:11 -080055 public static final String DEVICE_NOT_FOUND = "Device is not found";
Thomas Vachuska57a30992016-03-28 10:36:30 -070056 public static final String FLOWS = "flows";
Ray Milkey4f5de002014-12-17 19:26:11 -080057
58 final FlowRuleService service = get(FlowRuleService.class);
59 final ObjectNode root = mapper().createObjectNode();
Thomas Vachuska57a30992016-03-28 10:36:30 -070060 final ArrayNode flowsNode = root.putArray(FLOWS);
Ray Milkey4f5de002014-12-17 19:26:11 -080061
62 /**
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -070063 * Get all flow entries. Returns array of all flow rules in the system.
Andrea Campanella10c4adc2015-12-03 15:27:54 -080064 * @onos.rsModel Flows
Ray Milkey4f5de002014-12-17 19:26:11 -080065 * @return array of all the intents in the system
66 */
67 @GET
68 @Produces(MediaType.APPLICATION_JSON)
69 public Response getFlows() {
Ray Milkey4f5de002014-12-17 19:26:11 -080070 final Iterable<Device> devices = get(DeviceService.class).getDevices();
71 for (final Device device : devices) {
Phaneendra Mandaaec654c2015-09-23 19:02:23 +053072 final Iterable<FlowEntry> flowEntries = service.getFlowEntries(device.id());
73 if (flowEntries != null) {
74 for (final FlowEntry entry : flowEntries) {
Thomas Vachuska8683e012015-03-18 18:03:33 -070075 flowsNode.add(codec(FlowEntry.class).encode(entry, this));
Ray Milkey4f5de002014-12-17 19:26:11 -080076 }
77 }
78 }
79
Ray Milkey3f025692015-01-26 11:15:41 -080080 return ok(root).build();
Ray Milkey4f5de002014-12-17 19:26:11 -080081 }
82
83 /**
Thomas Vachuska57a30992016-03-28 10:36:30 -070084 * Create new flow rules. Creates and installs a new flow rules.<br>
85 * Instructions description:
86 * https://wiki.onosproject.org/display/ONOS/Flow+Rule+Instructions
87 * <br>
88 * Criteria description:
89 * https://wiki.onosproject.org/display/ONOS/Flow+Rule+Criteria
90 *
91 * @onos.rsModel FlowsBatchPost
92 * @param stream flow rules JSON
93 * @return status of the request - CREATED if the JSON is correct,
94 * BAD_REQUEST if the JSON is invalid
95 */
96 @POST
97 @Consumes(MediaType.APPLICATION_JSON)
98 @Produces(MediaType.APPLICATION_JSON)
99 public Response createFlows(InputStream stream) {
100 try {
101 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
102 ArrayNode flowsArray = (ArrayNode) jsonTree.get(FLOWS);
103 List<FlowRule> rules = codec(FlowRule.class).decode(flowsArray, this);
104 service.applyFlowRules(rules.toArray(new FlowRule[rules.size()]));
105 } catch (IOException ex) {
106 throw new IllegalArgumentException(ex);
107 }
108 return Response.ok().build();
109 }
110
111 /**
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700112 * Get flow entries of a device. Returns array of all flow rules for the
113 * specified device.
Andrea Campanella10c4adc2015-12-03 15:27:54 -0800114 * @onos.rsModel Flows
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700115 * @param deviceId device identifier
Ray Milkey4f5de002014-12-17 19:26:11 -0800116 * @return flow data as an array
117 */
118 @GET
119 @Produces(MediaType.APPLICATION_JSON)
120 @Path("{deviceId}")
121 public Response getFlowByDeviceId(@PathParam("deviceId") String deviceId) {
Phaneendra Mandaaec654c2015-09-23 19:02:23 +0530122 final Iterable<FlowEntry> flowEntries =
Ray Milkey4f5de002014-12-17 19:26:11 -0800123 service.getFlowEntries(DeviceId.deviceId(deviceId));
124
Phaneendra Mandaaec654c2015-09-23 19:02:23 +0530125 if (!flowEntries.iterator().hasNext()) {
Ray Milkey4f5de002014-12-17 19:26:11 -0800126 throw new ItemNotFoundException(DEVICE_NOT_FOUND);
127 }
Phaneendra Mandaaec654c2015-09-23 19:02:23 +0530128 for (final FlowEntry entry : flowEntries) {
Thomas Vachuska8683e012015-03-18 18:03:33 -0700129 flowsNode.add(codec(FlowEntry.class).encode(entry, this));
Ray Milkey4f5de002014-12-17 19:26:11 -0800130 }
Ray Milkey3f025692015-01-26 11:15:41 -0800131 return ok(root).build();
Ray Milkey4f5de002014-12-17 19:26:11 -0800132 }
133
134 /**
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700135 * Get flow rule. Returns the flow entry specified by the device id and
136 * flow rule id.
Andrea Campanella10c4adc2015-12-03 15:27:54 -0800137 * @onos.rsModel Flows
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700138 * @param deviceId device identifier
139 * @param flowId flow rule identifier
Ray Milkey4f5de002014-12-17 19:26:11 -0800140 * @return flow data as an array
141 */
142 @GET
143 @Produces(MediaType.APPLICATION_JSON)
144 @Path("{deviceId}/{flowId}")
145 public Response getFlowByDeviceIdAndFlowId(@PathParam("deviceId") String deviceId,
146 @PathParam("flowId") long flowId) {
Phaneendra Mandaaec654c2015-09-23 19:02:23 +0530147 final Iterable<FlowEntry> flowEntries =
Ray Milkey4f5de002014-12-17 19:26:11 -0800148 service.getFlowEntries(DeviceId.deviceId(deviceId));
149
Phaneendra Mandaaec654c2015-09-23 19:02:23 +0530150 if (!flowEntries.iterator().hasNext()) {
Ray Milkey4f5de002014-12-17 19:26:11 -0800151 throw new ItemNotFoundException(DEVICE_NOT_FOUND);
152 }
Phaneendra Mandaaec654c2015-09-23 19:02:23 +0530153 for (final FlowEntry entry : flowEntries) {
Ray Milkey4f5de002014-12-17 19:26:11 -0800154 if (entry.id().value() == flowId) {
Thomas Vachuska8683e012015-03-18 18:03:33 -0700155 flowsNode.add(codec(FlowEntry.class).encode(entry, this));
Ray Milkey4f5de002014-12-17 19:26:11 -0800156 }
157 }
Ray Milkey3f025692015-01-26 11:15:41 -0800158 return ok(root).build();
Ray Milkey4f5de002014-12-17 19:26:11 -0800159 }
Ray Milkeyd43fe452015-05-29 09:35:12 -0700160
161 /**
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700162 * Create new flow rule. Creates and installs a new flow rule for the
Andrea Campanella881f29f2016-03-03 19:18:42 -0800163 * specified device. <br>
164 * Instructions description:
165 * https://wiki.onosproject.org/display/ONOS/Flow+Rule+Instructions
166 * <br>
167 * Criteria description:
168 * https://wiki.onosproject.org/display/ONOS/Flow+Rule+Criteria
169 *
Andrea Campanella10c4adc2015-12-03 15:27:54 -0800170 * @onos.rsModel FlowsPost
Madan Jampani0dbac7a2015-06-25 10:37:45 -0700171 * @param deviceId device identifier
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700172 * @param stream flow rule JSON
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700173 * @return status of the request - CREATED if the JSON is correct,
Ray Milkeyd43fe452015-05-29 09:35:12 -0700174 * BAD_REQUEST if the JSON is invalid
175 */
176 @POST
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700177 @Path("{deviceId}")
Ray Milkeyd43fe452015-05-29 09:35:12 -0700178 @Consumes(MediaType.APPLICATION_JSON)
179 @Produces(MediaType.APPLICATION_JSON)
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700180 public Response createFlow(@PathParam("deviceId") String deviceId,
181 InputStream stream) {
182 URI location;
Ray Milkeyd43fe452015-05-29 09:35:12 -0700183 try {
Ray Milkey5d915f42015-08-13 10:27:53 -0700184 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
185 JsonNode specifiedDeviceId = jsonTree.get("deviceId");
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700186 if (specifiedDeviceId != null &&
187 !specifiedDeviceId.asText().equals(deviceId)) {
188 throw new IllegalArgumentException(
189 "Invalid deviceId in flow creation request");
190 }
Ray Milkey5d915f42015-08-13 10:27:53 -0700191 jsonTree.put("deviceId", deviceId);
192 FlowRule rule = codec(FlowRule.class).decode(jsonTree, this);
Ray Milkeyd43fe452015-05-29 09:35:12 -0700193 service.applyFlowRules(rule);
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700194 location = new URI(Long.toString(rule.id().value()));
195 } catch (IOException | URISyntaxException ex) {
Ray Milkey5d915f42015-08-13 10:27:53 -0700196 throw new IllegalArgumentException(ex);
Ray Milkeyd43fe452015-05-29 09:35:12 -0700197 }
Ray Milkey5d915f42015-08-13 10:27:53 -0700198
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700199 return Response
200 .created(location)
201 .build();
202 }
203
204 /**
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700205 * Remove flow rule. Removes the specified flow rule.
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700206 *
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700207 * @param deviceId device identifier
208 * @param flowId flow rule identifier
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700209 */
210 @DELETE
211 @Produces(MediaType.APPLICATION_JSON)
212 @Path("{deviceId}/{flowId}")
213 public void deleteFlowByDeviceIdAndFlowId(@PathParam("deviceId") String deviceId,
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700214 @PathParam("flowId") long flowId) {
Phaneendra Mandaaec654c2015-09-23 19:02:23 +0530215 final Iterable<FlowEntry> flowEntries =
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700216 service.getFlowEntries(DeviceId.deviceId(deviceId));
217
Phaneendra Mandaaec654c2015-09-23 19:02:23 +0530218 if (!flowEntries.iterator().hasNext()) {
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700219 throw new ItemNotFoundException(DEVICE_NOT_FOUND);
220 }
221
Phaneendra Mandaaec654c2015-09-23 19:02:23 +0530222 StreamSupport.stream(flowEntries.spliterator(), false)
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700223 .filter(entry -> entry.id().value() == flowId)
224 .forEach(service::removeFlowRules);
Ray Milkeyd43fe452015-05-29 09:35:12 -0700225 }
226
Ray Milkey4f5de002014-12-17 19:26:11 -0800227}