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.opendaylight.controller.md.sal.binding.api.DataBroker;
17 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
18 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
19 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
20 import org.opendaylight.genius.mdsalutil.MDSALUtil;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.PortOpData;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.SubnetOpData;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.port.op.data.PortOpDataEntry;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.port.op.data.PortOpDataEntryBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.port.op.data.PortOpDataEntryKey;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.SubnetOpDataEntry;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.SubnetOpDataEntryKey;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.subnet.op.data.entry.SubnetToDpn;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.subnet.op.data.entry.SubnetToDpnBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.subnet.op.data.entry.SubnetToDpnKey;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.subnet.op.data.entry.subnet.to.dpn.VpnInterfaces;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.subnet.op.data.entry.subnet.to.dpn.VpnInterfacesBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.subnet.op.data.entry.subnet.to.dpn.VpnInterfacesKey;
35 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
40 public class SubnetOpDpnManager {
41 private static final Logger LOG = LoggerFactory.getLogger(SubnetOpDpnManager.class);
43 private final DataBroker broker;
46 public SubnetOpDpnManager(final DataBroker db) {
50 private SubnetToDpn addDpnToSubnet(Uuid subnetId, BigInteger dpnId) {
52 InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier =
53 InstanceIdentifier.builder(SubnetOpData.class).child(SubnetOpDataEntry.class,
54 new SubnetOpDataEntryKey(subnetId)).build();
55 InstanceIdentifier<SubnetToDpn> dpnOpId =
56 subOpIdentifier.child(SubnetToDpn.class, new SubnetToDpnKey(dpnId));
57 Optional<SubnetToDpn> optionalSubDpn = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, dpnOpId);
58 if (optionalSubDpn.isPresent()) {
59 LOG.error("addDpnToSubnet: Cannot create, SubnetToDpn for subnet {} as DPN {}"
60 + " already seen in datastore", subnetId.getValue(), dpnId);
63 SubnetToDpnBuilder subDpnBuilder = new SubnetToDpnBuilder().setKey(new SubnetToDpnKey(dpnId));
64 List<VpnInterfaces> vpnIntfList = new ArrayList<>();
65 subDpnBuilder.setVpnInterfaces(vpnIntfList);
66 SubnetToDpn subDpn = subDpnBuilder.build();
67 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, dpnOpId, subDpn);
68 LOG.info("addDpnToSubnet: Created SubnetToDpn entry for subnet {} with DPNId {} ", subnetId.getValue(),
71 } catch (TransactionCommitFailedException ex) {
72 LOG.error("addDpnToSubnet: Creation of SubnetToDpn for subnet {} with DpnId {} failed",
73 subnetId.getValue(), dpnId, ex);
78 private void removeDpnFromSubnet(Uuid subnetId, BigInteger dpnId) {
80 InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier =
81 InstanceIdentifier.builder(SubnetOpData.class).child(SubnetOpDataEntry.class,
82 new SubnetOpDataEntryKey(subnetId)).build();
83 InstanceIdentifier<SubnetToDpn> dpnOpId =
84 subOpIdentifier.child(SubnetToDpn.class, new SubnetToDpnKey(dpnId));
85 Optional<SubnetToDpn> optionalSubDpn = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, dpnOpId);
86 if (!optionalSubDpn.isPresent()) {
87 LOG.warn("removeDpnFromSubnet: Cannot delete, SubnetToDpn for subnet {} DPN {} not available"
88 + " in datastore", subnetId.getValue(), dpnId);
91 LOG.trace("removeDpnFromSubnet: Deleting SubnetToDpn entry for subnet {} with DPNId {}",
92 subnetId.getValue(), dpnId);
93 SingleTransactionDataBroker.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, dpnOpId);
94 } catch (TransactionCommitFailedException ex) {
95 LOG.error("removeDpnFromSubnet: Deletion of SubnetToDpn for subnet {} with DPN {} failed",
96 subnetId.getValue(), dpnId, ex);
100 public SubnetToDpn addInterfaceToDpn(Uuid subnetId, BigInteger dpnId, String intfName) {
101 SubnetToDpn subDpn = null;
103 // Create and add SubnetOpDataEntry object for this subnet to the SubnetOpData container
104 InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier =
105 InstanceIdentifier.builder(SubnetOpData.class).child(SubnetOpDataEntry.class,
106 new SubnetOpDataEntryKey(subnetId)).build();
107 //Please use a synchronize block here as we donot need a cluster-wide lock
108 InstanceIdentifier<SubnetToDpn> dpnOpId =
109 subOpIdentifier.child(SubnetToDpn.class, new SubnetToDpnKey(dpnId));
110 Optional<SubnetToDpn> optionalSubDpn = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, dpnOpId);
111 if (!optionalSubDpn.isPresent()) {
112 // Create a new DPN Entry
113 subDpn = addDpnToSubnet(subnetId, dpnId);
115 subDpn = optionalSubDpn.get();
117 SubnetToDpnBuilder subDpnBuilder = new SubnetToDpnBuilder(subDpn);
118 List<VpnInterfaces> vpnIntfList = subDpnBuilder.getVpnInterfaces();
119 VpnInterfaces vpnIntfs =
120 new VpnInterfacesBuilder().setKey(new VpnInterfacesKey(intfName)).setInterfaceName(intfName).build();
121 vpnIntfList.add(vpnIntfs);
122 subDpnBuilder.setVpnInterfaces(vpnIntfList);
123 subDpn = subDpnBuilder.build();
125 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, dpnOpId, subDpn);
126 LOG.info("addInterfaceToDpn: Created SubnetToDpn entry for subnet {} with DPNId {} intfName {}",
127 subnetId.getValue(), dpnId, intfName);
128 } catch (TransactionCommitFailedException ex) {
129 LOG.error("addInterfaceToDpn: Addition of Interface {} for SubnetToDpn on subnet {} with DPN {} failed",
130 intfName, subnetId.getValue(), dpnId, ex);
136 public void addPortOpDataEntry(String intfName, Uuid subnetId, BigInteger dpnId) {
138 // Add to PortOpData as well.
139 PortOpDataEntryBuilder portOpBuilder = null;
140 PortOpDataEntry portOpEntry = null;
142 InstanceIdentifier<PortOpDataEntry> portOpIdentifier =
143 InstanceIdentifier.builder(PortOpData.class).child(PortOpDataEntry.class,
144 new PortOpDataEntryKey(intfName)).build();
145 Optional<PortOpDataEntry> optionalPortOp =
146 VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, portOpIdentifier);
147 if (!optionalPortOp.isPresent()) {
148 // Create PortOpDataEntry only if not present
150 new PortOpDataEntryBuilder().setKey(new PortOpDataEntryKey(intfName)).setPortId(intfName);
151 List<Uuid> listSubnet = new ArrayList<>();
152 listSubnet.add(subnetId);
153 portOpBuilder.setSubnetIds(listSubnet);
155 List<Uuid> listSubnet = optionalPortOp.get().getSubnetIds();
156 portOpBuilder = new PortOpDataEntryBuilder(optionalPortOp.get());
157 if (listSubnet == null) {
158 listSubnet = new ArrayList<>();
160 if (!listSubnet.contains(subnetId)) {
161 listSubnet.add(subnetId);
163 portOpBuilder.setSubnetIds(listSubnet);
165 if (dpnId != null && !dpnId.equals(BigInteger.ZERO)) {
166 portOpBuilder.setDpnId(dpnId);
168 portOpEntry = portOpBuilder.build();
169 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, portOpIdentifier,
171 LOG.info("addPortOpDataEntry: Created PortOpData entry for port {} with DPNId {} subnetId {}",
172 intfName, dpnId, subnetId.getValue());
173 } catch (TransactionCommitFailedException ex) {
174 LOG.error("addPortOpDataEntry: Addition of Interface {} for SubnetToDpn on subnet {} with DPN {} failed",
175 intfName, subnetId.getValue(), dpnId, ex);
179 public boolean removeInterfaceFromDpn(Uuid subnetId, BigInteger dpnId, String intfName) {
180 boolean dpnRemoved = false;
182 InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier =
183 InstanceIdentifier.builder(SubnetOpData.class).child(SubnetOpDataEntry.class,
184 new SubnetOpDataEntryKey(subnetId)).build();
185 InstanceIdentifier<SubnetToDpn> dpnOpId =
186 subOpIdentifier.child(SubnetToDpn.class, new SubnetToDpnKey(dpnId));
187 Optional<SubnetToDpn> optionalSubDpn = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, dpnOpId);
188 if (!optionalSubDpn.isPresent()) {
189 LOG.debug("removeInterfaceFromDpn: Cannot delete, SubnetToDpn for intf {} subnet {} DPN {}"
190 + " not available in datastore", intfName, subnetId.getValue(), dpnId);
194 SubnetToDpnBuilder subDpnBuilder = new SubnetToDpnBuilder(optionalSubDpn.get());
195 List<VpnInterfaces> vpnIntfList = subDpnBuilder.getVpnInterfaces();
196 VpnInterfaces vpnIntfs =
197 new VpnInterfacesBuilder().setKey(new VpnInterfacesKey(intfName)).setInterfaceName(intfName).build();
198 vpnIntfList.remove(vpnIntfs);
199 if (vpnIntfList.isEmpty()) {
200 // Remove the DPN as well
201 removeDpnFromSubnet(subnetId, dpnId);
204 subDpnBuilder.setVpnInterfaces(vpnIntfList);
205 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, dpnOpId,
206 subDpnBuilder.build());
208 LOG.info("removeInterfaceFromDpn: Removed interface {} from sunbet {} dpn {}",
209 intfName, subnetId.getValue(), dpnId);
210 } catch (TransactionCommitFailedException ex) {
211 LOG.error("removeInterfaceFromDpn: Deletion of Interface {} for SubnetToDpn on subnet {}"
212 + " with DPN {} failed", intfName, subnetId.getValue(), dpnId, ex);
218 public PortOpDataEntry removePortOpDataEntry(String intfName, Uuid subnetId) {
219 // Remove PortOpData and return out
220 InstanceIdentifier<PortOpDataEntry> portOpIdentifier =
221 InstanceIdentifier.builder(PortOpData.class).child(PortOpDataEntry.class,
222 new PortOpDataEntryKey(intfName)).build();
223 PortOpDataEntry portOpEntry = null;
224 Optional<PortOpDataEntry> optionalPortOp =
225 VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, portOpIdentifier);
226 if (!optionalPortOp.isPresent()) {
227 LOG.info("removePortOpDataEntry: Cannot delete, portOp for port {} is not available in datastore",
231 portOpEntry = optionalPortOp.get();
232 List<Uuid> listSubnet = portOpEntry.getSubnetIds();
233 if (listSubnet == null) {
234 listSubnet = new ArrayList<>();
236 if (subnetId != null && listSubnet.contains(subnetId)) {
237 listSubnet.remove(subnetId);
239 if (listSubnet.isEmpty() || subnetId == null) {
240 MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, portOpIdentifier);
241 LOG.info("removePortOpDataEntry: Deleted portOpData entry for port {}", intfName);
244 PortOpDataEntryBuilder portOpBuilder = null;
245 portOpBuilder = new PortOpDataEntryBuilder(portOpEntry);
246 portOpBuilder.setSubnetIds(listSubnet);
247 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, portOpIdentifier,
249 LOG.info("removePortOpDataEntry: Updated PortOpData entry for port {} with removing subnetId {}",
250 intfName, subnetId.getValue());
251 } catch (TransactionCommitFailedException ex) {
252 LOG.error("removePortOpDataEntry failed: Updated PortOpData entry for port {}"
253 + " with removing subnetId {}", intfName, subnetId.getValue());
261 public PortOpDataEntry getPortOpDataEntry(String intfName) {
262 // Remove PortOpData and return out
263 InstanceIdentifier<PortOpDataEntry> portOpIdentifier =
264 InstanceIdentifier.builder(PortOpData.class).child(PortOpDataEntry.class,
265 new PortOpDataEntryKey(intfName)).build();
266 Optional<PortOpDataEntry> optionalPortOp =
267 VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, portOpIdentifier);
268 if (!optionalPortOp.isPresent()) {
271 return optionalPortOp.get();