blob: a87250e2a944fab10ce5e691a4189121252b9134 [file] [log] [blame]
alshabibc7911792015-07-30 17:55:30 -07001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
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.provider.of.meter.impl;
17
alshabib1d2bc402015-07-31 17:04:11 -070018import org.onosproject.incubator.net.meter.Band;
19import org.onosproject.incubator.net.meter.Meter;
20import org.onosproject.incubator.net.meter.MeterId;
alshabibc7911792015-07-30 17:55:30 -070021import org.projectfloodlight.openflow.protocol.OFFactory;
22import org.projectfloodlight.openflow.protocol.OFMeterFlags;
23import org.projectfloodlight.openflow.protocol.OFMeterMod;
24import org.projectfloodlight.openflow.protocol.OFMeterModCommand;
25import org.projectfloodlight.openflow.protocol.meterband.OFMeterBand;
26import org.projectfloodlight.openflow.protocol.meterband.OFMeterBandDrop;
27import org.projectfloodlight.openflow.protocol.meterband.OFMeterBandDscpRemark;
28import org.slf4j.Logger;
29
30import java.util.Collection;
31import java.util.List;
32import java.util.stream.Collectors;
33
34import static com.google.common.base.Preconditions.checkArgument;
35import static com.google.common.base.Preconditions.checkNotNull;
36import static org.slf4j.LoggerFactory.getLogger;
37
38/**
39 * Builder for a meter modification.
40 */
41public final class MeterModBuilder {
42
43 private final Logger log = getLogger(getClass());
44
45 private final long xid;
46 private final OFFactory factory;
47 private Meter.Unit unit = Meter.Unit.KB_PER_SEC;
48 private boolean burst = false;
49 private Integer id;
50 private Collection<Band> bands;
51
52 public MeterModBuilder(long xid, OFFactory factory) {
53 this.xid = xid;
54 this.factory = factory;
55 }
56
57 public static MeterModBuilder builder(long xid, OFFactory factory) {
58 return new MeterModBuilder(xid, factory);
59 }
60
61 public MeterModBuilder withRateUnit(Meter.Unit unit) {
62 this.unit = unit;
63 return this;
64 }
65
66 public MeterModBuilder burst() {
67 this.burst = true;
68 return this;
69 }
70
71 public MeterModBuilder withId(MeterId meterId) {
72 this.id = meterId.id();
73 return this;
74 }
75
76 public MeterModBuilder withBands(Collection<Band> bands) {
77 this.bands = bands;
78 return this;
79 }
80
81 public OFMeterMod add() {
82 validate();
83 OFMeterMod.Builder builder = builderMeterMod();
84 builder.setCommand(OFMeterModCommand.ADD.ordinal());
85 return builder.build();
86 }
87
88 public OFMeterMod remove() {
89 validate();
90 OFMeterMod.Builder builder = builderMeterMod();
91 builder.setCommand(OFMeterModCommand.DELETE.ordinal());
92 return builder.build();
93 }
94
95 public OFMeterMod modify() {
96 validate();
97 OFMeterMod.Builder builder = builderMeterMod();
98 builder.setCommand(OFMeterModCommand.MODIFY.ordinal());
99 return builder.build();
100 }
101
102 private OFMeterMod.Builder builderMeterMod() {
103 OFMeterMod.Builder builder = factory.buildMeterMod();
104 int flags = 0;
105 if (burst) {
106 // covering loxi short comings.
107 flags |= 1 << OFMeterFlags.BURST.ordinal();
108 }
109 switch (unit) {
110 case PKTS_PER_SEC:
111 flags |= 1 << OFMeterFlags.PKTPS.ordinal();
112 break;
113 case KB_PER_SEC:
114 flags |= 1 << OFMeterFlags.KBPS.ordinal();
115 break;
116 default:
117 log.warn("Unknown unit type {}", unit);
118 }
119 builder.setBands(buildBands());
120 builder.setFlags(flags)
121 .setMeterId(id)
122 .setXid(xid);
123 return builder;
124 }
125
126 private List<OFMeterBand> buildBands() {
127 return bands.stream().map(b -> {
128 switch (b.type()) {
129 case DROP:
130 OFMeterBandDrop.Builder dropBuilder =
131 factory.meterBands().buildDrop();
132 if (burst) {
133 dropBuilder.setBurstSize(b.burst());
134 }
135 dropBuilder.setRate(b.rate());
136 return dropBuilder.build();
137 case REMARK:
138 OFMeterBandDscpRemark.Builder remarkBand =
139 factory.meterBands().buildDscpRemark();
140 if (burst) {
141 remarkBand.setBurstSize(b.burst());
142 }
143 remarkBand.setRate(b.rate());
144 remarkBand.setPrecLevel(b.dropPrecedence());
145 return remarkBand.build();
146 default:
147 log.warn("Unknown band type {}", b.type());
148 return null;
149 }
150 }).filter(value -> value != null).collect(Collectors.toList());
151 }
152
153 private void validate() {
154 checkNotNull(id, "id cannot be null");
155 checkNotNull(bands, "Must have bands");
156 checkArgument(bands.size() > 0, "Must have at lease one band");
157 }
158}