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
8 package org.opendaylight.protocol.bgp.rib.impl.config;
10 import static org.opendaylight.protocol.bgp.rib.impl.config.OpenConfigMappingUtil.getAfiSafiWithDefault;
11 import static org.opendaylight.protocol.bgp.rib.impl.config.OpenConfigMappingUtil.getGlobalClusterIdentifier;
12 import static org.opendaylight.protocol.bgp.rib.impl.config.OpenConfigMappingUtil.toTableTypes;
14 import com.google.common.base.Preconditions;
15 import com.google.common.util.concurrent.FluentFuture;
16 import java.util.List;
19 import java.util.stream.Collectors;
20 import org.opendaylight.mdsal.binding.api.DataBroker;
21 import org.opendaylight.mdsal.binding.api.TransactionChain;
22 import org.opendaylight.mdsal.binding.api.TransactionChainListener;
23 import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTreeFactory;
24 import org.opendaylight.mdsal.common.api.CommitInfo;
25 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
26 import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeService;
27 import org.opendaylight.mdsal.dom.api.DOMSchemaService;
28 import org.opendaylight.mdsal.dom.api.DOMTransactionChain;
29 import org.opendaylight.mdsal.dom.api.DOMTransactionChainListener;
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.CodecsRegistryImpl;
34 import org.opendaylight.protocol.bgp.rib.impl.RIBImpl;
35 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher;
36 import org.opendaylight.protocol.bgp.rib.impl.spi.CodecsRegistry;
37 import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
38 import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContextRegistry;
39 import org.opendaylight.protocol.bgp.rib.spi.BGPPeerTracker;
40 import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
41 import org.opendaylight.protocol.bgp.rib.spi.policy.BGPRibRoutingPolicy;
42 import org.opendaylight.protocol.bgp.rib.spi.state.BGPRibState;
43 import org.opendaylight.protocol.bgp.rib.spi.state.BGPRibStateConsumer;
44 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafi;
45 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.global.base.Config;
46 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Global;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
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.rev180329.BgpId;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.ClusterIdentifier;
57 import org.opendaylight.yangtools.concepts.ListenerRegistration;
58 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
59 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
60 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
61 import org.slf4j.Logger;
62 import org.slf4j.LoggerFactory;
64 public final class RibImpl implements RIB, BGPRibStateConsumer, AutoCloseable {
66 private static final Logger LOG = LoggerFactory.getLogger(RibImpl.class);
68 private final RIBExtensionConsumerContext extensions;
69 private final BGPDispatcher dispatcher;
70 private final BindingCodecTreeFactory codecTreeFactory;
71 private final DOMDataBroker domBroker;
72 private final DOMSchemaService domSchemaService;
73 private final BGPRibRoutingPolicyFactory policyProvider;
74 private RIBImpl ribImpl;
75 private ListenerRegistration<SchemaContextListener> schemaContextRegistration;
76 private List<AfiSafi> afiSafi;
77 private AsNumber asNumber;
78 private Ipv4Address routerId;
80 private ClusterIdentifier clusterId;
81 private final DataBroker dataBroker;
84 final RIBExtensionConsumerContext contextProvider,
85 final BGPDispatcher dispatcher,
86 final BGPRibRoutingPolicyFactory policyProvider,
87 final BindingCodecTreeFactory codecTreeFactory,
88 final DOMDataBroker domBroker,
89 final DataBroker dataBroker,
90 final DOMSchemaService domSchemaService
92 this.extensions = contextProvider;
93 this.dispatcher = dispatcher;
94 this.codecTreeFactory = codecTreeFactory;
95 this.domBroker = domBroker;
96 this.dataBroker = dataBroker;
97 this.domSchemaService = domSchemaService;
98 this.policyProvider = policyProvider;
101 void start(final Global global, final String instanceName, final BGPTableTypeRegistryConsumer tableTypeRegistry) {
102 Preconditions.checkState(this.ribImpl == null,
103 "Previous instance %s was not closed.", this);
104 this.ribImpl = createRib(global, instanceName, tableTypeRegistry);
105 this.schemaContextRegistration = this.domSchemaService.registerSchemaContextListener(this.ribImpl);
108 Boolean isGlobalEqual(final Global global) {
109 final List<AfiSafi> globalAfiSafi = getAfiSafiWithDefault(global.getAfiSafis(), true);
110 final Config globalConfig = global.getConfig();
111 final AsNumber globalAs = globalConfig.getAs();
112 final Ipv4Address globalRouterId = global.getConfig().getRouterId();
113 final ClusterIdentifier globalClusterId = getGlobalClusterIdentifier(globalConfig);
114 return this.afiSafi.containsAll(globalAfiSafi) && globalAfiSafi.containsAll(this.afiSafi)
115 && globalAs.equals(this.asNumber)
116 && globalRouterId.getValue().equals(this.routerId.getValue())
117 && globalClusterId.getValue().equals(this.clusterId.getValue());
121 public KeyedInstanceIdentifier<Rib, RibKey> getInstanceIdentifier() {
122 return this.ribImpl.getInstanceIdentifier();
126 public AsNumber getLocalAs() {
127 return this.ribImpl.getLocalAs();
131 public BgpId getBgpIdentifier() {
132 return this.ribImpl.getBgpIdentifier();
136 public Set<? extends BgpTableType> getLocalTables() {
137 return this.ribImpl.getLocalTables();
141 public BGPDispatcher getDispatcher() {
142 return this.ribImpl.getDispatcher();
146 public DOMTransactionChain createPeerDOMChain(final DOMTransactionChainListener listener) {
147 return this.ribImpl.createPeerDOMChain(listener);
151 public TransactionChain createPeerChain(final TransactionChainListener listener) {
152 return this.ribImpl.createPeerChain(listener);
156 public RIBExtensionConsumerContext getRibExtensions() {
157 return this.ribImpl.getRibExtensions();
161 public RIBSupportContextRegistry getRibSupportContext() {
162 return this.ribImpl.getRibSupportContext();
166 public YangInstanceIdentifier getYangRibId() {
167 return this.ribImpl.getYangRibId();
171 public CodecsRegistry getCodecsRegistry() {
172 return this.ribImpl.getCodecsRegistry();
176 public DOMDataTreeChangeService getService() {
177 return this.ribImpl.getService();
181 public DataBroker getDataBroker() {
182 return this.ribImpl.getDataBroker();
185 FluentFuture<? extends CommitInfo> closeServiceInstance() {
186 if (this.ribImpl != null) {
187 return this.ribImpl.closeServiceInstance();
189 return CommitInfo.emptyFluentFuture();
193 public void close() {
194 if (this.ribImpl != null) {
195 this.ribImpl.close();
198 if (this.schemaContextRegistration != null) {
199 this.schemaContextRegistration.close();
200 this.schemaContextRegistration = null;
205 public Set<TablesKey> getLocalTablesKeys() {
206 return this.ribImpl.getLocalTablesKeys();
210 public boolean supportsTable(final TablesKey tableKey) {
211 return this.ribImpl.supportsTable(tableKey);
215 public BGPRibRoutingPolicy getRibPolicies() {
216 return this.ribImpl.getRibPolicies();
220 public BGPPeerTracker getPeerTracker() {
221 return this.ribImpl.getPeerTracker();
225 public String toString() {
226 return this.ribImpl != null ? this.ribImpl.toString() : "";
229 private RIBImpl createRib(
231 final String bgpInstanceName,
232 final BGPTableTypeRegistryConsumer tableTypeRegistry) {
233 this.afiSafi = getAfiSafiWithDefault(global.getAfiSafis(), true);
234 final Config globalConfig = global.getConfig();
235 this.asNumber = globalConfig.getAs();
236 this.routerId = globalConfig.getRouterId();
237 this.clusterId = getGlobalClusterIdentifier(globalConfig);
238 final Map<TablesKey, PathSelectionMode> pathSelectionModes = OpenConfigMappingUtil
239 .toPathSelectionMode(this.afiSafi, tableTypeRegistry).entrySet()
241 .collect(Collectors.toMap(entry ->
242 new TablesKey(entry.getKey().getAfi(), entry.getKey().getSafi()), Map.Entry::getValue));
244 final BGPRibRoutingPolicy ribPolicy = this.policyProvider.buildBGPRibPolicy(this.asNumber.getValue(),
245 this.routerId, this.clusterId, RoutingPolicyUtil.getApplyPolicy(global.getApplyPolicy()));
246 final CodecsRegistryImpl codecsRegistry = CodecsRegistryImpl.create(codecTreeFactory,
247 this.extensions.getClassLoadingStrategy());
251 new RibId(bgpInstanceName),
253 new BgpId(this.routerId),
260 toTableTypes(this.afiSafi, tableTypeRegistry),
265 public BGPRibState getRIBState() {
266 return this.ribImpl.getRIBState();
269 public void instantiateServiceInstance() {
270 if (this.ribImpl != null) {
271 this.ribImpl.instantiateServiceInstance();
276 public void refreshTable(final TablesKey tk, final PeerId peerId) {
277 this.ribImpl.refreshTable(tk, peerId);