blob: 4ddf91de049c89fd85ef0fca281769fbfd97a176 [file] [log] [blame]
alshabib58fe6dc2015-08-19 17:16:13 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
alshabib58fe6dc2015-08-19 17:16:13 -07003 *
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.cli.net;
17
Ray Milkeyd84f89b2018-08-17 14:54:17 -070018import org.apache.karaf.shell.api.action.Argument;
19import org.apache.karaf.shell.api.action.Command;
Ray Milkey0068fd02018-10-11 15:45:39 -070020import org.apache.karaf.shell.api.action.Completion;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070021import org.apache.karaf.shell.api.action.lifecycle.Service;
22import org.apache.karaf.shell.api.action.Option;
alshabib58fe6dc2015-08-19 17:16:13 -070023import org.onosproject.cli.AbstractShellCommand;
24import org.onosproject.core.CoreService;
25import org.onosproject.net.DeviceId;
26import org.onosproject.net.meter.Band;
27import org.onosproject.net.meter.DefaultBand;
alshabibe1248b62015-08-20 17:21:55 -070028import org.onosproject.net.meter.DefaultMeterRequest;
alshabib58fe6dc2015-08-19 17:16:13 -070029import org.onosproject.net.meter.Meter;
alshabibe1248b62015-08-20 17:21:55 -070030import org.onosproject.net.meter.MeterRequest;
pierventrec0914ec2021-08-27 15:25:02 +020031import org.onosproject.net.meter.MeterScope;
alshabib58fe6dc2015-08-19 17:16:13 -070032import org.onosproject.net.meter.MeterService;
33
Jordi Ortiz3bbfd992017-01-21 19:29:52 +010034import static com.google.common.base.Strings.isNullOrEmpty;
Jordi Ortiz161445a2017-02-15 18:29:04 +010035
Jordi Ortiz3bbfd992017-01-21 19:29:52 +010036import java.util.HashSet;
37import java.util.Set;
alshabib58fe6dc2015-08-19 17:16:13 -070038
39/**
sangyun-han483731c2016-06-06 12:03:16 +090040 * Add a meter to a device.
alshabib58fe6dc2015-08-19 17:16:13 -070041 */
Ray Milkeyd84f89b2018-08-17 14:54:17 -070042@Service
Jordi Ortiz4c93e272017-01-30 13:25:51 +010043@Command(scope = "onos", name = "meter-add",
alshabib58fe6dc2015-08-19 17:16:13 -070044 description = "Adds a meter to a device (currently for testing)")
Jordi Ortiz4c93e272017-01-30 13:25:51 +010045public class MeterAddCommand extends AbstractShellCommand {
alshabib58fe6dc2015-08-19 17:16:13 -070046
Jordi Ortiz3bbfd992017-01-21 19:29:52 +010047 private Meter.Unit unit;
48 private Set<Band> bands = new HashSet<>();
pierventrec0914ec2021-08-27 15:25:02 +020049 private MeterScope scope;
50 private Long index;
Jordi Ortiz3bbfd992017-01-21 19:29:52 +010051
52 @Option(name = "-bd", aliases = "--bandDrop",
53 description = "Assign band DROP to this meter",
54 required = false, multiValued = false)
55 private boolean hasBandDrop = false;
56
57 @Option(name = "-br", aliases = "--bandRemark",
58 description = "Assign band REMARK to this meter",
59 required = false, multiValued = false)
60 private boolean hasBandRemark = false;
61
pierventrec0914ec2021-08-27 15:25:02 +020062 @Option(name = "-by", aliases = "--bandYel",
63 description = "Assign band MARK_YELLOW to this meter",
64 required = false, multiValued = false)
65 private boolean hasBandYel = false;
66
67 @Option(name = "-bre", aliases = "--bandRed",
68 description = "Assign band MARK_RED to this meter",
69 required = false, multiValued = false)
70 private boolean hasBandRed = false;
71
Jordi Ortiz3bbfd992017-01-21 19:29:52 +010072 @Option(name = "-up", aliases = "--unitPkts",
73 description = "Assign unit Packets per Second to this meter",
74 required = false, multiValued = false)
75 private boolean hasPkts = false;
76
77 @Option(name = "-uk", aliases = "--unitKbps",
78 description = "Assign unit Kilobits per Second to this meter",
79 required = false, multiValued = false)
80 private boolean hasKbps = false;
81
pierventrec0914ec2021-08-27 15:25:02 +020082 @Option(name = "-ub", aliases = "--unitBytes",
83 description = "Assign unit Bytes per Second to this meter",
84 required = false, multiValued = false)
85 private boolean hasBytes = false;
86
Jordi Ortiz3bbfd992017-01-21 19:29:52 +010087 @Option(name = "-ib", aliases = "--isBurst",
88 description = "Set meter applicable only to burst",
89 required = false, multiValued = false)
90 private boolean isBurst = false;
91
92 @Option(name = "-b", aliases = "--bandwidth", description = "Bandwidth",
pierventrec0914ec2021-08-27 15:25:02 +020093 required = false, multiValued = true)
94 private String[] bandwidthString = null;
Jordi Ortiz3bbfd992017-01-21 19:29:52 +010095
96 @Option(name = "-bs", aliases = "--burstSize", description = "Burst size",
pierventrec0914ec2021-08-27 15:25:02 +020097 required = false, multiValued = true)
98 private String[] burstSizeString = null;
99
100 @Option(name = "-sc", aliases = "--scope", description = "Scope",
Jordi Ortiz3bbfd992017-01-21 19:29:52 +0100101 required = false, multiValued = false)
pierventrec0914ec2021-08-27 15:25:02 +0200102 private String scopeString = null;
103
104 @Option(name = "-id", aliases = "--index", description = "Index",
105 required = false, multiValued = false)
106 private String indexString = null;
Jordi Ortiz3bbfd992017-01-21 19:29:52 +0100107
alshabib58fe6dc2015-08-19 17:16:13 -0700108 @Argument(index = 0, name = "uri", description = "Device ID",
109 required = true, multiValued = false)
Ray Milkey0068fd02018-10-11 15:45:39 -0700110 @Completion(DeviceIdCompleter.class)
Jordi Ortiz3bbfd992017-01-21 19:29:52 +0100111 private String uri = null;
alshabib58fe6dc2015-08-19 17:16:13 -0700112
alshabibe1248b62015-08-20 17:21:55 -0700113 private final String appId = "org.onosproject.cli.meterCmd";
alshabib58fe6dc2015-08-19 17:16:13 -0700114
Jordi Ortiz3bbfd992017-01-21 19:29:52 +0100115 private void checkOptions() {
116 // check units
117 if (hasPkts) {
118 unit = Meter.Unit.PKTS_PER_SEC;
pierventrec0914ec2021-08-27 15:25:02 +0200119 } else if (hasKbps) {
Jordi Ortiz3bbfd992017-01-21 19:29:52 +0100120 unit = Meter.Unit.KB_PER_SEC;
pierventrec0914ec2021-08-27 15:25:02 +0200121 } else if (hasBytes) {
122 unit = Meter.Unit.BYTES_PER_SEC;
Jordi Ortiz3bbfd992017-01-21 19:29:52 +0100123 }
124
pierventrec0914ec2021-08-27 15:25:02 +0200125 int numBands = 0;
126 if (hasBandDrop) {
127 numBands++;
128 }
129 if (hasBandRemark) {
130 numBands++;
131 }
132 if (hasBandYel) {
133 numBands++;
134 }
135 if (hasBandRed) {
136 numBands++;
137 }
138
139 long[] rates = new long[numBands];
140 long[] bursts = new long[numBands];
Jordi Ortiz3bbfd992017-01-21 19:29:52 +0100141 // check rate (does not take into account if it is kbps or pkts)
pierventrec0914ec2021-08-27 15:25:02 +0200142 if (bandwidthString != null && bandwidthString.length == numBands &&
143 burstSizeString != null && burstSizeString.length == numBands) {
144 for (int i = 0; i < bandwidthString.length; i++) {
145 rates[i] = 500L;
146 bursts[i] = 0L;
147 if (!isNullOrEmpty(bandwidthString[i])) {
148 rates[i] = Long.parseLong(bandwidthString[i]);
149 }
150 if (!isNullOrEmpty(burstSizeString[i])) {
151 bursts[i] = Long.parseLong(burstSizeString[i]);
152 }
153 }
154 } else if (bandwidthString != null && bandwidthString.length < numBands &&
155 burstSizeString != null && burstSizeString.length < numBands) {
156 for (int i = 0; i < numBands; i++) {
157 rates[i] = 500L;
158 bursts[i] = 0L;
159 if (i < bandwidthString.length && !isNullOrEmpty(bandwidthString[i])) {
160 rates[i] = Long.parseLong(bandwidthString[i]);
161 }
162 if (i < burstSizeString.length && !isNullOrEmpty(burstSizeString[i])) {
163 bursts[i] = Long.parseLong(burstSizeString[i]);
164 }
165 }
Jordi Ortiz3bbfd992017-01-21 19:29:52 +0100166 }
167
168 // Create bands
pierventrec0914ec2021-08-27 15:25:02 +0200169 int i = 0;
Jordi Ortiz3bbfd992017-01-21 19:29:52 +0100170 if (hasBandDrop) {
171 Band band = DefaultBand.builder()
172 .ofType(Band.Type.DROP)
pierventrec0914ec2021-08-27 15:25:02 +0200173 .withRate(rates[i])
174 .burstSize(bursts[i])
Jordi Ortiz3bbfd992017-01-21 19:29:52 +0100175 .build();
176 bands.add(band);
pierventrec0914ec2021-08-27 15:25:02 +0200177 i++;
Jordi Ortiz3bbfd992017-01-21 19:29:52 +0100178 }
179 if (hasBandRemark) {
180 Band band = DefaultBand.builder()
181 .ofType(Band.Type.REMARK)
pierventrec0914ec2021-08-27 15:25:02 +0200182 .withRate(rates[i])
183 .burstSize(bursts[i])
184 .build();
185 bands.add(band);
186 i++;
187 }
188 if (hasBandYel) {
189 Band band = DefaultBand.builder()
190 .ofType(Band.Type.MARK_YELLOW)
191 .withRate(rates[i])
192 .burstSize(bursts[i])
193 .build();
194 bands.add(band);
195 i++;
196 }
197 if (hasBandRed) {
198 Band band = DefaultBand.builder()
199 .ofType(Band.Type.MARK_RED)
200 .withRate(rates[i])
201 .burstSize(bursts[i])
Jordi Ortiz3bbfd992017-01-21 19:29:52 +0100202 .build();
203 bands.add(band);
204 }
pierventrec0914ec2021-08-27 15:25:02 +0200205
Jordi Ortiz3bbfd992017-01-21 19:29:52 +0100206 // default band is drop
207 if (bands.size() == 0) {
208 Band band = DefaultBand.builder()
209 .ofType(Band.Type.DROP)
pierventrec0914ec2021-08-27 15:25:02 +0200210 .withRate(500L)
211 .burstSize(0L)
Jordi Ortiz3bbfd992017-01-21 19:29:52 +0100212 .build();
213 bands.add(band);
214 }
215
pierventrec0914ec2021-08-27 15:25:02 +0200216 if (!isNullOrEmpty(scopeString)) {
217 scope = MeterScope.of(scopeString);
218 }
Jordi Ortiz3bbfd992017-01-21 19:29:52 +0100219
pierventrec0914ec2021-08-27 15:25:02 +0200220 if (!isNullOrEmpty(indexString) && scope != null) {
221 index = Long.parseLong(indexString);
222 }
Jordi Ortiz3bbfd992017-01-21 19:29:52 +0100223 }
224
alshabib58fe6dc2015-08-19 17:16:13 -0700225 @Override
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700226 protected void doExecute() {
alshabib58fe6dc2015-08-19 17:16:13 -0700227 MeterService service = get(MeterService.class);
228 CoreService coreService = get(CoreService.class);
229
230 DeviceId deviceId = DeviceId.deviceId(uri);
231
Jordi Ortiz3bbfd992017-01-21 19:29:52 +0100232 checkOptions();
alshabib58fe6dc2015-08-19 17:16:13 -0700233
Jordi Ortiz3bbfd992017-01-21 19:29:52 +0100234 MeterRequest.Builder builder = DefaultMeterRequest.builder()
alshabib58fe6dc2015-08-19 17:16:13 -0700235 .forDevice(deviceId)
236 .fromApp(coreService.registerApplication(appId))
Jordi Ortiz3bbfd992017-01-21 19:29:52 +0100237 .withUnit(unit)
238 .withBands(bands);
239
Jordi Ortiz3bbfd992017-01-21 19:29:52 +0100240 if (isBurst) {
241 builder = builder.burst();
242 }
243
pierventrec0914ec2021-08-27 15:25:02 +0200244 // Scope is by default global but we can still provide the index
245 // otherwise we can specify both scope and index or let the meter
246 // service allocate the meter for us. User defined index requires
247 // the user defined mode being active.
248 if (scope != null) {
249 builder = builder.withScope(scope);
250 }
251
252 if (index != null) {
253 builder = builder.withIndex(index);
254 }
255
Jordi Ortiz3bbfd992017-01-21 19:29:52 +0100256 MeterRequest request = builder.add();
alshabib58fe6dc2015-08-19 17:16:13 -0700257
Jordi Ortiz161445a2017-02-15 18:29:04 +0100258 Meter m = service.submit(request);
pierventrec0914ec2021-08-27 15:25:02 +0200259 log.info("Requested meter with cellId {}: {}", m.meterCellId().toString(), m.toString());
260 print("Requested meter with cellId %s: %s", m.meterCellId().toString(), m.toString());
alshabib58fe6dc2015-08-19 17:16:13 -0700261 }
262}