blob: 5d2a1014a939b25b9c4019aa9759af257654011f [file] [log] [blame]
alshabibc7911792015-07-30 17:55:30 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
alshabibc7911792015-07-30 17:55:30 -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.provider.of.meter.impl;
17
alshabib10c810b2015-08-18 16:59:04 -070018import org.onosproject.net.meter.Band;
19import org.onosproject.net.meter.Meter;
20import org.onosproject.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;
Sho SHIMIZU45906042016-01-13 23:05:54 -080032import java.util.Objects;
alshabibc7911792015-07-30 17:55:30 -070033import java.util.stream.Collectors;
34
35import static com.google.common.base.Preconditions.checkArgument;
36import static com.google.common.base.Preconditions.checkNotNull;
37import static org.slf4j.LoggerFactory.getLogger;
38
39/**
40 * Builder for a meter modification.
41 */
42public final class MeterModBuilder {
43
44 private final Logger log = getLogger(getClass());
45
46 private final long xid;
47 private final OFFactory factory;
48 private Meter.Unit unit = Meter.Unit.KB_PER_SEC;
49 private boolean burst = false;
alshabib7bb05012015-08-05 10:15:09 -070050 private Long id;
alshabibc7911792015-07-30 17:55:30 -070051 private Collection<Band> bands;
52
53 public MeterModBuilder(long xid, OFFactory factory) {
54 this.xid = xid;
55 this.factory = factory;
56 }
57
58 public static MeterModBuilder builder(long xid, OFFactory factory) {
59 return new MeterModBuilder(xid, factory);
60 }
61
62 public MeterModBuilder withRateUnit(Meter.Unit unit) {
63 this.unit = unit;
64 return this;
65 }
66
67 public MeterModBuilder burst() {
68 this.burst = true;
69 return this;
70 }
71
72 public MeterModBuilder withId(MeterId meterId) {
73 this.id = meterId.id();
74 return this;
75 }
76
77 public MeterModBuilder withBands(Collection<Band> bands) {
78 this.bands = bands;
79 return this;
80 }
81
82 public OFMeterMod add() {
83 validate();
84 OFMeterMod.Builder builder = builderMeterMod();
85 builder.setCommand(OFMeterModCommand.ADD.ordinal());
86 return builder.build();
87 }
88
89 public OFMeterMod remove() {
90 validate();
91 OFMeterMod.Builder builder = builderMeterMod();
92 builder.setCommand(OFMeterModCommand.DELETE.ordinal());
93 return builder.build();
94 }
95
96 public OFMeterMod modify() {
97 validate();
98 OFMeterMod.Builder builder = builderMeterMod();
99 builder.setCommand(OFMeterModCommand.MODIFY.ordinal());
100 return builder.build();
101 }
102
103 private OFMeterMod.Builder builderMeterMod() {
104 OFMeterMod.Builder builder = factory.buildMeterMod();
105 int flags = 0;
106 if (burst) {
107 // covering loxi short comings.
108 flags |= 1 << OFMeterFlags.BURST.ordinal();
109 }
110 switch (unit) {
111 case PKTS_PER_SEC:
112 flags |= 1 << OFMeterFlags.PKTPS.ordinal();
113 break;
114 case KB_PER_SEC:
115 flags |= 1 << OFMeterFlags.KBPS.ordinal();
116 break;
117 default:
118 log.warn("Unknown unit type {}", unit);
119 }
alshabib58fe6dc2015-08-19 17:16:13 -0700120 //FIXME: THIS WILL CHANGE IN OF1.4 to setBands.
121 builder.setMeters(buildBands());
alshabibc7911792015-07-30 17:55:30 -0700122 builder.setFlags(flags)
123 .setMeterId(id)
124 .setXid(xid);
125 return builder;
126 }
127
128 private List<OFMeterBand> buildBands() {
129 return bands.stream().map(b -> {
130 switch (b.type()) {
131 case DROP:
132 OFMeterBandDrop.Builder dropBuilder =
133 factory.meterBands().buildDrop();
134 if (burst) {
135 dropBuilder.setBurstSize(b.burst());
136 }
137 dropBuilder.setRate(b.rate());
138 return dropBuilder.build();
139 case REMARK:
140 OFMeterBandDscpRemark.Builder remarkBand =
141 factory.meterBands().buildDscpRemark();
142 if (burst) {
143 remarkBand.setBurstSize(b.burst());
144 }
145 remarkBand.setRate(b.rate());
146 remarkBand.setPrecLevel(b.dropPrecedence());
147 return remarkBand.build();
148 default:
149 log.warn("Unknown band type {}", b.type());
150 return null;
151 }
Sho SHIMIZU45906042016-01-13 23:05:54 -0800152 }).filter(Objects::nonNull).collect(Collectors.toList());
alshabibc7911792015-07-30 17:55:30 -0700153 }
154
155 private void validate() {
156 checkNotNull(id, "id cannot be null");
157 checkNotNull(bands, "Must have bands");
158 checkArgument(bands.size() > 0, "Must have at lease one band");
159 }
160}