blob: f177709e96944964b095e43819bb26aa3c6fa838 [file] [log] [blame]
Aihua Guoeb9b3782016-09-09 01:11:40 -04001/*
2 * Copyright 2016 Open Networking Laboratory
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.tetopology.management.impl;
17
18import static org.slf4j.LoggerFactory.getLogger;
19
20import java.util.List;
21import java.lang.annotation.ElementType;
22import java.math.BigDecimal;
23import java.math.BigInteger;
24import java.util.ArrayList;
25import java.util.Map;
26
27import org.apache.felix.scr.annotations.Activate;
28import org.apache.felix.scr.annotations.Component;
29import org.apache.felix.scr.annotations.Deactivate;
30import org.apache.felix.scr.annotations.Reference;
31import org.apache.felix.scr.annotations.ReferenceCardinality;
32import org.apache.felix.scr.annotations.Service;
33import org.onlab.packet.IpAddress;
34import org.onlab.util.KryoNamespace;
35import org.onosproject.store.AbstractStore;
36import org.onosproject.store.serializers.KryoNamespaces;
37import org.onosproject.store.service.ConsistentMap;
38import org.onosproject.store.service.MapEvent;
39import org.onosproject.store.service.MapEventListener;
40import org.onosproject.store.service.Serializer;
41import org.onosproject.store.service.StorageService;
42import org.onosproject.tetopology.management.api.KeyId;
43import org.onosproject.tetopology.management.api.Network;
44import org.onosproject.tetopology.management.api.Networks;
45import org.onosproject.tetopology.management.api.TeTopologyEvent;
46import org.onosproject.tetopology.management.api.TeTopologyId;
47import org.onosproject.tetopology.management.api.TeTopologyType;
48import org.onosproject.tetopology.management.api.link.AsNumber;
49import org.onosproject.tetopology.management.api.link.DefaultNetworkLink;
50import org.onosproject.tetopology.management.api.link.ExternalDomain;
51import org.onosproject.tetopology.management.api.link.TeIpv4;
52import org.onosproject.tetopology.management.api.link.TeIpv6;
53import org.onosproject.tetopology.management.api.link.Label;
54import org.onosproject.tetopology.management.api.link.LinkProtectionType;
55import org.onosproject.tetopology.management.api.link.NetworkLink;
56import org.onosproject.tetopology.management.api.link.NetworkLinkKey;
57import org.onosproject.tetopology.management.api.link.PathElement;
58import org.onosproject.tetopology.management.api.link.TeLink;
59import org.onosproject.tetopology.management.api.link.TeLinkAccessType;
60import org.onosproject.tetopology.management.api.link.UnderlayBackupPath;
61import org.onosproject.tetopology.management.api.link.UnderlayPrimaryPath;
62import org.onosproject.tetopology.management.api.link.UnnumberedLink;
63import org.onosproject.tetopology.management.api.link.UnreservedBandwidth;
64import org.onosproject.tetopology.management.api.node.ConnectivityMatrix;
65import org.onosproject.tetopology.management.api.node.DefaultNetworkNode;
66import org.onosproject.tetopology.management.api.node.DefaultTerminationPoint;
67import org.onosproject.tetopology.management.api.node.InterfaceSwitchingCapability;
68import org.onosproject.tetopology.management.api.node.NetworkNode;
69import org.onosproject.tetopology.management.api.node.NetworkNodeKey;
70import org.onosproject.tetopology.management.api.node.TeNetworkTopologyId;
71import org.onosproject.tetopology.management.api.node.TeNode;
72import org.onosproject.tetopology.management.api.node.TeStatus;
73import org.onosproject.tetopology.management.api.node.TeTerminationPoint;
74import org.onosproject.tetopology.management.api.node.TerminationCapability;
75import org.onosproject.tetopology.management.api.node.TerminationPoint;
76import org.onosproject.tetopology.management.api.node.TerminationPointKey;
77import org.onosproject.tetopology.management.api.node.TunnelTerminationPoint;
78import org.onosproject.tetopology.management.api.TeTopologyStore;
79import org.onosproject.tetopology.management.api.TeTopologyStoreDelegate;
80import org.onosproject.tetopology.management.api.DefaultNetwork;
81import org.onosproject.tetopology.management.api.DefaultNetworks;
82import org.onosproject.tetopology.management.api.InternalTeNetwork;
83import org.slf4j.Logger;
84
85/**
86 * Implementation of the IETF network store.
87 */
88@Component(immediate = true)
89@Service
90public class DistributedTeTopologyStore
91 extends AbstractStore<TeTopologyEvent, TeTopologyStoreDelegate>
92 implements TeTopologyStore {
93
94 private final Logger log = getLogger(getClass());
95
96 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
97 protected StorageService storageService;
98
99 // Track networks by network key
100 private ConsistentMap<KeyId, InternalTeNetwork> networkIdNetworkConsistentMap;
101 private Map<KeyId, InternalTeNetwork> networkIdNetworkMap;
102
103 // Listener for network events
104 private final MapEventListener<KeyId, InternalTeNetwork> networkMapListener = new InternalNetworkMapListener();
105
106 private static final Serializer NETWORK_SERIALIZER = Serializer
107 .using(new KryoNamespace.Builder().register(KryoNamespaces.API)
108 .register(KeyId.class)
109 .register(InternalTeNetwork.class)
110 .register(TeTopologyId.class)
111 .register(DefaultNetwork.class)
112 .register(DefaultNetworks.class)
113 .register(InternalTeNetwork.class)
114 .register(Network.class)
115 .register(Networks.class)
116 .register(TeTopologyType.class)
117 .register(TeIpv4.class)
118 .register(NetworkLinkKey.class)
119 .register(NetworkLink.class)
120 .register(PathElement.class)
121 .register(TeLink.class)
122 .register(UnderlayBackupPath.class)
123 .register(UnderlayPrimaryPath.class)
124 .register(UnnumberedLink.class)
125 .register(UnreservedBandwidth.class)
126 .register(InterfaceSwitchingCapability.class)
127 .register(NetworkNode.class)
128 .register(TeNode.class)
129 .register(TerminationPoint.class)
130 .register(TeTerminationPoint.class)
131 .register(TerminationCapability.class)
132 .register(TeStatus.class)
133 .register(TunnelTerminationPoint.class)
134 .register(DefaultNetworkLink.class)
135 .register(DefaultNetworkNode.class)
136 .register(DefaultTerminationPoint.class)
137 .register(TerminationPointKey.class)
138 .register(TeNetworkTopologyId.class)
139 .register(NetworkNodeKey.class)
140 .register(ConnectivityMatrix.class)
141 .register(TeTopologyId.class)
142 .register(TeLinkAccessType.class)
143 .register(BigInteger.class)
144 .register(String.class)
145 .register(Long.class)
146 .register(Boolean.class)
147 .register(BigDecimal.class)
148 .register(Short.class)
149 .register(IpAddress.class)
150 .register(Integer.class)
151 .register(ExternalDomain.class)
152 .register(ElementType.class)
153 .register(LinkProtectionType.class)
154 .register(Label.class)
155 .register(TeIpv6.class)
156 .register(AsNumber.class)
157 .build());
158
159 /**
160 * Distributed network store service activate method.
161 */
162 @Activate
163 public void activate() {
164 log.info("TE topology store is activated");
165 networkIdNetworkConsistentMap = storageService.<KeyId, InternalTeNetwork>consistentMapBuilder()
166 .withSerializer(NETWORK_SERIALIZER)
167 .withName("networkId-network")
168 .withRelaxedReadConsistency()
169 .build();
170 networkIdNetworkConsistentMap.addListener(networkMapListener);
171 networkIdNetworkMap = networkIdNetworkConsistentMap.asJavaMap();
172
173 log.info("Started");
174 }
175
176 /**
177 * Distributed network store service deactivate method.
178 */
179 @Deactivate
180 public void deactivate() {
181 networkIdNetworkConsistentMap.removeListener(networkMapListener);
182 log.info("Stopped");
183 }
184
185 @Override
186 public List<InternalTeNetwork> getNetworks(TeTopologyType type) {
187 List<InternalTeNetwork> networks = new ArrayList<>();
188
189 for (Map.Entry<KeyId, InternalTeNetwork> entry:networkIdNetworkMap.entrySet()) {
190 KeyId networkId = entry.getKey();
191 InternalTeNetwork network = entry.getValue();
192
193 if (network.getTeTopologyType() == type ||
194 type == TeTopologyType.ANY) {
195 networks.add(network);
196 }
197 }
198
199 return networks;
200 }
201
202 @Override
203 public InternalTeNetwork getNetwork(KeyId networkId) {
204 return networkIdNetworkMap.get(networkId);
205 }
206
207 @Override
208 public void updateNetwork(InternalTeNetwork network) {
209 //TODO - check the validity of the network before updating
210 log.info("network = {}", network);
211 networkIdNetworkMap.put(network.networkId(), network);
212 }
213
214 @Override
215 public void removeNetwork(KeyId networkId) {
216 networkIdNetworkMap.remove(networkId);
217 }
218
219 /**
220 * Listener class to map listener map events to the network events.
221 */
222 private class InternalNetworkMapListener implements MapEventListener<KeyId, InternalTeNetwork> {
223 @Override
224 public void event(MapEvent<KeyId, InternalTeNetwork> event) {
225 TeTopologyEvent.Type type = null;
226 TeTopologyEvent topologyEvent = null;
227 switch (event.type()) {
228 case INSERT:
229 type = TeTopologyEvent.Type.NETWORK_ADDED;
230 // Need to check if nodes/links are already in, otherwise errors
231 topologyEvent = new TeTopologyEvent(type, event.newValue().value());
232 break;
233 case UPDATE:
234 // Need to check what attributes change, and coordinate with other Node/Link events.
235 if ((event.oldValue().value() != null) && (event.newValue().value() == null)) {
236 type = TeTopologyEvent.Type.NETWORK_REMOVED;
237 topologyEvent = new TeTopologyEvent(type, event.oldValue().value());
238 } else {
239 type = TeTopologyEvent.Type.NETWORK_UPDATED;
240 topologyEvent = new TeTopologyEvent(type, event.newValue().value());
241 }
242 break;
243 case REMOVE:
244 type = TeTopologyEvent.Type.NETWORK_REMOVED;
245 topologyEvent = new TeTopologyEvent(type, event.oldValue().value());
246 break;
247 default:
248 log.error("Unsupported event type: {}", event.type());
249 }
250 log.info("Event type {}, Event {}", type, topologyEvent);
251 if (topologyEvent != null) {
252 notifyDelegate(topologyEvent);
253 }
254 }
255 }
256
257}
258