blob: 50bad959760869f2af8decb4bac54d74827ce35d [file] [log] [blame]
/*
* Copyright 2016-present Open Networking Foundation
*
* 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.bandwidthmgr;
import org.onlab.util.KryoNamespace;
import org.onosproject.bandwidthmgr.api.BandwidthMgmtStore;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.LinkKey;
import org.onosproject.net.config.NetworkConfigEvent;
import org.onosproject.net.config.NetworkConfigListener;
import org.onosproject.net.config.NetworkConfigService;
import org.onosproject.pcep.api.TeLinkConfig;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.ConsistentMap;
import org.onosproject.store.service.Serializer;
import org.onosproject.store.service.StorageService;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.LinkedHashSet;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.net.config.NetworkConfigEvent.Type.CONFIG_ADDED;
import static org.onosproject.net.config.NetworkConfigEvent.Type.CONFIG_REMOVED;
import static org.onosproject.net.config.NetworkConfigEvent.Type.CONFIG_UPDATED;
/**
* Manages the pool of available labels to devices, links and tunnels.
*/
@Component(immediate = true, service = BandwidthMgmtStore.class)
public class DistributedBandwidthMgmtStore implements BandwidthMgmtStore {
private static final Logger log = LoggerFactory.getLogger(BandwidthManager.class);
@Reference(cardinality = ReferenceCardinality.MANDATORY)
protected NetworkConfigService netCfgService;
@Reference(cardinality = ReferenceCardinality.MANDATORY)
protected StorageService storageService;
private InternalConfigListener cfgListener = new InternalConfigListener();
private ConsistentMap<LinkKey, Double> teCost;
// Locally maintain unreserved bandwidth of each link.
private ConsistentMap<LinkKey, Set<Double>> unResvBw;
// Mapping tunnel with link key with local reserved bandwidth
private ConsistentMap<LinkKey, Double> localReservedBw;
private static final Serializer SERIALIZER = Serializer
.using(new KryoNamespace.Builder().register(KryoNamespaces.API)
.register(KryoNamespaces.API)
.register(LinkKey.class)
.register(ConnectPoint.class)
.build());
@Activate
protected void activate() {
netCfgService.addListener(cfgListener);
localReservedBw = storageService.<LinkKey, Double>consistentMapBuilder()
.withName("local-reserved-bandwith")
.withSerializer(SERIALIZER)
.build();
unResvBw = storageService.<LinkKey, Set<Double>>consistentMapBuilder()
.withName("onos-unreserved-bandwidth")
.withSerializer(SERIALIZER)
.build();
teCost = storageService.<LinkKey, Double>consistentMapBuilder()
.withName("onos-tecost")
.withSerializer(SERIALIZER)
.build();
log.info("Started");
}
@Deactivate
protected void deactivate() {
netCfgService.removeListener(cfgListener);
log.info("Stopped");
}
@Override
public Double getTeCost(LinkKey linkKey) {
if (teCost.get(linkKey) != null) {
return teCost.get(linkKey).value();
}
return null;
}
@Override
public boolean allocLocalReservedBw(LinkKey linkkey, Double bandwidth) {
Double allocatedBw = null;
if (localReservedBw.get(linkkey) != null) {
allocatedBw = localReservedBw.get(linkkey).value();
}
if (allocatedBw != null) {
localReservedBw.put(linkkey, (allocatedBw + bandwidth));
} else {
localReservedBw.put(linkkey, bandwidth);
}
return true;
}
@Override
public boolean releaseLocalReservedBw(LinkKey linkkey, Double bandwidth) {
Double allocatedBw = null;
if (localReservedBw.get(linkkey) != null) {
allocatedBw = localReservedBw.get(linkkey).value();
}
if (allocatedBw == null || allocatedBw < bandwidth) {
return false;
}
Double releasedBw = allocatedBw - bandwidth;
if (releasedBw == 0.0) {
localReservedBw.remove(linkkey);
} else {
localReservedBw.put(linkkey, releasedBw);
}
return true;
}
@Override
public Double getAllocatedLocalReservedBw(LinkKey linkkey) {
return localReservedBw.get(linkkey) != null ? localReservedBw.get(linkkey).value() : null;
}
@Override
public boolean addUnreservedBw(LinkKey linkkey, Set<Double> bandwidth) {
unResvBw.put(linkkey, bandwidth);
return true;
}
@Override
public boolean removeUnreservedBw(LinkKey linkkey) {
unResvBw.remove(linkkey);
return true;
}
@Override
public Set<Double> getUnreservedBw(LinkKey linkkey) {
checkNotNull(linkkey);
return unResvBw.get(linkkey) != null ? unResvBw.get(linkkey).value() : null;
}
private class InternalConfigListener implements NetworkConfigListener {
@Override
public void event(NetworkConfigEvent event) {
if (event.configClass().equals(TeLinkConfig.class)) {
if ((event.type() != CONFIG_ADDED) && (event.type() != CONFIG_UPDATED)
&& (event.type() != CONFIG_REMOVED)) {
return;
}
LinkKey linkKey = (LinkKey) event.subject();
switch (event.type()) {
case CONFIG_ADDED:
case CONFIG_UPDATED:
TeLinkConfig cfg = netCfgService.getConfig(linkKey, TeLinkConfig.class);
if (cfg == null) {
log.error("Unable to get the configuration of the link.");
return;
}
Set<Double> unresvBw = new LinkedHashSet<>();
unresvBw.add(cfg.unResvBandwidth());
addUnreservedBw(linkKey, unresvBw);
if (cfg.teCost() != 0) {
teCost.put(linkKey, (double) cfg.teCost());
}
break;
case CONFIG_REMOVED:
removeUnreservedBw(linkKey);
localReservedBw.remove(linkKey);
teCost.remove(linkKey);
break;
default:
break;
}
}
}
}
}