2 * Copyright (c) 2016 Cisco Systems, Inc. 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
9 package org.opendaylight.protocol.bgp.rib.impl.config;
11 import static org.opendaylight.protocol.bgp.rib.impl.config.OpenConfigMappingUtil.getAfiSafiWithDefault;
12 import static org.opendaylight.protocol.bgp.rib.impl.config.OpenConfigMappingUtil.getClusterIdentifier;
13 import static org.opendaylight.protocol.bgp.rib.impl.config.OpenConfigMappingUtil.toTableTypes;
15 import com.google.common.base.Preconditions;
16 import com.google.common.util.concurrent.Futures;
17 import com.google.common.util.concurrent.ListenableFuture;
18 import java.util.List;
20 import java.util.Optional;
22 import java.util.stream.Collectors;
23 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
24 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
25 import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeService;
26 import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
27 import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTreeFactory;
28 import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
29 import org.opendaylight.mdsal.dom.api.DOMSchemaService;
30 import org.opendaylight.protocol.bgp.mode.api.PathSelectionMode;
31 import org.opendaylight.protocol.bgp.openconfig.routing.policy.spi.BGPRibRoutingPolicyFactory;
32 import org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryConsumer;
33 import org.opendaylight.protocol.bgp.rib.impl.BGPPeerTrackerImpl;
34 import org.opendaylight.protocol.bgp.rib.impl.CodecsRegistryImpl;
35 import org.opendaylight.protocol.bgp.rib.impl.RIBImpl;
36 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher;
37 import org.opendaylight.protocol.bgp.rib.impl.spi.CodecsRegistry;
38 import org.opendaylight.protocol.bgp.rib.impl.spi.ImportPolicyPeerTracker;
39 import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
40 import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContextRegistry;
41 import org.opendaylight.protocol.bgp.rib.spi.BGPPeerTracker;
42 import org.opendaylight.protocol.bgp.rib.spi.ExportPolicyPeerTracker;
43 import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
44 import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
45 import org.opendaylight.protocol.bgp.rib.spi.policy.BGPRibRoutingPolicy;
46 import org.opendaylight.protocol.bgp.rib.spi.state.BGPRIBState;
47 import org.opendaylight.protocol.bgp.rib.spi.state.BGPRIBStateConsumer;
48 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafi;
49 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.global.base.Config;
50 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Global;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.Attributes;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.BgpTableType;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.RibId;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.bgp.rib.Rib;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.bgp.rib.RibKey;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.TablesKey;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.BgpId;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.ClusterIdentifier;
61 import org.opendaylight.yangtools.concepts.ListenerRegistration;
62 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
63 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
64 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
65 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
66 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
67 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
68 import org.osgi.framework.ServiceRegistration;
69 import org.slf4j.Logger;
70 import org.slf4j.LoggerFactory;
72 public final class RibImpl implements RIB, BGPRIBStateConsumer, AutoCloseable {
74 private static final Logger LOG = LoggerFactory.getLogger(RibImpl.class);
76 private final RIBExtensionConsumerContext extensions;
77 private final BGPDispatcher dispatcher;
78 private final BindingCodecTreeFactory codecTreeFactory;
79 private final DOMDataBroker domBroker;
80 private final DOMSchemaService domSchemaService;
81 private final BGPRibRoutingPolicyFactory policyProvider;
82 private final BindingNormalizedNodeSerializer bindingSerializer;
83 private RIBImpl ribImpl;
84 private ServiceRegistration<?> serviceRegistration;
85 private ListenerRegistration<SchemaContextListener> schemaContextRegistration;
86 private List<AfiSafi> afiSafi;
87 private AsNumber asNumber;
88 private Ipv4Address routerId;
90 private ClusterIdentifier clusterId;
93 final RIBExtensionConsumerContext contextProvider,
94 final BGPDispatcher dispatcher,
95 final BGPRibRoutingPolicyFactory policyProvider,
96 final BindingCodecTreeFactory codecTreeFactory,
97 final DOMDataBroker domBroker,
98 final DOMSchemaService domSchemaService,
99 final BindingNormalizedNodeSerializer bindingSerializer
101 this.extensions = contextProvider;
102 this.dispatcher = dispatcher;
103 this.codecTreeFactory = codecTreeFactory;
104 this.domBroker = domBroker;
105 this.domSchemaService = domSchemaService;
106 this.policyProvider = policyProvider;
107 this.bindingSerializer = bindingSerializer;
110 void start(final Global global, final String instanceName, final BGPTableTypeRegistryConsumer tableTypeRegistry) {
111 Preconditions.checkState(this.ribImpl == null,
112 "Previous instance %s was not closed.", this);
113 this.ribImpl = createRib(global, instanceName, tableTypeRegistry);
114 this.schemaContextRegistration = this.domSchemaService.registerSchemaContextListener(this.ribImpl);
117 Boolean isGlobalEqual(final Global global) {
118 final List<AfiSafi> globalAfiSafi = getAfiSafiWithDefault(global.getAfiSafis(), true);
119 final Config globalConfig = global.getConfig();
120 final AsNumber globalAs = globalConfig.getAs();
121 final Ipv4Address globalRouterId = global.getConfig().getRouterId();
122 final ClusterIdentifier globalClusterId = getClusterIdentifier(globalConfig);
123 return this.afiSafi.containsAll(globalAfiSafi) && globalAfiSafi.containsAll(this.afiSafi)
124 && globalAs.equals(this.asNumber)
125 && globalRouterId.getValue().equals(this.routerId.getValue())
126 && globalClusterId.getValue().equals(this.clusterId.getValue());
130 public KeyedInstanceIdentifier<Rib, RibKey> getInstanceIdentifier() {
131 return this.ribImpl.getInstanceIdentifier();
135 public AsNumber getLocalAs() {
136 return this.ribImpl.getLocalAs();
140 public BgpId getBgpIdentifier() {
141 return this.ribImpl.getBgpIdentifier();
145 public Set<? extends BgpTableType> getLocalTables() {
146 return this.ribImpl.getLocalTables();
150 public BGPDispatcher getDispatcher() {
151 return this.ribImpl.getDispatcher();
155 public DOMTransactionChain createPeerChain(final TransactionChainListener listener) {
156 return this.ribImpl.createPeerChain(listener);
160 public RIBExtensionConsumerContext getRibExtensions() {
161 return this.ribImpl.getRibExtensions();
165 public RIBSupportContextRegistry getRibSupportContext() {
166 return this.ribImpl.getRibSupportContext();
170 public YangInstanceIdentifier getYangRibId() {
171 return this.ribImpl.getYangRibId();
175 public CodecsRegistry getCodecsRegistry() {
176 return this.ribImpl.getCodecsRegistry();
180 public DOMDataTreeChangeService getService() {
181 return this.ribImpl.getService();
184 ListenableFuture<Void> closeServiceInstance() {
185 if (this.ribImpl != null) {
186 return this.ribImpl.closeServiceInstance();
188 return Futures.immediateFuture(null);
192 public void close() {
193 if (this.ribImpl != null) {
195 this.ribImpl.close();
196 } catch (final Exception e) {
197 LOG.warn("Failed to close {} rib instance", this, e);
201 if (this.schemaContextRegistration != null) {
202 this.schemaContextRegistration.close();
203 this.schemaContextRegistration = null;
205 if (this.serviceRegistration != null) {
207 this.serviceRegistration.unregister();
208 } catch (final IllegalStateException e) {
209 LOG.warn("Failed to unregister {} service instance", this, e);
211 this.serviceRegistration = null;
215 void setServiceRegistration(final ServiceRegistration<?> serviceRegistration) {
216 this.serviceRegistration = serviceRegistration;
220 public ImportPolicyPeerTracker getImportPolicyPeerTracker() {
221 return this.ribImpl.getImportPolicyPeerTracker();
225 public ExportPolicyPeerTracker getExportPolicyPeerTracker(final TablesKey tablesKey) {
226 return this.ribImpl.getExportPolicyPeerTracker(tablesKey);
230 public Set<TablesKey> getLocalTablesKeys() {
231 return this.ribImpl.getLocalTablesKeys();
235 public boolean supportsTable(final TablesKey tableKey) {
236 return this.ribImpl.supportsTable(tableKey);
240 public BGPRibRoutingPolicy getRibPolicies() {
241 return this.ribImpl.getRibPolicies();
245 public BGPPeerTracker getPeerTracker() {
246 return this.ribImpl.getPeerTracker();
250 public String toString() {
251 return this.ribImpl != null ? this.ribImpl.toString() : "";
254 private RIBImpl createRib(
256 final String bgpInstanceName,
257 final BGPTableTypeRegistryConsumer tableTypeRegistry) {
258 this.afiSafi = getAfiSafiWithDefault(global.getAfiSafis(), true);
259 final Config globalConfig = global.getConfig();
260 this.asNumber = globalConfig.getAs();
261 this.routerId = globalConfig.getRouterId();
262 this.clusterId = getClusterIdentifier(globalConfig);
263 final BGPPeerTrackerImpl peerTracker = new BGPPeerTrackerImpl();
264 final Map<TablesKey, PathSelectionMode> pathSelectionModes = OpenConfigMappingUtil
265 .toPathSelectionMode(this.afiSafi, tableTypeRegistry, peerTracker).entrySet()
267 .collect(Collectors.toMap(entry ->
268 new TablesKey(entry.getKey().getAfi(), entry.getKey().getSafi()), Map.Entry::getValue));
270 final BGPRibRoutingPolicy ribPolicy = this.policyProvider.buildBGPRibPolicy(this.asNumber.getValue(),
271 this.routerId, this.clusterId, RoutingPolicyUtil.getApplyPolicy(global.getApplyPolicy()));
272 final CodecsRegistryImpl codecsRegistry = CodecsRegistryImpl.create(codecTreeFactory,
273 this.extensions.getClassLoadingStrategy());
276 new RibId(bgpInstanceName),
278 new BgpId(this.routerId),
286 toTableTypes(this.afiSafi, tableTypeRegistry),
288 this.bindingSerializer);
292 public BGPRIBState getRIBState() {
293 return this.ribImpl.getRIBState();
296 public void instantiateServiceInstance() {
297 if (this.ribImpl != null) {
298 this.ribImpl.instantiateServiceInstance();
303 public Optional<Attributes> getAttributes(
304 RIBSupport ribSupport,
305 NodeIdentifierWithPredicates routeIdentifier, NormalizedNode<?, ?> route) {
306 return this.ribImpl.getAttributes(ribSupport, routeIdentifier, route);
310 public Optional<ContainerNode> toNormalizedNodeAttribute(
311 final RIBSupport ribSupport,
312 final NodeIdentifierWithPredicates routeIdentifier,
313 final Optional<Attributes> attributes) {
314 return this.ribImpl.toNormalizedNodeAttribute(ribSupport, routeIdentifier, attributes);