Bump upstreams
[bgpcep.git] / bgp / rib-impl / src / main / java / org / opendaylight / protocol / bgp / rib / impl / config / RibImpl.java
1 /*
2  * Copyright (c) 2016 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 package org.opendaylight.protocol.bgp.rib.impl.config;
9
10 import static com.google.common.base.Preconditions.checkState;
11 import static java.util.Objects.requireNonNull;
12 import static org.opendaylight.protocol.bgp.rib.impl.config.OpenConfigMappingUtil.getAfiSafiWithDefault;
13 import static org.opendaylight.protocol.bgp.rib.impl.config.OpenConfigMappingUtil.getGlobalClusterIdentifier;
14 import static org.opendaylight.protocol.bgp.rib.impl.config.OpenConfigMappingUtil.toTableTypes;
15
16 import com.google.common.util.concurrent.FluentFuture;
17 import com.google.common.util.concurrent.Futures;
18 import com.google.common.util.concurrent.ListenableFuture;
19 import java.util.Collection;
20 import java.util.Map;
21 import java.util.Set;
22 import java.util.stream.Collectors;
23 import org.checkerframework.checker.lock.qual.GuardedBy;
24 import org.opendaylight.mdsal.common.api.CommitInfo;
25 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
26 import org.opendaylight.mdsal.dom.api.DOMDataBroker.DataTreeChangeExtension;
27 import org.opendaylight.mdsal.dom.api.DOMTransactionChain;
28 import org.opendaylight.protocol.bgp.mode.api.PathSelectionMode;
29 import org.opendaylight.protocol.bgp.openconfig.routing.policy.spi.BGPRibRoutingPolicyFactory;
30 import org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryConsumer;
31 import org.opendaylight.protocol.bgp.rib.impl.RIBImpl;
32 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher;
33 import org.opendaylight.protocol.bgp.rib.impl.spi.CodecsRegistry;
34 import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
35 import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContextRegistry;
36 import org.opendaylight.protocol.bgp.rib.spi.BGPPeerTracker;
37 import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
38 import org.opendaylight.protocol.bgp.rib.spi.policy.BGPRibRoutingPolicy;
39 import org.opendaylight.protocol.bgp.rib.spi.state.BGPRibState;
40 import org.opendaylight.protocol.bgp.rib.spi.state.BGPRibStateProvider;
41 import org.opendaylight.protocol.bgp.rib.spi.state.BGPStateProviderRegistry;
42 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafi;
43 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.global.base.Config;
44 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Global;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.BgpTableType;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.PeerId;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.RibId;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.Rib;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.RibKey;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.TablesKey;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.BgpId;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.ClusterIdentifier;
57 import org.opendaylight.yangtools.concepts.Registration;
58 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
59 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
60 import org.slf4j.Logger;
61 import org.slf4j.LoggerFactory;
62
63 public final class RibImpl implements RIB, BGPRibStateProvider {
64
65     private static final Logger LOG = LoggerFactory.getLogger(RibImpl.class);
66
67     private final RIBExtensionConsumerContext extensionProvider;
68     private final BGPDispatcher dispatcher;
69     private final CodecsRegistry codecsRegistry;
70     private final DOMDataBroker domBroker;
71     private final BGPRibRoutingPolicyFactory policyProvider;
72     private final BGPStateProviderRegistry stateProviderRegistry;
73     @GuardedBy("this")
74     private RIBImpl ribImpl;
75     @GuardedBy("this")
76     private Registration stateProviderRegistration;
77     @GuardedBy("this")
78     private Collection<AfiSafi> afiSafi;
79     @GuardedBy("this")
80     private AsNumber asNumber;
81     @GuardedBy("this")
82     private Ipv4AddressNoZone routerId;
83     @GuardedBy("this")
84     private ClusterIdentifier clusterId;
85     @GuardedBy("this")
86     private RibId ribId;
87
88     public RibImpl(
89             final RIBExtensionConsumerContext extensionProvider,
90             final BGPDispatcher dispatcher,
91             final BGPRibRoutingPolicyFactory policyProvider,
92             final CodecsRegistry codecsRegistry,
93             final BGPStateProviderRegistry stateProviderRegistry,
94             final DOMDataBroker domBroker) {
95         this.extensionProvider = requireNonNull(extensionProvider);
96         this.dispatcher = requireNonNull(dispatcher);
97         this.codecsRegistry = requireNonNull(codecsRegistry);
98         this.domBroker = requireNonNull(domBroker);
99         this.policyProvider = requireNonNull(policyProvider);
100         this.stateProviderRegistry = requireNonNull(stateProviderRegistry);
101     }
102
103     synchronized void start(final Global global, final String instanceName,
104             final BGPTableTypeRegistryConsumer tableTypeRegistry) {
105         checkState(ribImpl == null, "Previous instance %s was not closed.", this);
106         LOG.info("Starting BGP instance {}", instanceName);
107         ribId = new RibId(instanceName);
108         ribImpl = createRib(global, tableTypeRegistry);
109         stateProviderRegistration =  stateProviderRegistry.register(this);
110     }
111
112     synchronized ListenableFuture<?> stop() {
113         if (ribImpl == null) {
114             LOG.info("RIB instance {} already closed, skipping", ribId);
115             return Futures.immediateVoidFuture();
116         }
117
118         LOG.info("Closing RIB instance {}", ribId);
119         if (stateProviderRegistration != null) {
120             LOG.info("Unregistering state provider for RIB instance {}", ribId);
121             stateProviderRegistration.close();
122             stateProviderRegistration = null;
123         }
124
125         final var future = ribImpl.closeServiceInstance();
126         ribImpl = null;
127         return future;
128     }
129
130     synchronized boolean isGlobalEqual(final Global global) {
131         final Collection<AfiSafi> globalAfiSafi = getAfiSafiWithDefault(global.getAfiSafis(), true).values();
132         final Config globalConfig = global.getConfig();
133         final AsNumber globalAs = globalConfig.getAs();
134         final Ipv4Address globalRouterId = global.getConfig().getRouterId();
135         final ClusterIdentifier globalClusterId = getGlobalClusterIdentifier(globalConfig);
136         return afiSafi.containsAll(globalAfiSafi) && globalAfiSafi.containsAll(afiSafi)
137                 && globalAs.equals(asNumber)
138                 && globalRouterId.getValue().equals(routerId.getValue())
139                 && globalClusterId.getValue().equals(clusterId.getValue());
140     }
141
142     @Override
143     public synchronized KeyedInstanceIdentifier<Rib, RibKey> getInstanceIdentifier() {
144         return ribImpl.getInstanceIdentifier();
145     }
146
147     @Override
148     public synchronized AsNumber getLocalAs() {
149         return ribImpl.getLocalAs();
150     }
151
152     @Override
153     public synchronized BgpId getBgpIdentifier() {
154         return ribImpl.getBgpIdentifier();
155     }
156
157     @Override
158     public synchronized Set<? extends BgpTableType> getLocalTables() {
159         return ribImpl.getLocalTables();
160     }
161
162     @Override
163     public synchronized BGPDispatcher getDispatcher() {
164         return ribImpl.getDispatcher();
165     }
166
167     @Override
168     public synchronized DOMTransactionChain createPeerDOMChain() {
169         return ribImpl.createPeerDOMChain();
170     }
171
172     @Override
173     public synchronized RIBExtensionConsumerContext getRibExtensions() {
174         return ribImpl.getRibExtensions();
175     }
176
177     @Override
178     public synchronized RIBSupportContextRegistry getRibSupportContext() {
179         return ribImpl.getRibSupportContext();
180     }
181
182     @Override
183     public synchronized YangInstanceIdentifier getYangRibId() {
184         return ribImpl.getYangRibId();
185     }
186
187     @Override
188     public synchronized CodecsRegistry getCodecsRegistry() {
189         return ribImpl.getCodecsRegistry();
190     }
191
192     @Override
193     public synchronized DataTreeChangeExtension getService() {
194         return ribImpl.getService();
195     }
196
197     synchronized FluentFuture<? extends CommitInfo> closeServiceInstance() {
198         if (ribImpl != null) {
199             return ribImpl.closeServiceInstance();
200         }
201         return CommitInfo.emptyFluentFuture();
202     }
203
204     @Override
205     public synchronized Set<TablesKey> getLocalTablesKeys() {
206         return ribImpl.getLocalTablesKeys();
207     }
208
209     @Override
210     public synchronized boolean supportsTable(final TablesKey tableKey) {
211         return ribImpl.supportsTable(tableKey);
212     }
213
214     @Override
215     public synchronized BGPRibRoutingPolicy getRibPolicies() {
216         return ribImpl.getRibPolicies();
217     }
218
219     @Override
220     public synchronized BGPPeerTracker getPeerTracker() {
221         return ribImpl.getPeerTracker();
222     }
223
224     @Override
225     public synchronized String toString() {
226         return ribImpl != null ? ribImpl.toString() : "";
227     }
228
229     private synchronized RIBImpl createRib(
230             final Global global,
231             final BGPTableTypeRegistryConsumer tableTypeRegistry) {
232         afiSafi = getAfiSafiWithDefault(global.getAfiSafis(), true).values();
233         final Config globalConfig = global.getConfig();
234         asNumber = globalConfig.getAs();
235         routerId = IetfInetUtil.ipv4AddressNoZoneFor(globalConfig.getRouterId());
236         clusterId = getGlobalClusterIdentifier(globalConfig);
237         final Map<TablesKey, PathSelectionMode> pathSelectionModes = OpenConfigMappingUtil
238                 .toPathSelectionMode(afiSafi, tableTypeRegistry).entrySet()
239                 .stream()
240                 .collect(Collectors.toMap(entry ->
241                         new TablesKey(entry.getKey().getAfi(), entry.getKey().getSafi()), Map.Entry::getValue));
242
243         final BGPRibRoutingPolicy ribPolicy = policyProvider.buildBGPRibPolicy(asNumber.getValue().toJava(),
244                 routerId, clusterId, RoutingPolicyUtil.getApplyPolicy(global.getApplyPolicy()));
245
246         return new RIBImpl(
247                 tableTypeRegistry,
248                 ribId,
249                 asNumber,
250                 new BgpId(routerId),
251                 extensionProvider,
252                 dispatcher,
253                 codecsRegistry,
254                 domBroker,
255                 ribPolicy,
256                 toTableTypes(afiSafi, tableTypeRegistry),
257                 pathSelectionModes);
258     }
259
260     @Override
261     public synchronized BGPRibState getRIBState() {
262         return ribImpl.getRIBState();
263     }
264
265     public synchronized void instantiateServiceInstance() {
266         if (ribImpl != null) {
267             ribImpl.instantiateServiceInstance();
268         }
269     }
270
271     @Override
272     public synchronized void refreshTable(final TablesKey tk, final PeerId peerId) {
273         ribImpl.refreshTable(tk, peerId);
274     }
275 }