2 * Copyright (c) 2015 - 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
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
8 package org.opendaylight.netvirt.vpnmanager;
10 import java.util.ArrayList;
11 import java.util.List;
12 import java.util.stream.Collectors;
13 import javax.annotation.PostConstruct;
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.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
19 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
20 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
21 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTables;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTablesKey;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentrybase.RoutePaths;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryBuilder;
29 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
34 public class FibEntriesListener extends AsyncDataTreeChangeListenerBase<VrfEntry, FibEntriesListener> {
35 private static final Logger LOG = LoggerFactory.getLogger(FibEntriesListener.class);
36 private final DataBroker dataBroker;
37 private final ManagedNewTransactionRunner txRunner;
38 private final VpnInstanceListener vpnInstanceListener;
41 public FibEntriesListener(final DataBroker dataBroker, final VpnInstanceListener vpnInstanceListener) {
42 super(VrfEntry.class, FibEntriesListener.class);
43 this.dataBroker = dataBroker;
44 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
45 this.vpnInstanceListener = vpnInstanceListener;
50 LOG.info("{} start", getClass().getSimpleName());
51 registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
55 protected InstanceIdentifier<VrfEntry> getWildCardPath() {
56 return InstanceIdentifier.create(FibEntries.class).child(VrfTables.class).child(VrfEntry.class);
60 protected FibEntriesListener getDataTreeChangeListener() {
61 return FibEntriesListener.this;
66 protected void remove(InstanceIdentifier<VrfEntry> identifier,
68 LOG.trace("Remove Fib event - Key : {}, value : {} ", identifier, del);
69 final VrfTablesKey key = identifier.firstKeyOf(VrfTables.class, VrfTablesKey.class);
70 String rd = key.getRouteDistinguisher();
71 List<RoutePaths> routePaths = del.getRoutePaths();
72 removeLabelFromVpnInstance(rd, routePaths);
76 protected void update(InstanceIdentifier<VrfEntry> identifier,
77 VrfEntry original, VrfEntry update) {
78 final VrfTablesKey key = identifier.firstKeyOf(VrfTables.class, VrfTablesKey.class);
79 String rd = key.getRouteDistinguisher();
80 List<RoutePaths> originalRoutePaths = new ArrayList<>(original.getRoutePaths());
81 List<RoutePaths> updateRoutePaths = new ArrayList<>(update.getRoutePaths());
82 if (originalRoutePaths.size() < updateRoutePaths.size()) {
83 updateRoutePaths.removeAll(originalRoutePaths);
84 addLabelToVpnInstance(rd, updateRoutePaths);
85 } else if (originalRoutePaths.size() > updateRoutePaths.size()) {
86 originalRoutePaths.removeAll(updateRoutePaths);
87 removeLabelFromVpnInstance(rd, originalRoutePaths);
92 protected void add(InstanceIdentifier<VrfEntry> identifier,
94 LOG.trace("Add Vrf Entry event - Key : {}, value : {}", identifier, add);
95 final VrfTablesKey key = identifier.firstKeyOf(VrfTables.class, VrfTablesKey.class);
96 String rd = key.getRouteDistinguisher();
97 addLabelToVpnInstance(rd, add.getRoutePaths());
100 private void addLabelToVpnInstance(String rd, List<RoutePaths> routePaths) {
101 List<Long> labels = routePaths.stream().map(RoutePaths::getLabel).distinct()
102 .collect(Collectors.toList());
103 VpnInstanceOpDataEntry vpnInstanceOpData = vpnInstanceListener.getVpnInstanceOpData(rd);
104 if (vpnInstanceOpData != null) {
105 List<Long> routeIds = vpnInstanceOpData.getRouteEntryId() == null ? new ArrayList<>()
106 : vpnInstanceOpData.getRouteEntryId();
107 labels.forEach(label -> {
108 LOG.debug("Adding label to vpn info - {}", label);
109 if (!routeIds.contains(label)) {
113 ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx ->
114 tx.put(LogicalDatastoreType.OPERATIONAL,
115 VpnUtil.getVpnInstanceOpDataIdentifier(rd),
116 new VpnInstanceOpDataEntryBuilder(vpnInstanceOpData).setRouteEntryId(routeIds)
118 LOG, "Error adding label to VPN instance");
120 LOG.warn("No VPN Instance found for RD: {}", rd);
124 private void removeLabelFromVpnInstance(String rd, List<RoutePaths> routePaths) {
125 List<Long> labels = routePaths.stream().map(RoutePaths::getLabel).distinct()
126 .collect(Collectors.toList());
127 VpnInstanceOpDataEntry vpnInstanceOpData = vpnInstanceListener.getVpnInstanceOpData(rd);
128 if (vpnInstanceOpData != null) {
129 List<Long> routeIds = vpnInstanceOpData.getRouteEntryId();
130 if (routeIds == null) {
131 LOG.debug("Fib Route entry is empty.");
133 LOG.debug("Removing label from vpn info - {}", labels);
134 routeIds.removeAll(labels);
135 ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx ->
136 tx.put(LogicalDatastoreType.OPERATIONAL,
137 VpnUtil.getVpnInstanceOpDataIdentifier(rd),
138 new VpnInstanceOpDataEntryBuilder(vpnInstanceOpData).setRouteEntryId(routeIds)
140 LOG, "Error removing label from VPN instance");
143 LOG.warn("No VPN Instance found for RD: {}", rd);