blob: 00ad8efeae9fc071c5c4759d63c4ae44ff257fae [file] [log] [blame]
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.provider.of.meter.impl;
import org.onosproject.incubator.net.meter.Band;
import org.onosproject.incubator.net.meter.Meter;
import org.onosproject.incubator.net.meter.MeterId;
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.OFMeterFlags;
import org.projectfloodlight.openflow.protocol.OFMeterMod;
import org.projectfloodlight.openflow.protocol.OFMeterModCommand;
import org.projectfloodlight.openflow.protocol.meterband.OFMeterBand;
import org.projectfloodlight.openflow.protocol.meterband.OFMeterBandDrop;
import org.projectfloodlight.openflow.protocol.meterband.OFMeterBandDscpRemark;
import org.slf4j.Logger;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Builder for a meter modification.
*/
public final class MeterModBuilder {
private final Logger log = getLogger(getClass());
private final long xid;
private final OFFactory factory;
private Meter.Unit unit = Meter.Unit.KB_PER_SEC;
private boolean burst = false;
private Long id;
private Collection<Band> bands;
public MeterModBuilder(long xid, OFFactory factory) {
this.xid = xid;
this.factory = factory;
}
public static MeterModBuilder builder(long xid, OFFactory factory) {
return new MeterModBuilder(xid, factory);
}
public MeterModBuilder withRateUnit(Meter.Unit unit) {
this.unit = unit;
return this;
}
public MeterModBuilder burst() {
this.burst = true;
return this;
}
public MeterModBuilder withId(MeterId meterId) {
this.id = meterId.id();
return this;
}
public MeterModBuilder withBands(Collection<Band> bands) {
this.bands = bands;
return this;
}
public OFMeterMod add() {
validate();
OFMeterMod.Builder builder = builderMeterMod();
builder.setCommand(OFMeterModCommand.ADD.ordinal());
return builder.build();
}
public OFMeterMod remove() {
validate();
OFMeterMod.Builder builder = builderMeterMod();
builder.setCommand(OFMeterModCommand.DELETE.ordinal());
return builder.build();
}
public OFMeterMod modify() {
validate();
OFMeterMod.Builder builder = builderMeterMod();
builder.setCommand(OFMeterModCommand.MODIFY.ordinal());
return builder.build();
}
private OFMeterMod.Builder builderMeterMod() {
OFMeterMod.Builder builder = factory.buildMeterMod();
int flags = 0;
if (burst) {
// covering loxi short comings.
flags |= 1 << OFMeterFlags.BURST.ordinal();
}
switch (unit) {
case PKTS_PER_SEC:
flags |= 1 << OFMeterFlags.PKTPS.ordinal();
break;
case KB_PER_SEC:
flags |= 1 << OFMeterFlags.KBPS.ordinal();
break;
default:
log.warn("Unknown unit type {}", unit);
}
builder.setBands(buildBands());
builder.setFlags(flags)
.setMeterId(id)
.setXid(xid);
return builder;
}
private List<OFMeterBand> buildBands() {
return bands.stream().map(b -> {
switch (b.type()) {
case DROP:
OFMeterBandDrop.Builder dropBuilder =
factory.meterBands().buildDrop();
if (burst) {
dropBuilder.setBurstSize(b.burst());
}
dropBuilder.setRate(b.rate());
return dropBuilder.build();
case REMARK:
OFMeterBandDscpRemark.Builder remarkBand =
factory.meterBands().buildDscpRemark();
if (burst) {
remarkBand.setBurstSize(b.burst());
}
remarkBand.setRate(b.rate());
remarkBand.setPrecLevel(b.dropPrecedence());
return remarkBand.build();
default:
log.warn("Unknown band type {}", b.type());
return null;
}
}).filter(value -> value != null).collect(Collectors.toList());
}
private void validate() {
checkNotNull(id, "id cannot be null");
checkNotNull(bands, "Must have bands");
checkArgument(bands.size() > 0, "Must have at lease one band");
}
}