Migrate to MD-SAL APIs
[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 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;
13
14 import com.google.common.base.Preconditions;
15 import com.google.common.util.concurrent.FluentFuture;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Set;
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;
63
64 public final class RibImpl implements RIB, BGPRibStateConsumer, AutoCloseable {
65
66     private static final Logger LOG = LoggerFactory.getLogger(RibImpl.class);
67
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;
79
80     private ClusterIdentifier clusterId;
81     private final DataBroker dataBroker;
82
83     public RibImpl(
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
91     ) {
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;
99     }
100
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);
106     }
107
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());
118     }
119
120     @Override
121     public KeyedInstanceIdentifier<Rib, RibKey> getInstanceIdentifier() {
122         return this.ribImpl.getInstanceIdentifier();
123     }
124
125     @Override
126     public AsNumber getLocalAs() {
127         return this.ribImpl.getLocalAs();
128     }
129
130     @Override
131     public BgpId getBgpIdentifier() {
132         return this.ribImpl.getBgpIdentifier();
133     }
134
135     @Override
136     public Set<? extends BgpTableType> getLocalTables() {
137         return this.ribImpl.getLocalTables();
138     }
139
140     @Override
141     public BGPDispatcher getDispatcher() {
142         return this.ribImpl.getDispatcher();
143     }
144
145     @Override
146     public DOMTransactionChain createPeerDOMChain(final DOMTransactionChainListener listener) {
147         return this.ribImpl.createPeerDOMChain(listener);
148     }
149
150     @Override
151     public TransactionChain createPeerChain(final TransactionChainListener listener) {
152         return this.ribImpl.createPeerChain(listener);
153     }
154
155     @Override
156     public RIBExtensionConsumerContext getRibExtensions() {
157         return this.ribImpl.getRibExtensions();
158     }
159
160     @Override
161     public RIBSupportContextRegistry getRibSupportContext() {
162         return this.ribImpl.getRibSupportContext();
163     }
164
165     @Override
166     public YangInstanceIdentifier getYangRibId() {
167         return this.ribImpl.getYangRibId();
168     }
169
170     @Override
171     public CodecsRegistry getCodecsRegistry() {
172         return this.ribImpl.getCodecsRegistry();
173     }
174
175     @Override
176     public DOMDataTreeChangeService getService() {
177         return this.ribImpl.getService();
178     }
179
180     @Override
181     public DataBroker getDataBroker() {
182         return this.ribImpl.getDataBroker();
183     }
184
185     FluentFuture<? extends CommitInfo> closeServiceInstance() {
186         if (this.ribImpl != null) {
187             return this.ribImpl.closeServiceInstance();
188         }
189         return CommitInfo.emptyFluentFuture();
190     }
191
192     @Override
193     public void close() {
194         if (this.ribImpl != null) {
195             this.ribImpl.close();
196             this.ribImpl = null;
197         }
198         if (this.schemaContextRegistration != null) {
199             this.schemaContextRegistration.close();
200             this.schemaContextRegistration = null;
201         }
202     }
203
204     @Override
205     public Set<TablesKey> getLocalTablesKeys() {
206         return this.ribImpl.getLocalTablesKeys();
207     }
208
209     @Override
210     public boolean supportsTable(final TablesKey tableKey) {
211         return this.ribImpl.supportsTable(tableKey);
212     }
213
214     @Override
215     public BGPRibRoutingPolicy getRibPolicies() {
216         return this.ribImpl.getRibPolicies();
217     }
218
219     @Override
220     public BGPPeerTracker getPeerTracker() {
221         return this.ribImpl.getPeerTracker();
222     }
223
224     @Override
225     public String toString() {
226         return this.ribImpl != null ? this.ribImpl.toString() : "";
227     }
228
229     private RIBImpl createRib(
230             final Global global,
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()
240                 .stream()
241                 .collect(Collectors.toMap(entry ->
242                         new TablesKey(entry.getKey().getAfi(), entry.getKey().getSafi()), Map.Entry::getValue));
243
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());
248
249         return new RIBImpl(
250                 tableTypeRegistry,
251                 new RibId(bgpInstanceName),
252                 this.asNumber,
253                 new BgpId(this.routerId),
254                 this.extensions,
255                 this.dispatcher,
256                 codecsRegistry,
257                 this.domBroker,
258                 this.dataBroker,
259                 ribPolicy,
260                 toTableTypes(this.afiSafi, tableTypeRegistry),
261                 pathSelectionModes);
262     }
263
264     @Override
265     public BGPRibState getRIBState() {
266         return this.ribImpl.getRIBState();
267     }
268
269     public void instantiateServiceInstance() {
270         if (this.ribImpl != null) {
271             this.ribImpl.instantiateServiceInstance();
272         }
273     }
274
275     @Override
276     public void refreshTable(final TablesKey tk, final PeerId peerId) {
277         this.ribImpl.refreshTable(tk, peerId);
278     }
279 }