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