alshabib
Committed by Gerrit Code Review

moving meter service to incubator and initial implementation of

meter manager.

Change-Id: I6ef0d9476b58d00b37f7ef156ac7bdacca20185b
Showing 20 changed files with 796 additions and 21 deletions
......@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.net.meter;
package org.onosproject.incubator.net.meter;
/**
* Represents a band used within a meter.
......@@ -69,5 +69,51 @@ public interface Band {
*/
Type type();
interface Builder {
/**
* Assigns a rate to this band. The units for this rate
* are defined in the encapsulating meter.
*
* @param rate a long value
* @return this
*/
Builder withRate(long rate);
/**
* Assigns a burst size to this band. Only meaningful if
* the encapsulating meter is of burst type.
*
* @param burstSize a long value.
* @return this
*/
Builder burstSize(long burstSize);
/**
* Assigns the drop precedence for this band. Only meaningful if
* the band is of REMARK type.
*
* @param prec a short value
* @return this
*/
Builder dropPrecedence(short prec);
/**
* Assigns the @See Type of this band.
*
* @param type a band type
* @return this
*/
Builder ofType(Type type);
/**
* Builds the band.
*
* @return a band
*/
Band build();
}
}
......
/*
* 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.incubator.net.meter;
import static com.google.common.base.Preconditions.checkArgument;
/**
* A default implementation for a Band.
*/
public final class DefaultBand implements Band {
private final Type type;
private final long rate;
private final long burstSize;
private final short prec;
public DefaultBand(Type type, long rate,
long burstSize, short prec) {
this.type = type;
this.rate = rate;
this.burstSize = burstSize;
this.prec = prec;
}
@Override
public long rate() {
return rate;
}
@Override
public long burst() {
return burstSize;
}
@Override
public short dropPrecedence() {
return prec;
}
@Override
public Type type() {
return type;
}
public static Builder builder() {
return new Builder();
}
public static final class Builder implements Band.Builder {
private long rate;
private long burstSize;
private Short prec;
private Type type;
@Override
public Band.Builder withRate(long rate) {
this.rate = rate;
return this;
}
@Override
public Band.Builder burstSize(long burstSize) {
this.burstSize = burstSize;
return this;
}
@Override
public Band.Builder dropPrecedence(short prec) {
this.prec = prec;
return this;
}
@Override
public Band.Builder ofType(Type type) {
this.type = type;
return this;
}
@Override
public Band build() {
checkArgument(prec != null && type == Type.REMARK,
"Only REMARK bands can have a precendence.");
return new DefaultBand(type, rate, burstSize, prec);
}
}
}
/*
* 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.incubator.net.meter;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.DeviceId;
import java.util.Collection;
import java.util.Collections;
import java.util.Optional;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* A default implementation of a meter.
*/
public final class DefaultMeter implements Meter {
private final MeterId id;
private final ApplicationId appId;
private final Unit unit;
private final boolean burst;
private final Collection<Band> bands;
private final DeviceId deviceId;
private final Optional<MeterContext> context;
private DefaultMeter(DeviceId deviceId, MeterId id, ApplicationId appId,
Unit unit, boolean burst,
Collection<Band> bands, Optional<MeterContext> context) {
this.deviceId = deviceId;
this.id = id;
this.appId = appId;
this.unit = unit;
this.burst = burst;
this.bands = bands;
this.context = context;
}
@Override
public DeviceId deviceId() {
return deviceId;
}
@Override
public MeterId id() {
return id;
}
@Override
public ApplicationId appId() {
return appId;
}
@Override
public Unit unit() {
return unit;
}
@Override
public boolean isBurst() {
return burst;
}
@Override
public Collection<Band> bands() {
return bands;
}
@Override
public Optional<MeterContext> context() {
return null;
}
public static Builder builder() {
return new Builder();
}
public static final class Builder implements Meter.Builder {
private MeterId id;
private ApplicationId appId;
private Unit unit = Unit.KB_PER_SEC;
private boolean burst = false;
private Collection<Band> bands;
private DeviceId deviceId;
private Optional<MeterContext> context;
@Override
public Meter.Builder forDevice(DeviceId deviceId) {
this.deviceId = deviceId;
return this;
}
@Override
public Meter.Builder withId(int id) {
this.id = MeterId.meterId(id);
return this;
}
@Override
public Meter.Builder fromApp(ApplicationId appId) {
this.appId = appId;
return this;
}
@Override
public Meter.Builder withUnit(Unit unit) {
this.unit = unit;
return this;
}
@Override
public Meter.Builder burst() {
this.burst = true;
return this;
}
@Override
public Meter.Builder withBands(Collection<Band> bands) {
this.bands = Collections.unmodifiableCollection(bands);
return this;
}
@Override
public Meter.Builder withContext(MeterContext context) {
this.context = Optional.<MeterContext>ofNullable(context);
return this;
}
@Override
public Meter build() {
checkNotNull(deviceId, "Must specify a device");
checkNotNull(bands, "Must have bands.");
checkArgument(bands.size() > 0, "Must have at least one band.");
checkNotNull(appId, "Must have an application id");
checkNotNull(id, "Must specify a meter id");
return new DefaultMeter(deviceId, id, appId, unit, burst, bands, context);
}
}
}
......@@ -13,11 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.net.meter;
package org.onosproject.incubator.net.meter;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.DeviceId;
import java.util.Collection;
import java.util.Optional;
/**
* Represents a generalized meter to be deployed on a device.
......@@ -37,6 +39,13 @@ public interface Meter {
}
/**
* The target device for this meter.
*
* @return a device id
*/
DeviceId deviceId();
/**
* This meters id.
*
* @return a meter id
......@@ -71,4 +80,76 @@ public interface Meter {
*/
Collection<Band> bands();
/**
* Obtains an optional context.
*
* @return optional; which will be empty if there is no context.
* Otherwise it will return the context.
*/
Optional<MeterContext> context();
/**
* A meter builder.
*/
interface Builder {
/**
* Assigns the target device for this meter.
*
* @param deviceId a device id
* @return this
*/
Builder forDevice(DeviceId deviceId);
/**
* Assigns the id to this meter.
*
* @param id an integer
* @return this
*/
Builder withId(int id);
/**
* Assigns the application that built this meter.
*
* @param appId an application id
* @return this
*/
Builder fromApp(ApplicationId appId);
/**
* Assigns the @See Unit to use for this meter.
* Defaults to kb/s
*
* @param unit a unit
* @return this
*/
Builder withUnit(Unit unit);
/**
* Sets this meter as applicable to burst traffic only.
* Defaults to false.
*
* @return this
*/
Builder burst();
/**
* Assigns bands to this meter. There must be at least one band.
*
* @param bands a collection of bands
* @return this
*/
Builder withBands(Collection<Band> bands);
Builder withContext(MeterContext context);
/**
* Builds the meter based on the specified parameters.
*
* @return a meter
*/
Meter build();
}
}
......
/*
* 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.incubator.net.meter;
/**
* Created by ash on 01/08/15.
*/
public interface MeterContext {
/**
* Invoked on successful installation of the meter.
*
* @param op a meter operation
*/
default void onSuccess(MeterOperation op) {
}
/**
* Invoked when error is encountered while installing a meter.
*
* @param op a meter operation
* @param reason the reason why it failed
*/
default void onError(MeterOperation op, MeterFailReason reason) {
}
}
/*
* 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.incubator.net.meter;
import org.onosproject.event.AbstractEvent;
/**
* Entity that represents Meter events.
*/
public class MeterEvent extends AbstractEvent<MeterEvent.Type, Meter> {
enum Type {
/**
* Signals that a new meter has been added.
*/
METER_ADDED,
/**
* Signals that a meter has been removed.
*/
METER_REMOVED,
/**
* Signals that a meter has been added.
*/
METER_UPDATED,
/**
* Signals that a meter addition failed.
*/
METER_ADD_FAILED,
/**
* Signals that a meter removal failed.
*/
METER_REMOVE_FAILED,
/**
* Signals that a meter update failed.
*/
METER_UPDATE_FAILED
}
/**
* Creates an event of a given type and for the specified meter and the
* current time.
*
* @param type meter event type
* @param meter event subject
*/
public MeterEvent(Type type, Meter meter) {
super(type, meter);
}
/**
* Creates an event of a given type and for the specified meter and time.
*
* @param type meter event type
* @param meter event subject
* @param time occurrence time
*/
public MeterEvent(Type type, Meter meter, long time) {
super(type, meter, time);
}
}
......@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.net.meter;
package org.onosproject.incubator.net.meter;
/**
* Enum used to represent a meter failure condition.
......
......@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.net.meter;
package org.onosproject.incubator.net.meter;
import static com.google.common.base.Preconditions.checkArgument;
......@@ -31,7 +31,7 @@ public final class MeterId {
public static final MeterId CONTROLLER = new MeterId(0xFFFFFFFE);
public static final MeterId ALL = new MeterId(0xFFFFFFFF);
protected MeterId(int id) {
private MeterId(int id) {
checkArgument(id <= MAX, "id cannot be larger than 0xFFFF0000");
this.id = id;
}
......
/*
* 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.incubator.net.meter;
import org.onosproject.event.EventListener;
/**
* Entity capable of receiving Meter related events.
*/
public interface MeterListener extends EventListener<MeterEvent> {
}
......@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.net.meter;
package org.onosproject.incubator.net.meter;
import com.google.common.base.MoreObjects;
......
......@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.net.meter;
package org.onosproject.incubator.net.meter;
import com.google.common.collect.ImmutableList;
......
......@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.net.meter;
package org.onosproject.incubator.net.meter;
import org.onosproject.net.DeviceId;
import org.onosproject.net.provider.Provider;
......
......@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.net.meter;
package org.onosproject.incubator.net.meter;
import org.onosproject.net.provider.ProviderRegistry;
......
......@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.net.meter;
package org.onosproject.incubator.net.meter;
import org.onosproject.net.DeviceId;
import org.onosproject.net.provider.ProviderService;
......
/*
* 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.incubator.net.meter;
import org.onosproject.event.ListenerService;
/**
* Service for add/updating and removing meters. Meters are
* are assigned to flow to rate limit them and provide a certain
* quality of service.
*/
public interface MeterService
extends ListenerService<MeterEvent, MeterListener> {
/**
* Adds a meter to the system and performs it installation.
*
* @param meter a meter.
*/
void addMeter(Meter meter);
/**
* Updates a meter by adding statistic information to the meter.
*
* @param meter an updated meter
*/
void updateMeter(Meter meter);
/**
* Remove a meter from the system and the dataplane.
*
* @param meter a meter to remove
*/
void removeMeter(Meter meter);
/**
* Remove a meter from the system and the dataplane by meter id.
*
* @param id a meter id
*/
void removeMeter(MeterId id);
/**
* Fetch the meter by the meter id.
*
* @param id a meter id
* @return a meter
*/
Meter getMeter(MeterId id);
/**
* Allocate a meter id which must be used to create the meter.
*
* @return a meter id
*/
MeterId allocateMeterId();
}
/*
* 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.incubator.net.meter;
import org.onosproject.store.StoreDelegate;
/**
* Meter store delegate abstraction.
*/
public interface MeterStoreDelegate extends StoreDelegate<MeterEvent> {
}
......@@ -17,4 +17,4 @@
/**
* Flow meter model and related services.
*/
package org.onosproject.net.meter;
\ No newline at end of file
package org.onosproject.incubator.net.meter;
\ No newline at end of file
......
/*
* 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.incubator.net.meter.impl;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onosproject.incubator.net.meter.Meter;
import org.onosproject.incubator.net.meter.MeterEvent;
import org.onosproject.incubator.net.meter.MeterFailReason;
import org.onosproject.incubator.net.meter.MeterId;
import org.onosproject.incubator.net.meter.MeterListener;
import org.onosproject.incubator.net.meter.MeterOperation;
import org.onosproject.incubator.net.meter.MeterProvider;
import org.onosproject.incubator.net.meter.MeterProviderRegistry;
import org.onosproject.incubator.net.meter.MeterProviderService;
import org.onosproject.incubator.net.meter.MeterService;
import org.onosproject.incubator.net.meter.MeterStoreDelegate;
import org.onosproject.net.DeviceId;
import org.onosproject.net.provider.AbstractListenerProviderRegistry;
import org.onosproject.net.provider.AbstractProviderService;
import org.onosproject.store.service.AtomicCounter;
import org.onosproject.store.service.StorageService;
import org.slf4j.Logger;
import java.util.Collection;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Provides implementation of the meter service APIs.
*/
@Component(immediate = true)
@Service
public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, MeterListener,
MeterProvider, MeterProviderService>
implements MeterService, MeterProviderRegistry {
private final String meterIdentifier = "meter-id-counter";
private final Logger log = getLogger(getClass());
private final MeterStoreDelegate delegate = new InternalMeterStoreDelegate();
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected StorageService storageService;
private AtomicCounter meterIdCounter;
@Activate
public void activate() {
meterIdCounter = storageService.atomicCounterBuilder()
.withName(meterIdentifier)
.build();
log.info("Started");
}
@Deactivate
public void deactivate() {
log.info("Stopped");
}
@Override
protected MeterProviderService createProviderService(MeterProvider provider) {
return new InternalMeterProviderService(provider);
}
@Override
public void addMeter(Meter meter) {
}
@Override
public void updateMeter(Meter meter) {
}
@Override
public void removeMeter(Meter meter) {
}
@Override
public void removeMeter(MeterId id) {
}
@Override
public Meter getMeter(MeterId id) {
return null;
}
@Override
public MeterId allocateMeterId() {
// FIXME: This will break one day.
return MeterId.meterId((int) meterIdCounter.getAndIncrement());
}
private class InternalMeterProviderService
extends AbstractProviderService<MeterProvider>
implements MeterProviderService {
/**
* Creates a provider service on behalf of the specified provider.
*
* @param provider provider to which this service is being issued
*/
protected InternalMeterProviderService(MeterProvider provider) {
super(provider);
}
@Override
public void meterOperationFailed(MeterOperation operation, MeterFailReason reason) {
}
@Override
public void pushMeterMetrics(DeviceId deviceId, Collection<Meter> meterEntries) {
}
}
private class InternalMeterStoreDelegate implements MeterStoreDelegate {
@Override
public void notify(MeterEvent event) {
}
}
}
......@@ -15,9 +15,9 @@
*/
package org.onosproject.provider.of.meter.impl;
import org.onosproject.net.meter.Band;
import org.onosproject.net.meter.Meter;
import org.onosproject.net.meter.MeterId;
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;
......
......@@ -16,9 +16,11 @@
package org.onosproject.provider.of.meter.impl;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.RemovalCause;
import com.google.common.cache.RemovalNotification;
import com.google.common.collect.Maps;
import org.apache.felix.scr.annotations.Activate;
......@@ -27,13 +29,13 @@ import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onosproject.net.DeviceId;
import org.onosproject.net.meter.Meter;
import org.onosproject.net.meter.MeterFailReason;
import org.onosproject.net.meter.MeterOperation;
import org.onosproject.net.meter.MeterOperations;
import org.onosproject.net.meter.MeterProvider;
import org.onosproject.net.meter.MeterProviderRegistry;
import org.onosproject.net.meter.MeterProviderService;
import org.onosproject.incubator.net.meter.Meter;
import org.onosproject.incubator.net.meter.MeterFailReason;
import org.onosproject.incubator.net.meter.MeterOperation;
import org.onosproject.incubator.net.meter.MeterOperations;
import org.onosproject.incubator.net.meter.MeterProvider;
import org.onosproject.incubator.net.meter.MeterProviderRegistry;
import org.onosproject.incubator.net.meter.MeterProviderService;
import org.onosproject.net.provider.AbstractProvider;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.openflow.controller.Dpid;
......