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 com.google.common.base.Optional;
11 import java.math.BigInteger;
12 import java.util.ArrayList;
13 import java.util.List;
14 import javax.inject.Inject;
15 import javax.inject.Singleton;
16 import org.eclipse.jdt.annotation.Nullable;
17 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
19 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
20 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
21 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.PortOpData;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.SubnetOpData;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.port.op.data.PortOpDataEntry;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.port.op.data.PortOpDataEntryBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.port.op.data.PortOpDataEntryKey;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.SubnetOpDataEntry;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.SubnetOpDataEntryKey;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.subnet.op.data.entry.SubnetToDpn;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.subnet.op.data.entry.SubnetToDpnBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.subnet.op.data.entry.SubnetToDpnKey;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.subnet.op.data.entry.subnet.to.dpn.VpnInterfaces;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.subnet.op.data.entry.subnet.to.dpn.VpnInterfacesBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.subnet.op.data.entry.subnet.to.dpn.VpnInterfacesKey;
36 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
41 public class SubnetOpDpnManager {
42 private static final Logger LOG = LoggerFactory.getLogger(SubnetOpDpnManager.class);
44 private final DataBroker broker;
47 public SubnetOpDpnManager(final DataBroker db) {
52 private SubnetToDpn addDpnToSubnet(Uuid subnetId, BigInteger dpnId) {
54 InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier =
55 InstanceIdentifier.builder(SubnetOpData.class).child(SubnetOpDataEntry.class,
56 new SubnetOpDataEntryKey(subnetId)).build();
57 InstanceIdentifier<SubnetToDpn> dpnOpId =
58 subOpIdentifier.child(SubnetToDpn.class, new SubnetToDpnKey(dpnId));
59 Optional<SubnetToDpn> optionalSubDpn = SingleTransactionDataBroker.syncReadOptional(broker,
60 LogicalDatastoreType.OPERATIONAL, dpnOpId);
61 if (optionalSubDpn.isPresent()) {
62 LOG.error("addDpnToSubnet: Cannot create, SubnetToDpn for subnet {} as DPN {}"
63 + " already seen in datastore", subnetId.getValue(), dpnId);
66 SubnetToDpnBuilder subDpnBuilder = new SubnetToDpnBuilder().withKey(new SubnetToDpnKey(dpnId));
67 List<VpnInterfaces> vpnIntfList = new ArrayList<>();
68 subDpnBuilder.setVpnInterfaces(vpnIntfList);
69 SubnetToDpn subDpn = subDpnBuilder.build();
70 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, dpnOpId, subDpn,
71 VpnUtil.SINGLE_TRANSACTION_BROKER_NO_RETRY);
72 LOG.info("addDpnToSubnet: Created SubnetToDpn entry for subnet {} with DPNId {} ", subnetId.getValue(),
75 } catch (TransactionCommitFailedException ex) {
76 LOG.error("addDpnToSubnet: Creation of SubnetToDpn for subnet {} with DpnId {} failed",
77 subnetId.getValue(), dpnId, ex);
78 } catch (ReadFailedException e) {
79 LOG.error("addDpnToSubnet: Failed to read data store for subnet {} dpn {}", subnetId.getValue(),
85 private void removeDpnFromSubnet(Uuid subnetId, BigInteger dpnId) {
87 InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier =
88 InstanceIdentifier.builder(SubnetOpData.class).child(SubnetOpDataEntry.class,
89 new SubnetOpDataEntryKey(subnetId)).build();
90 InstanceIdentifier<SubnetToDpn> dpnOpId =
91 subOpIdentifier.child(SubnetToDpn.class, new SubnetToDpnKey(dpnId));
92 Optional<SubnetToDpn> optionalSubDpn = SingleTransactionDataBroker.syncReadOptional(broker,
93 LogicalDatastoreType.OPERATIONAL, dpnOpId);
94 if (!optionalSubDpn.isPresent()) {
95 LOG.warn("removeDpnFromSubnet: Cannot delete, SubnetToDpn for subnet {} DPN {} not available"
96 + " in datastore", subnetId.getValue(), dpnId);
99 LOG.trace("removeDpnFromSubnet: Deleting SubnetToDpn entry for subnet {} with DPNId {}",
100 subnetId.getValue(), dpnId);
101 SingleTransactionDataBroker.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, dpnOpId,
102 VpnUtil.SINGLE_TRANSACTION_BROKER_NO_RETRY);
103 } catch (TransactionCommitFailedException ex) {
104 LOG.error("removeDpnFromSubnet: Deletion of SubnetToDpn for subnet {} with DPN {} failed",
105 subnetId.getValue(), dpnId, ex);
106 } catch (ReadFailedException e) {
107 LOG.error("removeDpnFromSubnet: Failed to read data store for subnet {} dpn {}", subnetId, dpnId);
111 public SubnetToDpn addInterfaceToDpn(Uuid subnetId, BigInteger dpnId, String intfName) {
112 SubnetToDpn subDpn = null;
114 // Create and add SubnetOpDataEntry object for this subnet to the SubnetOpData container
115 InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier =
116 InstanceIdentifier.builder(SubnetOpData.class).child(SubnetOpDataEntry.class,
117 new SubnetOpDataEntryKey(subnetId)).build();
118 //Please use a synchronize block here as we donot need a cluster-wide lock
119 InstanceIdentifier<SubnetToDpn> dpnOpId =
120 subOpIdentifier.child(SubnetToDpn.class, new SubnetToDpnKey(dpnId));
121 Optional<SubnetToDpn> optionalSubDpn = SingleTransactionDataBroker.syncReadOptional(broker,
122 LogicalDatastoreType.OPERATIONAL, dpnOpId);
123 if (!optionalSubDpn.isPresent()) {
124 // Create a new DPN Entry
125 subDpn = addDpnToSubnet(subnetId, dpnId);
127 subDpn = optionalSubDpn.get();
129 SubnetToDpnBuilder subDpnBuilder = new SubnetToDpnBuilder(subDpn);
130 List<VpnInterfaces> vpnIntfList = subDpnBuilder.getVpnInterfaces();
131 VpnInterfaces vpnIntfs =
132 new VpnInterfacesBuilder().withKey(new VpnInterfacesKey(intfName)).setInterfaceName(intfName).build();
133 vpnIntfList.add(vpnIntfs);
134 subDpnBuilder.setVpnInterfaces(vpnIntfList);
135 subDpn = subDpnBuilder.build();
136 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, dpnOpId, subDpn,
137 VpnUtil.SINGLE_TRANSACTION_BROKER_NO_RETRY);
138 LOG.info("addInterfaceToDpn: Created SubnetToDpn entry for subnet {} with DPNId {} intfName {}",
139 subnetId.getValue(), dpnId, intfName);
140 } catch (TransactionCommitFailedException ex) {
141 LOG.error("addInterfaceToDpn: Addition of Interface {} for SubnetToDpn on subnet {} with DPN {} failed",
142 intfName, subnetId.getValue(), dpnId, ex);
143 } catch (ReadFailedException e) {
144 LOG.error("addInterfaceToDpn: Failed to read data store for interface {} subnet {} dpn {}", intfName,
150 public void addPortOpDataEntry(String intfName, Uuid subnetId, @Nullable BigInteger dpnId) {
152 // Add to PortOpData as well.
153 PortOpDataEntryBuilder portOpBuilder = null;
154 PortOpDataEntry portOpEntry = null;
155 InstanceIdentifier<PortOpDataEntry> portOpIdentifier =
156 InstanceIdentifier.builder(PortOpData.class).child(PortOpDataEntry.class,
157 new PortOpDataEntryKey(intfName)).build();
158 Optional<PortOpDataEntry> optionalPortOp = SingleTransactionDataBroker.syncReadOptional(broker,
159 LogicalDatastoreType.OPERATIONAL, portOpIdentifier);
160 if (!optionalPortOp.isPresent()) {
161 // Create PortOpDataEntry only if not present
163 new PortOpDataEntryBuilder().withKey(new PortOpDataEntryKey(intfName)).setPortId(intfName);
164 List<Uuid> listSubnet = new ArrayList<>();
165 listSubnet.add(subnetId);
166 portOpBuilder.setSubnetIds(listSubnet);
168 List<Uuid> listSubnet = optionalPortOp.get().getSubnetIds();
169 portOpBuilder = new PortOpDataEntryBuilder(optionalPortOp.get());
170 if (listSubnet == null) {
171 listSubnet = new ArrayList<>();
173 if (!listSubnet.contains(subnetId)) {
174 listSubnet.add(subnetId);
176 portOpBuilder.setSubnetIds(listSubnet);
178 if (dpnId != null && !dpnId.equals(BigInteger.ZERO)) {
179 portOpBuilder.setDpnId(dpnId);
181 portOpEntry = portOpBuilder.build();
182 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, portOpIdentifier,
183 portOpEntry, VpnUtil.SINGLE_TRANSACTION_BROKER_NO_RETRY);
184 LOG.info("addPortOpDataEntry: Created PortOpData entry for port {} with DPNId {} subnetId {}",
185 intfName, dpnId, subnetId.getValue());
186 } catch (TransactionCommitFailedException ex) {
187 LOG.error("addPortOpDataEntry: Addition of Interface {} for SubnetToDpn on subnet {} with DPN {} failed",
188 intfName, subnetId.getValue(), dpnId, ex);
189 } catch (ReadFailedException e) {
190 LOG.error("addPortOpDataEntry: Failed to read from data store for interface {} subnet {} dpn {}",
191 intfName, subnetId, dpnId);
195 public boolean removeInterfaceFromDpn(Uuid subnetId, BigInteger dpnId, String intfName) {
196 boolean dpnRemoved = false;
198 InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier =
199 InstanceIdentifier.builder(SubnetOpData.class).child(SubnetOpDataEntry.class,
200 new SubnetOpDataEntryKey(subnetId)).build();
201 InstanceIdentifier<SubnetToDpn> dpnOpId =
202 subOpIdentifier.child(SubnetToDpn.class, new SubnetToDpnKey(dpnId));
203 Optional<SubnetToDpn> optionalSubDpn = SingleTransactionDataBroker.syncReadOptional(broker,
204 LogicalDatastoreType.OPERATIONAL, dpnOpId);
205 if (!optionalSubDpn.isPresent()) {
206 LOG.debug("removeInterfaceFromDpn: Cannot delete, SubnetToDpn for intf {} subnet {} DPN {}"
207 + " not available in datastore", intfName, subnetId.getValue(), dpnId);
211 SubnetToDpnBuilder subDpnBuilder = new SubnetToDpnBuilder(optionalSubDpn.get());
212 List<VpnInterfaces> vpnIntfList = subDpnBuilder.getVpnInterfaces();
213 VpnInterfaces vpnIntfs =
214 new VpnInterfacesBuilder().withKey(new VpnInterfacesKey(intfName)).setInterfaceName(intfName).build();
215 vpnIntfList.remove(vpnIntfs);
216 if (vpnIntfList.isEmpty()) {
217 // Remove the DPN as well
218 removeDpnFromSubnet(subnetId, dpnId);
221 subDpnBuilder.setVpnInterfaces(vpnIntfList);
222 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, dpnOpId,
223 subDpnBuilder.build(), VpnUtil.SINGLE_TRANSACTION_BROKER_NO_RETRY);
225 LOG.info("removeInterfaceFromDpn: Removed interface {} from sunbet {} dpn {}",
226 intfName, subnetId.getValue(), dpnId);
227 } catch (TransactionCommitFailedException ex) {
228 LOG.error("removeInterfaceFromDpn: Deletion of Interface {} for SubnetToDpn on subnet {}"
229 + " with DPN {} failed", intfName, subnetId.getValue(), dpnId, ex);
230 } catch (ReadFailedException e) {
231 LOG.error("removeInterfaceFromDpn: Failed to read data store for interface {} subnet {} dpn {}",
232 intfName, subnetId, dpnId);
237 public PortOpDataEntry removePortOpDataEntry(String intfName, Uuid subnetId) {
238 // Remove PortOpData and return out
239 InstanceIdentifier<PortOpDataEntry> portOpIdentifier =
240 InstanceIdentifier.builder(PortOpData.class).child(PortOpDataEntry.class,
241 new PortOpDataEntryKey(intfName)).build();
242 PortOpDataEntry portOpEntry = null;
244 Optional<PortOpDataEntry> optionalPortOp = SingleTransactionDataBroker.syncReadOptional(broker,
245 LogicalDatastoreType.OPERATIONAL, portOpIdentifier);
246 if (!optionalPortOp.isPresent()) {
247 LOG.info("removePortOpDataEntry: Cannot delete, portOp for port {} is not available in datastore",
250 portOpEntry = optionalPortOp.get();
251 List<Uuid> listSubnet = portOpEntry.getSubnetIds();
252 if (listSubnet == null) {
253 listSubnet = new ArrayList<>();
255 if (subnetId != null && listSubnet.contains(subnetId)) {
256 listSubnet.remove(subnetId);
258 if (listSubnet.isEmpty() || subnetId == null) {
259 SingleTransactionDataBroker.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, portOpIdentifier,
260 VpnUtil.SINGLE_TRANSACTION_BROKER_NO_RETRY);
261 LOG.info("removePortOpDataEntry: Deleted portOpData entry for port {}", intfName);
263 PortOpDataEntryBuilder portOpBuilder = null;
264 portOpBuilder = new PortOpDataEntryBuilder(portOpEntry);
265 portOpBuilder.setSubnetIds(listSubnet);
266 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL,
267 portOpIdentifier, portOpEntry, VpnUtil.SINGLE_TRANSACTION_BROKER_NO_RETRY);
268 LOG.info("removePortOpDataEntry: Updated PortOpData entry for port {} with removing"
269 + " subnetId {}", intfName, subnetId.getValue());
273 } catch (ReadFailedException e) {
274 LOG.error("removePortOpDataEntry: Failed to read data store for interface {} subnet {}", intfName,
276 } catch (TransactionCommitFailedException e) {
277 LOG.error("removePortOpDataEntry: Failed to commit to data store for interface {} subnet {}", intfName,
283 public PortOpDataEntry getPortOpDataEntry(String intfName) {
284 PortOpDataEntry portOpDataEntry = null;
286 // Remove PortOpData and return out
287 InstanceIdentifier<PortOpDataEntry> portOpIdentifier =
288 InstanceIdentifier.builder(PortOpData.class).child(PortOpDataEntry.class,
289 new PortOpDataEntryKey(intfName)).build();
290 Optional<PortOpDataEntry> optionalPortOp = SingleTransactionDataBroker.syncReadOptional(broker,
291 LogicalDatastoreType.OPERATIONAL, portOpIdentifier);
292 if (optionalPortOp.isPresent()) {
293 portOpDataEntry = optionalPortOp.get();
295 } catch (ReadFailedException e) {
296 LOG.error("getPortOpDataEntry: Failed to read data store for interface {}", intfName);
298 return portOpDataEntry;