blob: ca16ecab32a3d87e194895444061858f5641d028 [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;
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +053056import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev20130715.IetfInetTypes;
janani b35f6cbc2017-03-24 21:56:58 +053057import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev20140508.ietfinterfaces.devices.device.Interfaces;
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +053058import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.IetfL3VpnSvc;
janani b35f6cbc2017-03-24 21:56:58 +053059import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.DefaultL3VpnSvc;
60import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.L3VpnSvc;
61import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.accessvpnpolicy.VpnAttachment;
62import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.accessvpnpolicy.vpnattachment.AttachmentFlavor;
63import 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 +053064import 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 +053065import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.l3vpnsvc.Sites;
66import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.l3vpnsvc.VpnServices;
67import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.l3vpnsvc.sites.Site;
68import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.l3vpnsvc.sites.site.SiteNetworkAccesses;
69import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.l3vpnsvc.sites.site.sitenetworkaccesses.SiteNetworkAccess;
70import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.l3vpnsvc.vpnservices.VpnSvc;
71import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siteattachmentbearer.Bearer;
72import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siteattachmentbearer.DefaultBearer;
73import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siteattachmentbearer.bearer.DefaultRequestedType;
74import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siteattachmentbearer.bearer.RequestedType;
75import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siteattachmentipconnection.IpConnection;
76import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siterouting.RoutingProtocols;
77import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siterouting.routingprotocols.RoutingProtocol;
78import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.instance.rev20160623.ietfnetworkinstance.devices.device.NetworkInstances;
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +053079import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev20130715.IetfYangTypes;
80import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.l3vpn.svc.ext.rev20160730.L3VpnSvcExt;
janani b35f6cbc2017-03-24 21:56:58 +053081import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.l3vpn.svc.ext.rev20160730.l3vpnsvcext.l3vpnsvc.sites.site.sitenetworkaccesses.sitenetworkaccess.bearer.DefaultAugmentedL3VpnBearer;
82import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.l3vpn.svc.ext.rev20160730.l3vpnsvcext.l3vpnsvc.sites.site.sitenetworkaccesses.sitenetworkaccess.bearer.requestedtype.DefaultAugmentedL3VpnRequestedType;
83import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.l3vpn.svc.ext.rev20160730.l3vpnsvcext.requestedtypegrouping.requestedtypeprofile.RequestedTypeChoice;
84import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.l3vpn.svc.ext.rev20160730.l3vpnsvcext.requestedtypegrouping.requestedtypeprofile.requestedtypechoice.DefaultDot1Qcase;
85import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.l3vpn.svc.ext.rev20160730.l3vpnsvcext.requestedtypegrouping.requestedtypeprofile.requestedtypechoice.DefaultPhysicalCase;
86import org.onosproject.yang.model.DataNode;
87import org.onosproject.yang.model.DefaultModelObjectData;
88import org.onosproject.yang.model.ModelConverter;
89import org.onosproject.yang.model.ModelObject;
90import org.onosproject.yang.model.ModelObjectData;
91import org.onosproject.yang.model.ModelObjectId;
92import org.onosproject.yang.model.NodeKey;
93import org.onosproject.yang.model.ResourceData;
94import org.onosproject.yang.model.ResourceId;
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +053095import org.onosproject.yang.model.YangModel;
96import org.onosproject.yang.model.YangModuleId;
97import org.onosproject.yang.runtime.DefaultAppModuleInfo;
98import org.onosproject.yang.runtime.DefaultModelRegistrationParam;
99import org.onosproject.yang.runtime.ModelRegistrationParam;
100import org.onosproject.yang.runtime.YangModelRegistry;
101import org.slf4j.Logger;
102import org.slf4j.LoggerFactory;
103
104import java.util.Iterator;
janani b35f6cbc2017-03-24 21:56:58 +0530105import java.util.List;
106import java.util.Map;
janani b176905a2017-03-28 17:36:18 +0530107import java.util.Timer;
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530108
janani b176905a2017-03-28 17:36:18 +0530109import static com.google.common.base.Preconditions.checkNotNull;
janani b35f6cbc2017-03-24 21:56:58 +0530110import static org.onosproject.config.DynamicConfigEvent.Type.NODE_ADDED;
111import static org.onosproject.config.DynamicConfigEvent.Type.NODE_DELETED;
Bharat saraswalcdfda202017-03-24 23:40:50 +0530112import static org.onosproject.l3vpn.netl3vpn.VpnType.HUB;
janani b35f6cbc2017-03-24 21:56:58 +0530113import static org.onosproject.l3vpn.netl3vpn.impl.BgpConstructionUtil.createBgpInfo;
114import static org.onosproject.l3vpn.netl3vpn.impl.InsConstructionUtil.createInstance;
janani b176905a2017-03-28 17:36:18 +0530115import static org.onosproject.l3vpn.netl3vpn.impl.InsConstructionUtil.deleteInstance;
janani b35f6cbc2017-03-24 21:56:58 +0530116import static org.onosproject.l3vpn.netl3vpn.impl.IntConstructionUtil.createInterface;
117import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.BEARER_NULL;
118import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.CONS_HUNDRED;
119import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.DEVICE_INFO_NULL;
janani b176905a2017-03-28 17:36:18 +0530120import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.EVENT_NULL;
janani b35f6cbc2017-03-24 21:56:58 +0530121import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.ID_LIMIT;
122import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.ID_LIMIT_EXCEEDED;
123import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.INT_INFO_NULL;
janani b176905a2017-03-28 17:36:18 +0530124import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.IP;
janani b35f6cbc2017-03-24 21:56:58 +0530125import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.IP_INT_INFO_NULL;
janani b176905a2017-03-28 17:36:18 +0530126import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.MAX_BATCH_MS;
127import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.MAX_EVENTS;
128import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.MAX_IDLE_MS;
janani b35f6cbc2017-03-24 21:56:58 +0530129import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.PORT_NAME;
130import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.SITE_ROLE_NULL;
131import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.SITE_VPN_MISMATCH;
janani b176905a2017-03-28 17:36:18 +0530132import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.TIMER;
133import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.UNKNOWN_EVENT;
janani b35f6cbc2017-03-24 21:56:58 +0530134import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.VPN_ATTACHMENT_NULL;
135import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.VPN_POLICY_NOT_SUPPORTED;
136import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.VPN_TYPE_UNSUPPORTED;
137import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getBgpCreateConfigObj;
138import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getIntCreateModObj;
139import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getIntNotAvailable;
140import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getMgmtIpUnAvailErr;
141import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getModIdForL3VpnSvc;
142import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getModIdForSites;
143import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getResourceData;
144import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getRole;
145import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getVpnCreateModObj;
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530146import static org.onosproject.yang.runtime.helperutils.YangApacheUtils.getYangModel;
147
148/**
149 * The IETF net l3vpn manager implementation.
janani bf41dec32017-03-24 18:44:07 +0530150 * // TODO: Implementation of the manager class.
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530151 */
152@Component(immediate = true)
153public class NetL3vpnManager {
154
155 private static final String APP_ID = "org.onosproject.app.l3vpn";
janani b35f6cbc2017-03-24 21:56:58 +0530156 private static final String L3_VPN_ID_TOPIC = "l3vpn-id";
janani b35f6cbc2017-03-24 21:56:58 +0530157
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530158 private final Logger log = LoggerFactory.getLogger(getClass());
159
janani b176905a2017-03-28 17:36:18 +0530160 private final DynamicConfigListener configListener =
161 new InternalConfigListener();
162
163 private final Accumulator<DynamicConfigEvent> accumulator =
164 new InternalEventAccumulator();
165
166 private final InternalLeadershipListener leadershipEventListener =
167 new InternalLeadershipListener();
168
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530169 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
170 protected CoreService coreService;
171
172 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
janani b35f6cbc2017-03-24 21:56:58 +0530173 protected DriverService driverService;
174
175 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
176 protected DeviceService deviceService;
177
178 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530179 protected YangModelRegistry modelRegistry;
180
janani b35f6cbc2017-03-24 21:56:58 +0530181 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
182 protected ModelConverter modelConverter;
183
184 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
185 protected DynamicConfigService configService;
186
187 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
188 protected NetL3VpnStore l3VpnStore;
189
Bharat saraswalcdfda202017-03-24 23:40:50 +0530190 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
191 protected LeadershipService leadershipService;
192
193 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
194 protected ClusterService clusterService;
195
janani b35f6cbc2017-03-24 21:56:58 +0530196 protected IdGenerator l3VpnIdGen;
janani b176905a2017-03-28 17:36:18 +0530197
Bharat saraswalcdfda202017-03-24 23:40:50 +0530198 private NodeId localNodeId;
janani b176905a2017-03-28 17:36:18 +0530199
Bharat saraswalcdfda202017-03-24 23:40:50 +0530200 private ApplicationId appId;
janani b35f6cbc2017-03-24 21:56:58 +0530201
janani b35f6cbc2017-03-24 21:56:58 +0530202 private ModelRegistrationParam regParam;
203
janani b35f6cbc2017-03-24 21:56:58 +0530204 private ResourceId id;
janani b176905a2017-03-28 17:36:18 +0530205
janani b35f6cbc2017-03-24 21:56:58 +0530206 private ResourceId module;
janani b176905a2017-03-28 17:36:18 +0530207
janani b35f6cbc2017-03-24 21:56:58 +0530208 private ResourceId sites;
janani b176905a2017-03-28 17:36:18 +0530209
Bharat saraswalcdfda202017-03-24 23:40:50 +0530210 private boolean isElectedLeader = false;
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530211
212 @Activate
213 protected void activate() {
Bharat saraswalcdfda202017-03-24 23:40:50 +0530214 appId = coreService.registerApplication(APP_ID);
janani b35f6cbc2017-03-24 21:56:58 +0530215 l3VpnIdGen = coreService.getIdGenerator(L3_VPN_ID_TOPIC);
Bharat saraswalcdfda202017-03-24 23:40:50 +0530216
217 localNodeId = clusterService.getLocalNode().id();
218
219 leadershipService.addListener(leadershipEventListener);
220 leadershipService.runForLeadership(appId.name());
221
janani b35f6cbc2017-03-24 21:56:58 +0530222 registerModel();
223 getResourceId();
224 configService.addListener(configListener);
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530225 log.info("Started");
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530226 }
227
228 @Deactivate
229 protected void deactivate() {
230 modelRegistry.unregisterModel(regParam);
janani b35f6cbc2017-03-24 21:56:58 +0530231 configService.removeListener(configListener);
Bharat saraswalcdfda202017-03-24 23:40:50 +0530232
233 leadershipService.withdraw(appId.name());
234 leadershipService.removeListener(leadershipEventListener);
235
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530236 log.info("Stopped");
237 }
238
239 private void registerModel() {
Bharat saraswalcdfda202017-03-24 23:40:50 +0530240 YangModel model = getYangModel(IetfInetTypes.class);
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +0530241 Iterator<YangModuleId> it = model.getYangModulesId().iterator();
242
243 //Create model registration param.
244 ModelRegistrationParam.Builder b =
245 DefaultModelRegistrationParam.builder().setYangModel(model);
246
247 YangModuleId id;
248 while (it.hasNext()) {
249 id = it.next();
250 switch (id.moduleName()) {
251 case "ietf-inet-types":
252 b.addAppModuleInfo(id, new DefaultAppModuleInfo(
253 IetfInetTypes.class, null));
254 break;
255 case "ietf-l3vpn-svc":
256 b.addAppModuleInfo(id, new DefaultAppModuleInfo(
257 IetfL3VpnSvc.class, null));
258 break;
259 case "ietf-yang-types":
260 b.addAppModuleInfo(id, new DefaultAppModuleInfo(
261 IetfYangTypes.class, null));
262 break;
263 case "l3vpn-svc-ext":
264 b.addAppModuleInfo(id, new DefaultAppModuleInfo(
265 L3VpnSvcExt.class, null));
266 break;
267 default:
268 break;
269 }
270 }
271 regParam = b.build();
272 modelRegistry.registerModel(regParam);
273 }
janani b35f6cbc2017-03-24 21:56:58 +0530274
275 /**
276 * Returns id as string. If the id is not in the freed list a new id is
277 * generated else the id from the freed list is used.
278 *
279 * @return id
280 */
281 private String getIdFromGen() {
282 Long value;
283 Iterable<Long> freeIds = l3VpnStore.getFreedIdList();
284 Iterator<Long> it = freeIds.iterator();
285 if (it.hasNext()) {
286 value = it.next();
287 l3VpnStore.removeIdFromFreeList(value);
288 } else {
289 value = l3VpnIdGen.getNewId();
290 }
291 if (value > ID_LIMIT) {
292 throw new RuntimeException(ID_LIMIT_EXCEEDED);
293 }
294 return CONS_HUNDRED + String.valueOf(value);
295 }
296
297 /**
298 * Returns the resource id, after constructing model object id and
299 * converting it.
300 */
301 private void getResourceId() {
302
303 ModelObjectId moduleId = ModelObjectId.builder().build();
304 module = getResourceVal(moduleId);
305
306 ModelObjectId svcId = getModIdForL3VpnSvc();
307 id = getResourceVal(svcId);
308
309 ModelObjectId sitesId = getModIdForSites();
310 sites = getResourceVal(sitesId);
311 }
312
313 /**
314 * Returns resource id from model converter.
315 *
316 * @param modelId model object id
317 * @return resource id
318 */
319 private ResourceId getResourceVal(ModelObjectId modelId) {
320 DefaultModelObjectData.Builder data = DefaultModelObjectData.builder()
Thomas Vachuskad17bc732017-03-24 11:46:55 -0700321 .identifier(modelId);
janani b35f6cbc2017-03-24 21:56:58 +0530322 ResourceData resData = modelConverter.createDataNode(data.build());
janani b176905a2017-03-28 17:36:18 +0530323 return resData.resourceId();
janani b35f6cbc2017-03-24 21:56:58 +0530324 }
325
326 /**
327 * Processes create request from the store, by taking the root object.
328 * The root object is then used for l3VPN processing.
329 *
330 * @param storeId store resource id
janani b176905a2017-03-28 17:36:18 +0530331 * @param node data node
janani b35f6cbc2017-03-24 21:56:58 +0530332 */
janani b176905a2017-03-28 17:36:18 +0530333 private void processCreateFromStore(ResourceId storeId, DataNode node) {
Bharat saraswal5b5bd9a2017-03-27 18:59:55 +0530334 if (isElectedLeader) {
janani b176905a2017-03-28 17:36:18 +0530335 List<NodeKey> keys = storeId.nodeKeys();
336 List<ModelObject> objects = null;
337 if (keys.size() == 1) {
338 objects = getModelObjects(node, module);
339 } else if (keys.size() == 2) {
340 objects = getModelObjects(node, id);
341 }
342 if (objects != null) {
343 for (ModelObject obj : objects) {
344 if (obj instanceof DefaultL3VpnSvc) {
345 DefaultL3VpnSvc l3VpnSvc = (DefaultL3VpnSvc) obj;
346 createGlobalConfig(l3VpnSvc);
347 } else if (obj instanceof DefaultSites) {
348 DefaultSites sites = (DefaultSites) obj;
349 createInterfaceConfig(sites);
350 }
Bharat saraswalcdfda202017-03-24 23:40:50 +0530351 }
janani b35f6cbc2017-03-24 21:56:58 +0530352 }
353 }
354 }
355
356 /**
Bharat saraswalcdfda202017-03-24 23:40:50 +0530357 * Processes delete request from the store, by taking the root object.
janani b176905a2017-03-28 17:36:18 +0530358 * The root object would have got deleted from store. So all the
359 * configurations are removed.
Bharat saraswalcdfda202017-03-24 23:40:50 +0530360 *
janani b176905a2017-03-28 17:36:18 +0530361 * @param dataNode data node
Bharat saraswalcdfda202017-03-24 23:40:50 +0530362 */
janani b176905a2017-03-28 17:36:18 +0530363 private void processDeleteFromStore(DataNode dataNode) {
Bharat saraswal5b5bd9a2017-03-27 18:59:55 +0530364 if (isElectedLeader) {
janani b176905a2017-03-28 17:36:18 +0530365 if (dataNode == null) {
366 //TODO: Delete for inner nodes.
367 deleteGlobalConfig(null);
368 }
Bharat saraswalcdfda202017-03-24 23:40:50 +0530369 }
370 }
371
372 /**
janani b176905a2017-03-28 17:36:18 +0530373 * Returns model objects of the store. The data node read from store
374 * gives the particular node. So the node's parent resource id is taken
375 * and the data node is given to model converter.
janani b35f6cbc2017-03-24 21:56:58 +0530376 *
janani b176905a2017-03-28 17:36:18 +0530377 * @param dataNode data node from store
378 * @param appId parent resource id
janani b35f6cbc2017-03-24 21:56:58 +0530379 * @return model objects
380 */
janani b176905a2017-03-28 17:36:18 +0530381 public List<ModelObject> getModelObjects(DataNode dataNode,
janani b35f6cbc2017-03-24 21:56:58 +0530382 ResourceId appId) {
janani b35f6cbc2017-03-24 21:56:58 +0530383 ResourceData data = getResourceData(dataNode, appId);
384 ModelObjectData modelData = modelConverter.createModel(data);
385 return modelData.modelObjects();
386 }
387
388 /**
389 * Returns true if the event resource id points to the root level node
390 * only and event is for addition and deletion; false otherwise.
391 *
392 * @param event config event
393 * @return true if event is supported; false otherwise
394 */
395 public boolean isSupported(DynamicConfigEvent event) {
396 ResourceId rsId = event.subject();
397 List<NodeKey> storeKeys = rsId.nodeKeys();
398 List<NodeKey> regKeys = id.nodeKeys();
janani b176905a2017-03-28 17:36:18 +0530399 List<NodeKey> sitesKeys = sites.nodeKeys();
janani b35f6cbc2017-03-24 21:56:58 +0530400 if (storeKeys != null) {
janani b176905a2017-03-28 17:36:18 +0530401 int storeSize = storeKeys.size();
402 if (storeSize == 1) {
janani b35f6cbc2017-03-24 21:56:58 +0530403 return storeKeys.get(0).equals(regKeys.get(1)) &&
404 (event.type() == NODE_ADDED ||
405 event.type() == NODE_DELETED);
janani b176905a2017-03-28 17:36:18 +0530406 } else if (storeSize == 2) {
407 return (storeKeys.get(0).equals(sitesKeys.get(1))) &&
408 storeKeys.get(1).equals(sitesKeys.get(2)) &&
409 (event.type() == NODE_ADDED ||
410 event.type() == NODE_DELETED);
janani b35f6cbc2017-03-24 21:56:58 +0530411 }
412 }
413 return false;
414 }
415
416 /***
janani b176905a2017-03-28 17:36:18 +0530417 * Creates all configuration in the standard device model.
janani b35f6cbc2017-03-24 21:56:58 +0530418 *
419 * @param l3VpnSvc l3VPN service object
420 */
421 void createGlobalConfig(L3VpnSvc l3VpnSvc) {
422 if (l3VpnSvc.vpnServices() != null) {
423 createVpnServices(l3VpnSvc.vpnServices());
424 }
425 if (l3VpnSvc.sites() != null) {
426 createInterfaceConfig(l3VpnSvc.sites());
427 }
428 }
429
430 /**
431 * Creates the VPN instances from the VPN services object, if only that
432 * VPN instance is not already created.
433 *
434 * @param vpnSvcs VPN services object
435 */
436 private void createVpnServices(VpnServices vpnSvcs) {
437 if (vpnSvcs != null && vpnSvcs.vpnSvc() != null) {
438 List<VpnSvc> svcList = vpnSvcs.vpnSvc();
439 for (VpnSvc svc : svcList) {
440 String vpnName = svc.vpnId().string();
441 l3VpnStore.addVpnInsIfAbsent(vpnName, new VpnInstance(vpnName));
442 }
443 }
444 }
445
446 /**
447 * Creates interface configuration from the site network access if
448 * available.
449 *
450 * @param sites sites object
451 */
452 private void createInterfaceConfig(Sites sites) {
453 if (sites.site() != null) {
454 List<Site> sitesList = sites.site();
455 for (Site site : sitesList) {
456 if (site.siteNetworkAccesses() != null) {
457 SiteNetworkAccesses accesses = site.siteNetworkAccesses();
458 List<SiteNetworkAccess> accessList =
459 accesses.siteNetworkAccess();
460 for (SiteNetworkAccess access : accessList) {
461 createFromAccess(access, site.siteId().string());
462 }
463 }
464 }
465 }
466 }
467
468 /**
469 * Creates the interface and VPN related configurations from the access
470 * and site id value.
471 *
472 * @param access site network access
473 * @param siteId site id
474 */
475 private void createFromAccess(SiteNetworkAccess access, String siteId) {
476 Map<AccessInfo, InterfaceInfo> intMap = l3VpnStore.getInterfaceInfo();
477 Map<String, VpnInstance> insMap = l3VpnStore.getVpnInstances();
478 String accessId = access.siteNetworkAccessId().string();
479 AccessInfo info = new AccessInfo(siteId, accessId);
480
481 if (intMap.get(info) == null) {
482 VpnSiteRole siteRole = getSiteRole(access.vpnAttachment());
483 VpnInstance instance = insMap.get(siteRole.name());
484 if (instance == null) {
485 throw new NetL3VpnException(SITE_VPN_MISMATCH);
486 }
487 buildFromAccess(instance, info, access, siteRole);
488 }
489 }
490
491 /**
492 * Returns the VPN site role from the VPN attachment.
493 *
494 * @param attach VPN attachment
495 * @return VPN site role
496 */
497 private VpnSiteRole getSiteRole(VpnAttachment attach) {
498 if (attach == null || attach.attachmentFlavor() == null) {
499 throw new NetL3VpnException(VPN_ATTACHMENT_NULL);
500 }
501 AttachmentFlavor flavor = attach.attachmentFlavor();
502 if (!(flavor instanceof DefaultVpnId)) {
503 throw new NetL3VpnException(VPN_POLICY_NOT_SUPPORTED);
504 }
505 DefaultVpnId vpnId = (DefaultVpnId) flavor;
506 if (vpnId.siteRole() == null) {
507 throw new NetL3VpnException(SITE_ROLE_NULL);
508 }
509 VpnType role = getRole(vpnId.siteRole());
janani b176905a2017-03-28 17:36:18 +0530510 return new VpnSiteRole(String.valueOf(vpnId.vpnId()), role);
janani b35f6cbc2017-03-24 21:56:58 +0530511 }
512
513 /**
514 * Builds the required details for device standard model from the site
515 * network access info available.
516 *
517 * @param instance VPN instance
518 * @param info access info
519 * @param access network access
520 * @param role VPN site role
521 */
522 private void buildFromAccess(VpnInstance instance, AccessInfo info,
523 SiteNetworkAccess access, VpnSiteRole role) {
524 Bearer bearer = access.bearer();
525 if (bearer == null) {
526 throw new NetL3VpnException(BEARER_NULL);
527 }
528
529 RequestedType reqType = bearer.requestedType();
530 IpConnection connect = access.ipConnection();
531 RoutingProtocols pro = access.routingProtocols();
532
533 if (reqType == null || connect == null) {
534 throw new NetL3VpnException(IP_INT_INFO_NULL);
535 }
536 buildDeviceDetails(instance, info, role, bearer, connect,
537 reqType, pro);
538 }
539
540 /**
541 * Builds the device details such as, VPN instance value if it is for
542 * the first time, interface values and BGP info if available in service.
543 *
544 * @param instance VPN instance
545 * @param accInfo access info
546 * @param role VPN site role
547 * @param bearer bearer object
548 * @param connect ip connect object
549 * @param reqType requested type
550 * @param pro routing protocol
551 */
552 private void buildDeviceDetails(VpnInstance instance, AccessInfo accInfo,
553 VpnSiteRole role, Bearer bearer,
554 IpConnection connect, RequestedType reqType,
555 RoutingProtocols pro) {
556 Map<AccessInfo, InterfaceInfo> interMap = l3VpnStore.getInterfaceInfo();
557 InterfaceInfo intInfo = interMap.get(accInfo);
558 if (intInfo != null) {
559 return;
560 }
561
562 DeviceInfo info = buildDevVpnIns(bearer, instance, role, connect);
563 String portName = getInterfaceName(info, reqType);
564 buildDevVpnInt(info, instance, connect, portName, accInfo);
565
566 if (pro != null && pro.routingProtocol() != null) {
567 buildBgpInfo(pro.routingProtocol(), info,
568 role.name(), connect, accInfo);
569 }
570 InterfaceInfo interInfo = new InterfaceInfo(info, portName,
571 instance.vpnName());
572 l3VpnStore.addInterfaceInfo(accInfo, interInfo);
573 }
574
575 /**
576 * Builds device VPN instance with the service objects. It returns
577 *
578 * @param bearer bearer object
579 * @param ins VPN instance
580 * @param role VPN site role
581 * @param connect ip connection
582 * @return return
583 */
584 private DeviceInfo buildDevVpnIns(Bearer bearer, VpnInstance ins,
585 VpnSiteRole role, IpConnection connect) {
586 DefaultAugmentedL3VpnBearer augBearer = ((DefaultBearer) bearer)
587 .augmentation(DefaultAugmentedL3VpnBearer.class);
588 DeviceId id = getDeviceId(augBearer);
589 Map<DeviceId, DeviceInfo> devices = ins.devInfo();
590 DeviceInfo info = null;
591 if (devices != null) {
592 info = devices.get(id);
593 }
594 if (info == null) {
595 info = createVpnInstance(id, role, ins, connect);
596 }
597 return info;
598 }
599
600 /**
601 * Returns the device id from the bearer augment attachment of service.
602 * If the attachment in augment is not available it throws error.
603 *
604 * @param attach augmented bearer
605 * @return device id
606 */
607 private DeviceId getDeviceId(DefaultAugmentedL3VpnBearer attach) {
608 if (attach == null || attach.bearerAttachment() == null ||
609 attach.bearerAttachment().peMgmtIp() == null ||
610 attach.bearerAttachment().peMgmtIp().string() == null) {
611 throw new NetL3VpnException(DEVICE_INFO_NULL);
612 }
613 String ip = attach.bearerAttachment().peMgmtIp().string();
614 return getId(ip);
615 }
616
617 /**
618 * Returns the device id whose management ip address matches with the ip
619 * received.
620 *
621 * @param ip ip address
622 * @return device id
623 */
624 public DeviceId getId(String ip) {
625 for (Device device : deviceService.getAvailableDevices()) {
janani b176905a2017-03-28 17:36:18 +0530626 String val = device.annotations().value(IP);
janani b35f6cbc2017-03-24 21:56:58 +0530627 if (ip.equals(val)) {
628 return device.id();
629 }
630 }
631 throw new NetL3VpnException(getMgmtIpUnAvailErr(ip));
632 }
633
634 /**
635 * Creates the VPN instance by constructing standard device model of
636 * instances. It adds the RD and RT values to the VPN instance.
637 *
638 * @param id device id
639 * @param role VPN site role
640 * @param inst VPN instance
641 * @param ip ip connection
642 * @return device info
643 */
644 private DeviceInfo createVpnInstance(DeviceId id, VpnSiteRole role,
645 VpnInstance inst, IpConnection ip) {
646 Map<AccessInfo, InterfaceInfo> intMap = l3VpnStore.getInterfaceInfo();
647 generateRdRt(inst, role);
648 DeviceInfo info = new DeviceInfo(id);
649 inst.addDevInfo(id, info);
650
651 NetworkInstances instances = createInstance(inst, role, ip);
652 ModelObjectData devMod = getVpnCreateModObj(intMap, instances,
653 id.toString());
654 ModelObjectData driMod = info.processCreateInstance(driverService,
655 devMod);
656 ResourceData resData = modelConverter.createDataNode(driMod);
657 addToStore(resData);
janani b36b1d772017-03-27 15:01:28 +0530658 l3VpnStore.addVpnIns(inst.vpnName(), inst);
janani b35f6cbc2017-03-24 21:56:58 +0530659 return info;
660 }
661
662 /**
663 * Adds the resource data that is received from the driver, after
664 * converting from the model object data.
665 *
666 * @param resData resource data
667 */
668 private void addToStore(ResourceData resData) {
669 if (resData != null && resData.dataNodes() != null) {
670 List<DataNode> dataNodes = resData.dataNodes();
671 for (DataNode node : dataNodes) {
672 configService.createNodeRecursive(resData.resourceId(), node);
673 }
674 }
675 }
676
677 /**
678 * Generates RD and RT value for the VPN instance for the first time VPN
679 * instance creation.
680 *
681 * @param ins VPN instance
682 * @param role VPN site role
683 */
684 private void generateRdRt(VpnInstance ins, VpnSiteRole role) {
685 ins.type(role.role());
686 VpnConfig config = ins.vpnConfig();
687 String rd = null;
688 if (config == null) {
689 rd = getIdFromGen();
690 }
691 switch (ins.type()) {
692 case ANY_TO_ANY:
693 if (config == null) {
694 config = new FullMeshVpnConfig(rd);
695 config.rd(rd);
696 }
697 break;
698
699 case HUB:
700 case SPOKE:
701 if (config == null) {
702 config = new HubSpokeVpnConfig();
703 config.rd(rd);
704 }
705 createImpRtVal((HubSpokeVpnConfig) config, ins.type());
706 createExpRtVal((HubSpokeVpnConfig) config, ins.type());
707 break;
708
709 default:
710 throw new NetL3VpnException(VPN_TYPE_UNSUPPORTED);
711 }
712 ins.vpnConfig(config);
713 }
714
715 /**
716 * Creates import RT value for HUB and SPOKE, according to the type, if
717 * the values are not present.
718 *
719 * @param config VPN config
720 * @param type VPN type
721 */
722 private void createImpRtVal(HubSpokeVpnConfig config, VpnType type) {
723 if (type == HUB) {
724 if (config.hubImpRt() != null) {
725 return;
726 }
727 setHubImpRt(config);
728 } else {
729 if (config.spokeImpRt() != null) {
730 return;
731 }
732 config.spokeImpRt(config.rd());
733 }
734 }
735
736 /**
737 * Sets the HUB import RT, from the spoke export RT. If it is not
738 * available a new ID is generated.
739 *
740 * @param config VPN config
741 */
742 public void setHubImpRt(HubSpokeVpnConfig config) {
743 String hubImp;
744 if (config.spokeExpRt() != null) {
745 hubImp = config.spokeExpRt();
746 } else {
747 hubImp = getIdFromGen();
748 }
749 config.hubImpRt(hubImp);
750 }
751
752 /**
753 * Creates export RT value for HUB and SPOKE, according to the type, if
754 * the values are not present.
755 *
756 * @param config VPN config
757 * @param type VPN type
758 */
759 private void createExpRtVal(HubSpokeVpnConfig config, VpnType type) {
760 if (type == HUB) {
761 if (config.hubExpRt() != null) {
762 return;
763 }
764 config.hubExpRt(config.rd());
765 } else {
766 if (config.spokeExpRt() != null) {
767 return;
768 }
769 setSpokeExpRt(config);
770 }
771 }
772
773 /**
774 * Sets the SPOKE export RT, from the hub import RT. If it is not
775 * available a new ID is generated.
776 *
777 * @param config VPN config
778 */
779 public void setSpokeExpRt(HubSpokeVpnConfig config) {
780 String spokeExp;
781 if (config.hubImpRt() != null) {
782 spokeExp = config.hubImpRt();
783 } else {
784 spokeExp = getIdFromGen();
785 }
786 config.spokeExpRt(spokeExp);
787 }
788
789 /**
790 * Returns the interface name from the requested type service object.
791 *
792 * @param info device info
793 * @param reqType requested type
794 * @return interface name
795 */
796 private String getInterfaceName(DeviceInfo info, RequestedType reqType) {
797 DefaultAugmentedL3VpnRequestedType req =
798 ((DefaultRequestedType) reqType).augmentation(
799 DefaultAugmentedL3VpnRequestedType.class);
800 if (req == null || req.requestedTypeProfile() == null ||
801 req.requestedTypeProfile().requestedTypeChoice() == null) {
802 throw new NetL3VpnException(INT_INFO_NULL);
803 }
804 RequestedTypeChoice reqChoice = req.requestedTypeProfile()
805 .requestedTypeChoice();
806 return getNameFromChoice(reqChoice, info.deviceId());
807 }
808
809 /**
810 * Returns the interface name from the type choice provided.
811 *
812 * @param choice service choice
813 * @param id device id
814 * @return interface name
815 */
816 private String getNameFromChoice(RequestedTypeChoice choice, DeviceId id) {
817 if (choice == null) {
818 throw new NetL3VpnException(INT_INFO_NULL);
819 }
820 String intName;
821 if (choice instanceof DefaultDot1Qcase) {
822 if (((DefaultDot1Qcase) choice).dot1q() == null ||
823 ((DefaultDot1Qcase) choice).dot1q()
824 .physicalIf() == null) {
825 throw new NetL3VpnException(INT_INFO_NULL);
826 }
827 intName = ((DefaultDot1Qcase) choice).dot1q().physicalIf();
828 } else {
829 if (((DefaultPhysicalCase) choice).physical() == null ||
830 ((DefaultPhysicalCase) choice).physical()
831 .physicalIf() == null) {
832 throw new NetL3VpnException(INT_INFO_NULL);
833 }
834 intName = ((DefaultPhysicalCase) choice).physical().physicalIf();
835 }
836 return getPortName(intName, id);
837 }
838
839 /**
840 * Returns the port name when it the port is available in the device.
841 *
842 * @param intName interface name
843 * @param id device id
844 * @return port name
845 */
846 private String getPortName(String intName, DeviceId id) {
847 List<Port> ports = deviceService.getPorts(id);
848 for (Port port : ports) {
849 String pName = port.annotations().value(PORT_NAME);
850 if (pName.equals(intName)) {
851 return intName;
852 }
853 }
854 throw new NetL3VpnException(getIntNotAvailable(intName));
855 }
856
857 /**
858 * Builds the interface for the device binding with the VPN instance.
859 *
860 * @param info device info
861 * @param ins VPN instance
862 * @param connect IP connection
863 * @param pName port name
864 * @param access access info
865 */
866 private void buildDevVpnInt(DeviceInfo info, VpnInstance ins,
867 IpConnection connect, String pName,
868 AccessInfo access) {
869 Map<AccessInfo, InterfaceInfo> intMap = l3VpnStore.getInterfaceInfo();
870 info.addAccessInfo(access);
871 info.addIfName(pName);
872 Interfaces interfaces = createInterface(pName, ins.vpnName(),
873 connect);
874 ModelObjectData devMod = getIntCreateModObj(
875 intMap, interfaces, info.deviceId().toString());
876 ModelObjectData driMod = info.processCreateInterface(driverService,
877 devMod);
878 ResourceData resData = modelConverter.createDataNode(driMod);
879 addToStore(resData);
880 }
881
882 /**
883 * Builds the BGP information from the routes that are given from the
884 * service.
885 *
886 * @param routes routing protocol
887 * @param info device info
888 * @param name VPN name
889 * @param connect IP connection
890 * @param access access info
891 */
892 private void buildBgpInfo(List<RoutingProtocol> routes, DeviceInfo info,
893 String name, IpConnection connect,
894 AccessInfo access) {
895 Map<BgpInfo, DeviceId> bgpMap = l3VpnStore.getBgpInfo();
896 BgpInfo intBgp = createBgpInfo(routes, info, name, connect, access);
897 if (intBgp != null) {
898 intBgp.vpnName(name);
899 BgpDriverInfo config = getBgpCreateConfigObj(
900 bgpMap, info.deviceId().toString());
901 ModelObjectData driData = info.processCreateBgpInfo(
902 driverService, intBgp, config);
903 l3VpnStore.addBgpInfo(info.bgpInfo(), info.deviceId());
904 ResourceData resData = modelConverter.createDataNode(driData);
905 addToStore(resData);
906 }
907 }
908
909 /**
janani b176905a2017-03-28 17:36:18 +0530910 * Creates all configuration in the standard device model.
911 *
912 * @param l3VpnSvc l3 VPN service
913 */
914 void deleteGlobalConfig(L3VpnSvc l3VpnSvc) {
915 deleteGlobalVpn(l3VpnSvc);
916 //TODO: Site and access deletion needs to be added.
917 }
918
919 /**
920 * Deletes the global VPN from the device model and delete from the device.
921 *
922 * @param l3VpnSvc L3 VPN service
923 */
924 private void deleteGlobalVpn(L3VpnSvc l3VpnSvc) {
925 Map<String, VpnInstance> insMap = l3VpnStore.getVpnInstances();
926 //TODO: check for VPN delete deleting interface from store.
927 if (l3VpnSvc == null || l3VpnSvc.vpnServices() == null ||
928 l3VpnSvc.vpnServices().vpnSvc() == null) {
929 for (Map.Entry<String, VpnInstance> vpnMap : insMap.entrySet()) {
930 deleteVpnInstance(vpnMap.getValue(), false);
931 }
932 return;
933 }
934 List<VpnSvc> vpnList = l3VpnSvc.vpnServices().vpnSvc();
935 for (Map.Entry<String, VpnInstance> vpnMap : insMap.entrySet()) {
936 boolean isPresent = isVpnPresent(vpnMap.getKey(), vpnList);
937 if (!isPresent) {
938 deleteVpnInstance(vpnMap.getValue(), false);
939 }
940 }
941 }
942
943 /**
944 * Returns true if the VPN in the distributed map is also present in the
945 * service; false otherwise.
946 *
947 * @param vpnName VPN name from store
948 * @param vpnList VPN list from service
949 * @return true if VPN available; false otherwise
950 */
951 private boolean isVpnPresent(String vpnName, List<VpnSvc> vpnList) {
952 for (VpnSvc svc : vpnList) {
953 if (svc.vpnId().string().equals(vpnName)) {
954 return true;
955 }
956 }
957 return false;
958 }
959
960 /**
961 * Deletes the VPN instance by constructing standard device model of
962 * instances.
963 *
964 * @param instance VPN instance
965 * @param isIntDeleted if interface already removed.
966 */
967 private void deleteVpnInstance(VpnInstance instance, boolean isIntDeleted) {
968 Map<DeviceId, DeviceInfo> devices = instance.devInfo();
969 for (Map.Entry<DeviceId, DeviceInfo> device : devices.entrySet()) {
970 Map<AccessInfo, InterfaceInfo> intMap =
971 l3VpnStore.getInterfaceInfo();
972 NetworkInstances ins = deleteInstance(instance.vpnName());
973 DeviceInfo dev = device.getValue();
974
975 ModelObjectData devMod = getVpnCreateModObj(
976 intMap, ins, dev.deviceId().toString());
977 ModelObjectData driMod = dev.processDeleteInstance(driverService,
978 devMod);
979 ResourceData resData = modelConverter.createDataNode(driMod);
980 deleteFromStore(resData);
981 if (!isIntDeleted) {
982 //TODO: Remove from store.
983 remInterfaceFromMap(dev);
984 }
985 }
986 l3VpnStore.removeVpnInstance(instance.vpnName());
987 }
988
989 /**
990 * Deletes the resource data that is received from the driver, after
991 * converting from the model object data.
992 *
993 * @param resData resource data
994 */
995 private void deleteFromStore(ResourceData resData) {
996 if (resData != null) {
997 configService.deleteNode(resData.resourceId());
998 }
999 }
1000
1001 /**
1002 * Removes the interface from the app distributed map, if the driver
1003 * interfaces are already removed from the store.
1004 *
1005 * @param deviceInfo device info
1006 */
1007 private void remInterfaceFromMap(DeviceInfo deviceInfo) {
1008 List<AccessInfo> accesses = deviceInfo.accesses();
1009 for (AccessInfo access : accesses) {
1010 l3VpnStore.removeInterfaceInfo(access);
1011 }
1012 deviceInfo.ifNames(null);
1013 deviceInfo.accesses(null);
1014 }
1015
1016 /**
1017 * Signals that the leadership has changed.
1018 *
1019 * @param isLeader true if this instance is now the leader, otherwise false
1020 */
1021 private void leaderChanged(boolean isLeader) {
1022 log.debug("Leader changed: {}", isLeader);
1023 isElectedLeader = isLeader;
1024 }
1025
1026 /**
janani b35f6cbc2017-03-24 21:56:58 +05301027 * Representation of internal listener, listening for dynamic config event.
1028 */
1029 private class InternalConfigListener implements DynamicConfigListener {
1030
1031 @Override
1032 public boolean isRelevant(DynamicConfigEvent event) {
1033 return isSupported(event);
1034 }
1035
1036 @Override
1037 public void event(DynamicConfigEvent event) {
janani b176905a2017-03-28 17:36:18 +05301038 accumulator.add(event);
janani b35f6cbc2017-03-24 21:56:58 +05301039 }
1040 }
Bharat saraswalcdfda202017-03-24 23:40:50 +05301041
1042 /**
janani b176905a2017-03-28 17:36:18 +05301043 * Accumulates events to allow processing after a desired number of
1044 * events were accumulated.
Bharat saraswalcdfda202017-03-24 23:40:50 +05301045 */
janani b176905a2017-03-28 17:36:18 +05301046 private class InternalEventAccumulator extends
1047 AbstractAccumulator<DynamicConfigEvent> {
1048
1049 /**
1050 * Constructs the event accumulator with timer and event limit.
1051 */
1052 protected InternalEventAccumulator() {
1053 super(new Timer(TIMER), MAX_EVENTS, MAX_BATCH_MS, MAX_IDLE_MS);
1054 }
1055
1056 @Override
1057 public void processItems(List<DynamicConfigEvent> events) {
1058 for (DynamicConfigEvent event : events) {
1059 checkNotNull(event, EVENT_NULL);
1060 Filter filter = new Filter();
1061 DataNode node;
1062 try {
1063 node = configService.readNode(event.subject(), filter);
1064 } catch (FailedException e) {
1065 node = null;
1066 }
1067 switch (event.type()) {
1068 case NODE_ADDED:
1069 processCreateFromStore(event.subject(), node);
1070 break;
1071
1072 case NODE_DELETED:
1073 processDeleteFromStore(node);
1074 break;
1075
1076 default:
1077 log.warn(UNKNOWN_EVENT, event.type());
1078 break;
1079 }
1080 }
1081 }
Bharat saraswalcdfda202017-03-24 23:40:50 +05301082 }
1083
1084 /**
1085 * A listener for leadership events.
1086 */
1087 private class InternalLeadershipListener implements LeadershipEventListener {
1088
1089 @Override
1090 public boolean isRelevant(LeadershipEvent event) {
1091 return event.subject().topic().equals(appId.name());
1092 }
1093
1094 @Override
1095 public void event(LeadershipEvent event) {
1096 switch (event.type()) {
1097 case LEADER_CHANGED:
1098 case LEADER_AND_CANDIDATES_CHANGED:
1099 if (localNodeId.equals(event.subject().leaderNodeId())) {
1100 log.info("Net l3vpn manager gained leadership");
1101 leaderChanged(true);
1102 } else {
1103 log.info("Net l3vpn manager leader changed. New " +
1104 "leader is {}", event.subject()
1105 .leaderNodeId());
1106 leaderChanged(false);
1107 }
1108 default:
1109 break;
1110 }
1111 }
1112 }
Gaurav Agrawalc6d536f2017-03-17 11:56:31 +05301113}