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.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTables;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTablesKey;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentrybase.RoutePaths;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryBuilder;
26 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
31 public class FibEntriesListener extends AsyncDataTreeChangeListenerBase<VrfEntry, FibEntriesListener> {
32 private static final Logger LOG = LoggerFactory.getLogger(FibEntriesListener.class);
33 private final DataBroker dataBroker;
34 private final VpnInstanceListener vpnInstanceListener;
37 public FibEntriesListener(final DataBroker dataBroker, final VpnInstanceListener vpnInstanceListener) {
38 super(VrfEntry.class, FibEntriesListener.class);
39 this.dataBroker = dataBroker;
40 this.vpnInstanceListener = vpnInstanceListener;
45 LOG.info("{} start", getClass().getSimpleName());
46 registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
50 protected InstanceIdentifier<VrfEntry> getWildCardPath() {
51 return InstanceIdentifier.create(FibEntries.class).child(VrfTables.class).child(VrfEntry.class);
55 protected FibEntriesListener getDataTreeChangeListener() {
56 return FibEntriesListener.this;
61 protected void remove(InstanceIdentifier<VrfEntry> identifier,
63 LOG.trace("Remove Fib event - Key : {}, value : {} ", identifier, del);
64 final VrfTablesKey key = identifier.firstKeyOf(VrfTables.class, VrfTablesKey.class);
65 String rd = key.getRouteDistinguisher();
66 List<RoutePaths> routePaths = del.getRoutePaths();
67 removeLabelFromVpnInstance(rd, routePaths);
71 protected void update(InstanceIdentifier<VrfEntry> identifier,
72 VrfEntry original, VrfEntry update) {
73 final VrfTablesKey key = identifier.firstKeyOf(VrfTables.class, VrfTablesKey.class);
74 String rd = key.getRouteDistinguisher();
75 List<RoutePaths> originalRoutePaths = new ArrayList<>(original.getRoutePaths());
76 List<RoutePaths> updateRoutePaths = new ArrayList<>(update.getRoutePaths());
77 if (originalRoutePaths.size() < updateRoutePaths.size()) {
78 updateRoutePaths.removeAll(originalRoutePaths);
79 addLabelToVpnInstance(rd, updateRoutePaths);
80 } else if (originalRoutePaths.size() > updateRoutePaths.size()) {
81 originalRoutePaths.removeAll(updateRoutePaths);
82 removeLabelFromVpnInstance(rd, originalRoutePaths);
87 protected void add(InstanceIdentifier<VrfEntry> identifier,
89 LOG.trace("Add Vrf Entry event - Key : {}, value : {}", identifier, add);
90 final VrfTablesKey key = identifier.firstKeyOf(VrfTables.class, VrfTablesKey.class);
91 String rd = key.getRouteDistinguisher();
92 addLabelToVpnInstance(rd, add.getRoutePaths());
95 private void addLabelToVpnInstance(String rd, List<RoutePaths> routePaths) {
96 List<Long> labels = routePaths.stream().map(RoutePaths::getLabel).distinct()
97 .collect(Collectors.toList());
98 VpnInstanceOpDataEntry vpnInstanceOpData = vpnInstanceListener.getVpnInstanceOpData(rd);
99 if (vpnInstanceOpData != null) {
100 List<Long> routeIds = vpnInstanceOpData.getRouteEntryId() == null ? new ArrayList<>()
101 : vpnInstanceOpData.getRouteEntryId();
102 labels.forEach(label -> {
103 LOG.debug("Adding label to vpn info - {}", label);
104 if (!routeIds.contains(label)) {
108 TransactionUtil.asyncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
109 VpnUtil.getVpnInstanceOpDataIdentifier(rd),
110 new VpnInstanceOpDataEntryBuilder(vpnInstanceOpData).setRouteEntryId(routeIds).build(),
111 TransactionUtil.DEFAULT_CALLBACK);
113 LOG.warn("No VPN Instance found for RD: {}", rd);
117 private void removeLabelFromVpnInstance(String rd, List<RoutePaths> routePaths) {
118 List<Long> labels = routePaths.stream().map(RoutePaths::getLabel).distinct()
119 .collect(Collectors.toList());
120 VpnInstanceOpDataEntry vpnInstanceOpData = vpnInstanceListener.getVpnInstanceOpData(rd);
121 if (vpnInstanceOpData != null) {
122 List<Long> routeIds = vpnInstanceOpData.getRouteEntryId();
123 if (routeIds == null) {
124 LOG.debug("Fib Route entry is empty.");
126 LOG.debug("Removing label from vpn info - {}", labels);
127 routeIds.removeAll(labels);
128 TransactionUtil.asyncWrite(
130 LogicalDatastoreType.OPERATIONAL,
131 VpnUtil.getVpnInstanceOpDataIdentifier(rd),
132 new VpnInstanceOpDataEntryBuilder(vpnInstanceOpData).setRouteEntryId(
133 routeIds).build(), TransactionUtil.DEFAULT_CALLBACK);
136 LOG.warn("No VPN Instance found for RD: {}", rd);