blob: 3b45c7d1fbe6279c1ee6c1e1c7a78732cfe2de84 [file] [log] [blame]
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +05301/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +05303 *
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 */
janani bf41dec32017-03-24 18:44:07 +053016package org.onosproject.l3vpn.netl3vpn.impl;
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +053017
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;
janani b176905a2017-03-28 17:36:18 +053023import org.onlab.util.AbstractAccumulator;
24import org.onlab.util.Accumulator;
Bharat saraswalcdfda202017-03-24 23:40:50 +053025import org.onosproject.cluster.ClusterService;
26import org.onosproject.cluster.LeadershipEvent;
27import org.onosproject.cluster.LeadershipEventListener;
28import org.onosproject.cluster.LeadershipService;
29import org.onosproject.cluster.NodeId;
janani b35f6cbc2017-03-24 21:56:58 +053030import org.onosproject.config.DynamicConfigEvent;
31import org.onosproject.config.DynamicConfigListener;
32import org.onosproject.config.DynamicConfigService;
janani b176905a2017-03-28 17:36:18 +053033import org.onosproject.config.FailedException;
34import org.onosproject.config.Filter;
Bharat saraswalcdfda202017-03-24 23:40:50 +053035import org.onosproject.core.ApplicationId;
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +053036import org.onosproject.core.CoreService;
janani b35f6cbc2017-03-24 21:56:58 +053037import org.onosproject.core.IdGenerator;
38import org.onosproject.l3vpn.netl3vpn.AccessInfo;
39import org.onosproject.l3vpn.netl3vpn.BgpDriverInfo;
40import org.onosproject.l3vpn.netl3vpn.BgpInfo;
41import org.onosproject.l3vpn.netl3vpn.DeviceInfo;
42import org.onosproject.l3vpn.netl3vpn.FullMeshVpnConfig;
43import org.onosproject.l3vpn.netl3vpn.HubSpokeVpnConfig;
44import org.onosproject.l3vpn.netl3vpn.InterfaceInfo;
45import org.onosproject.l3vpn.netl3vpn.NetL3VpnException;
46import org.onosproject.l3vpn.netl3vpn.NetL3VpnStore;
47import org.onosproject.l3vpn.netl3vpn.VpnConfig;
48import org.onosproject.l3vpn.netl3vpn.VpnInstance;
49import org.onosproject.l3vpn.netl3vpn.VpnSiteRole;
50import org.onosproject.l3vpn.netl3vpn.VpnType;
janani b35f6cbc2017-03-24 21:56:58 +053051import org.onosproject.net.DeviceId;
52import org.onosproject.net.Port;
53import org.onosproject.net.device.DeviceService;
54import org.onosproject.net.driver.DriverService;
janani b9ed76be2017-08-29 19:11:33 +053055import org.onosproject.pce.pceservice.api.PceService;
Vidyashree Rama04147ca2017-05-26 11:32:47 +053056import org.onosproject.yang.gen.v1.ietfinterfaces.rev20140508.ietfinterfaces.devices.device.Interfaces;
57import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.DefaultL3VpnSvc;
58import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.L3VpnSvc;
59import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.accessvpnpolicy.VpnAttachment;
60import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.accessvpnpolicy.vpnattachment.AttachmentFlavor;
61import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.accessvpnpolicy.vpnattachment.attachmentflavor.DefaultVpnId;
62import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.l3vpnsvc.DefaultSites;
63import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.l3vpnsvc.Sites;
64import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.l3vpnsvc.VpnServices;
65import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.l3vpnsvc.sites.Site;
66import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.l3vpnsvc.sites.site.SiteNetworkAccesses;
67import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.l3vpnsvc.sites.site.sitenetworkaccesses.SiteNetworkAccess;
68import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.l3vpnsvc.vpnservices.VpnSvc;
69import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.siteattachmentbearer.Bearer;
Vidyashree Rama04147ca2017-05-26 11:32:47 +053070import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.siteattachmentbearer.bearer.RequestedType;
71import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.siteattachmentipconnection.IpConnection;
72import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.siterouting.RoutingProtocols;
73import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.siterouting.routingprotocols.RoutingProtocol;
74import org.onosproject.yang.gen.v1.ietfnetworkinstance.rev20160623.ietfnetworkinstance.devices.device.NetworkInstances;
75import org.onosproject.yang.gen.v1.l3vpnsvcext.rev20160730.l3vpnsvcext.l3vpnsvc.sites.site.sitenetworkaccesses.sitenetworkaccess.bearer.DefaultAugmentedL3VpnBearer;
76import org.onosproject.yang.gen.v1.l3vpnsvcext.rev20160730.l3vpnsvcext.l3vpnsvc.sites.site.sitenetworkaccesses.sitenetworkaccess.bearer.requestedtype.DefaultAugmentedL3VpnRequestedType;
77import org.onosproject.yang.gen.v1.l3vpnsvcext.rev20160730.l3vpnsvcext.requestedtypegrouping.requestedtypeprofile.RequestedTypeChoice;
78import org.onosproject.yang.gen.v1.l3vpnsvcext.rev20160730.l3vpnsvcext.requestedtypegrouping.requestedtypeprofile.requestedtypechoice.DefaultDot1Qcase;
79import org.onosproject.yang.gen.v1.l3vpnsvcext.rev20160730.l3vpnsvcext.requestedtypegrouping.requestedtypeprofile.requestedtypechoice.DefaultPhysicalCase;
janani b35f6cbc2017-03-24 21:56:58 +053080import org.onosproject.yang.model.DataNode;
81import org.onosproject.yang.model.DefaultModelObjectData;
82import org.onosproject.yang.model.ModelConverter;
83import org.onosproject.yang.model.ModelObject;
84import org.onosproject.yang.model.ModelObjectData;
85import org.onosproject.yang.model.ModelObjectId;
86import org.onosproject.yang.model.NodeKey;
87import org.onosproject.yang.model.ResourceData;
88import org.onosproject.yang.model.ResourceId;
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +053089import org.slf4j.Logger;
90import org.slf4j.LoggerFactory;
91
92import java.util.Iterator;
janani b35f6cbc2017-03-24 21:56:58 +053093import java.util.List;
94import java.util.Map;
janani b176905a2017-03-28 17:36:18 +053095import java.util.Timer;
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +053096
janani b176905a2017-03-28 17:36:18 +053097import static com.google.common.base.Preconditions.checkNotNull;
janani b35f6cbc2017-03-24 21:56:58 +053098import static org.onosproject.config.DynamicConfigEvent.Type.NODE_ADDED;
99import static org.onosproject.config.DynamicConfigEvent.Type.NODE_DELETED;
Bharat saraswalcdfda202017-03-24 23:40:50 +0530100import static org.onosproject.l3vpn.netl3vpn.VpnType.HUB;
janani b35f6cbc2017-03-24 21:56:58 +0530101import static org.onosproject.l3vpn.netl3vpn.impl.BgpConstructionUtil.createBgpInfo;
102import static org.onosproject.l3vpn.netl3vpn.impl.InsConstructionUtil.createInstance;
janani b176905a2017-03-28 17:36:18 +0530103import static org.onosproject.l3vpn.netl3vpn.impl.InsConstructionUtil.deleteInstance;
janani b35f6cbc2017-03-24 21:56:58 +0530104import static org.onosproject.l3vpn.netl3vpn.impl.IntConstructionUtil.createInterface;
105import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.BEARER_NULL;
106import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.CONS_HUNDRED;
107import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.DEVICE_INFO_NULL;
janani b176905a2017-03-28 17:36:18 +0530108import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.EVENT_NULL;
janani b35f6cbc2017-03-24 21:56:58 +0530109import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.ID_LIMIT;
110import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.ID_LIMIT_EXCEEDED;
111import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.INT_INFO_NULL;
112import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.IP_INT_INFO_NULL;
janani b176905a2017-03-28 17:36:18 +0530113import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.MAX_BATCH_MS;
114import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.MAX_EVENTS;
115import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.MAX_IDLE_MS;
janani b35f6cbc2017-03-24 21:56:58 +0530116import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.PORT_NAME;
117import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.SITE_ROLE_NULL;
118import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.SITE_VPN_MISMATCH;
janani b176905a2017-03-28 17:36:18 +0530119import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.TIMER;
120import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.UNKNOWN_EVENT;
janani b35f6cbc2017-03-24 21:56:58 +0530121import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.VPN_ATTACHMENT_NULL;
122import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.VPN_POLICY_NOT_SUPPORTED;
123import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.VPN_TYPE_UNSUPPORTED;
124import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getBgpCreateConfigObj;
janani b9ed76be2017-08-29 19:11:33 +0530125import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getId;
janani b35f6cbc2017-03-24 21:56:58 +0530126import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getIntCreateModObj;
127import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getIntNotAvailable;
janani b35f6cbc2017-03-24 21:56:58 +0530128import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getModIdForL3VpnSvc;
129import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getModIdForSites;
130import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getResourceData;
131import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getRole;
janani bd821b182017-03-30 16:34:49 +0530132import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getVpnBgpDelModObj;
janani b35f6cbc2017-03-24 21:56:58 +0530133import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getVpnCreateModObj;
janani bd821b182017-03-30 16:34:49 +0530134import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getVpnDelModObj;
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530135
136/**
137 * The IETF net l3vpn manager implementation.
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530138 */
139@Component(immediate = true)
janani bd821b182017-03-30 16:34:49 +0530140public class NetL3VpnManager {
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530141
142 private static final String APP_ID = "org.onosproject.app.l3vpn";
janani b35f6cbc2017-03-24 21:56:58 +0530143 private static final String L3_VPN_ID_TOPIC = "l3vpn-id";
janani b9ed76be2017-08-29 19:11:33 +0530144 private static final String TNL_ID_TOPIC = "l3vpn-tnl-id";
janani b35f6cbc2017-03-24 21:56:58 +0530145
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530146 private final Logger log = LoggerFactory.getLogger(getClass());
147
janani b176905a2017-03-28 17:36:18 +0530148 private final DynamicConfigListener configListener =
149 new InternalConfigListener();
150
151 private final Accumulator<DynamicConfigEvent> accumulator =
152 new InternalEventAccumulator();
153
154 private final InternalLeadershipListener leadershipEventListener =
155 new InternalLeadershipListener();
156
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530157 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
158 protected CoreService coreService;
159
160 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
janani b35f6cbc2017-03-24 21:56:58 +0530161 protected DriverService driverService;
162
163 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
164 protected DeviceService deviceService;
165
166 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
janani b35f6cbc2017-03-24 21:56:58 +0530167 protected ModelConverter modelConverter;
168
169 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
170 protected DynamicConfigService configService;
171
172 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
173 protected NetL3VpnStore l3VpnStore;
174
Bharat saraswalcdfda202017-03-24 23:40:50 +0530175 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
176 protected LeadershipService leadershipService;
177
178 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
179 protected ClusterService clusterService;
180
janani b9ed76be2017-08-29 19:11:33 +0530181 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
182 protected PceService pceService;
183
janani b35f6cbc2017-03-24 21:56:58 +0530184 protected IdGenerator l3VpnIdGen;
janani b176905a2017-03-28 17:36:18 +0530185
janani b9ed76be2017-08-29 19:11:33 +0530186 protected IdGenerator tnlIdGen;
187
Bharat saraswalcdfda202017-03-24 23:40:50 +0530188 private NodeId localNodeId;
janani b176905a2017-03-28 17:36:18 +0530189
Bharat saraswalcdfda202017-03-24 23:40:50 +0530190 private ApplicationId appId;
janani b35f6cbc2017-03-24 21:56:58 +0530191
janani b35f6cbc2017-03-24 21:56:58 +0530192 private ResourceId id;
janani b176905a2017-03-28 17:36:18 +0530193
janani b35f6cbc2017-03-24 21:56:58 +0530194 private ResourceId module;
janani b176905a2017-03-28 17:36:18 +0530195
janani b35f6cbc2017-03-24 21:56:58 +0530196 private ResourceId sites;
janani b176905a2017-03-28 17:36:18 +0530197
Gaurav Agrawal8dbd2732017-04-14 18:57:30 +0530198 private boolean isElectedLeader;
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530199
janani b9ed76be2017-08-29 19:11:33 +0530200 private NetL3VpnTunnelHandler tnlHandler;
201
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530202 @Activate
203 protected void activate() {
Bharat saraswalcdfda202017-03-24 23:40:50 +0530204 appId = coreService.registerApplication(APP_ID);
janani b35f6cbc2017-03-24 21:56:58 +0530205 l3VpnIdGen = coreService.getIdGenerator(L3_VPN_ID_TOPIC);
janani b9ed76be2017-08-29 19:11:33 +0530206 tnlIdGen = coreService.getIdGenerator(TNL_ID_TOPIC);
Bharat saraswalcdfda202017-03-24 23:40:50 +0530207 localNodeId = clusterService.getLocalNode().id();
Bharat saraswalcdfda202017-03-24 23:40:50 +0530208 leadershipService.addListener(leadershipEventListener);
209 leadershipService.runForLeadership(appId.name());
janani b35f6cbc2017-03-24 21:56:58 +0530210 getResourceId();
211 configService.addListener(configListener);
janani b9ed76be2017-08-29 19:11:33 +0530212 tnlHandler = new NetL3VpnTunnelHandler(
213 pceService, driverService, configService, l3VpnStore,
214 deviceService, tnlIdGen, modelConverter);
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530215 log.info("Started");
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530216 }
217
218 @Deactivate
219 protected void deactivate() {
janani b35f6cbc2017-03-24 21:56:58 +0530220 configService.removeListener(configListener);
Bharat saraswalcdfda202017-03-24 23:40:50 +0530221 leadershipService.withdraw(appId.name());
222 leadershipService.removeListener(leadershipEventListener);
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530223 log.info("Stopped");
224 }
225
janani b35f6cbc2017-03-24 21:56:58 +0530226 /**
227 * Returns id as string. If the id is not in the freed list a new id is
228 * generated else the id from the freed list is used.
229 *
230 * @return id
231 */
232 private String getIdFromGen() {
233 Long value;
234 Iterable<Long> freeIds = l3VpnStore.getFreedIdList();
235 Iterator<Long> it = freeIds.iterator();
236 if (it.hasNext()) {
237 value = it.next();
238 l3VpnStore.removeIdFromFreeList(value);
239 } else {
240 value = l3VpnIdGen.getNewId();
241 }
242 if (value > ID_LIMIT) {
243 throw new RuntimeException(ID_LIMIT_EXCEEDED);
244 }
245 return CONS_HUNDRED + String.valueOf(value);
246 }
247
248 /**
249 * Returns the resource id, after constructing model object id and
250 * converting it.
251 */
252 private void getResourceId() {
253
254 ModelObjectId moduleId = ModelObjectId.builder().build();
255 module = getResourceVal(moduleId);
256
257 ModelObjectId svcId = getModIdForL3VpnSvc();
258 id = getResourceVal(svcId);
259
260 ModelObjectId sitesId = getModIdForSites();
261 sites = getResourceVal(sitesId);
262 }
263
264 /**
265 * Returns resource id from model converter.
266 *
267 * @param modelId model object id
268 * @return resource id
269 */
270 private ResourceId getResourceVal(ModelObjectId modelId) {
271 DefaultModelObjectData.Builder data = DefaultModelObjectData.builder()
Thomas Vachuskad17bc732017-03-24 11:46:55 -0700272 .identifier(modelId);
janani b35f6cbc2017-03-24 21:56:58 +0530273 ResourceData resData = modelConverter.createDataNode(data.build());
janani b176905a2017-03-28 17:36:18 +0530274 return resData.resourceId();
janani b35f6cbc2017-03-24 21:56:58 +0530275 }
276
277 /**
278 * Processes create request from the store, by taking the root object.
279 * The root object is then used for l3VPN processing.
280 *
281 * @param storeId store resource id
janani b176905a2017-03-28 17:36:18 +0530282 * @param node data node
janani b35f6cbc2017-03-24 21:56:58 +0530283 */
janani b176905a2017-03-28 17:36:18 +0530284 private void processCreateFromStore(ResourceId storeId, DataNode node) {
Bharat saraswal5b5bd9a2017-03-27 18:59:55 +0530285 if (isElectedLeader) {
janani b176905a2017-03-28 17:36:18 +0530286 List<NodeKey> keys = storeId.nodeKeys();
287 List<ModelObject> objects = null;
288 if (keys.size() == 1) {
289 objects = getModelObjects(node, module);
290 } else if (keys.size() == 2) {
291 objects = getModelObjects(node, id);
292 }
293 if (objects != null) {
294 for (ModelObject obj : objects) {
295 if (obj instanceof DefaultL3VpnSvc) {
296 DefaultL3VpnSvc l3VpnSvc = (DefaultL3VpnSvc) obj;
297 createGlobalConfig(l3VpnSvc);
298 } else if (obj instanceof DefaultSites) {
299 DefaultSites sites = (DefaultSites) obj;
300 createInterfaceConfig(sites);
301 }
Bharat saraswalcdfda202017-03-24 23:40:50 +0530302 }
janani b35f6cbc2017-03-24 21:56:58 +0530303 }
304 }
305 }
306
307 /**
Bharat saraswalcdfda202017-03-24 23:40:50 +0530308 * Processes delete request from the store, by taking the root object.
janani b176905a2017-03-28 17:36:18 +0530309 * The root object would have got deleted from store. So all the
310 * configurations are removed.
Bharat saraswalcdfda202017-03-24 23:40:50 +0530311 *
janani b176905a2017-03-28 17:36:18 +0530312 * @param dataNode data node
Bharat saraswalcdfda202017-03-24 23:40:50 +0530313 */
janani b176905a2017-03-28 17:36:18 +0530314 private void processDeleteFromStore(DataNode dataNode) {
Bharat saraswal5b5bd9a2017-03-27 18:59:55 +0530315 if (isElectedLeader) {
janani b176905a2017-03-28 17:36:18 +0530316 if (dataNode == null) {
317 //TODO: Delete for inner nodes.
318 deleteGlobalConfig(null);
319 }
Bharat saraswalcdfda202017-03-24 23:40:50 +0530320 }
321 }
322
323 /**
janani b176905a2017-03-28 17:36:18 +0530324 * Returns model objects of the store. The data node read from store
325 * gives the particular node. So the node's parent resource id is taken
326 * and the data node is given to model converter.
janani b35f6cbc2017-03-24 21:56:58 +0530327 *
janani b176905a2017-03-28 17:36:18 +0530328 * @param dataNode data node from store
329 * @param appId parent resource id
janani b35f6cbc2017-03-24 21:56:58 +0530330 * @return model objects
331 */
janani b176905a2017-03-28 17:36:18 +0530332 public List<ModelObject> getModelObjects(DataNode dataNode,
janani b35f6cbc2017-03-24 21:56:58 +0530333 ResourceId appId) {
janani b35f6cbc2017-03-24 21:56:58 +0530334 ResourceData data = getResourceData(dataNode, appId);
335 ModelObjectData modelData = modelConverter.createModel(data);
336 return modelData.modelObjects();
337 }
338
339 /**
340 * Returns true if the event resource id points to the root level node
341 * only and event is for addition and deletion; false otherwise.
342 *
343 * @param event config event
344 * @return true if event is supported; false otherwise
345 */
346 public boolean isSupported(DynamicConfigEvent event) {
347 ResourceId rsId = event.subject();
348 List<NodeKey> storeKeys = rsId.nodeKeys();
349 List<NodeKey> regKeys = id.nodeKeys();
janani b176905a2017-03-28 17:36:18 +0530350 List<NodeKey> sitesKeys = sites.nodeKeys();
janani b35f6cbc2017-03-24 21:56:58 +0530351 if (storeKeys != null) {
janani b176905a2017-03-28 17:36:18 +0530352 int storeSize = storeKeys.size();
353 if (storeSize == 1) {
janani b35f6cbc2017-03-24 21:56:58 +0530354 return storeKeys.get(0).equals(regKeys.get(1)) &&
355 (event.type() == NODE_ADDED ||
356 event.type() == NODE_DELETED);
janani b176905a2017-03-28 17:36:18 +0530357 } else if (storeSize == 2) {
358 return (storeKeys.get(0).equals(sitesKeys.get(1))) &&
359 storeKeys.get(1).equals(sitesKeys.get(2)) &&
360 (event.type() == NODE_ADDED ||
361 event.type() == NODE_DELETED);
janani b35f6cbc2017-03-24 21:56:58 +0530362 }
363 }
364 return false;
365 }
366
367 /***
janani b176905a2017-03-28 17:36:18 +0530368 * Creates all configuration in the standard device model.
janani b35f6cbc2017-03-24 21:56:58 +0530369 *
370 * @param l3VpnSvc l3VPN service object
371 */
372 void createGlobalConfig(L3VpnSvc l3VpnSvc) {
373 if (l3VpnSvc.vpnServices() != null) {
374 createVpnServices(l3VpnSvc.vpnServices());
375 }
376 if (l3VpnSvc.sites() != null) {
377 createInterfaceConfig(l3VpnSvc.sites());
378 }
379 }
380
381 /**
382 * Creates the VPN instances from the VPN services object, if only that
383 * VPN instance is not already created.
384 *
385 * @param vpnSvcs VPN services object
386 */
387 private void createVpnServices(VpnServices vpnSvcs) {
388 if (vpnSvcs != null && vpnSvcs.vpnSvc() != null) {
389 List<VpnSvc> svcList = vpnSvcs.vpnSvc();
390 for (VpnSvc svc : svcList) {
391 String vpnName = svc.vpnId().string();
392 l3VpnStore.addVpnInsIfAbsent(vpnName, new VpnInstance(vpnName));
393 }
394 }
395 }
396
397 /**
398 * Creates interface configuration from the site network access if
399 * available.
400 *
401 * @param sites sites object
402 */
403 private void createInterfaceConfig(Sites sites) {
404 if (sites.site() != null) {
405 List<Site> sitesList = sites.site();
406 for (Site site : sitesList) {
407 if (site.siteNetworkAccesses() != null) {
408 SiteNetworkAccesses accesses = site.siteNetworkAccesses();
409 List<SiteNetworkAccess> accessList =
410 accesses.siteNetworkAccess();
411 for (SiteNetworkAccess access : accessList) {
412 createFromAccess(access, site.siteId().string());
413 }
414 }
415 }
416 }
417 }
418
419 /**
420 * Creates the interface and VPN related configurations from the access
421 * and site id value.
422 *
423 * @param access site network access
424 * @param siteId site id
425 */
426 private void createFromAccess(SiteNetworkAccess access, String siteId) {
427 Map<AccessInfo, InterfaceInfo> intMap = l3VpnStore.getInterfaceInfo();
428 Map<String, VpnInstance> insMap = l3VpnStore.getVpnInstances();
429 String accessId = access.siteNetworkAccessId().string();
430 AccessInfo info = new AccessInfo(siteId, accessId);
431
432 if (intMap.get(info) == null) {
433 VpnSiteRole siteRole = getSiteRole(access.vpnAttachment());
434 VpnInstance instance = insMap.get(siteRole.name());
435 if (instance == null) {
436 throw new NetL3VpnException(SITE_VPN_MISMATCH);
437 }
438 buildFromAccess(instance, info, access, siteRole);
439 }
440 }
441
442 /**
443 * Returns the VPN site role from the VPN attachment.
444 *
445 * @param attach VPN attachment
446 * @return VPN site role
447 */
448 private VpnSiteRole getSiteRole(VpnAttachment attach) {
449 if (attach == null || attach.attachmentFlavor() == null) {
450 throw new NetL3VpnException(VPN_ATTACHMENT_NULL);
451 }
452 AttachmentFlavor flavor = attach.attachmentFlavor();
453 if (!(flavor instanceof DefaultVpnId)) {
454 throw new NetL3VpnException(VPN_POLICY_NOT_SUPPORTED);
455 }
456 DefaultVpnId vpnId = (DefaultVpnId) flavor;
457 if (vpnId.siteRole() == null) {
458 throw new NetL3VpnException(SITE_ROLE_NULL);
459 }
460 VpnType role = getRole(vpnId.siteRole());
janani b176905a2017-03-28 17:36:18 +0530461 return new VpnSiteRole(String.valueOf(vpnId.vpnId()), role);
janani b35f6cbc2017-03-24 21:56:58 +0530462 }
463
464 /**
465 * Builds the required details for device standard model from the site
466 * network access info available.
467 *
468 * @param instance VPN instance
469 * @param info access info
470 * @param access network access
471 * @param role VPN site role
472 */
473 private void buildFromAccess(VpnInstance instance, AccessInfo info,
474 SiteNetworkAccess access, VpnSiteRole role) {
475 Bearer bearer = access.bearer();
476 if (bearer == null) {
477 throw new NetL3VpnException(BEARER_NULL);
478 }
479
480 RequestedType reqType = bearer.requestedType();
481 IpConnection connect = access.ipConnection();
482 RoutingProtocols pro = access.routingProtocols();
483
484 if (reqType == null || connect == null) {
485 throw new NetL3VpnException(IP_INT_INFO_NULL);
486 }
487 buildDeviceDetails(instance, info, role, bearer, connect,
488 reqType, pro);
489 }
490
491 /**
492 * Builds the device details such as, VPN instance value if it is for
493 * the first time, interface values and BGP info if available in service.
494 *
495 * @param instance VPN instance
496 * @param accInfo access info
497 * @param role VPN site role
498 * @param bearer bearer object
499 * @param connect ip connect object
500 * @param reqType requested type
501 * @param pro routing protocol
502 */
503 private void buildDeviceDetails(VpnInstance instance, AccessInfo accInfo,
504 VpnSiteRole role, Bearer bearer,
505 IpConnection connect, RequestedType reqType,
506 RoutingProtocols pro) {
507 Map<AccessInfo, InterfaceInfo> interMap = l3VpnStore.getInterfaceInfo();
508 InterfaceInfo intInfo = interMap.get(accInfo);
509 if (intInfo != null) {
510 return;
511 }
512
513 DeviceInfo info = buildDevVpnIns(bearer, instance, role, connect);
514 String portName = getInterfaceName(info, reqType);
515 buildDevVpnInt(info, instance, connect, portName, accInfo);
516
517 if (pro != null && pro.routingProtocol() != null) {
518 buildBgpInfo(pro.routingProtocol(), info,
519 role.name(), connect, accInfo);
520 }
521 InterfaceInfo interInfo = new InterfaceInfo(info, portName,
522 instance.vpnName());
523 l3VpnStore.addInterfaceInfo(accInfo, interInfo);
janani bd821b182017-03-30 16:34:49 +0530524 l3VpnStore.addVpnIns(instance.vpnName(), instance);
janani b35f6cbc2017-03-24 21:56:58 +0530525 }
526
527 /**
528 * Builds device VPN instance with the service objects. It returns
529 *
530 * @param bearer bearer object
531 * @param ins VPN instance
532 * @param role VPN site role
533 * @param connect ip connection
534 * @return return
535 */
536 private DeviceInfo buildDevVpnIns(Bearer bearer, VpnInstance ins,
537 VpnSiteRole role, IpConnection connect) {
janani b9ed76be2017-08-29 19:11:33 +0530538 DefaultAugmentedL3VpnBearer augBearer = bearer.augmentation(
539 DefaultAugmentedL3VpnBearer.class);
janani b35f6cbc2017-03-24 21:56:58 +0530540 DeviceId id = getDeviceId(augBearer);
541 Map<DeviceId, DeviceInfo> devices = ins.devInfo();
542 DeviceInfo info = null;
543 if (devices != null) {
544 info = devices.get(id);
545 }
546 if (info == null) {
547 info = createVpnInstance(id, role, ins, connect);
548 }
549 return info;
550 }
551
552 /**
553 * Returns the device id from the bearer augment attachment of service.
554 * If the attachment in augment is not available it throws error.
555 *
556 * @param attach augmented bearer
557 * @return device id
558 */
559 private DeviceId getDeviceId(DefaultAugmentedL3VpnBearer attach) {
560 if (attach == null || attach.bearerAttachment() == null ||
561 attach.bearerAttachment().peMgmtIp() == null ||
562 attach.bearerAttachment().peMgmtIp().string() == null) {
563 throw new NetL3VpnException(DEVICE_INFO_NULL);
564 }
565 String ip = attach.bearerAttachment().peMgmtIp().string();
janani b9ed76be2017-08-29 19:11:33 +0530566 return getId(ip, true, deviceService.getAvailableDevices());
janani b35f6cbc2017-03-24 21:56:58 +0530567 }
568
569 /**
570 * Creates the VPN instance by constructing standard device model of
571 * instances. It adds the RD and RT values to the VPN instance.
572 *
573 * @param id device id
574 * @param role VPN site role
575 * @param inst VPN instance
576 * @param ip ip connection
577 * @return device info
578 */
579 private DeviceInfo createVpnInstance(DeviceId id, VpnSiteRole role,
580 VpnInstance inst, IpConnection ip) {
581 Map<AccessInfo, InterfaceInfo> intMap = l3VpnStore.getInterfaceInfo();
582 generateRdRt(inst, role);
janani b9ed76be2017-08-29 19:11:33 +0530583 DeviceInfo info = new DeviceInfo(id, role.role());
janani b35f6cbc2017-03-24 21:56:58 +0530584
585 NetworkInstances instances = createInstance(inst, role, ip);
586 ModelObjectData devMod = getVpnCreateModObj(intMap, instances,
587 id.toString());
janani b9ed76be2017-08-29 19:11:33 +0530588 inst.addDevInfo(id, info);
589 l3VpnStore.addVpnIns(inst.vpnName(), inst);
590
janani b35f6cbc2017-03-24 21:56:58 +0530591 ModelObjectData driMod = info.processCreateInstance(driverService,
592 devMod);
593 ResourceData resData = modelConverter.createDataNode(driMod);
594 addToStore(resData);
janani b9ed76be2017-08-29 19:11:33 +0530595 checkAndUpdateTunnel(inst, id);
janani b35f6cbc2017-03-24 21:56:58 +0530596 return info;
597 }
598
599 /**
janani b9ed76be2017-08-29 19:11:33 +0530600 * Checks if the tunnel can be established and creates the tunnel from
601 * source to destination.
602 *
603 * @param inst VPN instance
604 * @param id device id
605 */
606 private void checkAndUpdateTunnel(VpnInstance inst, DeviceId id) {
607 Map<DeviceId, DeviceInfo> devInfo = inst.devInfo();
608 int devSize = devInfo.size();
609 String vpnName = inst.vpnName();
610 if (devSize != 1) {
611 DeviceInfo info = devInfo.get(id);
612 tnlHandler.createSrcInfo(vpnName, info);
613 for (Map.Entry<DeviceId, DeviceInfo> device : devInfo.entrySet()) {
614 DeviceInfo val = device.getValue();
615 if (val != info) {
616 tnlHandler.createSrcDesTunnel(val);
617 }
618 }
619 }
620 }
621
622 /**
janani b35f6cbc2017-03-24 21:56:58 +0530623 * Adds the resource data that is received from the driver, after
624 * converting from the model object data.
625 *
626 * @param resData resource data
627 */
628 private void addToStore(ResourceData resData) {
629 if (resData != null && resData.dataNodes() != null) {
630 List<DataNode> dataNodes = resData.dataNodes();
631 for (DataNode node : dataNodes) {
Sithara Punnassery7b0c15e2017-07-07 15:08:19 -0700632 configService.createNode(resData.resourceId(), node);
janani b35f6cbc2017-03-24 21:56:58 +0530633 }
634 }
635 }
636
637 /**
638 * Generates RD and RT value for the VPN instance for the first time VPN
639 * instance creation.
640 *
641 * @param ins VPN instance
642 * @param role VPN site role
643 */
644 private void generateRdRt(VpnInstance ins, VpnSiteRole role) {
645 ins.type(role.role());
646 VpnConfig config = ins.vpnConfig();
647 String rd = null;
648 if (config == null) {
649 rd = getIdFromGen();
650 }
651 switch (ins.type()) {
652 case ANY_TO_ANY:
653 if (config == null) {
654 config = new FullMeshVpnConfig(rd);
655 config.rd(rd);
656 }
657 break;
658
659 case HUB:
660 case SPOKE:
661 if (config == null) {
662 config = new HubSpokeVpnConfig();
663 config.rd(rd);
664 }
665 createImpRtVal((HubSpokeVpnConfig) config, ins.type());
666 createExpRtVal((HubSpokeVpnConfig) config, ins.type());
667 break;
668
669 default:
670 throw new NetL3VpnException(VPN_TYPE_UNSUPPORTED);
671 }
672 ins.vpnConfig(config);
673 }
674
675 /**
676 * Creates import RT value for HUB and SPOKE, according to the type, if
677 * the values are not present.
678 *
679 * @param config VPN config
680 * @param type VPN type
681 */
682 private void createImpRtVal(HubSpokeVpnConfig config, VpnType type) {
683 if (type == HUB) {
684 if (config.hubImpRt() != null) {
685 return;
686 }
687 setHubImpRt(config);
688 } else {
689 if (config.spokeImpRt() != null) {
690 return;
691 }
692 config.spokeImpRt(config.rd());
693 }
694 }
695
696 /**
697 * Sets the HUB import RT, from the spoke export RT. If it is not
698 * available a new ID is generated.
699 *
700 * @param config VPN config
701 */
702 public void setHubImpRt(HubSpokeVpnConfig config) {
703 String hubImp;
704 if (config.spokeExpRt() != null) {
705 hubImp = config.spokeExpRt();
706 } else {
707 hubImp = getIdFromGen();
708 }
709 config.hubImpRt(hubImp);
710 }
711
712 /**
713 * Creates export RT value for HUB and SPOKE, according to the type, if
714 * the values are not present.
715 *
716 * @param config VPN config
717 * @param type VPN type
718 */
719 private void createExpRtVal(HubSpokeVpnConfig config, VpnType type) {
720 if (type == HUB) {
721 if (config.hubExpRt() != null) {
722 return;
723 }
724 config.hubExpRt(config.rd());
725 } else {
726 if (config.spokeExpRt() != null) {
727 return;
728 }
729 setSpokeExpRt(config);
730 }
731 }
732
733 /**
734 * Sets the SPOKE export RT, from the hub import RT. If it is not
735 * available a new ID is generated.
736 *
737 * @param config VPN config
738 */
739 public void setSpokeExpRt(HubSpokeVpnConfig config) {
740 String spokeExp;
741 if (config.hubImpRt() != null) {
742 spokeExp = config.hubImpRt();
743 } else {
744 spokeExp = getIdFromGen();
745 }
746 config.spokeExpRt(spokeExp);
747 }
748
749 /**
750 * Returns the interface name from the requested type service object.
751 *
752 * @param info device info
753 * @param reqType requested type
754 * @return interface name
755 */
756 private String getInterfaceName(DeviceInfo info, RequestedType reqType) {
janani b9ed76be2017-08-29 19:11:33 +0530757 DefaultAugmentedL3VpnRequestedType req = reqType.augmentation(
758 DefaultAugmentedL3VpnRequestedType.class);
janani b35f6cbc2017-03-24 21:56:58 +0530759 if (req == null || req.requestedTypeProfile() == null ||
760 req.requestedTypeProfile().requestedTypeChoice() == null) {
761 throw new NetL3VpnException(INT_INFO_NULL);
762 }
763 RequestedTypeChoice reqChoice = req.requestedTypeProfile()
764 .requestedTypeChoice();
765 return getNameFromChoice(reqChoice, info.deviceId());
766 }
767
768 /**
769 * Returns the interface name from the type choice provided.
770 *
771 * @param choice service choice
772 * @param id device id
773 * @return interface name
774 */
775 private String getNameFromChoice(RequestedTypeChoice choice, DeviceId id) {
776 if (choice == null) {
777 throw new NetL3VpnException(INT_INFO_NULL);
778 }
779 String intName;
780 if (choice instanceof DefaultDot1Qcase) {
781 if (((DefaultDot1Qcase) choice).dot1q() == null ||
782 ((DefaultDot1Qcase) choice).dot1q()
783 .physicalIf() == null) {
784 throw new NetL3VpnException(INT_INFO_NULL);
785 }
786 intName = ((DefaultDot1Qcase) choice).dot1q().physicalIf();
787 } else {
788 if (((DefaultPhysicalCase) choice).physical() == null ||
789 ((DefaultPhysicalCase) choice).physical()
790 .physicalIf() == null) {
791 throw new NetL3VpnException(INT_INFO_NULL);
792 }
793 intName = ((DefaultPhysicalCase) choice).physical().physicalIf();
794 }
795 return getPortName(intName, id);
796 }
797
798 /**
799 * Returns the port name when it the port is available in the device.
800 *
801 * @param intName interface name
802 * @param id device id
803 * @return port name
804 */
805 private String getPortName(String intName, DeviceId id) {
806 List<Port> ports = deviceService.getPorts(id);
807 for (Port port : ports) {
808 String pName = port.annotations().value(PORT_NAME);
809 if (pName.equals(intName)) {
810 return intName;
811 }
812 }
813 throw new NetL3VpnException(getIntNotAvailable(intName));
814 }
815
816 /**
817 * Builds the interface for the device binding with the VPN instance.
818 *
819 * @param info device info
820 * @param ins VPN instance
821 * @param connect IP connection
822 * @param pName port name
823 * @param access access info
824 */
825 private void buildDevVpnInt(DeviceInfo info, VpnInstance ins,
826 IpConnection connect, String pName,
827 AccessInfo access) {
828 Map<AccessInfo, InterfaceInfo> intMap = l3VpnStore.getInterfaceInfo();
829 info.addAccessInfo(access);
830 info.addIfName(pName);
831 Interfaces interfaces = createInterface(pName, ins.vpnName(),
832 connect);
833 ModelObjectData devMod = getIntCreateModObj(
janani bd821b182017-03-30 16:34:49 +0530834 info.ifNames(), interfaces, info.deviceId().toString());
janani b35f6cbc2017-03-24 21:56:58 +0530835 ModelObjectData driMod = info.processCreateInterface(driverService,
836 devMod);
837 ResourceData resData = modelConverter.createDataNode(driMod);
838 addToStore(resData);
839 }
840
841 /**
842 * Builds the BGP information from the routes that are given from the
843 * service.
844 *
845 * @param routes routing protocol
846 * @param info device info
847 * @param name VPN name
848 * @param connect IP connection
849 * @param access access info
850 */
851 private void buildBgpInfo(List<RoutingProtocol> routes, DeviceInfo info,
852 String name, IpConnection connect,
853 AccessInfo access) {
854 Map<BgpInfo, DeviceId> bgpMap = l3VpnStore.getBgpInfo();
855 BgpInfo intBgp = createBgpInfo(routes, info, name, connect, access);
856 if (intBgp != null) {
857 intBgp.vpnName(name);
858 BgpDriverInfo config = getBgpCreateConfigObj(
janani bd821b182017-03-30 16:34:49 +0530859 bgpMap, info.deviceId().toString(), info.bgpInfo(), intBgp);
janani b35f6cbc2017-03-24 21:56:58 +0530860 ModelObjectData driData = info.processCreateBgpInfo(
861 driverService, intBgp, config);
862 l3VpnStore.addBgpInfo(info.bgpInfo(), info.deviceId());
863 ResourceData resData = modelConverter.createDataNode(driData);
864 addToStore(resData);
865 }
866 }
867
868 /**
janani b176905a2017-03-28 17:36:18 +0530869 * Creates all configuration in the standard device model.
870 *
871 * @param l3VpnSvc l3 VPN service
872 */
873 void deleteGlobalConfig(L3VpnSvc l3VpnSvc) {
874 deleteGlobalVpn(l3VpnSvc);
875 //TODO: Site and access deletion needs to be added.
876 }
877
878 /**
879 * Deletes the global VPN from the device model and delete from the device.
880 *
881 * @param l3VpnSvc L3 VPN service
882 */
883 private void deleteGlobalVpn(L3VpnSvc l3VpnSvc) {
884 Map<String, VpnInstance> insMap = l3VpnStore.getVpnInstances();
885 //TODO: check for VPN delete deleting interface from store.
886 if (l3VpnSvc == null || l3VpnSvc.vpnServices() == null ||
887 l3VpnSvc.vpnServices().vpnSvc() == null) {
888 for (Map.Entry<String, VpnInstance> vpnMap : insMap.entrySet()) {
889 deleteVpnInstance(vpnMap.getValue(), false);
890 }
891 return;
892 }
893 List<VpnSvc> vpnList = l3VpnSvc.vpnServices().vpnSvc();
894 for (Map.Entry<String, VpnInstance> vpnMap : insMap.entrySet()) {
895 boolean isPresent = isVpnPresent(vpnMap.getKey(), vpnList);
896 if (!isPresent) {
897 deleteVpnInstance(vpnMap.getValue(), false);
898 }
899 }
900 }
901
902 /**
903 * Returns true if the VPN in the distributed map is also present in the
904 * service; false otherwise.
905 *
906 * @param vpnName VPN name from store
907 * @param vpnList VPN list from service
908 * @return true if VPN available; false otherwise
909 */
910 private boolean isVpnPresent(String vpnName, List<VpnSvc> vpnList) {
911 for (VpnSvc svc : vpnList) {
912 if (svc.vpnId().string().equals(vpnName)) {
913 return true;
914 }
915 }
916 return false;
917 }
918
919 /**
920 * Deletes the VPN instance by constructing standard device model of
921 * instances.
922 *
923 * @param instance VPN instance
924 * @param isIntDeleted if interface already removed.
925 */
926 private void deleteVpnInstance(VpnInstance instance, boolean isIntDeleted) {
927 Map<DeviceId, DeviceInfo> devices = instance.devInfo();
janani bd821b182017-03-30 16:34:49 +0530928 if (devices != null) {
929 for (Map.Entry<DeviceId, DeviceInfo> device : devices.entrySet()) {
930 NetworkInstances ins = deleteInstance(instance.vpnName());
931 DeviceInfo dev = device.getValue();
932 if (!isIntDeleted) {
933 remVpnBgp(dev);
934 remInterfaceFromMap(dev);
935 }
936 Map<AccessInfo, InterfaceInfo> intMap =
937 l3VpnStore.getInterfaceInfo();
938 String id = dev.deviceId().toString();
939 ModelObjectData devMod = getVpnDelModObj(intMap, ins, id);
940 ModelObjectData driMod = dev.processDeleteInstance(
941 driverService, devMod);
942 ResourceData resData = modelConverter.createDataNode(driMod);
943 deleteFromStore(resData);
janani b9ed76be2017-08-29 19:11:33 +0530944 tnlHandler.deleteTunnel(dev, instance.vpnName());
janani b176905a2017-03-28 17:36:18 +0530945 }
janani bd821b182017-03-30 16:34:49 +0530946 l3VpnStore.removeVpnInstance(instance.vpnName());
janani b176905a2017-03-28 17:36:18 +0530947 }
janani bd821b182017-03-30 16:34:49 +0530948 }
949
950 /**
951 * Removes the BGP information for that complete VPN instance.
952 *
953 * @param dev device info
954 */
955 private void remVpnBgp(DeviceInfo dev) {
956 BgpInfo devBgp = dev.bgpInfo();
957 if (devBgp != null) {
958 l3VpnStore.removeBgpInfo(devBgp);
959 BgpInfo delInfo = new BgpInfo();
960 delInfo.vpnName(devBgp.vpnName());
961 String id = dev.deviceId().toString();
962 Map<BgpInfo, DeviceId> bgpMap = l3VpnStore.getBgpInfo();
963 BgpDriverInfo driConfig = getVpnBgpDelModObj(bgpMap, id);
964 ModelObjectData driData = dev.processDeleteBgpInfo(
965 driverService, delInfo, driConfig);
966 ResourceData resData = modelConverter.createDataNode(driData);
967 deleteFromStore(resData);
968 l3VpnStore.removeBgpInfo(devBgp);
969 }
janani b176905a2017-03-28 17:36:18 +0530970 }
971
972 /**
973 * Deletes the resource data that is received from the driver, after
974 * converting from the model object data.
975 *
976 * @param resData resource data
977 */
978 private void deleteFromStore(ResourceData resData) {
979 if (resData != null) {
Sithara Punnassery7b0c15e2017-07-07 15:08:19 -0700980 configService.deleteNode(resData.resourceId());
janani b176905a2017-03-28 17:36:18 +0530981 }
982 }
983
984 /**
985 * Removes the interface from the app distributed map, if the driver
986 * interfaces are already removed from the store.
987 *
988 * @param deviceInfo device info
989 */
990 private void remInterfaceFromMap(DeviceInfo deviceInfo) {
991 List<AccessInfo> accesses = deviceInfo.accesses();
janani bd821b182017-03-30 16:34:49 +0530992 if (accesses != null) {
993 for (AccessInfo access : accesses) {
994 l3VpnStore.removeInterfaceInfo(access);
995 }
janani b176905a2017-03-28 17:36:18 +0530996 }
997 deviceInfo.ifNames(null);
998 deviceInfo.accesses(null);
999 }
1000
1001 /**
1002 * Signals that the leadership has changed.
1003 *
1004 * @param isLeader true if this instance is now the leader, otherwise false
1005 */
1006 private void leaderChanged(boolean isLeader) {
1007 log.debug("Leader changed: {}", isLeader);
1008 isElectedLeader = isLeader;
1009 }
1010
1011 /**
janani b35f6cbc2017-03-24 21:56:58 +05301012 * Representation of internal listener, listening for dynamic config event.
1013 */
1014 private class InternalConfigListener implements DynamicConfigListener {
1015
1016 @Override
1017 public boolean isRelevant(DynamicConfigEvent event) {
1018 return isSupported(event);
1019 }
1020
1021 @Override
1022 public void event(DynamicConfigEvent event) {
janani b176905a2017-03-28 17:36:18 +05301023 accumulator.add(event);
janani b35f6cbc2017-03-24 21:56:58 +05301024 }
1025 }
Bharat saraswalcdfda202017-03-24 23:40:50 +05301026
1027 /**
janani b176905a2017-03-28 17:36:18 +05301028 * Accumulates events to allow processing after a desired number of
1029 * events were accumulated.
Bharat saraswalcdfda202017-03-24 23:40:50 +05301030 */
janani b176905a2017-03-28 17:36:18 +05301031 private class InternalEventAccumulator extends
1032 AbstractAccumulator<DynamicConfigEvent> {
1033
1034 /**
1035 * Constructs the event accumulator with timer and event limit.
1036 */
1037 protected InternalEventAccumulator() {
1038 super(new Timer(TIMER), MAX_EVENTS, MAX_BATCH_MS, MAX_IDLE_MS);
1039 }
1040
1041 @Override
1042 public void processItems(List<DynamicConfigEvent> events) {
1043 for (DynamicConfigEvent event : events) {
1044 checkNotNull(event, EVENT_NULL);
Yuta HIGUCHIac85ee12017-08-03 20:07:35 -07001045 Filter filter = Filter.builder().build();
janani b176905a2017-03-28 17:36:18 +05301046 DataNode node;
1047 try {
1048 node = configService.readNode(event.subject(), filter);
1049 } catch (FailedException e) {
1050 node = null;
1051 }
1052 switch (event.type()) {
1053 case NODE_ADDED:
1054 processCreateFromStore(event.subject(), node);
1055 break;
1056
1057 case NODE_DELETED:
1058 processDeleteFromStore(node);
1059 break;
1060
1061 default:
1062 log.warn(UNKNOWN_EVENT, event.type());
1063 break;
1064 }
1065 }
1066 }
Bharat saraswalcdfda202017-03-24 23:40:50 +05301067 }
1068
1069 /**
1070 * A listener for leadership events.
1071 */
1072 private class InternalLeadershipListener implements LeadershipEventListener {
1073
1074 @Override
1075 public boolean isRelevant(LeadershipEvent event) {
1076 return event.subject().topic().equals(appId.name());
1077 }
1078
1079 @Override
1080 public void event(LeadershipEvent event) {
1081 switch (event.type()) {
1082 case LEADER_CHANGED:
1083 case LEADER_AND_CANDIDATES_CHANGED:
1084 if (localNodeId.equals(event.subject().leaderNodeId())) {
1085 log.info("Net l3vpn manager gained leadership");
1086 leaderChanged(true);
1087 } else {
1088 log.info("Net l3vpn manager leader changed. New " +
1089 "leader is {}", event.subject()
1090 .leaderNodeId());
1091 leaderChanged(false);
1092 }
1093 default:
1094 break;
1095 }
1096 }
1097 }
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +05301098}