Convert itm-impl to use mdsal-binding-util
[genius.git] / itm / itm-impl / src / main / java / org / opendaylight / genius / itm / confighelpers / OvsdbTepRemoveConfigHelper.java
1 /*
2  * Copyright (c) 2016, 2017 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.genius.itm.confighelpers;
9
10 import com.google.common.util.concurrent.ListenableFuture;
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.Map;
14 import java.util.Objects;
15 import org.eclipse.jdt.annotation.Nullable;
16 import org.opendaylight.genius.itm.globals.ITMConstants;
17 import org.opendaylight.genius.itm.impl.ItmUtils;
18 import org.opendaylight.genius.mdsalutil.MDSALUtil;
19 import org.opendaylight.mdsal.binding.api.DataBroker;
20 import org.opendaylight.mdsal.binding.util.Datastore;
21 import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunner;
22 import org.opendaylight.mdsal.binding.util.TypedWriteTransaction;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.NotHostedTransportZones;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.not.hosted.transport.zones.TepsInNotHostedTransportZone;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.not.hosted.transport.zones.TepsInNotHostedTransportZoneKey;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.not.hosted.transport.zones.tepsinnothostedtransportzone.UnknownVteps;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.not.hosted.transport.zones.tepsinnothostedtransportzone.UnknownVtepsKey;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneKey;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Vteps;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.VtepsKey;
35 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
36 import org.opendaylight.yangtools.yang.common.Uint64;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 public final class OvsdbTepRemoveConfigHelper {
41
42     private static final Logger LOG = LoggerFactory.getLogger(OvsdbTepRemoveConfigHelper.class);
43
44     private OvsdbTepRemoveConfigHelper() {
45
46     }
47
48     /**
49      * Removes the TEP from ITM configuration/operational Datastore in one of the following cases.
50      * 1) default transport zone
51      * 2) Configured transport zone
52      * 3) Unhosted transport zone
53      * Function checks for above three cases and calls other sub-function to remove the TEP
54      *
55      * @param tepIp TEP-IP address in string
56      * @param strDpnId bridge datapath ID in string
57      * @param tzName transport zone name in string
58      * @param dataBroker data broker handle to perform operations on config/operational datastore
59      * @param txRunner ManagedNewTransactionRunner object
60      */
61     public static List<? extends ListenableFuture<?>> removeTepReceivedFromOvsdb(String tepIp, String strDpnId,
62                                                                                  String tzName, DataBroker dataBroker,
63                                                                                  ManagedNewTransactionRunner txRunner) {
64         List<ListenableFuture<?>> futures = new ArrayList<>();
65         Uint64 dpnId = Uint64.ZERO;
66         LOG.trace("Remove TEP: TEP-IP: {}, TZ name: {}, DPID: {}", tepIp, tzName, strDpnId);
67
68         if (strDpnId != null && !strDpnId.isEmpty()) {
69             dpnId = MDSALUtil.getDpnId(strDpnId);
70         }
71         // Get tep IP
72         IpAddress tepIpAddress = IpAddressBuilder.getDefaultInstance(tepIp);
73         TransportZone transportZone;
74
75         // Case: TZ name is not given from OVS's other_config parameters.
76         if (tzName == null) {
77             tzName = ITMConstants.DEFAULT_TRANSPORT_ZONE;
78             // add TEP into default-TZ
79             transportZone = ItmUtils.getTransportZoneFromConfigDS(tzName, dataBroker);
80             if (transportZone == null) {
81                 LOG.error("Error: default-transport-zone is not yet created.");
82                 return futures;
83             }
84             LOG.trace("Remove TEP from default-transport-zone.");
85         } else {
86             // Case: Add TEP into corresponding TZ created from Northbound.
87             transportZone = ItmUtils.getTransportZoneFromConfigDS(tzName, dataBroker);
88             String name = tzName;
89             Uint64 id = dpnId;
90             if (transportZone == null) {
91                 // Case: TZ is not configured from Northbound, then add TEP into
92                 // "teps-in-not-hosted-transport-zone"
93                 LOG.trace("Removing TEP from teps-in-not-hosted-transport-zone list.");
94                 futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(Datastore.OPERATIONAL,
95                     tx -> removeUnknownTzTepFromTepsNotHosted(name, tepIpAddress, id, dataBroker, tx)));
96                 return futures;
97             } else {
98                 LOG.trace("Remove TEP from transport-zone already configured by Northbound.");
99             }
100         }
101
102         // Remove TEP from (default transport-zone) OR (transport-zone already configured by Northbound)
103
104         @Nullable Map<VtepsKey, Vteps> vtepList = transportZone.getVteps();
105         if (vtepList == null || vtepList.isEmpty()) {
106             //  case: vtep list does not exist or it has no elements
107             LOG.trace("No vtep list in subnet list of transport-zone. Nothing to do.");
108         } else {
109             //  case: vtep list has elements
110             boolean vtepFound = false;
111             Vteps oldVtep = null;
112
113             for (Vteps vtep : vtepList.values()) {
114                 if (Objects.equals(vtep.getDpnId(), dpnId)) {
115                     vtepFound = true;
116                     oldVtep = vtep;
117                     break;
118                 }
119             }
120             if (vtepFound) {
121                 // vtep is found, update it with tep-ip
122                 LOG.trace("Remove TEP from vtep list in subnet list of transport-zone.");
123                 dpnId = oldVtep.getDpnId();
124                 String name = tzName;
125                 Uint64 id = dpnId;
126                 futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(Datastore.CONFIGURATION,
127                     tx -> removeVtepFromTZConfig(name, id, tx)));
128             } else {
129                 LOG.trace(
130                         "TEP is not found in the vtep list in subnet list of transport-zone. Nothing to do.");
131             }
132         }
133         return futures;
134     }
135
136     /**
137      * Removes the TEP from subnet list in the transport zone list
138      * from ITM configuration Datastore by delete operation with write transaction.
139      *
140      * @param dpnId bridge datapath ID
141      * @param tzName transport zone name in string
142      * @param tx TypedWriteTransaction object
143      */
144     private static void removeVtepFromTZConfig(String tzName, Uint64 dpnId,
145                                                TypedWriteTransaction<Datastore.Configuration> tx) {
146
147         VtepsKey vtepkey = new VtepsKey(dpnId);
148
149         InstanceIdentifier<Vteps> vtepPath = InstanceIdentifier.builder(TransportZones.class)
150                 .child(TransportZone.class, new TransportZoneKey(tzName))
151                 .child(Vteps.class, vtepkey).build();
152
153         LOG.trace("Removing TEP from (TZ: {} DPN-ID: {}) inside ITM Config DS.",
154                 tzName, dpnId);
155         // remove vtep
156         tx.delete(vtepPath);
157     }
158
159     /**
160      * Removes the TEP from the not-hosted transport zone in the TepsNotHosted list
161      * from ITM Operational Datastore.
162      *
163      * @param tzName transport zone name in string
164      * @param tepIpAddress TEP IP address in IpAddress object
165      * @param dpnId bridge datapath ID
166      * @param dataBroker data broker handle to perform operations on operational datastore
167      * @param tx TypedWriteTransaction object
168      */
169     public static void removeUnknownTzTepFromTepsNotHosted(String tzName, IpAddress tepIpAddress,
170                                                            Uint64 dpnId, DataBroker dataBroker,
171                                                            TypedWriteTransaction<Datastore.Operational> tx) {
172         Map<UnknownVtepsKey, UnknownVteps> vtepList;
173         TepsInNotHostedTransportZone tepsInNotHostedTransportZone =
174                 ItmUtils.getUnknownTransportZoneFromITMOperDS(tzName, dataBroker);
175         if (tepsInNotHostedTransportZone == null) {
176             LOG.trace("Unhosted TransportZone ({}) does not exist in OperDS. Nothing to do for TEP removal.", tzName);
177             return;
178         } else {
179             vtepList = tepsInNotHostedTransportZone.getUnknownVteps();
180             if (vtepList == null || vtepList.isEmpty()) {
181                 //  case: vtep list does not exist or it has no elements
182                 LOG.trace("Remove TEP from unhosted TZ ({}) when no vtep-list in the TZ. Nothing to do.", tzName);
183             } else {
184                 //  case: vtep list has elements
185                 boolean vtepFound = false;
186
187                 for (UnknownVteps vtep : vtepList.values()) {
188                     if (Objects.equals(vtep.getDpnId(), dpnId)) {
189                         vtepFound = true;
190                         break;
191                     }
192                 }
193                 if (vtepFound) {
194                     // vtep is found, update it with tep-ip
195                     LOG.trace(
196                             "Remove TEP with IP ({}) from unhosted TZ ({}) inside not-hosted-transport-zones list.",
197                             tepIpAddress, tzName);
198                     if (vtepList.size() == 1) {
199                         removeTzFromTepsNotHosted(tzName, tx);
200                     } else {
201                         removeVtepFromTepsNotHosted(tzName, dpnId, tx);
202                     }
203                 }
204             }
205         }
206     }
207
208     /**
209      * Removes the TEP from unknown vtep list under the transport zone in the TepsNotHosted list
210      * from ITM operational Datastore by delete operation with write transaction.
211      *
212      * @param tzName transport zone name in string
213      * @param dpnId bridge datapath ID
214      * @param tx TypedWriteTransaction object
215      */
216     private static void removeVtepFromTepsNotHosted(String tzName, Uint64 dpnId,
217                                                     TypedWriteTransaction<Datastore.Operational> tx) {
218         InstanceIdentifier<UnknownVteps> vtepPath = InstanceIdentifier.builder(NotHostedTransportZones.class)
219                 .child(TepsInNotHostedTransportZone.class, new TepsInNotHostedTransportZoneKey(tzName))
220                 .child(UnknownVteps.class, new UnknownVtepsKey(dpnId)).build();
221         LOG.trace("Removing TEP from unhosted (TZ: {}, DPID: {}) inside ITM Oper DS.", tzName, dpnId);
222         tx.delete(vtepPath);
223     }
224
225     /**
226      * Removes the transport zone in the TepsNotHosted list
227      * from ITM operational Datastore by delete operation with write transaction.
228      *
229      * @param tzName transport zone name in string
230      * @param tx TypedWriteTransaction object
231      */
232     private static void removeTzFromTepsNotHosted(String tzName, TypedWriteTransaction<Datastore.Operational> tx) {
233         InstanceIdentifier<TepsInNotHostedTransportZone> tepsInNotHostedTransportZoneIid =
234                 InstanceIdentifier.builder(NotHostedTransportZones.class).child(TepsInNotHostedTransportZone.class,
235                         new TepsInNotHostedTransportZoneKey(tzName)).build();
236         LOG.trace("Removing TZ ({})from not-hosted-transport-zones list inside ITM Oper DS.", tzName);
237         tx.delete(tepsInNotHostedTransportZoneIid);
238     }
239 }