Bug-4827: BGP Add-Path OpenConfig Support II
[bgpcep.git] / bgp / openconfig-impl / src / main / java / org / opendaylight / protocol / bgp / openconfig / impl / util / OpenConfigUtil.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. 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
9 package org.opendaylight.protocol.bgp.openconfig.impl.util;
10
11 import com.google.common.base.Optional;
12 import com.google.common.collect.BiMap;
13 import com.google.common.collect.ImmutableBiMap;
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.function.BiFunction;
19 import org.opendaylight.protocol.bgp.mode.api.PathSelectionMode;
20 import org.opendaylight.protocol.bgp.mode.impl.add.n.paths.AddPathBestNPathSelection;
21 import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
22 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafi;
23 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafiBuilder;
24 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.use.multiple.paths.UseMultiplePathsBuilder;
25 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.use.multiple.paths.use.multiple.paths.ConfigBuilder;
26 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.use.multiple.paths.use.multiple.paths.EbgpBuilder;
27 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.use.multiple.paths.use.multiple.paths.IbgpBuilder;
28 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.AfiSafi1;
29 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.AfiSafi1Builder;
30 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.AfiSafi2;
31 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.AfiSafi2Builder;
32 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.Bgp;
33 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.AfiSafiType;
34 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.IPV4LABELLEDUNICAST;
35 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.IPV4UNICAST;
36 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.IPV6LABELLEDUNICAST;
37 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.IPV6UNICAST;
38 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.L2VPNEVPN;
39 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.L3VPNIPV4UNICAST;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.EvpnSubsequentAddressFamily;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.L2vpnAddressFamily;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.FlowspecSubsequentAddressFamily;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.LabeledUnicastSubsequentAddressFamily;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.LinkstateAddressFamily;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.LinkstateSubsequentAddressFamily;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.mp.capabilities.add.path.capability.AddressFamilies;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev150930.Ipv4Flow;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev150930.Ipv6Flow;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev150930.Linkstate;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv6AddressFamily;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.MplsLabeledVpnSubsequentAddressFamily;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily;
56 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
57
58 public final class OpenConfigUtil {
59
60     private static final char EQUALS = '=';
61
62     public static final InstanceIdentifier<Bgp> BGP_IID = InstanceIdentifier.create(Bgp.class);
63
64     public static final String APPLICATION_PEER_GROUP_NAME = "application-peers";
65
66     public static final String FAILED_TO_READ_SERVICE = "Failed to read service.";
67
68     private static final BiMap<BgpTableType, Class<? extends AfiSafiType>> TABLETYPE_TO_AFISAFI;
69
70     static {
71         final ImmutableBiMap.Builder<BgpTableType, Class<? extends AfiSafiType>> b = ImmutableBiMap.builder();
72         b.put(new BgpTableTypeImpl(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class), IPV4UNICAST.class);
73         b.put(new BgpTableTypeImpl(Ipv6AddressFamily.class, UnicastSubsequentAddressFamily.class), IPV6UNICAST.class);
74         b.put(new BgpTableTypeImpl(Ipv4AddressFamily.class, LabeledUnicastSubsequentAddressFamily.class), IPV4LABELLEDUNICAST.class);
75         b.put(new BgpTableTypeImpl(Ipv6AddressFamily.class, LabeledUnicastSubsequentAddressFamily.class), IPV6LABELLEDUNICAST.class);
76         b.put(new BgpTableTypeImpl(Ipv4AddressFamily.class, MplsLabeledVpnSubsequentAddressFamily.class), L3VPNIPV4UNICAST.class);
77         b.put(new BgpTableTypeImpl(LinkstateAddressFamily.class, LinkstateSubsequentAddressFamily.class), Linkstate.class);
78         b.put(new BgpTableTypeImpl(Ipv4AddressFamily.class, FlowspecSubsequentAddressFamily.class), Ipv4Flow.class);
79         b.put(new BgpTableTypeImpl(Ipv6AddressFamily.class, FlowspecSubsequentAddressFamily.class), Ipv6Flow.class);
80         b.put(new BgpTableTypeImpl(L2vpnAddressFamily.class, EvpnSubsequentAddressFamily.class), L2VPNEVPN.class);
81         TABLETYPE_TO_AFISAFI = b.build();
82     }
83
84     private OpenConfigUtil() {
85         throw new UnsupportedOperationException();
86     }
87
88     public static Optional<AfiSafi> toAfiSafi(final BgpTableType tableType) {
89         final Class<? extends AfiSafiType> afiSafi = TABLETYPE_TO_AFISAFI.get(tableType);
90         if (afiSafi != null) {
91             return Optional.of(new AfiSafiBuilder().setAfiSafiName(afiSafi).build());
92         }
93         return Optional.absent();
94     }
95
96     public static Optional<BgpTableType> toBgpTableType(final Class<? extends AfiSafiType> afiSafi) {
97         return Optional.fromNullable(TABLETYPE_TO_AFISAFI.inverse().get(afiSafi));
98     }
99
100     public static List<AfiSafi> toAfiSafis(final List<BgpTableType> advertizedTables, final BiFunction<AfiSafi, BgpTableType, AfiSafi> function) {
101         final List<AfiSafi> afiSafis = new ArrayList<>(advertizedTables.size());
102         for (final BgpTableType tableType : advertizedTables) {
103             final Optional<AfiSafi> afiSafiMaybe = toAfiSafi(new BgpTableTypeImpl(tableType.getAfi(), tableType.getSafi()));
104             if (afiSafiMaybe.isPresent()) {
105                 final AfiSafi afiSafi = function.apply(afiSafiMaybe.get(), tableType);
106                 afiSafis.add(afiSafi);
107             }
108         }
109         return afiSafis;
110     }
111
112     public static String getModuleName(final String provider) {
113         return provider.substring(provider.lastIndexOf(EQUALS) + 2, provider.length() - 2);
114     }
115
116     public static String getModuleType(final String provider) {
117         return provider.substring(provider.indexOf(EQUALS) + 2, provider.indexOf("']"));
118     }
119
120     public static AfiSafi toNeigborAfiSafiMultiPath(final AfiSafi afiSafi, final BgpTableType tableType, final Collection<AddressFamilies> addPathCapabilities) {
121         final java.util.Optional<AddressFamilies> addPathMayBe = addPathCapabilities.stream().filter(
122                 af -> af.getAfi() == tableType.getAfi() && af.getSafi() == tableType.getSafi()).findFirst();
123         if (addPathMayBe.isPresent()) {
124             final AfiSafi2 afiSafi3 = new AfiSafi2Builder().setUseMultiplePaths(
125                     new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.use.multiple.paths.neighbor.UseMultiplePathsBuilder().setConfig(
126                     new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.use.multiple.paths.neighbor.use.multiple.paths.ConfigBuilder()
127                         .setEnabled(true).build()).build()).build();
128             return new AfiSafiBuilder(afiSafi).addAugmentation(AfiSafi2.class, afiSafi3).build();
129         }
130         return afiSafi;
131     }
132
133     public static AfiSafi toGlobalAfiSafiMultiPath(final AfiSafi afiSafi, final BgpTableType tableType, final Map<TablesKey, PathSelectionMode> pathSelectionModes) {
134         final PathSelectionMode pathSelection = pathSelectionModes.get(new TablesKey(tableType.getAfi(), tableType.getSafi()));
135         if (pathSelection == null) {
136             return afiSafi;
137         }
138         final Long maxPaths;
139         if (pathSelection instanceof AddPathBestNPathSelection) {
140             maxPaths = ((AddPathBestNPathSelection) pathSelection).getNBestPaths();
141         } else {
142             maxPaths = null;
143         }
144         final AfiSafi1 afiSafi1 = new AfiSafi1Builder().setUseMultiplePaths(
145                 new UseMultiplePathsBuilder().setConfig(new ConfigBuilder().setEnabled(true).build())
146                     .setEbgp(maxPaths != null ? new EbgpBuilder().setConfig(
147                             new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.use.multiple.paths.use.multiple.paths.ebgp.ConfigBuilder()
148                                 .setMaximumPaths(maxPaths)
149                                 .build()).build() : null)
150                     .setIbgp(maxPaths != null ? new IbgpBuilder().setConfig(
151                         new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.use.multiple.paths.use.multiple.paths.ibgp.ConfigBuilder()
152                             .setMaximumPaths(maxPaths).build()).build() : null).build()).build();
153         return new AfiSafiBuilder(afiSafi).addAugmentation(AfiSafi1.class, afiSafi1).build();
154     }
155 }