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;
21 import java.util.stream.Collectors;
22 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
23 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
24 import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeService;
25 import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
26 import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTreeFactory;
27 import org.opendaylight.mdsal.dom.api.DOMSchemaService;
28 import org.opendaylight.protocol.bgp.mode.api.PathSelectionMode;
29 import org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryConsumer;
30 import org.opendaylight.protocol.bgp.rib.impl.RIBImpl;
31 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher;
32 import org.opendaylight.protocol.bgp.rib.impl.spi.CodecsRegistry;
33 import org.opendaylight.protocol.bgp.rib.impl.spi.ImportPolicyPeerTracker;
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.ExportPolicyPeerTracker;
37 import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
38 import org.opendaylight.protocol.bgp.rib.spi.state.BGPRIBState;
39 import org.opendaylight.protocol.bgp.rib.spi.state.BGPRIBStateConsumer;
40 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafi;
41 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.global.base.Config;
42 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Global;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.BgpTableType;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.RibId;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.bgp.rib.Rib;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.bgp.rib.RibKey;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.TablesKey;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.BgpId;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.ClusterIdentifier;
52 import org.opendaylight.yangtools.concepts.ListenerRegistration;
53 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
54 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
55 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
56 import org.osgi.framework.ServiceRegistration;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
60 public final class RibImpl implements RIB, BGPRIBStateConsumer, AutoCloseable {
62 private static final Logger LOG = LoggerFactory.getLogger(RibImpl.class);
64 private final RIBExtensionConsumerContext extensions;
65 private final BGPDispatcher dispatcher;
66 private final BindingCodecTreeFactory codecTreeFactory;
67 private final DOMDataBroker domBroker;
68 private final DOMSchemaService domSchemaService;
69 private RIBImpl ribImpl;
70 private ServiceRegistration<?> serviceRegistration;
71 private ListenerRegistration<SchemaContextListener> schemaContextRegistration;
72 private List<AfiSafi> afiSafi;
73 private AsNumber asNumber;
74 private Ipv4Address routerId;
76 private ClusterIdentifier clusterId;
78 public RibImpl(final RIBExtensionConsumerContext contextProvider, final BGPDispatcher dispatcher,
79 final BindingCodecTreeFactory codecTreeFactory, final DOMDataBroker domBroker,
80 final DOMSchemaService domSchemaService) {
81 this.extensions = contextProvider;
82 this.dispatcher = dispatcher;
83 this.codecTreeFactory = codecTreeFactory;
84 this.domBroker = domBroker;
85 this.domSchemaService = domSchemaService;
88 void start(final Global global, final String instanceName, final BGPTableTypeRegistryConsumer tableTypeRegistry) {
89 Preconditions.checkState(this.ribImpl == null,
90 "Previous instance %s was not closed.", this);
91 this.ribImpl = createRib(global, instanceName, tableTypeRegistry);
92 this.schemaContextRegistration = this.domSchemaService.registerSchemaContextListener(this.ribImpl);
95 Boolean isGlobalEqual(final Global global) {
96 final List<AfiSafi> globalAfiSafi = getAfiSafiWithDefault(global.getAfiSafis(), true);
97 final Config globalConfig = global.getConfig();
98 final AsNumber globalAs = globalConfig.getAs();
99 final Ipv4Address globalRouterId = global.getConfig().getRouterId();
100 final ClusterIdentifier globalClusterId = getClusterIdentifier(globalConfig);
101 return this.afiSafi.containsAll(globalAfiSafi) && globalAfiSafi.containsAll(this.afiSafi)
102 && globalAs.equals(this.asNumber)
103 && globalRouterId.getValue().equals(this.routerId.getValue())
104 && globalClusterId.getValue().equals(this.clusterId.getValue());
108 public KeyedInstanceIdentifier<Rib, RibKey> getInstanceIdentifier() {
109 return this.ribImpl.getInstanceIdentifier();
113 public AsNumber getLocalAs() {
114 return this.ribImpl.getLocalAs();
118 public BgpId getBgpIdentifier() {
119 return this.ribImpl.getBgpIdentifier();
123 public Set<? extends BgpTableType> getLocalTables() {
124 return this.ribImpl.getLocalTables();
128 public BGPDispatcher getDispatcher() {
129 return this.ribImpl.getDispatcher();
133 public DOMTransactionChain createPeerChain(final TransactionChainListener listener) {
134 return this.ribImpl.createPeerChain(listener);
138 public RIBExtensionConsumerContext getRibExtensions() {
139 return this.ribImpl.getRibExtensions();
143 public RIBSupportContextRegistry getRibSupportContext() {
144 return this.ribImpl.getRibSupportContext();
148 public YangInstanceIdentifier getYangRibId() {
149 return this.ribImpl.getYangRibId();
153 public CodecsRegistry getCodecsRegistry() {
154 return this.ribImpl.getCodecsRegistry();
158 public DOMDataTreeChangeService getService() {
159 return this.ribImpl.getService();
162 ListenableFuture<Void> closeServiceInstance() {
163 if (this.ribImpl != null) {
164 return this.ribImpl.closeServiceInstance();
166 return Futures.immediateFuture(null);
170 public void close() {
171 if (this.ribImpl != null) {
173 this.ribImpl.close();
174 } catch (final Exception e) {
175 LOG.warn("Failed to close {} rib instance", this, e);
179 if (this.schemaContextRegistration != null) {
180 this.schemaContextRegistration.close();
181 this.schemaContextRegistration = null;
183 if (this.serviceRegistration != null) {
185 this.serviceRegistration.unregister();
186 } catch (final IllegalStateException e) {
187 LOG.warn("Failed to unregister {} service instance", this, e);
189 this.serviceRegistration = null;
193 void setServiceRegistration(final ServiceRegistration<?> serviceRegistration) {
194 this.serviceRegistration = serviceRegistration;
198 public ImportPolicyPeerTracker getImportPolicyPeerTracker() {
199 return this.ribImpl.getImportPolicyPeerTracker();
203 public ExportPolicyPeerTracker getExportPolicyPeerTracker(final TablesKey tablesKey) {
204 return this.ribImpl.getExportPolicyPeerTracker(tablesKey);
208 public Set<TablesKey> getLocalTablesKeys() {
209 return this.ribImpl.getLocalTablesKeys();
213 public String toString() {
214 return this.ribImpl != null ? this.ribImpl.toString() : "";
217 private RIBImpl createRib(
219 final String bgpInstanceName,
220 final BGPTableTypeRegistryConsumer tableTypeRegistry) {
221 this.afiSafi = getAfiSafiWithDefault(global.getAfiSafis(), true);
222 final Config globalConfig = global.getConfig();
223 this.asNumber = globalConfig.getAs();
224 this.routerId = globalConfig.getRouterId();
225 this.clusterId = getClusterIdentifier(globalConfig);
226 final Map<TablesKey, PathSelectionMode> pathSelectionModes = OpenConfigMappingUtil
227 .toPathSelectionMode(this.afiSafi, tableTypeRegistry).entrySet()
229 .collect(Collectors.toMap(entry ->
230 new TablesKey(entry.getKey().getAfi(), entry.getKey().getSafi()), Map.Entry::getValue));
232 new RibId(bgpInstanceName),
234 new BgpId(this.routerId),
238 this.codecTreeFactory,
240 toTableTypes(this.afiSafi, tableTypeRegistry),
242 this.extensions.getClassLoadingStrategy());
246 public BGPRIBState getRIBState() {
247 return this.ribImpl.getRIBState();
250 public void instantiateServiceInstance() {
251 if (this.ribImpl != null) {
252 this.ribImpl.instantiateServiceInstance();