2 * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.netvirt.vpnmanager;
10 import java.util.ArrayList;
11 import java.util.HashMap;
12 import java.util.List;
14 import java.util.Optional;
15 import java.util.concurrent.ExecutionException;
16 import javax.inject.Inject;
17 import javax.inject.Singleton;
18 import org.eclipse.jdt.annotation.Nullable;
19 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
20 import org.opendaylight.mdsal.binding.api.DataBroker;
21 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
22 import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.PortOpData;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.SubnetOpData;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.port.op.data.PortOpDataEntry;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.port.op.data.PortOpDataEntryBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.port.op.data.PortOpDataEntryKey;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.SubnetOpDataEntry;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.SubnetOpDataEntryKey;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.subnet.op.data.entry.SubnetToDpn;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.subnet.op.data.entry.SubnetToDpnBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.subnet.op.data.entry.SubnetToDpnKey;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.subnet.op.data.entry.subnet.to.dpn.VpnInterfaces;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.subnet.op.data.entry.subnet.to.dpn.VpnInterfacesBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.subnet.op.data.entry.subnet.to.dpn.VpnInterfacesKey;
37 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
38 import org.opendaylight.yangtools.yang.common.Uint64;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
43 public class SubnetOpDpnManager {
44 private static final Logger LOG = LoggerFactory.getLogger(SubnetOpDpnManager.class);
46 private final DataBroker broker;
49 public SubnetOpDpnManager(final DataBroker db) {
54 private SubnetToDpn addDpnToSubnet(Uuid subnetId, Uint64 dpnId) {
56 InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier =
57 InstanceIdentifier.builder(SubnetOpData.class).child(SubnetOpDataEntry.class,
58 new SubnetOpDataEntryKey(subnetId)).build();
59 InstanceIdentifier<SubnetToDpn> dpnOpId =
60 subOpIdentifier.child(SubnetToDpn.class, new SubnetToDpnKey(dpnId));
61 Optional<SubnetToDpn> optionalSubDpn = SingleTransactionDataBroker.syncReadOptional(broker,
62 LogicalDatastoreType.OPERATIONAL, dpnOpId);
63 if (optionalSubDpn.isPresent()) {
64 LOG.error("addDpnToSubnet: Cannot create, SubnetToDpn for subnet {} as DPN {}"
65 + " already seen in datastore", subnetId.getValue(), dpnId);
68 SubnetToDpnBuilder subDpnBuilder = new SubnetToDpnBuilder().withKey(new SubnetToDpnKey(dpnId));
69 Map<VpnInterfacesKey, VpnInterfaces> vpnInterfaceMap = new HashMap<>();
70 subDpnBuilder.setVpnInterfaces(vpnInterfaceMap);
71 SubnetToDpn subDpn = subDpnBuilder.build();
72 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, dpnOpId, subDpn,
73 VpnUtil.SINGLE_TRANSACTION_BROKER_NO_RETRY);
74 LOG.info("addDpnToSubnet: Created SubnetToDpn entry for subnet {} with DPNId {} ", subnetId.getValue(),
77 } catch (TransactionCommitFailedException ex) {
78 LOG.error("addDpnToSubnet: Creation of SubnetToDpn for subnet {} with DpnId {} failed",
79 subnetId.getValue(), dpnId, ex);
80 } catch (InterruptedException | ExecutionException e) {
81 LOG.error("addDpnToSubnet: Failed to read data store for subnet {} dpn {}", subnetId.getValue(),
87 private void removeDpnFromSubnet(Uuid subnetId, Uint64 dpnId) {
89 InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier =
90 InstanceIdentifier.builder(SubnetOpData.class).child(SubnetOpDataEntry.class,
91 new SubnetOpDataEntryKey(subnetId)).build();
92 InstanceIdentifier<SubnetToDpn> dpnOpId =
93 subOpIdentifier.child(SubnetToDpn.class, new SubnetToDpnKey(dpnId));
94 Optional<SubnetToDpn> optionalSubDpn = SingleTransactionDataBroker.syncReadOptional(broker,
95 LogicalDatastoreType.OPERATIONAL, dpnOpId);
96 if (!optionalSubDpn.isPresent()) {
97 LOG.warn("removeDpnFromSubnet: Cannot delete, SubnetToDpn for subnet {} DPN {} not available"
98 + " in datastore", subnetId.getValue(), dpnId);
101 LOG.trace("removeDpnFromSubnet: Deleting SubnetToDpn entry for subnet {} with DPNId {}",
102 subnetId.getValue(), dpnId);
103 SingleTransactionDataBroker.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, dpnOpId,
104 VpnUtil.SINGLE_TRANSACTION_BROKER_NO_RETRY);
105 } catch (TransactionCommitFailedException ex) {
106 LOG.error("removeDpnFromSubnet: Deletion of SubnetToDpn for subnet {} with DPN {} failed",
107 subnetId.getValue(), dpnId, ex);
108 } catch (InterruptedException | ExecutionException e) {
109 LOG.error("removeDpnFromSubnet: Failed to read data store for subnet {} dpn {}", subnetId, dpnId);
113 public SubnetToDpn addInterfaceToDpn(Uuid subnetId, Uint64 dpnId, String intfName) {
114 SubnetToDpn subDpn = null;
116 // Create and add SubnetOpDataEntry object for this subnet to the SubnetOpData container
117 InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier =
118 InstanceIdentifier.builder(SubnetOpData.class).child(SubnetOpDataEntry.class,
119 new SubnetOpDataEntryKey(subnetId)).build();
120 //Please use a synchronize block here as we donot need a cluster-wide lock
121 InstanceIdentifier<SubnetToDpn> dpnOpId =
122 subOpIdentifier.child(SubnetToDpn.class, new SubnetToDpnKey(dpnId));
123 Optional<SubnetToDpn> optionalSubDpn = SingleTransactionDataBroker.syncReadOptional(broker,
124 LogicalDatastoreType.OPERATIONAL, dpnOpId);
125 if (!optionalSubDpn.isPresent()) {
126 // Create a new DPN Entry
127 subDpn = addDpnToSubnet(subnetId, dpnId);
129 subDpn = optionalSubDpn.get();
131 SubnetToDpnBuilder subDpnBuilder = new SubnetToDpnBuilder(subDpn);
132 Map<VpnInterfacesKey, VpnInterfaces> vpnInterfaceMap = new HashMap<>();
133 vpnInterfaceMap = subDpnBuilder.getVpnInterfaces() != null
134 ? new HashMap<>(subDpnBuilder.getVpnInterfaces()) : vpnInterfaceMap;
135 VpnInterfaces vpnIntfs =
136 new VpnInterfacesBuilder().withKey(new VpnInterfacesKey(intfName)).setInterfaceName(intfName).build();
137 vpnInterfaceMap.put(vpnIntfs.key(), vpnIntfs);
138 subDpnBuilder.setVpnInterfaces(vpnInterfaceMap);
139 subDpn = subDpnBuilder.build();
140 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, dpnOpId, subDpn,
141 VpnUtil.SINGLE_TRANSACTION_BROKER_NO_RETRY);
142 LOG.info("addInterfaceToDpn: Created SubnetToDpn entry for subnet {} with DPNId {} intfName {}",
143 subnetId.getValue(), dpnId, intfName);
144 } catch (TransactionCommitFailedException ex) {
145 LOG.error("addInterfaceToDpn: Addition of Interface {} for SubnetToDpn on subnet {} with DPN {} failed",
146 intfName, subnetId.getValue(), dpnId, ex);
147 } catch (InterruptedException | ExecutionException e) {
148 LOG.error("addInterfaceToDpn: Failed to read data store for interface {} subnet {} dpn {}", intfName,
154 public void addPortOpDataEntry(String intfName, Uuid subnetId, @Nullable Uint64 dpnId) {
156 // Add to PortOpData as well.
157 PortOpDataEntryBuilder portOpBuilder = null;
158 PortOpDataEntry portOpEntry = null;
159 InstanceIdentifier<PortOpDataEntry> portOpIdentifier =
160 InstanceIdentifier.builder(PortOpData.class).child(PortOpDataEntry.class,
161 new PortOpDataEntryKey(intfName)).build();
162 Optional<PortOpDataEntry> optionalPortOp = SingleTransactionDataBroker.syncReadOptional(broker,
163 LogicalDatastoreType.OPERATIONAL, portOpIdentifier);
164 if (!optionalPortOp.isPresent()) {
165 // Create PortOpDataEntry only if not present
167 new PortOpDataEntryBuilder().withKey(new PortOpDataEntryKey(intfName)).setPortId(intfName);
168 List<Uuid> listSubnet = new ArrayList<>();
169 listSubnet.add(subnetId);
170 portOpBuilder.setSubnetIds(listSubnet);
172 PortOpDataEntry portEntry = optionalPortOp.get();
173 List<Uuid> listSubnet = new ArrayList<>();
174 listSubnet = (portEntry.getSubnetIds() != null && !portEntry.getSubnetIds().isEmpty())
175 ? new ArrayList<>(portEntry.getSubnetIds()) : listSubnet;
176 portOpBuilder = new PortOpDataEntryBuilder(optionalPortOp.get());
177 if (listSubnet == null) {
178 listSubnet = new ArrayList<>();
180 if (!listSubnet.contains(subnetId)) {
181 listSubnet.add(subnetId);
183 portOpBuilder.setSubnetIds(listSubnet);
185 if (dpnId != null && !dpnId.equals(Uint64.ZERO)) {
186 portOpBuilder.setDpnId(dpnId);
188 portOpEntry = portOpBuilder.build();
189 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, portOpIdentifier,
190 portOpEntry, VpnUtil.SINGLE_TRANSACTION_BROKER_NO_RETRY);
191 LOG.info("addPortOpDataEntry: Created PortOpData entry for port {} with DPNId {} subnetId {}",
192 intfName, dpnId, subnetId.getValue());
193 } catch (TransactionCommitFailedException ex) {
194 LOG.error("addPortOpDataEntry: Addition of Interface {} for SubnetToDpn on subnet {} with DPN {} failed",
195 intfName, subnetId.getValue(), dpnId, ex);
196 } catch (InterruptedException | ExecutionException e) {
197 LOG.error("addPortOpDataEntry: Failed to read from data store for interface {} subnet {} dpn {}",
198 intfName, subnetId, dpnId);
202 public boolean removeInterfaceFromDpn(Uuid subnetId, Uint64 dpnId, String intfName) {
203 boolean dpnRemoved = false;
205 InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier =
206 InstanceIdentifier.builder(SubnetOpData.class).child(SubnetOpDataEntry.class,
207 new SubnetOpDataEntryKey(subnetId)).build();
208 InstanceIdentifier<SubnetToDpn> dpnOpId =
209 subOpIdentifier.child(SubnetToDpn.class, new SubnetToDpnKey(dpnId));
210 Optional<SubnetToDpn> optionalSubDpn = SingleTransactionDataBroker.syncReadOptional(broker,
211 LogicalDatastoreType.OPERATIONAL, dpnOpId);
212 if (!optionalSubDpn.isPresent()) {
213 LOG.debug("removeInterfaceFromDpn: Cannot delete, SubnetToDpn for intf {} subnet {} DPN {}"
214 + " not available in datastore", intfName, subnetId.getValue(), dpnId);
218 SubnetToDpnBuilder subDpnBuilder = new SubnetToDpnBuilder(optionalSubDpn.get());
219 Map<VpnInterfacesKey, VpnInterfaces> vpnInterfaceMap = new HashMap<>();
221 vpnInterfaceMap = (subDpnBuilder.getVpnInterfaces() != null && !subDpnBuilder.getVpnInterfaces().isEmpty())
222 ? new HashMap<>(subDpnBuilder.getVpnInterfaces()) : vpnInterfaceMap;
223 VpnInterfaces vpnIntfs =
224 new VpnInterfacesBuilder().withKey(new VpnInterfacesKey(intfName)).setInterfaceName(intfName).build();
225 vpnInterfaceMap.remove(vpnIntfs.key());
226 if (vpnInterfaceMap.isEmpty()) {
227 // Remove the DPN as well
228 removeDpnFromSubnet(subnetId, dpnId);
231 subDpnBuilder.setVpnInterfaces(vpnInterfaceMap);
232 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, dpnOpId,
233 subDpnBuilder.build(), VpnUtil.SINGLE_TRANSACTION_BROKER_NO_RETRY);
235 LOG.info("removeInterfaceFromDpn: Removed interface {} from sunbet {} dpn {}",
236 intfName, subnetId.getValue(), dpnId);
237 } catch (TransactionCommitFailedException ex) {
238 LOG.error("removeInterfaceFromDpn: Deletion of Interface {} for SubnetToDpn on subnet {}"
239 + " with DPN {} failed", intfName, subnetId.getValue(), dpnId, ex);
240 } catch (InterruptedException | ExecutionException e) {
241 LOG.error("removeInterfaceFromDpn: Failed to read data store for interface {} subnet {} dpn {}",
242 intfName, subnetId, dpnId);
247 public PortOpDataEntry removePortOpDataEntry(String intfName, Uuid subnetId) {
248 // Remove PortOpData and return out
249 InstanceIdentifier<PortOpDataEntry> portOpIdentifier =
250 InstanceIdentifier.builder(PortOpData.class).child(PortOpDataEntry.class,
251 new PortOpDataEntryKey(intfName)).build();
252 PortOpDataEntry portOpEntry = null;
254 Optional<PortOpDataEntry> optionalPortOp = SingleTransactionDataBroker.syncReadOptional(broker,
255 LogicalDatastoreType.OPERATIONAL, portOpIdentifier);
256 if (!optionalPortOp.isPresent()) {
257 LOG.info("removePortOpDataEntry: Cannot delete, portOp for port {} is not available in datastore",
260 portOpEntry = optionalPortOp.get();
261 List<Uuid> listSubnet = new ArrayList<>();
262 listSubnet = (portOpEntry.getSubnetIds() != null && !portOpEntry.getSubnetIds().isEmpty())
263 ? new ArrayList<>(portOpEntry.getSubnetIds()) : listSubnet;
264 if (listSubnet == null) {
265 listSubnet = new ArrayList<>();
267 if (subnetId != null && listSubnet.contains(subnetId)) {
268 listSubnet.remove(subnetId);
270 if (listSubnet.isEmpty() || subnetId == null) {
271 SingleTransactionDataBroker.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, portOpIdentifier,
272 VpnUtil.SINGLE_TRANSACTION_BROKER_NO_RETRY);
273 LOG.info("removePortOpDataEntry: Deleted portOpData entry for port {}", intfName);
275 PortOpDataEntryBuilder portOpBuilder = null;
276 portOpBuilder = new PortOpDataEntryBuilder(portOpEntry);
277 portOpBuilder.setSubnetIds(listSubnet);
278 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL,
279 portOpIdentifier, portOpEntry, VpnUtil.SINGLE_TRANSACTION_BROKER_NO_RETRY);
280 LOG.info("removePortOpDataEntry: Updated PortOpData entry for port {} with removing"
281 + " subnetId {}", intfName, subnetId.getValue());
285 } catch (InterruptedException | ExecutionException e) {
286 LOG.error("removePortOpDataEntry: Failed to read data store for interface {} subnet {}", intfName,
288 } catch (TransactionCommitFailedException e) {
289 LOG.error("removePortOpDataEntry: Failed to commit to data store for interface {} subnet {}", intfName,
295 public PortOpDataEntry getPortOpDataEntry(String intfName) {
296 PortOpDataEntry portOpDataEntry = null;
298 // Remove PortOpData and return out
299 InstanceIdentifier<PortOpDataEntry> portOpIdentifier =
300 InstanceIdentifier.builder(PortOpData.class).child(PortOpDataEntry.class,
301 new PortOpDataEntryKey(intfName)).build();
302 Optional<PortOpDataEntry> optionalPortOp = SingleTransactionDataBroker.syncReadOptional(broker,
303 LogicalDatastoreType.OPERATIONAL, portOpIdentifier);
304 if (optionalPortOp.isPresent()) {
305 portOpDataEntry = optionalPortOp.get();
307 } catch (InterruptedException | ExecutionException e) {
308 LOG.error("getPortOpDataEntry: Failed to read data store for interface {}", intfName);
310 return portOpDataEntry;