blob: a0875d59bd103e5f4bcf0609f713c6dbaa2a5c73 [file] [log] [blame]
Jian Liecb3c0f2015-12-15 10:07:49 -08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Jian Liecb3c0f2015-12-15 10:07:49 -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.ArrayNode;
20import com.fasterxml.jackson.databind.node.ObjectNode;
21import org.onosproject.net.Device;
22import org.onosproject.net.DeviceId;
23import org.onosproject.net.device.DeviceService;
24import org.onosproject.net.group.DefaultGroupDescription;
25import org.onosproject.net.group.DefaultGroupKey;
26import org.onosproject.net.group.Group;
27import org.onosproject.net.group.GroupDescription;
28import org.onosproject.net.group.GroupKey;
29import org.onosproject.net.group.GroupService;
30import org.onosproject.rest.AbstractWebResource;
31
32import javax.ws.rs.Consumes;
33import javax.ws.rs.DELETE;
34import javax.ws.rs.GET;
35import javax.ws.rs.POST;
36import javax.ws.rs.Path;
37import javax.ws.rs.PathParam;
38import javax.ws.rs.Produces;
Jian Li9d616492016-03-09 10:52:49 -080039import javax.ws.rs.core.Context;
Jian Liecb3c0f2015-12-15 10:07:49 -080040import javax.ws.rs.core.MediaType;
41import javax.ws.rs.core.Response;
Jian Li9d616492016-03-09 10:52:49 -080042import javax.ws.rs.core.UriBuilder;
43import javax.ws.rs.core.UriInfo;
Jian Liecb3c0f2015-12-15 10:07:49 -080044import java.io.IOException;
45import java.io.InputStream;
Jian Liecb3c0f2015-12-15 10:07:49 -080046
Varun Sharma1853b3f2016-07-18 14:37:13 +053047import org.onlab.util.HexString;
Jian Lia7f86ce2015-12-20 13:42:10 -080048import static org.onlab.util.Tools.nullIsNotFound;
Ray Milkey86ee5e82018-04-02 15:33:07 -070049import static org.onlab.util.Tools.readTreeFromStream;
Jian Lia7f86ce2015-12-20 13:42:10 -080050
Jian Liecb3c0f2015-12-15 10:07:49 -080051/**
52 * Query and program group rules.
53 */
54
55@Path("groups")
56public class GroupsWebResource extends AbstractWebResource {
Jian Li9d616492016-03-09 10:52:49 -080057
58 @Context
Jian Licc730a62016-05-10 16:36:16 -070059 private UriInfo uriInfo;
Jian Li9d616492016-03-09 10:52:49 -080060
Jian Licc730a62016-05-10 16:36:16 -070061 private static final String DEVICE_INVALID = "Invalid deviceId in group creation request";
62 private static final String GROUP_NOT_FOUND = "Group was not found";
Jian Liecb3c0f2015-12-15 10:07:49 -080063
Jian Licc730a62016-05-10 16:36:16 -070064 private final GroupService groupService = get(GroupService.class);
65 private final ObjectNode root = mapper().createObjectNode();
66 private final ArrayNode groupsNode = root.putArray("groups");
Jian Liecb3c0f2015-12-15 10:07:49 -080067
68 /**
69 * Returns all groups of all devices.
Jian Lia7f86ce2015-12-20 13:42:10 -080070 *
Jian Licc730a62016-05-10 16:36:16 -070071 * @return 200 OK with array of all the groups in the system
Jian Lia7f86ce2015-12-20 13:42:10 -080072 * @onos.rsModel Groups
Jian Liecb3c0f2015-12-15 10:07:49 -080073 */
74 @GET
75 @Produces(MediaType.APPLICATION_JSON)
76 public Response getGroups() {
77 final Iterable<Device> devices = get(DeviceService.class).getDevices();
78 devices.forEach(device -> {
79 final Iterable<Group> groups = groupService.getGroups(device.id());
80 if (groups != null) {
81 groups.forEach(group -> groupsNode.add(codec(Group.class).encode(group, this)));
82 }
83 });
84
85 return ok(root).build();
86 }
87
88 /**
89 * Returns all groups associated with the given device.
90 *
91 * @param deviceId device identifier
Jian Licc730a62016-05-10 16:36:16 -070092 * @return 200 OK with array of all the groups in the system
Jian Lia7f86ce2015-12-20 13:42:10 -080093 * @onos.rsModel Groups
Jian Liecb3c0f2015-12-15 10:07:49 -080094 */
95 @GET
96 @Produces(MediaType.APPLICATION_JSON)
97 @Path("{deviceId}")
98 public Response getGroupsByDeviceId(@PathParam("deviceId") String deviceId) {
99 final Iterable<Group> groups = groupService.getGroups(DeviceId.deviceId(deviceId));
100
101 groups.forEach(group -> groupsNode.add(codec(Group.class).encode(group, this)));
102
103 return ok(root).build();
104 }
105
106 /**
Jian Lia7f86ce2015-12-20 13:42:10 -0800107 * Returns a group with the given deviceId and appCookie.
108 *
109 * @param deviceId device identifier
110 * @param appCookie group key
Jian Licc730a62016-05-10 16:36:16 -0700111 * @return 200 OK with a group entry in the system
Jian Lia7f86ce2015-12-20 13:42:10 -0800112 * @onos.rsModel Group
113 */
114 @GET
115 @Produces(MediaType.APPLICATION_JSON)
116 @Path("{deviceId}/{appCookie}")
117 public Response getGroupByDeviceIdAndAppCookie(@PathParam("deviceId") String deviceId,
118 @PathParam("appCookie") String appCookie) {
119 final DeviceId deviceIdInstance = DeviceId.deviceId(deviceId);
Varun Sharma1853b3f2016-07-18 14:37:13 +0530120
121 if (!appCookie.startsWith("0x")) {
122 throw new IllegalArgumentException("APP_COOKIE must be a hex string starts with 0x");
123 }
124 final GroupKey appCookieInstance = new DefaultGroupKey(HexString.fromHexString(
125 appCookie.split("0x")[1], ""));
Jian Lia7f86ce2015-12-20 13:42:10 -0800126
127 Group group = nullIsNotFound(groupService.getGroup(deviceIdInstance, appCookieInstance),
128 GROUP_NOT_FOUND);
129
130 groupsNode.add(codec(Group.class).encode(group, this));
131 return ok(root).build();
132 }
133
134 /**
Jian Liecb3c0f2015-12-15 10:07:49 -0800135 * Create new group rule. Creates and installs a new group rule for the
136 * specified device.
137 *
138 * @param deviceId device identifier
139 * @param stream group rule JSON
Jian Liecb3c0f2015-12-15 10:07:49 -0800140 * @return status of the request - CREATED if the JSON is correct,
141 * BAD_REQUEST if the JSON is invalid
Jian Lia7f86ce2015-12-20 13:42:10 -0800142 * @onos.rsModel GroupsPost
Jian Liecb3c0f2015-12-15 10:07:49 -0800143 */
144 @POST
145 @Path("{deviceId}")
146 @Consumes(MediaType.APPLICATION_JSON)
147 @Produces(MediaType.APPLICATION_JSON)
148 public Response createGroup(@PathParam("deviceId") String deviceId,
149 InputStream stream) {
Jian Liecb3c0f2015-12-15 10:07:49 -0800150 try {
Jian Li9d616492016-03-09 10:52:49 -0800151
Ray Milkey86ee5e82018-04-02 15:33:07 -0700152 ObjectNode jsonTree = readTreeFromStream(mapper(), stream);
Jian Liecb3c0f2015-12-15 10:07:49 -0800153 JsonNode specifiedDeviceId = jsonTree.get("deviceId");
154
155 if (specifiedDeviceId != null &&
156 !specifiedDeviceId.asText().equals(deviceId)) {
157 throw new IllegalArgumentException(DEVICE_INVALID);
158 }
159 jsonTree.put("deviceId", deviceId);
160 Group group = codec(Group.class).decode(jsonTree, this);
161 GroupDescription description = new DefaultGroupDescription(
162 group.deviceId(), group.type(), group.buckets(),
163 group.appCookie(), group.id().id(), group.appId());
164 groupService.addGroup(description);
Jian Li9d616492016-03-09 10:52:49 -0800165 UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
166 .path("groups")
167 .path(deviceId)
168 .path(Long.toString(group.id().id()));
169 return Response
170 .created(locationBuilder.build())
171 .build();
172 } catch (IOException ex) {
Jian Liecb3c0f2015-12-15 10:07:49 -0800173 throw new IllegalArgumentException(ex);
174 }
Jian Liecb3c0f2015-12-15 10:07:49 -0800175 }
176
177 /**
178 * Removes the specified group.
179 *
180 * @param deviceId device identifier
181 * @param appCookie application cookie to be used for lookup
Jian Lic2a542b2016-05-10 11:48:19 -0700182 * @return 204 NO CONTENT
Jian Liecb3c0f2015-12-15 10:07:49 -0800183 */
184 @DELETE
Jian Liecb3c0f2015-12-15 10:07:49 -0800185 @Path("{deviceId}/{appCookie}")
Jian Lic2a542b2016-05-10 11:48:19 -0700186 public Response deleteGroupByDeviceIdAndAppCookie(@PathParam("deviceId") String deviceId,
187 @PathParam("appCookie") String appCookie) {
Jian Liecb3c0f2015-12-15 10:07:49 -0800188 DeviceId deviceIdInstance = DeviceId.deviceId(deviceId);
Varun Sharma1853b3f2016-07-18 14:37:13 +0530189
190 if (!appCookie.startsWith("0x")) {
191 throw new IllegalArgumentException("APP_COOKIE must be a hex string starts with 0x");
192 }
193 GroupKey appCookieInstance = new DefaultGroupKey(HexString.fromHexString(
194 appCookie.split("0x")[1], ""));
Jian Liecb3c0f2015-12-15 10:07:49 -0800195
196 groupService.removeGroup(deviceIdInstance, appCookieInstance, null);
Jian Lic2a542b2016-05-10 11:48:19 -0700197 return Response.noContent().build();
Jian Liecb3c0f2015-12-15 10:07:49 -0800198 }
199}