blob: 7d427ba5d7464164e5db6b40f6f64c8d3914a42e [file] [log] [blame]
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +05301/*
2 * Copyright 2017-present 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 */
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;
51import org.onosproject.net.Device;
52import org.onosproject.net.DeviceId;
53import org.onosproject.net.Port;
54import org.onosproject.net.device.DeviceService;
55import org.onosproject.net.driver.DriverService;
janani b35f6cbc2017-03-24 21:56:58 +053056import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev20140508.ietfinterfaces.devices.device.Interfaces;
janani b35f6cbc2017-03-24 21:56:58 +053057import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.DefaultL3VpnSvc;
58import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.L3VpnSvc;
59import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.accessvpnpolicy.VpnAttachment;
60import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.accessvpnpolicy.vpnattachment.AttachmentFlavor;
61import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.accessvpnpolicy.vpnattachment.attachmentflavor.DefaultVpnId;
janani b176905a2017-03-28 17:36:18 +053062import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.l3vpnsvc.DefaultSites;
janani b35f6cbc2017-03-24 21:56:58 +053063import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.l3vpnsvc.Sites;
64import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.l3vpnsvc.VpnServices;
65import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.l3vpnsvc.sites.Site;
66import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.l3vpnsvc.sites.site.SiteNetworkAccesses;
67import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.l3vpnsvc.sites.site.sitenetworkaccesses.SiteNetworkAccess;
68import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.l3vpnsvc.vpnservices.VpnSvc;
69import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siteattachmentbearer.Bearer;
70import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siteattachmentbearer.DefaultBearer;
71import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siteattachmentbearer.bearer.DefaultRequestedType;
72import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siteattachmentbearer.bearer.RequestedType;
73import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siteattachmentipconnection.IpConnection;
74import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siterouting.RoutingProtocols;
75import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siterouting.routingprotocols.RoutingProtocol;
76import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.instance.rev20160623.ietfnetworkinstance.devices.device.NetworkInstances;
janani b35f6cbc2017-03-24 21:56:58 +053077import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.l3vpn.svc.ext.rev20160730.l3vpnsvcext.l3vpnsvc.sites.site.sitenetworkaccesses.sitenetworkaccess.bearer.DefaultAugmentedL3VpnBearer;
78import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.l3vpn.svc.ext.rev20160730.l3vpnsvcext.l3vpnsvc.sites.site.sitenetworkaccesses.sitenetworkaccess.bearer.requestedtype.DefaultAugmentedL3VpnRequestedType;
79import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.l3vpn.svc.ext.rev20160730.l3vpnsvcext.requestedtypegrouping.requestedtypeprofile.RequestedTypeChoice;
80import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.l3vpn.svc.ext.rev20160730.l3vpnsvcext.requestedtypegrouping.requestedtypeprofile.requestedtypechoice.DefaultDot1Qcase;
81import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.l3vpn.svc.ext.rev20160730.l3vpnsvcext.requestedtypegrouping.requestedtypeprofile.requestedtypechoice.DefaultPhysicalCase;
82import org.onosproject.yang.model.DataNode;
83import org.onosproject.yang.model.DefaultModelObjectData;
84import org.onosproject.yang.model.ModelConverter;
85import org.onosproject.yang.model.ModelObject;
86import org.onosproject.yang.model.ModelObjectData;
87import org.onosproject.yang.model.ModelObjectId;
88import org.onosproject.yang.model.NodeKey;
89import org.onosproject.yang.model.ResourceData;
90import org.onosproject.yang.model.ResourceId;
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +053091import org.slf4j.Logger;
92import org.slf4j.LoggerFactory;
93
94import java.util.Iterator;
janani b35f6cbc2017-03-24 21:56:58 +053095import java.util.List;
96import java.util.Map;
janani b176905a2017-03-28 17:36:18 +053097import java.util.Timer;
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +053098
janani b176905a2017-03-28 17:36:18 +053099import static com.google.common.base.Preconditions.checkNotNull;
janani b35f6cbc2017-03-24 21:56:58 +0530100import static org.onosproject.config.DynamicConfigEvent.Type.NODE_ADDED;
101import static org.onosproject.config.DynamicConfigEvent.Type.NODE_DELETED;
Bharat saraswalcdfda202017-03-24 23:40:50 +0530102import static org.onosproject.l3vpn.netl3vpn.VpnType.HUB;
janani b35f6cbc2017-03-24 21:56:58 +0530103import static org.onosproject.l3vpn.netl3vpn.impl.BgpConstructionUtil.createBgpInfo;
104import static org.onosproject.l3vpn.netl3vpn.impl.InsConstructionUtil.createInstance;
janani b176905a2017-03-28 17:36:18 +0530105import static org.onosproject.l3vpn.netl3vpn.impl.InsConstructionUtil.deleteInstance;
janani b35f6cbc2017-03-24 21:56:58 +0530106import static org.onosproject.l3vpn.netl3vpn.impl.IntConstructionUtil.createInterface;
107import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.BEARER_NULL;
108import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.CONS_HUNDRED;
109import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.DEVICE_INFO_NULL;
janani b176905a2017-03-28 17:36:18 +0530110import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.EVENT_NULL;
janani b35f6cbc2017-03-24 21:56:58 +0530111import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.ID_LIMIT;
112import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.ID_LIMIT_EXCEEDED;
113import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.INT_INFO_NULL;
janani b176905a2017-03-28 17:36:18 +0530114import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.IP;
janani b35f6cbc2017-03-24 21:56:58 +0530115import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.IP_INT_INFO_NULL;
janani b176905a2017-03-28 17:36:18 +0530116import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.MAX_BATCH_MS;
117import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.MAX_EVENTS;
118import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.MAX_IDLE_MS;
janani b35f6cbc2017-03-24 21:56:58 +0530119import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.PORT_NAME;
120import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.SITE_ROLE_NULL;
121import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.SITE_VPN_MISMATCH;
janani b176905a2017-03-28 17:36:18 +0530122import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.TIMER;
123import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.UNKNOWN_EVENT;
janani b35f6cbc2017-03-24 21:56:58 +0530124import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.VPN_ATTACHMENT_NULL;
125import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.VPN_POLICY_NOT_SUPPORTED;
126import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.VPN_TYPE_UNSUPPORTED;
127import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getBgpCreateConfigObj;
128import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getIntCreateModObj;
129import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getIntNotAvailable;
130import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getMgmtIpUnAvailErr;
131import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getModIdForL3VpnSvc;
132import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getModIdForSites;
133import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getResourceData;
134import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getRole;
janani bd821b182017-03-30 16:34:49 +0530135import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getVpnBgpDelModObj;
janani b35f6cbc2017-03-24 21:56:58 +0530136import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getVpnCreateModObj;
janani bd821b182017-03-30 16:34:49 +0530137import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getVpnDelModObj;
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530138
139/**
140 * The IETF net l3vpn manager implementation.
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530141 */
142@Component(immediate = true)
janani bd821b182017-03-30 16:34:49 +0530143public class NetL3VpnManager {
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530144
145 private static final String APP_ID = "org.onosproject.app.l3vpn";
janani b35f6cbc2017-03-24 21:56:58 +0530146 private static final String L3_VPN_ID_TOPIC = "l3vpn-id";
janani b35f6cbc2017-03-24 21:56:58 +0530147
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530148 private final Logger log = LoggerFactory.getLogger(getClass());
149
janani b176905a2017-03-28 17:36:18 +0530150 private final DynamicConfigListener configListener =
151 new InternalConfigListener();
152
153 private final Accumulator<DynamicConfigEvent> accumulator =
154 new InternalEventAccumulator();
155
156 private final InternalLeadershipListener leadershipEventListener =
157 new InternalLeadershipListener();
158
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530159 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
160 protected CoreService coreService;
161
162 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
janani b35f6cbc2017-03-24 21:56:58 +0530163 protected DriverService driverService;
164
165 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
166 protected DeviceService deviceService;
167
168 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
janani b35f6cbc2017-03-24 21:56:58 +0530169 protected ModelConverter modelConverter;
170
171 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
172 protected DynamicConfigService configService;
173
174 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
175 protected NetL3VpnStore l3VpnStore;
176
Bharat saraswalcdfda202017-03-24 23:40:50 +0530177 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
178 protected LeadershipService leadershipService;
179
180 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
181 protected ClusterService clusterService;
182
janani b35f6cbc2017-03-24 21:56:58 +0530183 protected IdGenerator l3VpnIdGen;
janani b176905a2017-03-28 17:36:18 +0530184
Bharat saraswalcdfda202017-03-24 23:40:50 +0530185 private NodeId localNodeId;
janani b176905a2017-03-28 17:36:18 +0530186
Bharat saraswalcdfda202017-03-24 23:40:50 +0530187 private ApplicationId appId;
janani b35f6cbc2017-03-24 21:56:58 +0530188
janani b35f6cbc2017-03-24 21:56:58 +0530189 private ResourceId id;
janani b176905a2017-03-28 17:36:18 +0530190
janani b35f6cbc2017-03-24 21:56:58 +0530191 private ResourceId module;
janani b176905a2017-03-28 17:36:18 +0530192
janani b35f6cbc2017-03-24 21:56:58 +0530193 private ResourceId sites;
janani b176905a2017-03-28 17:36:18 +0530194
Gaurav Agrawal8dbd2732017-04-14 18:57:30 +0530195 private boolean isElectedLeader;
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530196
197 @Activate
198 protected void activate() {
Bharat saraswalcdfda202017-03-24 23:40:50 +0530199 appId = coreService.registerApplication(APP_ID);
janani b35f6cbc2017-03-24 21:56:58 +0530200 l3VpnIdGen = coreService.getIdGenerator(L3_VPN_ID_TOPIC);
Bharat saraswalcdfda202017-03-24 23:40:50 +0530201 localNodeId = clusterService.getLocalNode().id();
Bharat saraswalcdfda202017-03-24 23:40:50 +0530202 leadershipService.addListener(leadershipEventListener);
203 leadershipService.runForLeadership(appId.name());
janani b35f6cbc2017-03-24 21:56:58 +0530204 getResourceId();
205 configService.addListener(configListener);
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530206 log.info("Started");
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530207 }
208
209 @Deactivate
210 protected void deactivate() {
janani b35f6cbc2017-03-24 21:56:58 +0530211 configService.removeListener(configListener);
Bharat saraswalcdfda202017-03-24 23:40:50 +0530212 leadershipService.withdraw(appId.name());
213 leadershipService.removeListener(leadershipEventListener);
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530214 log.info("Stopped");
215 }
216
janani b35f6cbc2017-03-24 21:56:58 +0530217 /**
218 * Returns id as string. If the id is not in the freed list a new id is
219 * generated else the id from the freed list is used.
220 *
221 * @return id
222 */
223 private String getIdFromGen() {
224 Long value;
225 Iterable<Long> freeIds = l3VpnStore.getFreedIdList();
226 Iterator<Long> it = freeIds.iterator();
227 if (it.hasNext()) {
228 value = it.next();
229 l3VpnStore.removeIdFromFreeList(value);
230 } else {
231 value = l3VpnIdGen.getNewId();
232 }
233 if (value > ID_LIMIT) {
234 throw new RuntimeException(ID_LIMIT_EXCEEDED);
235 }
236 return CONS_HUNDRED + String.valueOf(value);
237 }
238
239 /**
240 * Returns the resource id, after constructing model object id and
241 * converting it.
242 */
243 private void getResourceId() {
244
245 ModelObjectId moduleId = ModelObjectId.builder().build();
246 module = getResourceVal(moduleId);
247
248 ModelObjectId svcId = getModIdForL3VpnSvc();
249 id = getResourceVal(svcId);
250
251 ModelObjectId sitesId = getModIdForSites();
252 sites = getResourceVal(sitesId);
253 }
254
255 /**
256 * Returns resource id from model converter.
257 *
258 * @param modelId model object id
259 * @return resource id
260 */
261 private ResourceId getResourceVal(ModelObjectId modelId) {
262 DefaultModelObjectData.Builder data = DefaultModelObjectData.builder()
Thomas Vachuskad17bc732017-03-24 11:46:55 -0700263 .identifier(modelId);
janani b35f6cbc2017-03-24 21:56:58 +0530264 ResourceData resData = modelConverter.createDataNode(data.build());
janani b176905a2017-03-28 17:36:18 +0530265 return resData.resourceId();
janani b35f6cbc2017-03-24 21:56:58 +0530266 }
267
268 /**
269 * Processes create request from the store, by taking the root object.
270 * The root object is then used for l3VPN processing.
271 *
272 * @param storeId store resource id
janani b176905a2017-03-28 17:36:18 +0530273 * @param node data node
janani b35f6cbc2017-03-24 21:56:58 +0530274 */
janani b176905a2017-03-28 17:36:18 +0530275 private void processCreateFromStore(ResourceId storeId, DataNode node) {
Bharat saraswal5b5bd9a2017-03-27 18:59:55 +0530276 if (isElectedLeader) {
janani b176905a2017-03-28 17:36:18 +0530277 List<NodeKey> keys = storeId.nodeKeys();
278 List<ModelObject> objects = null;
279 if (keys.size() == 1) {
280 objects = getModelObjects(node, module);
281 } else if (keys.size() == 2) {
282 objects = getModelObjects(node, id);
283 }
284 if (objects != null) {
285 for (ModelObject obj : objects) {
286 if (obj instanceof DefaultL3VpnSvc) {
287 DefaultL3VpnSvc l3VpnSvc = (DefaultL3VpnSvc) obj;
288 createGlobalConfig(l3VpnSvc);
289 } else if (obj instanceof DefaultSites) {
290 DefaultSites sites = (DefaultSites) obj;
291 createInterfaceConfig(sites);
292 }
Bharat saraswalcdfda202017-03-24 23:40:50 +0530293 }
janani b35f6cbc2017-03-24 21:56:58 +0530294 }
295 }
296 }
297
298 /**
Bharat saraswalcdfda202017-03-24 23:40:50 +0530299 * Processes delete request from the store, by taking the root object.
janani b176905a2017-03-28 17:36:18 +0530300 * The root object would have got deleted from store. So all the
301 * configurations are removed.
Bharat saraswalcdfda202017-03-24 23:40:50 +0530302 *
janani b176905a2017-03-28 17:36:18 +0530303 * @param dataNode data node
Bharat saraswalcdfda202017-03-24 23:40:50 +0530304 */
janani b176905a2017-03-28 17:36:18 +0530305 private void processDeleteFromStore(DataNode dataNode) {
Bharat saraswal5b5bd9a2017-03-27 18:59:55 +0530306 if (isElectedLeader) {
janani b176905a2017-03-28 17:36:18 +0530307 if (dataNode == null) {
308 //TODO: Delete for inner nodes.
309 deleteGlobalConfig(null);
310 }
Bharat saraswalcdfda202017-03-24 23:40:50 +0530311 }
312 }
313
314 /**
janani b176905a2017-03-28 17:36:18 +0530315 * Returns model objects of the store. The data node read from store
316 * gives the particular node. So the node's parent resource id is taken
317 * and the data node is given to model converter.
janani b35f6cbc2017-03-24 21:56:58 +0530318 *
janani b176905a2017-03-28 17:36:18 +0530319 * @param dataNode data node from store
320 * @param appId parent resource id
janani b35f6cbc2017-03-24 21:56:58 +0530321 * @return model objects
322 */
janani b176905a2017-03-28 17:36:18 +0530323 public List<ModelObject> getModelObjects(DataNode dataNode,
janani b35f6cbc2017-03-24 21:56:58 +0530324 ResourceId appId) {
janani b35f6cbc2017-03-24 21:56:58 +0530325 ResourceData data = getResourceData(dataNode, appId);
326 ModelObjectData modelData = modelConverter.createModel(data);
327 return modelData.modelObjects();
328 }
329
330 /**
331 * Returns true if the event resource id points to the root level node
332 * only and event is for addition and deletion; false otherwise.
333 *
334 * @param event config event
335 * @return true if event is supported; false otherwise
336 */
337 public boolean isSupported(DynamicConfigEvent event) {
338 ResourceId rsId = event.subject();
339 List<NodeKey> storeKeys = rsId.nodeKeys();
340 List<NodeKey> regKeys = id.nodeKeys();
janani b176905a2017-03-28 17:36:18 +0530341 List<NodeKey> sitesKeys = sites.nodeKeys();
janani b35f6cbc2017-03-24 21:56:58 +0530342 if (storeKeys != null) {
janani b176905a2017-03-28 17:36:18 +0530343 int storeSize = storeKeys.size();
344 if (storeSize == 1) {
janani b35f6cbc2017-03-24 21:56:58 +0530345 return storeKeys.get(0).equals(regKeys.get(1)) &&
346 (event.type() == NODE_ADDED ||
347 event.type() == NODE_DELETED);
janani b176905a2017-03-28 17:36:18 +0530348 } else if (storeSize == 2) {
349 return (storeKeys.get(0).equals(sitesKeys.get(1))) &&
350 storeKeys.get(1).equals(sitesKeys.get(2)) &&
351 (event.type() == NODE_ADDED ||
352 event.type() == NODE_DELETED);
janani b35f6cbc2017-03-24 21:56:58 +0530353 }
354 }
355 return false;
356 }
357
358 /***
janani b176905a2017-03-28 17:36:18 +0530359 * Creates all configuration in the standard device model.
janani b35f6cbc2017-03-24 21:56:58 +0530360 *
361 * @param l3VpnSvc l3VPN service object
362 */
363 void createGlobalConfig(L3VpnSvc l3VpnSvc) {
364 if (l3VpnSvc.vpnServices() != null) {
365 createVpnServices(l3VpnSvc.vpnServices());
366 }
367 if (l3VpnSvc.sites() != null) {
368 createInterfaceConfig(l3VpnSvc.sites());
369 }
370 }
371
372 /**
373 * Creates the VPN instances from the VPN services object, if only that
374 * VPN instance is not already created.
375 *
376 * @param vpnSvcs VPN services object
377 */
378 private void createVpnServices(VpnServices vpnSvcs) {
379 if (vpnSvcs != null && vpnSvcs.vpnSvc() != null) {
380 List<VpnSvc> svcList = vpnSvcs.vpnSvc();
381 for (VpnSvc svc : svcList) {
382 String vpnName = svc.vpnId().string();
383 l3VpnStore.addVpnInsIfAbsent(vpnName, new VpnInstance(vpnName));
384 }
385 }
386 }
387
388 /**
389 * Creates interface configuration from the site network access if
390 * available.
391 *
392 * @param sites sites object
393 */
394 private void createInterfaceConfig(Sites sites) {
395 if (sites.site() != null) {
396 List<Site> sitesList = sites.site();
397 for (Site site : sitesList) {
398 if (site.siteNetworkAccesses() != null) {
399 SiteNetworkAccesses accesses = site.siteNetworkAccesses();
400 List<SiteNetworkAccess> accessList =
401 accesses.siteNetworkAccess();
402 for (SiteNetworkAccess access : accessList) {
403 createFromAccess(access, site.siteId().string());
404 }
405 }
406 }
407 }
408 }
409
410 /**
411 * Creates the interface and VPN related configurations from the access
412 * and site id value.
413 *
414 * @param access site network access
415 * @param siteId site id
416 */
417 private void createFromAccess(SiteNetworkAccess access, String siteId) {
418 Map<AccessInfo, InterfaceInfo> intMap = l3VpnStore.getInterfaceInfo();
419 Map<String, VpnInstance> insMap = l3VpnStore.getVpnInstances();
420 String accessId = access.siteNetworkAccessId().string();
421 AccessInfo info = new AccessInfo(siteId, accessId);
422
423 if (intMap.get(info) == null) {
424 VpnSiteRole siteRole = getSiteRole(access.vpnAttachment());
425 VpnInstance instance = insMap.get(siteRole.name());
426 if (instance == null) {
427 throw new NetL3VpnException(SITE_VPN_MISMATCH);
428 }
429 buildFromAccess(instance, info, access, siteRole);
430 }
431 }
432
433 /**
434 * Returns the VPN site role from the VPN attachment.
435 *
436 * @param attach VPN attachment
437 * @return VPN site role
438 */
439 private VpnSiteRole getSiteRole(VpnAttachment attach) {
440 if (attach == null || attach.attachmentFlavor() == null) {
441 throw new NetL3VpnException(VPN_ATTACHMENT_NULL);
442 }
443 AttachmentFlavor flavor = attach.attachmentFlavor();
444 if (!(flavor instanceof DefaultVpnId)) {
445 throw new NetL3VpnException(VPN_POLICY_NOT_SUPPORTED);
446 }
447 DefaultVpnId vpnId = (DefaultVpnId) flavor;
448 if (vpnId.siteRole() == null) {
449 throw new NetL3VpnException(SITE_ROLE_NULL);
450 }
451 VpnType role = getRole(vpnId.siteRole());
janani b176905a2017-03-28 17:36:18 +0530452 return new VpnSiteRole(String.valueOf(vpnId.vpnId()), role);
janani b35f6cbc2017-03-24 21:56:58 +0530453 }
454
455 /**
456 * Builds the required details for device standard model from the site
457 * network access info available.
458 *
459 * @param instance VPN instance
460 * @param info access info
461 * @param access network access
462 * @param role VPN site role
463 */
464 private void buildFromAccess(VpnInstance instance, AccessInfo info,
465 SiteNetworkAccess access, VpnSiteRole role) {
466 Bearer bearer = access.bearer();
467 if (bearer == null) {
468 throw new NetL3VpnException(BEARER_NULL);
469 }
470
471 RequestedType reqType = bearer.requestedType();
472 IpConnection connect = access.ipConnection();
473 RoutingProtocols pro = access.routingProtocols();
474
475 if (reqType == null || connect == null) {
476 throw new NetL3VpnException(IP_INT_INFO_NULL);
477 }
478 buildDeviceDetails(instance, info, role, bearer, connect,
479 reqType, pro);
480 }
481
482 /**
483 * Builds the device details such as, VPN instance value if it is for
484 * the first time, interface values and BGP info if available in service.
485 *
486 * @param instance VPN instance
487 * @param accInfo access info
488 * @param role VPN site role
489 * @param bearer bearer object
490 * @param connect ip connect object
491 * @param reqType requested type
492 * @param pro routing protocol
493 */
494 private void buildDeviceDetails(VpnInstance instance, AccessInfo accInfo,
495 VpnSiteRole role, Bearer bearer,
496 IpConnection connect, RequestedType reqType,
497 RoutingProtocols pro) {
498 Map<AccessInfo, InterfaceInfo> interMap = l3VpnStore.getInterfaceInfo();
499 InterfaceInfo intInfo = interMap.get(accInfo);
500 if (intInfo != null) {
501 return;
502 }
503
504 DeviceInfo info = buildDevVpnIns(bearer, instance, role, connect);
505 String portName = getInterfaceName(info, reqType);
506 buildDevVpnInt(info, instance, connect, portName, accInfo);
507
508 if (pro != null && pro.routingProtocol() != null) {
509 buildBgpInfo(pro.routingProtocol(), info,
510 role.name(), connect, accInfo);
511 }
512 InterfaceInfo interInfo = new InterfaceInfo(info, portName,
513 instance.vpnName());
514 l3VpnStore.addInterfaceInfo(accInfo, interInfo);
janani bd821b182017-03-30 16:34:49 +0530515 l3VpnStore.addVpnIns(instance.vpnName(), instance);
janani b35f6cbc2017-03-24 21:56:58 +0530516 }
517
518 /**
519 * Builds device VPN instance with the service objects. It returns
520 *
521 * @param bearer bearer object
522 * @param ins VPN instance
523 * @param role VPN site role
524 * @param connect ip connection
525 * @return return
526 */
527 private DeviceInfo buildDevVpnIns(Bearer bearer, VpnInstance ins,
528 VpnSiteRole role, IpConnection connect) {
529 DefaultAugmentedL3VpnBearer augBearer = ((DefaultBearer) bearer)
530 .augmentation(DefaultAugmentedL3VpnBearer.class);
531 DeviceId id = getDeviceId(augBearer);
532 Map<DeviceId, DeviceInfo> devices = ins.devInfo();
533 DeviceInfo info = null;
534 if (devices != null) {
535 info = devices.get(id);
536 }
537 if (info == null) {
538 info = createVpnInstance(id, role, ins, connect);
539 }
540 return info;
541 }
542
543 /**
544 * Returns the device id from the bearer augment attachment of service.
545 * If the attachment in augment is not available it throws error.
546 *
547 * @param attach augmented bearer
548 * @return device id
549 */
550 private DeviceId getDeviceId(DefaultAugmentedL3VpnBearer attach) {
551 if (attach == null || attach.bearerAttachment() == null ||
552 attach.bearerAttachment().peMgmtIp() == null ||
553 attach.bearerAttachment().peMgmtIp().string() == null) {
554 throw new NetL3VpnException(DEVICE_INFO_NULL);
555 }
556 String ip = attach.bearerAttachment().peMgmtIp().string();
557 return getId(ip);
558 }
559
560 /**
561 * Returns the device id whose management ip address matches with the ip
562 * received.
563 *
564 * @param ip ip address
565 * @return device id
566 */
567 public DeviceId getId(String ip) {
568 for (Device device : deviceService.getAvailableDevices()) {
janani b176905a2017-03-28 17:36:18 +0530569 String val = device.annotations().value(IP);
janani b35f6cbc2017-03-24 21:56:58 +0530570 if (ip.equals(val)) {
571 return device.id();
572 }
573 }
574 throw new NetL3VpnException(getMgmtIpUnAvailErr(ip));
575 }
576
577 /**
578 * Creates the VPN instance by constructing standard device model of
579 * instances. It adds the RD and RT values to the VPN instance.
580 *
581 * @param id device id
582 * @param role VPN site role
583 * @param inst VPN instance
584 * @param ip ip connection
585 * @return device info
586 */
587 private DeviceInfo createVpnInstance(DeviceId id, VpnSiteRole role,
588 VpnInstance inst, IpConnection ip) {
589 Map<AccessInfo, InterfaceInfo> intMap = l3VpnStore.getInterfaceInfo();
590 generateRdRt(inst, role);
591 DeviceInfo info = new DeviceInfo(id);
janani b35f6cbc2017-03-24 21:56:58 +0530592
593 NetworkInstances instances = createInstance(inst, role, ip);
594 ModelObjectData devMod = getVpnCreateModObj(intMap, instances,
595 id.toString());
596 ModelObjectData driMod = info.processCreateInstance(driverService,
597 devMod);
598 ResourceData resData = modelConverter.createDataNode(driMod);
599 addToStore(resData);
janani b36b1d772017-03-27 15:01:28 +0530600 l3VpnStore.addVpnIns(inst.vpnName(), inst);
janani bd821b182017-03-30 16:34:49 +0530601 inst.addDevInfo(id, info);
janani b35f6cbc2017-03-24 21:56:58 +0530602 return info;
603 }
604
605 /**
606 * Adds the resource data that is received from the driver, after
607 * converting from the model object data.
608 *
609 * @param resData resource data
610 */
611 private void addToStore(ResourceData resData) {
612 if (resData != null && resData.dataNodes() != null) {
613 List<DataNode> dataNodes = resData.dataNodes();
614 for (DataNode node : dataNodes) {
615 configService.createNodeRecursive(resData.resourceId(), node);
616 }
617 }
618 }
619
620 /**
621 * Generates RD and RT value for the VPN instance for the first time VPN
622 * instance creation.
623 *
624 * @param ins VPN instance
625 * @param role VPN site role
626 */
627 private void generateRdRt(VpnInstance ins, VpnSiteRole role) {
628 ins.type(role.role());
629 VpnConfig config = ins.vpnConfig();
630 String rd = null;
631 if (config == null) {
632 rd = getIdFromGen();
633 }
634 switch (ins.type()) {
635 case ANY_TO_ANY:
636 if (config == null) {
637 config = new FullMeshVpnConfig(rd);
638 config.rd(rd);
639 }
640 break;
641
642 case HUB:
643 case SPOKE:
644 if (config == null) {
645 config = new HubSpokeVpnConfig();
646 config.rd(rd);
647 }
648 createImpRtVal((HubSpokeVpnConfig) config, ins.type());
649 createExpRtVal((HubSpokeVpnConfig) config, ins.type());
650 break;
651
652 default:
653 throw new NetL3VpnException(VPN_TYPE_UNSUPPORTED);
654 }
655 ins.vpnConfig(config);
656 }
657
658 /**
659 * Creates import RT value for HUB and SPOKE, according to the type, if
660 * the values are not present.
661 *
662 * @param config VPN config
663 * @param type VPN type
664 */
665 private void createImpRtVal(HubSpokeVpnConfig config, VpnType type) {
666 if (type == HUB) {
667 if (config.hubImpRt() != null) {
668 return;
669 }
670 setHubImpRt(config);
671 } else {
672 if (config.spokeImpRt() != null) {
673 return;
674 }
675 config.spokeImpRt(config.rd());
676 }
677 }
678
679 /**
680 * Sets the HUB import RT, from the spoke export RT. If it is not
681 * available a new ID is generated.
682 *
683 * @param config VPN config
684 */
685 public void setHubImpRt(HubSpokeVpnConfig config) {
686 String hubImp;
687 if (config.spokeExpRt() != null) {
688 hubImp = config.spokeExpRt();
689 } else {
690 hubImp = getIdFromGen();
691 }
692 config.hubImpRt(hubImp);
693 }
694
695 /**
696 * Creates export RT value for HUB and SPOKE, according to the type, if
697 * the values are not present.
698 *
699 * @param config VPN config
700 * @param type VPN type
701 */
702 private void createExpRtVal(HubSpokeVpnConfig config, VpnType type) {
703 if (type == HUB) {
704 if (config.hubExpRt() != null) {
705 return;
706 }
707 config.hubExpRt(config.rd());
708 } else {
709 if (config.spokeExpRt() != null) {
710 return;
711 }
712 setSpokeExpRt(config);
713 }
714 }
715
716 /**
717 * Sets the SPOKE export RT, from the hub import RT. If it is not
718 * available a new ID is generated.
719 *
720 * @param config VPN config
721 */
722 public void setSpokeExpRt(HubSpokeVpnConfig config) {
723 String spokeExp;
724 if (config.hubImpRt() != null) {
725 spokeExp = config.hubImpRt();
726 } else {
727 spokeExp = getIdFromGen();
728 }
729 config.spokeExpRt(spokeExp);
730 }
731
732 /**
733 * Returns the interface name from the requested type service object.
734 *
735 * @param info device info
736 * @param reqType requested type
737 * @return interface name
738 */
739 private String getInterfaceName(DeviceInfo info, RequestedType reqType) {
740 DefaultAugmentedL3VpnRequestedType req =
741 ((DefaultRequestedType) reqType).augmentation(
742 DefaultAugmentedL3VpnRequestedType.class);
743 if (req == null || req.requestedTypeProfile() == null ||
744 req.requestedTypeProfile().requestedTypeChoice() == null) {
745 throw new NetL3VpnException(INT_INFO_NULL);
746 }
747 RequestedTypeChoice reqChoice = req.requestedTypeProfile()
748 .requestedTypeChoice();
749 return getNameFromChoice(reqChoice, info.deviceId());
750 }
751
752 /**
753 * Returns the interface name from the type choice provided.
754 *
755 * @param choice service choice
756 * @param id device id
757 * @return interface name
758 */
759 private String getNameFromChoice(RequestedTypeChoice choice, DeviceId id) {
760 if (choice == null) {
761 throw new NetL3VpnException(INT_INFO_NULL);
762 }
763 String intName;
764 if (choice instanceof DefaultDot1Qcase) {
765 if (((DefaultDot1Qcase) choice).dot1q() == null ||
766 ((DefaultDot1Qcase) choice).dot1q()
767 .physicalIf() == null) {
768 throw new NetL3VpnException(INT_INFO_NULL);
769 }
770 intName = ((DefaultDot1Qcase) choice).dot1q().physicalIf();
771 } else {
772 if (((DefaultPhysicalCase) choice).physical() == null ||
773 ((DefaultPhysicalCase) choice).physical()
774 .physicalIf() == null) {
775 throw new NetL3VpnException(INT_INFO_NULL);
776 }
777 intName = ((DefaultPhysicalCase) choice).physical().physicalIf();
778 }
779 return getPortName(intName, id);
780 }
781
782 /**
783 * Returns the port name when it the port is available in the device.
784 *
785 * @param intName interface name
786 * @param id device id
787 * @return port name
788 */
789 private String getPortName(String intName, DeviceId id) {
790 List<Port> ports = deviceService.getPorts(id);
791 for (Port port : ports) {
792 String pName = port.annotations().value(PORT_NAME);
793 if (pName.equals(intName)) {
794 return intName;
795 }
796 }
797 throw new NetL3VpnException(getIntNotAvailable(intName));
798 }
799
800 /**
801 * Builds the interface for the device binding with the VPN instance.
802 *
803 * @param info device info
804 * @param ins VPN instance
805 * @param connect IP connection
806 * @param pName port name
807 * @param access access info
808 */
809 private void buildDevVpnInt(DeviceInfo info, VpnInstance ins,
810 IpConnection connect, String pName,
811 AccessInfo access) {
812 Map<AccessInfo, InterfaceInfo> intMap = l3VpnStore.getInterfaceInfo();
813 info.addAccessInfo(access);
814 info.addIfName(pName);
815 Interfaces interfaces = createInterface(pName, ins.vpnName(),
816 connect);
817 ModelObjectData devMod = getIntCreateModObj(
janani bd821b182017-03-30 16:34:49 +0530818 info.ifNames(), interfaces, info.deviceId().toString());
janani b35f6cbc2017-03-24 21:56:58 +0530819 ModelObjectData driMod = info.processCreateInterface(driverService,
820 devMod);
821 ResourceData resData = modelConverter.createDataNode(driMod);
822 addToStore(resData);
823 }
824
825 /**
826 * Builds the BGP information from the routes that are given from the
827 * service.
828 *
829 * @param routes routing protocol
830 * @param info device info
831 * @param name VPN name
832 * @param connect IP connection
833 * @param access access info
834 */
835 private void buildBgpInfo(List<RoutingProtocol> routes, DeviceInfo info,
836 String name, IpConnection connect,
837 AccessInfo access) {
838 Map<BgpInfo, DeviceId> bgpMap = l3VpnStore.getBgpInfo();
839 BgpInfo intBgp = createBgpInfo(routes, info, name, connect, access);
840 if (intBgp != null) {
841 intBgp.vpnName(name);
842 BgpDriverInfo config = getBgpCreateConfigObj(
janani bd821b182017-03-30 16:34:49 +0530843 bgpMap, info.deviceId().toString(), info.bgpInfo(), intBgp);
janani b35f6cbc2017-03-24 21:56:58 +0530844 ModelObjectData driData = info.processCreateBgpInfo(
845 driverService, intBgp, config);
846 l3VpnStore.addBgpInfo(info.bgpInfo(), info.deviceId());
847 ResourceData resData = modelConverter.createDataNode(driData);
848 addToStore(resData);
849 }
850 }
851
852 /**
janani b176905a2017-03-28 17:36:18 +0530853 * Creates all configuration in the standard device model.
854 *
855 * @param l3VpnSvc l3 VPN service
856 */
857 void deleteGlobalConfig(L3VpnSvc l3VpnSvc) {
858 deleteGlobalVpn(l3VpnSvc);
859 //TODO: Site and access deletion needs to be added.
860 }
861
862 /**
863 * Deletes the global VPN from the device model and delete from the device.
864 *
865 * @param l3VpnSvc L3 VPN service
866 */
867 private void deleteGlobalVpn(L3VpnSvc l3VpnSvc) {
868 Map<String, VpnInstance> insMap = l3VpnStore.getVpnInstances();
869 //TODO: check for VPN delete deleting interface from store.
870 if (l3VpnSvc == null || l3VpnSvc.vpnServices() == null ||
871 l3VpnSvc.vpnServices().vpnSvc() == null) {
872 for (Map.Entry<String, VpnInstance> vpnMap : insMap.entrySet()) {
873 deleteVpnInstance(vpnMap.getValue(), false);
874 }
875 return;
876 }
877 List<VpnSvc> vpnList = l3VpnSvc.vpnServices().vpnSvc();
878 for (Map.Entry<String, VpnInstance> vpnMap : insMap.entrySet()) {
879 boolean isPresent = isVpnPresent(vpnMap.getKey(), vpnList);
880 if (!isPresent) {
881 deleteVpnInstance(vpnMap.getValue(), false);
882 }
883 }
884 }
885
886 /**
887 * Returns true if the VPN in the distributed map is also present in the
888 * service; false otherwise.
889 *
890 * @param vpnName VPN name from store
891 * @param vpnList VPN list from service
892 * @return true if VPN available; false otherwise
893 */
894 private boolean isVpnPresent(String vpnName, List<VpnSvc> vpnList) {
895 for (VpnSvc svc : vpnList) {
896 if (svc.vpnId().string().equals(vpnName)) {
897 return true;
898 }
899 }
900 return false;
901 }
902
903 /**
904 * Deletes the VPN instance by constructing standard device model of
905 * instances.
906 *
907 * @param instance VPN instance
908 * @param isIntDeleted if interface already removed.
909 */
910 private void deleteVpnInstance(VpnInstance instance, boolean isIntDeleted) {
911 Map<DeviceId, DeviceInfo> devices = instance.devInfo();
janani bd821b182017-03-30 16:34:49 +0530912 if (devices != null) {
913 for (Map.Entry<DeviceId, DeviceInfo> device : devices.entrySet()) {
914 NetworkInstances ins = deleteInstance(instance.vpnName());
915 DeviceInfo dev = device.getValue();
916 if (!isIntDeleted) {
917 remVpnBgp(dev);
918 remInterfaceFromMap(dev);
919 }
920 Map<AccessInfo, InterfaceInfo> intMap =
921 l3VpnStore.getInterfaceInfo();
922 String id = dev.deviceId().toString();
923 ModelObjectData devMod = getVpnDelModObj(intMap, ins, id);
924 ModelObjectData driMod = dev.processDeleteInstance(
925 driverService, devMod);
926 ResourceData resData = modelConverter.createDataNode(driMod);
927 deleteFromStore(resData);
janani b176905a2017-03-28 17:36:18 +0530928 }
janani bd821b182017-03-30 16:34:49 +0530929 l3VpnStore.removeVpnInstance(instance.vpnName());
janani b176905a2017-03-28 17:36:18 +0530930 }
janani bd821b182017-03-30 16:34:49 +0530931 }
932
933 /**
934 * Removes the BGP information for that complete VPN instance.
935 *
936 * @param dev device info
937 */
938 private void remVpnBgp(DeviceInfo dev) {
939 BgpInfo devBgp = dev.bgpInfo();
940 if (devBgp != null) {
941 l3VpnStore.removeBgpInfo(devBgp);
942 BgpInfo delInfo = new BgpInfo();
943 delInfo.vpnName(devBgp.vpnName());
944 String id = dev.deviceId().toString();
945 Map<BgpInfo, DeviceId> bgpMap = l3VpnStore.getBgpInfo();
946 BgpDriverInfo driConfig = getVpnBgpDelModObj(bgpMap, id);
947 ModelObjectData driData = dev.processDeleteBgpInfo(
948 driverService, delInfo, driConfig);
949 ResourceData resData = modelConverter.createDataNode(driData);
950 deleteFromStore(resData);
951 l3VpnStore.removeBgpInfo(devBgp);
952 }
janani b176905a2017-03-28 17:36:18 +0530953 }
954
955 /**
956 * Deletes the resource data that is received from the driver, after
957 * converting from the model object data.
958 *
959 * @param resData resource data
960 */
961 private void deleteFromStore(ResourceData resData) {
962 if (resData != null) {
janani bd821b182017-03-30 16:34:49 +0530963 configService.deleteNodeRecursive(resData.resourceId());
janani b176905a2017-03-28 17:36:18 +0530964 }
965 }
966
967 /**
968 * Removes the interface from the app distributed map, if the driver
969 * interfaces are already removed from the store.
970 *
971 * @param deviceInfo device info
972 */
973 private void remInterfaceFromMap(DeviceInfo deviceInfo) {
974 List<AccessInfo> accesses = deviceInfo.accesses();
janani bd821b182017-03-30 16:34:49 +0530975 if (accesses != null) {
976 for (AccessInfo access : accesses) {
977 l3VpnStore.removeInterfaceInfo(access);
978 }
janani b176905a2017-03-28 17:36:18 +0530979 }
980 deviceInfo.ifNames(null);
981 deviceInfo.accesses(null);
982 }
983
984 /**
985 * Signals that the leadership has changed.
986 *
987 * @param isLeader true if this instance is now the leader, otherwise false
988 */
989 private void leaderChanged(boolean isLeader) {
990 log.debug("Leader changed: {}", isLeader);
991 isElectedLeader = isLeader;
992 }
993
994 /**
janani b35f6cbc2017-03-24 21:56:58 +0530995 * Representation of internal listener, listening for dynamic config event.
996 */
997 private class InternalConfigListener implements DynamicConfigListener {
998
999 @Override
1000 public boolean isRelevant(DynamicConfigEvent event) {
1001 return isSupported(event);
1002 }
1003
1004 @Override
1005 public void event(DynamicConfigEvent event) {
janani b176905a2017-03-28 17:36:18 +05301006 accumulator.add(event);
janani b35f6cbc2017-03-24 21:56:58 +05301007 }
1008 }
Bharat saraswalcdfda202017-03-24 23:40:50 +05301009
1010 /**
janani b176905a2017-03-28 17:36:18 +05301011 * Accumulates events to allow processing after a desired number of
1012 * events were accumulated.
Bharat saraswalcdfda202017-03-24 23:40:50 +05301013 */
janani b176905a2017-03-28 17:36:18 +05301014 private class InternalEventAccumulator extends
1015 AbstractAccumulator<DynamicConfigEvent> {
1016
1017 /**
1018 * Constructs the event accumulator with timer and event limit.
1019 */
1020 protected InternalEventAccumulator() {
1021 super(new Timer(TIMER), MAX_EVENTS, MAX_BATCH_MS, MAX_IDLE_MS);
1022 }
1023
1024 @Override
1025 public void processItems(List<DynamicConfigEvent> events) {
1026 for (DynamicConfigEvent event : events) {
1027 checkNotNull(event, EVENT_NULL);
1028 Filter filter = new Filter();
1029 DataNode node;
1030 try {
1031 node = configService.readNode(event.subject(), filter);
1032 } catch (FailedException e) {
1033 node = null;
1034 }
1035 switch (event.type()) {
1036 case NODE_ADDED:
1037 processCreateFromStore(event.subject(), node);
1038 break;
1039
1040 case NODE_DELETED:
1041 processDeleteFromStore(node);
1042 break;
1043
1044 default:
1045 log.warn(UNKNOWN_EVENT, event.type());
1046 break;
1047 }
1048 }
1049 }
Bharat saraswalcdfda202017-03-24 23:40:50 +05301050 }
1051
1052 /**
1053 * A listener for leadership events.
1054 */
1055 private class InternalLeadershipListener implements LeadershipEventListener {
1056
1057 @Override
1058 public boolean isRelevant(LeadershipEvent event) {
1059 return event.subject().topic().equals(appId.name());
1060 }
1061
1062 @Override
1063 public void event(LeadershipEvent event) {
1064 switch (event.type()) {
1065 case LEADER_CHANGED:
1066 case LEADER_AND_CANDIDATES_CHANGED:
1067 if (localNodeId.equals(event.subject().leaderNodeId())) {
1068 log.info("Net l3vpn manager gained leadership");
1069 leaderChanged(true);
1070 } else {
1071 log.info("Net l3vpn manager leader changed. New " +
1072 "leader is {}", event.subject()
1073 .leaderNodeId());
1074 leaderChanged(false);
1075 }
1076 default:
1077 break;
1078 }
1079 }
1080 }
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +05301081}