blob: c21166aee1eef567860e670e616e0275d1589881 [file] [log] [blame]
Sean Condon96b896d2017-12-11 12:44:29 -08001/*
2 * Copyright 2017-present Open Networking Foundation
3 *
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.incubator.net.l2monitoring.cfm.impl;
17
18import org.apache.felix.scr.annotations.Activate;
19import org.apache.felix.scr.annotations.Component;
20import org.apache.felix.scr.annotations.Deactivate;
21import org.apache.felix.scr.annotations.Reference;
22import org.apache.felix.scr.annotations.ReferenceCardinality;
23import org.apache.felix.scr.annotations.Service;
24import org.onlab.packet.IpAddress;
25import org.onlab.packet.VlanId;
26import org.onlab.util.KryoNamespace;
27import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMep;
28import org.onosproject.incubator.net.l2monitoring.cfm.Mep;
29import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaId2Octet;
30import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdCharStr;
31import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdIccY1731;
32import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdPrimaryVid;
33import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdRfc2685VpnId;
34import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
35import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
36import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
37import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdDomainName;
38import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdMacUint;
39import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdNone;
40import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
41import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepKeyId;
42import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepEvent;
43import org.onosproject.incubator.net.l2monitoring.cfm.service.MepStore;
44import org.onosproject.incubator.net.l2monitoring.cfm.service.MepStoreDelegate;
45import org.onosproject.net.DeviceId;
46import org.onosproject.net.NetworkResource;
47import org.onosproject.net.PortNumber;
48import org.onosproject.store.AbstractStore;
49import org.onosproject.store.serializers.KryoNamespaces;
50import org.onosproject.store.service.ConsistentMap;
51import org.onosproject.store.service.MapEvent;
52import org.onosproject.store.service.MapEventListener;
53import org.onosproject.store.service.Serializer;
54import org.onosproject.store.service.StorageService;
55import org.slf4j.Logger;
56import org.slf4j.LoggerFactory;
57
58import java.time.Duration;
59import java.util.Collection;
60import java.util.Map;
61import java.util.Optional;
62import java.util.stream.Collectors;
63
64/**
65 * MEP Store implementation backed by consistent map.
66 */
67@Component(immediate = true)
68@Service
69public class DistributedMepStore extends AbstractStore<CfmMepEvent, MepStoreDelegate>
70 implements MepStore {
71
72 private final Logger log = LoggerFactory.getLogger(getClass());
73
74 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
75 protected StorageService storageService;
76
77 private ConsistentMap<MepKeyId, Mep> mepConsistentMap;
78 private Map<MepKeyId, Mep> mepMap;
79
80 private MapEventListener<MepKeyId, Mep> mapListener = null;
81
82 @Activate
83 public void activate() {
84 mepConsistentMap = storageService
85 .<MepKeyId, Mep>consistentMapBuilder()
86 .withName("onos-cfm-mep-map")
87 .withSerializer(Serializer.using(new KryoNamespace.Builder()
88 .register(KryoNamespaces.API)
89 .register(DefaultMep.class)
90 .register(MepId.class)
91 .register(MepKeyId.class)
92 .register(NetworkResource.class)
93 .register(DeviceId.class)
94 .register(PortNumber.class)
95 .register(Mep.MepDirection.class)
96 .register(VlanId.class)
97 .register(Mep.Priority.class)
98 .register(Mep.FngAddress.class)
99 .register(Mep.FngAddressType.class)
100 .register(IpAddress.class)
101 .register(Mep.LowestFaultDefect.class)
102 .register(Duration.class)
103 .register(MdIdCharStr.class)
104 .register(MdIdDomainName.class)
105 .register(MdIdMacUint.class)
106 .register(MdIdNone.class)
107 .register(MaIdCharStr.class)
108 .register(MaIdShort.class)
109 .register(MaId2Octet.class)
110 .register(MaIdIccY1731.class)
111 .register(MaIdPrimaryVid.class)
112 .register(MaIdRfc2685VpnId.class)
113 .build("mep")))
114 .build();
115 mapListener = new InternalMepListener();
116 mepConsistentMap.addListener(mapListener);
117
118 mepMap = mepConsistentMap.asJavaMap();
119 log.info("MepStore started");
120 }
121
122 @Deactivate
123 public void deactivate() {
124 mepConsistentMap.removeListener(mapListener);
125 log.info("MepStore stopped");
126 }
127
128 @Override
129 public Collection<Mep> getAllMeps() {
130 return mepMap.values();
131 }
132
133 @Override
134 public Collection<Mep> getMepsByMd(MdId mdName) {
135 return mepMap.values().stream()
136 .filter(mep -> mep.mdId().equals(mdName))
137 .collect(Collectors.toList());
138 }
139
140 @Override
141 public Collection<Mep> getMepsByMdMa(MdId mdName, MaIdShort maName) {
142 return mepMap.values().stream()
143 .filter(mep -> mep.mdId().equals(mdName) && mep.maId().equals(maName))
144 .collect(Collectors.toList());
145 }
146
147 @Override
148 public Collection<Mep> getMepsByDeviceId(DeviceId deviceId) {
149 return mepMap.values().stream()
150 .filter(mep -> mep.deviceId().equals(deviceId))
151 .collect(Collectors.toList());
152 }
153
154 @Override
155 public Optional<Mep> getMep(MepKeyId mepKeyId) {
156 return mepMap.values().stream()
157 .filter(mep -> mep.mdId().equals(mepKeyId.mdId()) &&
158 mep.maId().equals(mepKeyId.maId()) &&
159 mep.mepId().equals(mepKeyId.mepId()))
160 .findFirst();
161 }
162
163 @Override
164 public boolean deleteMep(MepKeyId mepKeyId) {
165 return mepMap.remove(mepKeyId) == null ? false : true;
166 }
167
168 @Override
169 public boolean createUpdateMep(MepKeyId mepKeyId, Mep mep) {
170 return mepMap.put(mepKeyId, mep) == null ? false : true;
171 }
172
173 private class InternalMepListener implements MapEventListener<MepKeyId, Mep> {
174
175 @Override
176 public void event(MapEvent<MepKeyId, Mep> mapEvent) {
177 final CfmMepEvent.Type type;
178
179 switch (mapEvent.type()) {
180 case INSERT:
181 type = CfmMepEvent.Type.MEP_ADDED;
182 break;
183 case UPDATE:
184 type = CfmMepEvent.Type.MEP_UPDATED;
185 break;
186 default:
187 case REMOVE:
188 type = CfmMepEvent.Type.MEP_REMOVED;
189 }
190 notifyDelegate(new CfmMepEvent(type, mapEvent.key()));
191 }
192 }
193}