blob: c21166aee1eef567860e670e616e0275d1589881 [file] [log] [blame]
/*
* Copyright 2017-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.incubator.net.l2monitoring.cfm.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.onlab.packet.IpAddress;
import org.onlab.packet.VlanId;
import org.onlab.util.KryoNamespace;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMep;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaId2Octet;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdIccY1731;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdPrimaryVid;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdRfc2685VpnId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdDomainName;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdMacUint;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdNone;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepKeyId;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepEvent;
import org.onosproject.incubator.net.l2monitoring.cfm.service.MepStore;
import org.onosproject.incubator.net.l2monitoring.cfm.service.MepStoreDelegate;
import org.onosproject.net.DeviceId;
import org.onosproject.net.NetworkResource;
import org.onosproject.net.PortNumber;
import org.onosproject.store.AbstractStore;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.ConsistentMap;
import org.onosproject.store.service.MapEvent;
import org.onosproject.store.service.MapEventListener;
import org.onosproject.store.service.Serializer;
import org.onosproject.store.service.StorageService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.Duration;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* MEP Store implementation backed by consistent map.
*/
@Component(immediate = true)
@Service
public class DistributedMepStore extends AbstractStore<CfmMepEvent, MepStoreDelegate>
implements MepStore {
private final Logger log = LoggerFactory.getLogger(getClass());
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected StorageService storageService;
private ConsistentMap<MepKeyId, Mep> mepConsistentMap;
private Map<MepKeyId, Mep> mepMap;
private MapEventListener<MepKeyId, Mep> mapListener = null;
@Activate
public void activate() {
mepConsistentMap = storageService
.<MepKeyId, Mep>consistentMapBuilder()
.withName("onos-cfm-mep-map")
.withSerializer(Serializer.using(new KryoNamespace.Builder()
.register(KryoNamespaces.API)
.register(DefaultMep.class)
.register(MepId.class)
.register(MepKeyId.class)
.register(NetworkResource.class)
.register(DeviceId.class)
.register(PortNumber.class)
.register(Mep.MepDirection.class)
.register(VlanId.class)
.register(Mep.Priority.class)
.register(Mep.FngAddress.class)
.register(Mep.FngAddressType.class)
.register(IpAddress.class)
.register(Mep.LowestFaultDefect.class)
.register(Duration.class)
.register(MdIdCharStr.class)
.register(MdIdDomainName.class)
.register(MdIdMacUint.class)
.register(MdIdNone.class)
.register(MaIdCharStr.class)
.register(MaIdShort.class)
.register(MaId2Octet.class)
.register(MaIdIccY1731.class)
.register(MaIdPrimaryVid.class)
.register(MaIdRfc2685VpnId.class)
.build("mep")))
.build();
mapListener = new InternalMepListener();
mepConsistentMap.addListener(mapListener);
mepMap = mepConsistentMap.asJavaMap();
log.info("MepStore started");
}
@Deactivate
public void deactivate() {
mepConsistentMap.removeListener(mapListener);
log.info("MepStore stopped");
}
@Override
public Collection<Mep> getAllMeps() {
return mepMap.values();
}
@Override
public Collection<Mep> getMepsByMd(MdId mdName) {
return mepMap.values().stream()
.filter(mep -> mep.mdId().equals(mdName))
.collect(Collectors.toList());
}
@Override
public Collection<Mep> getMepsByMdMa(MdId mdName, MaIdShort maName) {
return mepMap.values().stream()
.filter(mep -> mep.mdId().equals(mdName) && mep.maId().equals(maName))
.collect(Collectors.toList());
}
@Override
public Collection<Mep> getMepsByDeviceId(DeviceId deviceId) {
return mepMap.values().stream()
.filter(mep -> mep.deviceId().equals(deviceId))
.collect(Collectors.toList());
}
@Override
public Optional<Mep> getMep(MepKeyId mepKeyId) {
return mepMap.values().stream()
.filter(mep -> mep.mdId().equals(mepKeyId.mdId()) &&
mep.maId().equals(mepKeyId.maId()) &&
mep.mepId().equals(mepKeyId.mepId()))
.findFirst();
}
@Override
public boolean deleteMep(MepKeyId mepKeyId) {
return mepMap.remove(mepKeyId) == null ? false : true;
}
@Override
public boolean createUpdateMep(MepKeyId mepKeyId, Mep mep) {
return mepMap.put(mepKeyId, mep) == null ? false : true;
}
private class InternalMepListener implements MapEventListener<MepKeyId, Mep> {
@Override
public void event(MapEvent<MepKeyId, Mep> mapEvent) {
final CfmMepEvent.Type type;
switch (mapEvent.type()) {
case INSERT:
type = CfmMepEvent.Type.MEP_ADDED;
break;
case UPDATE:
type = CfmMepEvent.Type.MEP_UPDATED;
break;
default:
case REMOVE:
type = CfmMepEvent.Type.MEP_REMOVED;
}
notifyDelegate(new CfmMepEvent(type, mapEvent.key()));
}
}
}