blob: 0e88e34e12fdd00f9b917de7749ee112aee27d8d [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;
22import java.util.stream.StreamSupport;
Ray Milkey4f5de002014-12-17 19:26:11 -080023
Ray Milkeyd43fe452015-05-29 09:35:12 -070024import javax.ws.rs.Consumes;
Ray Milkeyeb5c7172015-06-23 14:59:27 -070025import javax.ws.rs.DELETE;
Thomas Vachuska8683e012015-03-18 18:03:33 -070026import javax.ws.rs.GET;
Ray Milkeyd43fe452015-05-29 09:35:12 -070027import javax.ws.rs.POST;
Thomas Vachuska8683e012015-03-18 18:03:33 -070028import javax.ws.rs.Path;
29import javax.ws.rs.PathParam;
30import javax.ws.rs.Produces;
31import javax.ws.rs.core.MediaType;
32import javax.ws.rs.core.Response;
Ray Milkey4f5de002014-12-17 19:26:11 -080033
Ray Milkeyd43fe452015-05-29 09:35:12 -070034import org.onlab.util.ItemNotFoundException;
35import org.onosproject.net.Device;
36import org.onosproject.net.DeviceId;
37import org.onosproject.net.device.DeviceService;
38import org.onosproject.net.flow.FlowEntry;
39import org.onosproject.net.flow.FlowRule;
40import org.onosproject.net.flow.FlowRuleService;
41import org.onosproject.rest.AbstractWebResource;
42
Ray Milkeyeb5c7172015-06-23 14:59:27 -070043import com.fasterxml.jackson.databind.JsonNode;
Ray Milkeyd43fe452015-05-29 09:35:12 -070044import com.fasterxml.jackson.databind.node.ArrayNode;
45import com.fasterxml.jackson.databind.node.ObjectNode;
46
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 {
53 public static final String DEVICE_NOT_FOUND = "Device is not found";
54
55 final FlowRuleService service = get(FlowRuleService.class);
56 final ObjectNode root = mapper().createObjectNode();
57 final ArrayNode flowsNode = root.putArray("flows");
Ray Milkey4f5de002014-12-17 19:26:11 -080058
59 /**
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -070060 * Get all flow entries. Returns array of all flow rules in the system.
Ray Milkey4f5de002014-12-17 19:26:11 -080061 *
62 * @return array of all the intents in the system
63 */
64 @GET
65 @Produces(MediaType.APPLICATION_JSON)
66 public Response getFlows() {
Ray Milkey4f5de002014-12-17 19:26:11 -080067 final Iterable<Device> devices = get(DeviceService.class).getDevices();
68 for (final Device device : devices) {
Phaneendra Mandaaec654c2015-09-23 19:02:23 +053069 final Iterable<FlowEntry> flowEntries = service.getFlowEntries(device.id());
70 if (flowEntries != null) {
71 for (final FlowEntry entry : flowEntries) {
Thomas Vachuska8683e012015-03-18 18:03:33 -070072 flowsNode.add(codec(FlowEntry.class).encode(entry, this));
Ray Milkey4f5de002014-12-17 19:26:11 -080073 }
74 }
75 }
76
Ray Milkey3f025692015-01-26 11:15:41 -080077 return ok(root).build();
Ray Milkey4f5de002014-12-17 19:26:11 -080078 }
79
80 /**
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -070081 * Get flow entries of a device. Returns array of all flow rules for the
82 * specified device.
Ray Milkey4f5de002014-12-17 19:26:11 -080083 *
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -070084 * @param deviceId device identifier
Ray Milkey4f5de002014-12-17 19:26:11 -080085 * @return flow data as an array
86 */
87 @GET
88 @Produces(MediaType.APPLICATION_JSON)
89 @Path("{deviceId}")
90 public Response getFlowByDeviceId(@PathParam("deviceId") String deviceId) {
Phaneendra Mandaaec654c2015-09-23 19:02:23 +053091 final Iterable<FlowEntry> flowEntries =
Ray Milkey4f5de002014-12-17 19:26:11 -080092 service.getFlowEntries(DeviceId.deviceId(deviceId));
93
Phaneendra Mandaaec654c2015-09-23 19:02:23 +053094 if (!flowEntries.iterator().hasNext()) {
Ray Milkey4f5de002014-12-17 19:26:11 -080095 throw new ItemNotFoundException(DEVICE_NOT_FOUND);
96 }
Phaneendra Mandaaec654c2015-09-23 19:02:23 +053097 for (final FlowEntry entry : flowEntries) {
Thomas Vachuska8683e012015-03-18 18:03:33 -070098 flowsNode.add(codec(FlowEntry.class).encode(entry, this));
Ray Milkey4f5de002014-12-17 19:26:11 -080099 }
Ray Milkey3f025692015-01-26 11:15:41 -0800100 return ok(root).build();
Ray Milkey4f5de002014-12-17 19:26:11 -0800101 }
102
103 /**
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700104 * Get flow rule. Returns the flow entry specified by the device id and
105 * flow rule id.
Ray Milkey4f5de002014-12-17 19:26:11 -0800106 *
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700107 * @param deviceId device identifier
108 * @param flowId flow rule identifier
Ray Milkey4f5de002014-12-17 19:26:11 -0800109 * @return flow data as an array
110 */
111 @GET
112 @Produces(MediaType.APPLICATION_JSON)
113 @Path("{deviceId}/{flowId}")
114 public Response getFlowByDeviceIdAndFlowId(@PathParam("deviceId") String deviceId,
115 @PathParam("flowId") long flowId) {
Phaneendra Mandaaec654c2015-09-23 19:02:23 +0530116 final Iterable<FlowEntry> flowEntries =
Ray Milkey4f5de002014-12-17 19:26:11 -0800117 service.getFlowEntries(DeviceId.deviceId(deviceId));
118
Phaneendra Mandaaec654c2015-09-23 19:02:23 +0530119 if (!flowEntries.iterator().hasNext()) {
Ray Milkey4f5de002014-12-17 19:26:11 -0800120 throw new ItemNotFoundException(DEVICE_NOT_FOUND);
121 }
Phaneendra Mandaaec654c2015-09-23 19:02:23 +0530122 for (final FlowEntry entry : flowEntries) {
Ray Milkey4f5de002014-12-17 19:26:11 -0800123 if (entry.id().value() == flowId) {
Thomas Vachuska8683e012015-03-18 18:03:33 -0700124 flowsNode.add(codec(FlowEntry.class).encode(entry, this));
Ray Milkey4f5de002014-12-17 19:26:11 -0800125 }
126 }
Ray Milkey3f025692015-01-26 11:15:41 -0800127 return ok(root).build();
Ray Milkey4f5de002014-12-17 19:26:11 -0800128 }
Ray Milkeyd43fe452015-05-29 09:35:12 -0700129
130 /**
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700131 * Create new flow rule. Creates and installs a new flow rule for the
132 * specified device.
Ray Milkeyd43fe452015-05-29 09:35:12 -0700133 *
Madan Jampani0dbac7a2015-06-25 10:37:45 -0700134 * @param deviceId device identifier
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700135 * @param stream flow rule JSON
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700136 * @return status of the request - CREATED if the JSON is correct,
Ray Milkeyd43fe452015-05-29 09:35:12 -0700137 * BAD_REQUEST if the JSON is invalid
138 */
139 @POST
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700140 @Path("{deviceId}")
Ray Milkeyd43fe452015-05-29 09:35:12 -0700141 @Consumes(MediaType.APPLICATION_JSON)
142 @Produces(MediaType.APPLICATION_JSON)
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700143 public Response createFlow(@PathParam("deviceId") String deviceId,
144 InputStream stream) {
145 URI location;
Ray Milkeyd43fe452015-05-29 09:35:12 -0700146 try {
Ray Milkey5d915f42015-08-13 10:27:53 -0700147 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
148 JsonNode specifiedDeviceId = jsonTree.get("deviceId");
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700149 if (specifiedDeviceId != null &&
150 !specifiedDeviceId.asText().equals(deviceId)) {
151 throw new IllegalArgumentException(
152 "Invalid deviceId in flow creation request");
153 }
Ray Milkey5d915f42015-08-13 10:27:53 -0700154 jsonTree.put("deviceId", deviceId);
155 FlowRule rule = codec(FlowRule.class).decode(jsonTree, this);
Ray Milkeyd43fe452015-05-29 09:35:12 -0700156 service.applyFlowRules(rule);
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700157 location = new URI(Long.toString(rule.id().value()));
158 } catch (IOException | URISyntaxException ex) {
Ray Milkey5d915f42015-08-13 10:27:53 -0700159 throw new IllegalArgumentException(ex);
Ray Milkeyd43fe452015-05-29 09:35:12 -0700160 }
Ray Milkey5d915f42015-08-13 10:27:53 -0700161
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700162 return Response
163 .created(location)
164 .build();
165 }
166
167 /**
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700168 * Remove flow rule. Removes the specified flow rule.
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700169 *
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700170 * @param deviceId device identifier
171 * @param flowId flow rule identifier
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700172 */
173 @DELETE
174 @Produces(MediaType.APPLICATION_JSON)
175 @Path("{deviceId}/{flowId}")
176 public void deleteFlowByDeviceIdAndFlowId(@PathParam("deviceId") String deviceId,
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700177 @PathParam("flowId") long flowId) {
Phaneendra Mandaaec654c2015-09-23 19:02:23 +0530178 final Iterable<FlowEntry> flowEntries =
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700179 service.getFlowEntries(DeviceId.deviceId(deviceId));
180
Phaneendra Mandaaec654c2015-09-23 19:02:23 +0530181 if (!flowEntries.iterator().hasNext()) {
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700182 throw new ItemNotFoundException(DEVICE_NOT_FOUND);
183 }
184
Phaneendra Mandaaec654c2015-09-23 19:02:23 +0530185 StreamSupport.stream(flowEntries.spliterator(), false)
Ray Milkeyeb5c7172015-06-23 14:59:27 -0700186 .filter(entry -> entry.id().value() == flowId)
187 .forEach(service::removeFlowRules);
Ray Milkeyd43fe452015-05-29 09:35:12 -0700188 }
189
Ray Milkey4f5de002014-12-17 19:26:11 -0800190}