Fix build faliures due to OFPlugin checktyle fixes
[netvirt.git] / vpnservice / bgpmanager / bgpmanager-impl / src / main / java / org / opendaylight / netvirt / bgpmanager / FibDSWriter.java
1 /*
2  * Copyright (c) 2015 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.bgpmanager;
9
10 import com.google.common.base.Optional;
11 import com.google.common.base.Preconditions;
12 import java.util.Collections;
13 import java.util.List;
14 import java.util.stream.Collectors;
15 import javax.inject.Inject;
16 import javax.inject.Singleton;
17 import org.apache.commons.lang3.StringUtils;
18 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
19 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
20 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
21 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
22 import org.opendaylight.netvirt.fibmanager.api.FibHelper;
23 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
24 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.AddressFamily;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.VrfEntryBase.EncapType;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTables;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTablesKey;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.macvrfentries.MacVrfEntry;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.macvrfentries.MacVrfEntryBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.macvrfentries.MacVrfEntryKey;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntryBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntryKey;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentrybase.RoutePaths;
36 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
37 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41 @Singleton
42 public class FibDSWriter {
43     private static final Logger LOG = LoggerFactory.getLogger(FibDSWriter.class);
44     private final DataBroker dataBroker;
45     private final SingleTransactionDataBroker singleTxDB;
46     private final BgpUtil bgpUtil;
47
48     @Inject
49     public FibDSWriter(final DataBroker dataBroker, final BgpUtil bgpUtil) {
50         this.dataBroker = dataBroker;
51         this.bgpUtil = bgpUtil;
52         this.singleTxDB = new SingleTransactionDataBroker(dataBroker);
53     }
54
55     public synchronized void addFibEntryToDS(String rd, String macAddress, String prefix, List<String> nextHopList,
56                                              VrfEntry.EncapType encapType, int label, long l3vni,
57                                              String gatewayMacAddress, RouteOrigin origin) {
58         if (rd == null || rd.isEmpty()) {
59             LOG.error("Prefix {} not associated with vpn", prefix);
60             return;
61         }
62
63         Preconditions.checkNotNull(nextHopList, "NextHopList can't be null");
64         for (String nextHop : nextHopList) {
65             if (nextHop == null || nextHop.isEmpty()) {
66                 LOG.error("nextHop list contains null element");
67                 return;
68             }
69             LOG.debug("Created vrfEntry for {} nexthop {} label {}", prefix, nextHop, label);
70         }
71
72         // Looking for existing prefix in MDSAL database
73         InstanceIdentifier<VrfEntry> vrfEntryId =
74                 InstanceIdentifier.builder(FibEntries.class)
75                         .child(VrfTables.class, new VrfTablesKey(rd))
76                         .child(VrfEntry.class, new VrfEntryKey(prefix)).build();
77
78         VrfEntryBuilder vrfEntryBuilder = new VrfEntryBuilder().setDestPrefix(prefix).setOrigin(origin.getValue());
79         buildVpnEncapSpecificInfo(vrfEntryBuilder, encapType, label, l3vni, macAddress,
80                 gatewayMacAddress, nextHopList);
81         bgpUtil.update(LogicalDatastoreType.CONFIGURATION, vrfEntryId, vrfEntryBuilder.build());
82     }
83
84     public void addMacEntryToDS(String rd, String macAddress, String prefix,
85                                 List<String> nextHopList, VrfEntry.EncapType encapType,
86                                 long l2vni, String gatewayMacAddress, RouteOrigin origin) {
87         if (StringUtils.isEmpty(rd)) {
88             LOG.error("Mac {} not associated with vpn", macAddress);
89             return;
90         }
91
92         Preconditions.checkNotNull(nextHopList, "NextHopList can't be null");
93         for (String nextHop : nextHopList) {
94             if (StringUtils.isEmpty(nextHop)) {
95                 LOG.error("nextHop list contains null element for macVrf");
96                 return;
97             }
98         }
99
100         MacVrfEntryBuilder macEntryBuilder = new MacVrfEntryBuilder().setOrigin(origin.getValue());
101         buildVpnEncapSpecificInfo(macEntryBuilder, encapType, l2vni, macAddress,
102                 gatewayMacAddress, nextHopList);
103         macEntryBuilder.setMac(macAddress);
104         macEntryBuilder.setDestPrefix(prefix);
105         InstanceIdentifier<MacVrfEntry> macEntryId =
106                 InstanceIdentifier.builder(FibEntries.class)
107                         .child(VrfTables.class, new VrfTablesKey(rd))
108                         .child(MacVrfEntry.class, new MacVrfEntryKey(macAddress)).build();
109         bgpUtil.update(LogicalDatastoreType.CONFIGURATION, macEntryId, macEntryBuilder.build());
110     }
111
112     private static void buildVpnEncapSpecificInfo(VrfEntryBuilder builder,
113             VrfEntry.EncapType encapType, long label, long l3vni, String macAddress,
114             String gatewayMac, List<String> nextHopList) {
115         if (!encapType.equals(VrfEntry.EncapType.Mplsgre)) {
116             builder.setL3vni(l3vni);
117         }
118         builder.setEncapType(encapType);
119         builder.setGatewayMacAddress(gatewayMac);
120         Long lbl = encapType.equals(VrfEntry.EncapType.Mplsgre) ? label : null;
121         List<RoutePaths> routePaths = nextHopList.stream()
122                         .filter(StringUtils::isNotEmpty)
123                         .map(nextHop -> FibHelper.buildRoutePath(nextHop, lbl)).collect(Collectors.toList());
124         builder.setRoutePaths(routePaths);
125     }
126
127     private static void buildVpnEncapSpecificInfo(MacVrfEntryBuilder builder,
128                                                   VrfEntry.EncapType encapType, long l2vni, String macAddress,
129                                                   String gatewayMac, List<String> nextHopList) {
130         builder.setEncapType(encapType);
131         builder.setGatewayMacAddress(gatewayMac);
132         builder.setL2vni(l2vni);
133         List<RoutePaths> routePaths = nextHopList.stream()
134                 .filter(StringUtils::isNotEmpty)
135                 .map(nextHop -> FibHelper.buildRoutePath(nextHop, null)).collect(Collectors.toList());
136         builder.setRoutePaths(routePaths);
137     }
138
139     public synchronized void removeFibEntryFromDS(String rd, String prefix) {
140
141         if (rd == null || rd.isEmpty()) {
142             LOG.error("Prefix {} not associated with vpn", prefix);
143             return;
144         }
145         LOG.debug("Removing fib entry with destination prefix {} from vrf table for rd {}", prefix, rd);
146
147         InstanceIdentifierBuilder<VrfEntry> idBuilder =
148                 InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)).child(
149                         VrfEntry.class, new VrfEntryKey(prefix));
150         InstanceIdentifier<VrfEntry> vrfEntryId = idBuilder.build();
151         bgpUtil.delete(LogicalDatastoreType.CONFIGURATION, vrfEntryId);
152
153     }
154
155     public void removeMacEntryFromDS(String rd, String macAddress) {
156
157         if (StringUtils.isEmpty(rd)) {
158             LOG.error("Mac {} not associated with vpn", macAddress);
159             return;
160         }
161         LOG.debug("Removing Mac fib entry with Mac {} from vrf table for rd {}", macAddress, rd);
162
163         InstanceIdentifierBuilder<MacVrfEntry> idBuilder =
164                 InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)).child(
165                         MacVrfEntry.class, new MacVrfEntryKey(macAddress));
166         InstanceIdentifier<MacVrfEntry> macEntryId = idBuilder.build();
167         bgpUtil.delete(LogicalDatastoreType.CONFIGURATION, macEntryId);
168
169     }
170
171     public synchronized void removeOrUpdateFibEntryFromDS(String rd, String prefix, String nextHop) {
172
173         if (rd == null || rd.isEmpty()) {
174             LOG.error("Prefix {} not associated with vpn", prefix);
175             return;
176         }
177         LOG.debug("Removing fib entry with destination prefix {} from vrf table for rd {} and nextHop {}",
178                 prefix, rd, nextHop);
179         try {
180             InstanceIdentifier<VrfEntry> vrfEntryId =
181                     InstanceIdentifier.builder(FibEntries.class)
182                     .child(VrfTables.class, new VrfTablesKey(rd))
183                     .child(VrfEntry.class, new VrfEntryKey(prefix)).build();
184             Optional<VrfEntry> existingVrfEntry =
185                     singleTxDB.syncReadOptional(LogicalDatastoreType.CONFIGURATION, vrfEntryId);
186             List<RoutePaths> routePaths =
187                     existingVrfEntry.toJavaUtil().map(VrfEntry::getRoutePaths).orElse(Collections.emptyList());
188             if (routePaths.size() == 1) {
189                 if (routePaths.get(0).getNexthopAddress().equals(nextHop)) {
190                     bgpUtil.delete(LogicalDatastoreType.CONFIGURATION, vrfEntryId);
191                 }
192             } else {
193                 routePaths.stream()
194                     .map(RoutePaths::getNexthopAddress)
195                     .filter(nextHopAddress -> nextHopAddress.equals(nextHop))
196                     .findFirst()
197                     .ifPresent(nh -> {
198                         InstanceIdentifier<RoutePaths> routePathId =
199                                 FibHelper.buildRoutePathId(rd, prefix, nextHop);
200                         bgpUtil.delete(LogicalDatastoreType.CONFIGURATION, routePathId);
201                     });
202             }
203         } catch (ReadFailedException e) {
204             LOG.error("Error while reading vrfEntry for rd {}, prefix {}", rd, prefix);
205             return;
206         }
207     }
208
209
210     public synchronized void removeVrfSubFamilyFromDS(String rd, AddressFamily addressFamily) {
211
212         if (rd == null) {
213             return;
214         }
215         LOG.debug("removeVrfSubFamilyFromDS : addressFamily {} from vrf rd {}",
216                   addressFamily, rd);
217
218         InstanceIdentifier<VrfTables> id = InstanceIdentifier.create(FibEntries.class)
219             .child(VrfTables.class, new VrfTablesKey(rd));
220         try {
221             VrfTables vrfTable = singleTxDB.syncRead(LogicalDatastoreType.CONFIGURATION, id);
222             if (vrfTable != null) {
223                 List<VrfEntry> vrfEntries = vrfTable.getVrfEntry();
224                 if (vrfEntries == null) {
225                     String errMsg = "removeVrfSubFamilyFromDS : VrfEntry not found for rd " + rd;
226                     LOG.error(errMsg);
227                     return;
228                 }
229                 for (VrfEntry vrfEntry : vrfEntries) {
230                     boolean found = false;
231                     if (vrfEntry.getEncapType() != null) {
232                         if (!vrfEntry.getEncapType().equals(EncapType.Mplsgre)
233                              && addressFamily == AddressFamily.L2VPN) {
234                             found = true;
235                         } else if (vrfEntry.getEncapType().equals(EncapType.Mplsgre)) {
236                             if (addressFamily == AddressFamily.IPV4
237                                 && FibHelper.isIpv4Prefix(vrfEntry.getDestPrefix())) {
238                                 found = true;
239                             } else if (addressFamily == AddressFamily.IPV6
240                                        && FibHelper.isIpv6Prefix(vrfEntry.getDestPrefix())) {
241                                 found = true;
242                             }
243                         }
244                     }
245                     if (found == false) {
246                         continue;
247                     }
248                     bgpUtil.removeVrfEntry(rd, vrfEntry);
249                 }
250             }
251         } catch (ReadFailedException rfe) {
252             String errMsg = "removeVrfSubFamilyFromDS : Internal Error rd " + rd;
253             LOG.error(errMsg, rfe);
254         }
255         return;
256     }
257
258     public synchronized void removeVrfFromDS(String rd) {
259         LOG.debug("Removing vrf table for  rd {}", rd);
260
261         InstanceIdentifierBuilder<VrfTables> idBuilder =
262                 InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd));
263         InstanceIdentifier<VrfTables> vrfTableId = idBuilder.build();
264
265         bgpUtil.delete(LogicalDatastoreType.CONFIGURATION, vrfTableId);
266
267     }
268 }