blob: 0f423a4e6e27b4d865e3eded0ef047f4fa1a6416 [file] [log] [blame]
Jian Li5c411232015-12-16 15:29:16 -08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Jian Li5c411232015-12-16 15:29:16 -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;
pierventrec0914ec2021-08-27 15:25:02 +020021import org.onosproject.core.ApplicationId;
22import org.onosproject.core.CoreService;
Jian Li5c411232015-12-16 15:29:16 -080023import org.onosproject.net.DeviceId;
Yoonseon Han59ecdf32016-09-28 14:18:59 -070024import org.onosproject.net.device.DeviceService;
Jian Li5c411232015-12-16 15:29:16 -080025import org.onosproject.net.meter.DefaultMeterRequest;
26import org.onosproject.net.meter.Meter;
pierventrec0914ec2021-08-27 15:25:02 +020027import org.onosproject.net.meter.MeterCellId;
Jian Li5c411232015-12-16 15:29:16 -080028import org.onosproject.net.meter.MeterId;
29import org.onosproject.net.meter.MeterRequest;
pierventrec0914ec2021-08-27 15:25:02 +020030import org.onosproject.net.meter.MeterScope;
Jian Li5c411232015-12-16 15:29:16 -080031import org.onosproject.net.meter.MeterService;
pierventrec0914ec2021-08-27 15:25:02 +020032import org.onosproject.net.pi.model.PiMeterId;
33import org.onosproject.net.pi.runtime.PiMeterCellId;
Jian Li5c411232015-12-16 15:29:16 -080034import org.onosproject.rest.AbstractWebResource;
Jian Li5c411232015-12-16 15:29:16 -080035
36import javax.ws.rs.Consumes;
37import javax.ws.rs.DELETE;
38import javax.ws.rs.GET;
39import javax.ws.rs.POST;
40import javax.ws.rs.Path;
41import javax.ws.rs.PathParam;
42import javax.ws.rs.Produces;
Jian Li9d616492016-03-09 10:52:49 -080043import javax.ws.rs.core.Context;
Jian Li5c411232015-12-16 15:29:16 -080044import javax.ws.rs.core.MediaType;
45import javax.ws.rs.core.Response;
Jian Li9d616492016-03-09 10:52:49 -080046import javax.ws.rs.core.UriBuilder;
47import javax.ws.rs.core.UriInfo;
Jian Li5c411232015-12-16 15:29:16 -080048import java.io.IOException;
49import java.io.InputStream;
Jian Li5c411232015-12-16 15:29:16 -080050
51import static org.onlab.util.Tools.nullIsNotFound;
Ray Milkey86ee5e82018-04-02 15:33:07 -070052import static org.onlab.util.Tools.readTreeFromStream;
Jian Li5c411232015-12-16 15:29:16 -080053
54/**
55 * Query and program meter rules.
56 */
57@Path("meters")
58public class MetersWebResource extends AbstractWebResource {
Jian Li9d616492016-03-09 10:52:49 -080059
60 @Context
Jian Licc730a62016-05-10 16:36:16 -070061 private UriInfo uriInfo;
Jian Li9d616492016-03-09 10:52:49 -080062
Jian Licc730a62016-05-10 16:36:16 -070063 private static final String DEVICE_INVALID = "Invalid deviceId in meter creation request";
64 private static final String METER_NOT_FOUND = "Meter is not found for ";
Jian Li5c411232015-12-16 15:29:16 -080065
Jian Licc730a62016-05-10 16:36:16 -070066 private final ObjectNode root = mapper().createObjectNode();
67 private final ArrayNode metersNode = root.putArray("meters");
Jian Li5c411232015-12-16 15:29:16 -080068
pierventrec0914ec2021-08-27 15:25:02 +020069 private static final String REST_APP_ID = "org.onosproject.rest";
70 private ApplicationId applicationId;
71
Jian Li5c411232015-12-16 15:29:16 -080072 /**
73 * Returns all meters of all devices.
74 *
Jian Licc730a62016-05-10 16:36:16 -070075 * @return 200 OK with array of all the meters in the system
Jian Li5c411232015-12-16 15:29:16 -080076 * @onos.rsModel Meters
77 */
78 @GET
79 @Produces(MediaType.APPLICATION_JSON)
80 public Response getMeters() {
Andrea Campanella0ab52ba2020-06-10 13:24:38 +020081 MeterService meterService = get(MeterService.class);
Jian Li5c411232015-12-16 15:29:16 -080082 final Iterable<Meter> meters = meterService.getAllMeters();
83 if (meters != null) {
84 meters.forEach(meter -> metersNode.add(codec(Meter.class).encode(meter, this)));
85 }
86 return ok(root).build();
87 }
88
89 /**
Jian Lia4faf4f2016-01-06 00:22:52 -080090 * Returns a collection of meters by the device id.
91 *
92 * @param deviceId device identifier
Jian Licc730a62016-05-10 16:36:16 -070093 * @return 200 OK with array of meters which belongs to specified device
Jian Lia4faf4f2016-01-06 00:22:52 -080094 * @onos.rsModel Meters
95 */
96 @GET
97 @Produces(MediaType.APPLICATION_JSON)
98 @Path("{deviceId}")
99 public Response getMetersByDeviceId(@PathParam("deviceId") String deviceId) {
100 DeviceId did = DeviceId.deviceId(deviceId);
Andrea Campanella0ab52ba2020-06-10 13:24:38 +0200101 MeterService meterService = get(MeterService.class);
Jian Lia4faf4f2016-01-06 00:22:52 -0800102 final Iterable<Meter> meters = meterService.getMeters(did);
103 if (meters != null) {
104 meters.forEach(meter -> metersNode.add(codec(Meter.class).encode(meter, this)));
105 }
106 return ok(root).build();
107 }
108
109 /**
Jian Li5c411232015-12-16 15:29:16 -0800110 * Returns a meter by the meter id.
111 *
112 * @param deviceId device identifier
Jian Lidfba7392016-01-22 16:46:58 -0800113 * @param meterId meter identifier
Jian Licc730a62016-05-10 16:36:16 -0700114 * @return 200 OK with a meter, return 404 if no entry has been found
Jian Li5c411232015-12-16 15:29:16 -0800115 * @onos.rsModel Meter
116 */
117 @GET
118 @Produces(MediaType.APPLICATION_JSON)
119 @Path("{deviceId}/{meterId}")
120 public Response getMeterByDeviceIdAndMeterId(@PathParam("deviceId") String deviceId,
121 @PathParam("meterId") String meterId) {
122 DeviceId did = DeviceId.deviceId(deviceId);
pierventrec0914ec2021-08-27 15:25:02 +0200123 MeterCellId mid = MeterId.meterId(Long.valueOf(meterId));
Andrea Campanella0ab52ba2020-06-10 13:24:38 +0200124 MeterService meterService = get(MeterService.class);
Jian Li5c411232015-12-16 15:29:16 -0800125 final Meter meter = nullIsNotFound(meterService.getMeter(did, mid),
pierventrec0914ec2021-08-27 15:25:02 +0200126 METER_NOT_FOUND + mid);
Jian Li5c411232015-12-16 15:29:16 -0800127
128 metersNode.add(codec(Meter.class).encode(meter, this));
129 return ok(root).build();
130 }
131
132 /**
pierventrec0914ec2021-08-27 15:25:02 +0200133 * Returns a meter by the meter cell id.
134 *
135 * @param deviceId device identifier
136 * @param scope scope identifier
137 * @param index index
138 * @return 200 OK with a meter, return 404 if no entry has been found
139 * @onos.rsModel Meter
140 */
141 @GET
142 @Produces(MediaType.APPLICATION_JSON)
143 @Path("{deviceId}/{scope}/{index}")
144 public Response getMeterByDeviceIdAndMeterCellId(@PathParam("deviceId") String deviceId,
145 @PathParam("scope") String scope,
146 @PathParam("index") String index) {
147 DeviceId did = DeviceId.deviceId(deviceId);
148 MeterScope meterScope = MeterScope.of(scope);
149 long meterIndex = Long.parseLong(index);
150 MeterCellId meterCellId;
151 if (meterScope.equals(MeterScope.globalScope())) {
152 meterCellId = MeterId.meterId(meterIndex);
153 } else {
154 meterCellId = PiMeterCellId.ofIndirect(PiMeterId.of(meterScope.id()), meterIndex);
155 }
156
157 MeterService meterService = get(MeterService.class);
158 final Meter meter = nullIsNotFound(meterService.getMeter(did, meterCellId),
159 METER_NOT_FOUND + meterCellId);
160
161 metersNode.add(codec(Meter.class).encode(meter, this));
162 return ok(root).build();
163 }
164
165 /**
166 * Returns a collection of meters by the device id and meter scope.
167 *
168 * @param deviceId device identifier
169 * @param scope scope identifier
170 * @return 200 OK with array of meters which belongs to specified device
171 * @onos.rsModel Meters
172 */
173 @GET
174 @Produces(MediaType.APPLICATION_JSON)
175 @Path("scope/{deviceId}/{scope}")
176 public Response getMetersByDeviceIdAndScope(@PathParam("deviceId") String deviceId,
177 @PathParam("scope") String scope) {
178 DeviceId did = DeviceId.deviceId(deviceId);
179 MeterScope meterScope = MeterScope.of(scope);
180 MeterService meterService = get(MeterService.class);
181 final Iterable<Meter> meters = meterService.getMeters(did, meterScope);
182 if (meters != null) {
183 meters.forEach(meter -> metersNode.add(codec(Meter.class).encode(meter, this)));
184 }
185 return ok(root).build();
186 }
187
188 /**
Jian Licc730a62016-05-10 16:36:16 -0700189 * Creates new meter rule. Creates and installs a new meter rule for the
Jian Li5c411232015-12-16 15:29:16 -0800190 * specified device.
191 *
192 * @param deviceId device identifier
193 * @param stream meter rule JSON
194 * @return status of the request - CREATED if the JSON is correct,
195 * BAD_REQUEST if the JSON is invalid
196 * @onos.rsModel MeterPost
197 */
198 @POST
199 @Path("{deviceId}")
200 @Consumes(MediaType.APPLICATION_JSON)
201 @Produces(MediaType.APPLICATION_JSON)
202 public Response createMeter(@PathParam("deviceId") String deviceId,
203 InputStream stream) {
Jian Li5c411232015-12-16 15:29:16 -0800204 try {
Ray Milkey86ee5e82018-04-02 15:33:07 -0700205 ObjectNode jsonTree = readTreeFromStream(mapper(), stream);
Jian Li5c411232015-12-16 15:29:16 -0800206 JsonNode specifiedDeviceId = jsonTree.get("deviceId");
207
Yoonseon Han59ecdf32016-09-28 14:18:59 -0700208 if ((specifiedDeviceId != null &&
209 !specifiedDeviceId.asText().equals(deviceId)) ||
210 get(DeviceService.class).getDevice(DeviceId.deviceId(deviceId))
211 == null) {
Jian Li5c411232015-12-16 15:29:16 -0800212 throw new IllegalArgumentException(DEVICE_INVALID);
213 }
Yoonseon Han59ecdf32016-09-28 14:18:59 -0700214
Jian Li5c411232015-12-16 15:29:16 -0800215 jsonTree.put("deviceId", deviceId);
Yoonseon Han59ecdf32016-09-28 14:18:59 -0700216 final MeterRequest meterRequest = codec(MeterRequest.class)
217 .decode(jsonTree, this);
218
Andrea Campanella0ab52ba2020-06-10 13:24:38 +0200219 MeterService meterService = get(MeterService.class);
Jian Li5c411232015-12-16 15:29:16 -0800220 final Meter meter = meterService.submit(meterRequest);
Jian Li9d616492016-03-09 10:52:49 -0800221
222 UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
223 .path("meters")
224 .path(deviceId)
225 .path(Long.toString(meter.id().id()));
226 return Response
227 .created(locationBuilder.build())
228 .build();
229 } catch (IOException ex) {
Jian Li5c411232015-12-16 15:29:16 -0800230 throw new IllegalArgumentException(ex);
231 }
Jian Li5c411232015-12-16 15:29:16 -0800232 }
233
234 /**
pierventrec0914ec2021-08-27 15:25:02 +0200235 * Removes the meter by device id and meter id.
Jian Li5c411232015-12-16 15:29:16 -0800236 *
237 * @param deviceId device identifier
238 * @param meterId meter identifier
Jian Lic2a542b2016-05-10 11:48:19 -0700239 * @return 204 NO CONTENT
Jian Li5c411232015-12-16 15:29:16 -0800240 */
241 @DELETE
Jian Li5c411232015-12-16 15:29:16 -0800242 @Path("{deviceId}/{meterId}")
Jian Lic2a542b2016-05-10 11:48:19 -0700243 public Response deleteMeterByDeviceIdAndMeterId(@PathParam("deviceId") String deviceId,
pierventrec0914ec2021-08-27 15:25:02 +0200244 @PathParam("meterId") String meterId) {
Jian Li5c411232015-12-16 15:29:16 -0800245 DeviceId did = DeviceId.deviceId(deviceId);
pierventrec0914ec2021-08-27 15:25:02 +0200246 MeterCellId mid = MeterId.meterId(Long.valueOf(meterId));
247 MeterRequest meterRequest = deleteRequest(did);
Andrea Campanella0ab52ba2020-06-10 13:24:38 +0200248
249 MeterService meterService = get(MeterService.class);
pierventrec0914ec2021-08-27 15:25:02 +0200250 meterService.withdraw(meterRequest, mid);
251
Jian Lic2a542b2016-05-10 11:48:19 -0700252 return Response.noContent().build();
Jian Li5c411232015-12-16 15:29:16 -0800253 }
254
255 /**
pierventrec0914ec2021-08-27 15:25:02 +0200256 * Removes the meter by the device id and meter cell id.
Jian Li5c411232015-12-16 15:29:16 -0800257 *
pierventrec0914ec2021-08-27 15:25:02 +0200258 * @param deviceId device identifier
259 * @param scope scope identifier
260 * @param index index
261 * @return 204 NO CONTENT
Jian Li5c411232015-12-16 15:29:16 -0800262 */
pierventrec0914ec2021-08-27 15:25:02 +0200263 @DELETE
264 @Path("{deviceId}/{scope}/{index}")
265 public Response deleteMeterByDeviceIdAndMeterCellId(@PathParam("deviceId") String deviceId,
266 @PathParam("scope") String scope,
267 @PathParam("index") String index) {
268 DeviceId did = DeviceId.deviceId(deviceId);
269 MeterScope meterScope = MeterScope.of(scope);
270 long meterIndex = Long.parseLong(index);
271 MeterCellId meterCellId;
272 if (meterScope.equals(MeterScope.globalScope())) {
273 meterCellId = MeterId.meterId(meterIndex);
Jian Li5c411232015-12-16 15:29:16 -0800274 } else {
pierventrec0914ec2021-08-27 15:25:02 +0200275 meterCellId = PiMeterCellId.ofIndirect(PiMeterId.of(meterScope.id()), meterIndex);
276 }
277 MeterRequest meterRequest = deleteRequest(did);
278
279 MeterService meterService = get(MeterService.class);
280 meterService.withdraw(meterRequest, meterCellId);
281
282 return Response.noContent().build();
283 }
284
285 private MeterRequest deleteRequest(DeviceId did) {
286 CoreService coreService = getService(CoreService.class);
287 if (applicationId == null) {
288 applicationId = coreService.registerApplication(REST_APP_ID);
Jian Li5c411232015-12-16 15:29:16 -0800289 }
290
pierventrec0914ec2021-08-27 15:25:02 +0200291 return DefaultMeterRequest.builder()
292 .forDevice(did)
293 .fromApp(applicationId)
294 .remove();
Jian Li5c411232015-12-16 15:29:16 -0800295 }
Jian Li9d616492016-03-09 10:52:49 -0800296}