e734221e0ab6aa90f14a5cfb5268fa798b211320
[netvirt.git] /
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 org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
16 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
17 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
18 import org.opendaylight.genius.mdsalutil.MDSALUtil;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.PortOpData;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.SubnetOpData;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.port.op.data.PortOpDataEntry;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.port.op.data.PortOpDataEntryBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.port.op.data.PortOpDataEntryKey;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.SubnetOpDataEntry;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.SubnetOpDataEntryKey;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.subnet.op.data.entry.SubnetToDpn;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.subnet.op.data.entry.SubnetToDpnBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.subnet.op.data.entry.SubnetToDpnKey;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.subnet.op.data.entry.subnet.to.dpn.VpnInterfaces;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.subnet.op.data.entry.subnet.to.dpn.VpnInterfacesBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.subnet.op.data.entry.subnet.to.dpn.VpnInterfacesKey;
33 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37
38 public class SubnetOpDpnManager {
39     private static final Logger LOG = LoggerFactory.getLogger(SubnetOpDpnManager.class);
40
41     private final DataBroker broker;
42
43     public SubnetOpDpnManager(final DataBroker db) {
44         broker = db;
45     }
46
47     private SubnetToDpn addDpnToSubnet(Uuid subnetId, BigInteger dpnId) {
48         try {
49             InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier =
50                 InstanceIdentifier.builder(SubnetOpData.class).child(SubnetOpDataEntry.class,
51                     new SubnetOpDataEntryKey(subnetId)).build();
52             InstanceIdentifier<SubnetToDpn> dpnOpId =
53                 subOpIdentifier.child(SubnetToDpn.class, new SubnetToDpnKey(dpnId));
54             Optional<SubnetToDpn> optionalSubDpn = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, dpnOpId);
55             if (optionalSubDpn.isPresent()) {
56                 LOG.error("addDpnToSubnet: Cannot create, SubnetToDpn for subnet {} as DPN {}"
57                         + " already seen in datastore", subnetId.getValue(), dpnId);
58                 return null;
59             }
60             SubnetToDpnBuilder subDpnBuilder = new SubnetToDpnBuilder().setKey(new SubnetToDpnKey(dpnId));
61             List<VpnInterfaces> vpnIntfList = new ArrayList<>();
62             subDpnBuilder.setVpnInterfaces(vpnIntfList);
63             SubnetToDpn subDpn = subDpnBuilder.build();
64             SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, dpnOpId, subDpn);
65             LOG.info("addDpnToSubnet: Created SubnetToDpn entry for subnet {} with DPNId {} ", subnetId.getValue(),
66                     dpnId);
67             return subDpn;
68         } catch (TransactionCommitFailedException ex) {
69             LOG.error("addDpnToSubnet: Creation of SubnetToDpn for subnet {} with DpnId {} failed",
70                     subnetId.getValue(), dpnId, ex);
71             return null;
72         }
73     }
74
75     private void removeDpnFromSubnet(Uuid subnetId, BigInteger dpnId) {
76         try {
77             InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier =
78                 InstanceIdentifier.builder(SubnetOpData.class).child(SubnetOpDataEntry.class,
79                     new SubnetOpDataEntryKey(subnetId)).build();
80             InstanceIdentifier<SubnetToDpn> dpnOpId =
81                 subOpIdentifier.child(SubnetToDpn.class, new SubnetToDpnKey(dpnId));
82             Optional<SubnetToDpn> optionalSubDpn = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, dpnOpId);
83             if (!optionalSubDpn.isPresent()) {
84                 LOG.warn("removeDpnFromSubnet: Cannot delete, SubnetToDpn for subnet {} DPN {} not available"
85                         + " in datastore", subnetId.getValue(), dpnId);
86                 return;
87             }
88             LOG.trace("removeDpnFromSubnet: Deleting SubnetToDpn entry for subnet {} with DPNId {}",
89                     subnetId.getValue(), dpnId);
90             SingleTransactionDataBroker.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, dpnOpId);
91         } catch (TransactionCommitFailedException ex) {
92             LOG.error("removeDpnFromSubnet: Deletion of SubnetToDpn for subnet {} with DPN {} failed",
93                     subnetId.getValue(), dpnId, ex);
94         }
95     }
96
97     public SubnetToDpn addInterfaceToDpn(Uuid subnetId, BigInteger dpnId, String intfName) {
98         SubnetToDpn subDpn = null;
99         try {
100             // Create and add SubnetOpDataEntry object for this subnet to the SubnetOpData container
101             InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier =
102                 InstanceIdentifier.builder(SubnetOpData.class).child(SubnetOpDataEntry.class,
103                     new SubnetOpDataEntryKey(subnetId)).build();
104             //Please use a synchronize block here as we donot need a cluster-wide lock
105             InstanceIdentifier<SubnetToDpn> dpnOpId =
106                 subOpIdentifier.child(SubnetToDpn.class, new SubnetToDpnKey(dpnId));
107             Optional<SubnetToDpn> optionalSubDpn = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, dpnOpId);
108             if (!optionalSubDpn.isPresent()) {
109                 // Create a new DPN Entry
110                 subDpn = addDpnToSubnet(subnetId, dpnId);
111             } else {
112                 subDpn = optionalSubDpn.get();
113             }
114             SubnetToDpnBuilder subDpnBuilder = new SubnetToDpnBuilder(subDpn);
115             List<VpnInterfaces> vpnIntfList = subDpnBuilder.getVpnInterfaces();
116             VpnInterfaces vpnIntfs =
117                 new VpnInterfacesBuilder().setKey(new VpnInterfacesKey(intfName)).setInterfaceName(intfName).build();
118             vpnIntfList.add(vpnIntfs);
119             subDpnBuilder.setVpnInterfaces(vpnIntfList);
120             subDpn = subDpnBuilder.build();
121
122             SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, dpnOpId, subDpn);
123             LOG.info("addInterfaceToDpn: Created SubnetToDpn entry for subnet {} with DPNId {} intfName {}",
124                     subnetId.getValue(), dpnId, intfName);
125         } catch (TransactionCommitFailedException ex) {
126             LOG.error("addInterfaceToDpn: Addition of Interface {} for SubnetToDpn on subnet {} with DPN {} failed",
127                     intfName, subnetId.getValue(), dpnId, ex);
128             return null;
129         }
130         return subDpn;
131     }
132
133     public void addPortOpDataEntry(String intfName, Uuid subnetId, BigInteger dpnId) {
134         try {
135             // Add to PortOpData as well.
136             PortOpDataEntryBuilder portOpBuilder = null;
137             PortOpDataEntry portOpEntry = null;
138
139             InstanceIdentifier<PortOpDataEntry> portOpIdentifier =
140                 InstanceIdentifier.builder(PortOpData.class).child(PortOpDataEntry.class,
141                     new PortOpDataEntryKey(intfName)).build();
142             Optional<PortOpDataEntry> optionalPortOp =
143                 VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, portOpIdentifier);
144             if (!optionalPortOp.isPresent()) {
145                 // Create PortOpDataEntry only if not present
146                 portOpBuilder =
147                     new PortOpDataEntryBuilder().setKey(new PortOpDataEntryKey(intfName)).setPortId(intfName);
148                 portOpBuilder.setSubnetId(subnetId);
149             } else {
150                 portOpBuilder = new PortOpDataEntryBuilder(optionalPortOp.get());
151                 portOpBuilder.setSubnetId(subnetId);
152             }
153             if (dpnId != null && !dpnId.equals(BigInteger.ZERO)) {
154                 portOpBuilder.setDpnId(dpnId);
155             }
156             portOpEntry = portOpBuilder.build();
157             SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, portOpIdentifier,
158                 portOpEntry);
159             LOG.info("addPortOpDataEntry: Created PortOpData entry for port {} with DPNId {} intfName {}",
160                     intfName, dpnId, intfName);
161         } catch (TransactionCommitFailedException ex) {
162             LOG.error("addPortOpDataEntry: Addition of Interface {} for SubnetToDpn on subnet {} with DPN {} failed",
163                     intfName, subnetId.getValue(), dpnId, ex);
164         }
165     }
166
167     public boolean removeInterfaceFromDpn(Uuid subnetId, BigInteger dpnId, String intfName) {
168         boolean dpnRemoved = false;
169         try {
170             InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier =
171                 InstanceIdentifier.builder(SubnetOpData.class).child(SubnetOpDataEntry.class,
172                     new SubnetOpDataEntryKey(subnetId)).build();
173             InstanceIdentifier<SubnetToDpn> dpnOpId =
174                 subOpIdentifier.child(SubnetToDpn.class, new SubnetToDpnKey(dpnId));
175             Optional<SubnetToDpn> optionalSubDpn = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, dpnOpId);
176             if (!optionalSubDpn.isPresent()) {
177                 LOG.debug("removeInterfaceFromDpn: Cannot delete, SubnetToDpn for intf {} subnet {} DPN {}"
178                         + " not available in datastore", intfName, subnetId.getValue(), dpnId);
179                 return false;
180             }
181
182             SubnetToDpnBuilder subDpnBuilder = new SubnetToDpnBuilder(optionalSubDpn.get());
183             List<VpnInterfaces> vpnIntfList = subDpnBuilder.getVpnInterfaces();
184             VpnInterfaces vpnIntfs =
185                 new VpnInterfacesBuilder().setKey(new VpnInterfacesKey(intfName)).setInterfaceName(intfName).build();
186             vpnIntfList.remove(vpnIntfs);
187             if (vpnIntfList.isEmpty()) {
188                 // Remove the DPN as well
189                 removeDpnFromSubnet(subnetId, dpnId);
190                 dpnRemoved = true;
191             } else {
192                 subDpnBuilder.setVpnInterfaces(vpnIntfList);
193                 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, dpnOpId,
194                     subDpnBuilder.build());
195             }
196             LOG.info("removeInterfaceFromDpn: Removed interface {} from sunbet {} dpn {}",
197                     intfName, subnetId.getValue(), dpnId);
198         } catch (TransactionCommitFailedException ex) {
199             LOG.error("removeInterfaceFromDpn: Deletion of Interface {} for SubnetToDpn on subnet {}"
200                     + " with DPN {} failed", intfName, subnetId.getValue(), dpnId, ex);
201             return false;
202         }
203         return dpnRemoved;
204     }
205
206     public PortOpDataEntry removePortOpDataEntry(String intfName) {
207         // Remove PortOpData and return out
208         InstanceIdentifier<PortOpDataEntry> portOpIdentifier =
209             InstanceIdentifier.builder(PortOpData.class).child(PortOpDataEntry.class,
210                 new PortOpDataEntryKey(intfName)).build();
211         PortOpDataEntry portOpEntry = null;
212         Optional<PortOpDataEntry> optionalPortOp =
213             VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, portOpIdentifier);
214         if (!optionalPortOp.isPresent()) {
215             LOG.info("removePortOpDataEntry: Cannot delete, portOp for port {} is not available in datastore",
216                     intfName);
217             return null;
218         } else {
219             portOpEntry = optionalPortOp.get();
220             MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, portOpIdentifier);
221             LOG.info("removePortOpDataEntry: Deleted portOpData entry for port {}", intfName);
222         }
223         return portOpEntry;
224     }
225
226     public PortOpDataEntry getPortOpDataEntry(String intfName) {
227         // Remove PortOpData and return out
228         InstanceIdentifier<PortOpDataEntry> portOpIdentifier =
229             InstanceIdentifier.builder(PortOpData.class).child(PortOpDataEntry.class,
230                 new PortOpDataEntryKey(intfName)).build();
231         Optional<PortOpDataEntry> optionalPortOp =
232             VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, portOpIdentifier);
233         if (!optionalPortOp.isPresent()) {
234             return null;
235         }
236         return optionalPortOp.get();
237     }
238
239 }