5c968a97ba7a3412be902b9d4504650be3e64e63
[netvirt.git] / vpnmanager / impl / src / main / java / org / opendaylight / netvirt / vpnmanager / SubnetOpDpnManager.java
1 /*
2  * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.netvirt.vpnmanager;
9
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;
38
39 @Singleton
40 public class SubnetOpDpnManager {
41     private static final Logger LOG = LoggerFactory.getLogger(SubnetOpDpnManager.class);
42
43     private final DataBroker broker;
44
45     @Inject
46     public SubnetOpDpnManager(final DataBroker db) {
47         broker = db;
48     }
49
50     private SubnetToDpn addDpnToSubnet(Uuid subnetId, BigInteger dpnId) {
51         try {
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);
61                 return null;
62             }
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(),
69                     dpnId);
70             return subDpn;
71         } catch (TransactionCommitFailedException ex) {
72             LOG.error("addDpnToSubnet: Creation of SubnetToDpn for subnet {} with DpnId {} failed",
73                     subnetId.getValue(), dpnId, ex);
74             return null;
75         }
76     }
77
78     private void removeDpnFromSubnet(Uuid subnetId, BigInteger dpnId) {
79         try {
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);
89                 return;
90             }
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);
97         }
98     }
99
100     public SubnetToDpn addInterfaceToDpn(Uuid subnetId, BigInteger dpnId, String intfName) {
101         SubnetToDpn subDpn = null;
102         try {
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);
114             } else {
115                 subDpn = optionalSubDpn.get();
116             }
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();
124
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);
131             return null;
132         }
133         return subDpn;
134     }
135
136     public void addPortOpDataEntry(String intfName, Uuid subnetId, BigInteger dpnId) {
137         try {
138             // Add to PortOpData as well.
139             PortOpDataEntryBuilder portOpBuilder = null;
140             PortOpDataEntry portOpEntry = null;
141
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
149                 portOpBuilder =
150                     new PortOpDataEntryBuilder().setKey(new PortOpDataEntryKey(intfName)).setPortId(intfName);
151                 List<Uuid> listSubnet = new ArrayList<>();
152                 listSubnet.add(subnetId);
153                 portOpBuilder.setSubnetIds(listSubnet);
154             } else {
155                 List<Uuid> listSubnet = optionalPortOp.get().getSubnetIds();
156                 portOpBuilder = new PortOpDataEntryBuilder(optionalPortOp.get());
157                 if (listSubnet == null) {
158                     listSubnet = new ArrayList<>();
159                 }
160                 if (!listSubnet.contains(subnetId)) {
161                     listSubnet.add(subnetId);
162                 }
163                 portOpBuilder.setSubnetIds(listSubnet);
164             }
165             if (dpnId != null && !dpnId.equals(BigInteger.ZERO)) {
166                 portOpBuilder.setDpnId(dpnId);
167             }
168             portOpEntry = portOpBuilder.build();
169             SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, portOpIdentifier,
170                 portOpEntry);
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);
176         }
177     }
178
179     public boolean removeInterfaceFromDpn(Uuid subnetId, BigInteger dpnId, String intfName) {
180         boolean dpnRemoved = false;
181         try {
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);
191                 return false;
192             }
193
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);
202                 dpnRemoved = true;
203             } else {
204                 subDpnBuilder.setVpnInterfaces(vpnIntfList);
205                 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, dpnOpId,
206                     subDpnBuilder.build());
207             }
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);
213             return false;
214         }
215         return dpnRemoved;
216     }
217
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",
228                     intfName);
229             return null;
230         } else {
231             portOpEntry = optionalPortOp.get();
232             List<Uuid> listSubnet = portOpEntry.getSubnetIds();
233             if (listSubnet == null) {
234                 listSubnet = new ArrayList<>();
235             }
236             if (subnetId != null && listSubnet.contains(subnetId)) {
237                 listSubnet.remove(subnetId);
238             }
239             if (listSubnet.isEmpty() || subnetId == null) {
240                 MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, portOpIdentifier);
241                 LOG.info("removePortOpDataEntry: Deleted portOpData entry for port {}", intfName);
242             } else {
243                 try {
244                     PortOpDataEntryBuilder portOpBuilder = null;
245                     portOpBuilder = new PortOpDataEntryBuilder(portOpEntry);
246                     portOpBuilder.setSubnetIds(listSubnet);
247                     SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, portOpIdentifier,
248                         portOpEntry);
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());
254                 }
255                 return null;
256             }
257         }
258         return portOpEntry;
259     }
260
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()) {
269             return null;
270         }
271         return optionalPortOp.get();
272     }
273
274 }