Update MRI projects for Aluminium
[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.Collection;
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.common.api.CommitInfo;
24 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
25 import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeService;
26 import org.opendaylight.mdsal.dom.api.DOMTransactionChain;
27 import org.opendaylight.mdsal.dom.api.DOMTransactionChainListener;
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.BGPRibStateConsumer;
41 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafi;
42 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.global.base.Config;
43 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Global;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.BgpTableType;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.PeerId;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.RibId;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.Rib;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.RibKey;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.TablesKey;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.BgpId;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.ClusterIdentifier;
56 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
57 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
58 import org.osgi.framework.ServiceRegistration;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
61
62 public final class RibImpl implements RIB, BGPRibStateConsumer, AutoCloseable {
63
64     private static final Logger LOG = LoggerFactory.getLogger(RibImpl.class);
65
66     private final RIBExtensionConsumerContext extensions;
67     private final BGPDispatcher dispatcher;
68     private final CodecsRegistry codecsRegistry;
69     private final DOMDataBroker domBroker;
70     private final BGPRibRoutingPolicyFactory policyProvider;
71     private RIBImpl ribImpl;
72     private ServiceRegistration<?> serviceRegistration;
73     private Collection<AfiSafi> afiSafi;
74     private AsNumber asNumber;
75     private Ipv4AddressNoZone routerId;
76
77     private ClusterIdentifier clusterId;
78     private final DataBroker dataBroker;
79
80     public RibImpl(
81             final RIBExtensionConsumerContext contextProvider,
82             final BGPDispatcher dispatcher,
83             final BGPRibRoutingPolicyFactory policyProvider,
84             final CodecsRegistry codecsRegistry,
85             final DOMDataBroker domBroker,
86             final DataBroker dataBroker
87     ) {
88         this.extensions = contextProvider;
89         this.dispatcher = dispatcher;
90         this.codecsRegistry = codecsRegistry;
91         this.domBroker = domBroker;
92         this.dataBroker = dataBroker;
93         this.policyProvider = policyProvider;
94     }
95
96     void start(final Global global, final String instanceName, final BGPTableTypeRegistryConsumer tableTypeRegistry) {
97         Preconditions.checkState(this.ribImpl == null,
98                 "Previous instance %s was not closed.", this);
99         this.ribImpl = createRib(global, instanceName, tableTypeRegistry);
100     }
101
102     Boolean isGlobalEqual(final Global global) {
103         final Collection<AfiSafi> globalAfiSafi = getAfiSafiWithDefault(global.getAfiSafis(), true).values();
104         final Config globalConfig = global.getConfig();
105         final AsNumber globalAs = globalConfig.getAs();
106         final Ipv4Address globalRouterId = global.getConfig().getRouterId();
107         final ClusterIdentifier globalClusterId = getGlobalClusterIdentifier(globalConfig);
108         return this.afiSafi.containsAll(globalAfiSafi) && globalAfiSafi.containsAll(this.afiSafi)
109                 && globalAs.equals(this.asNumber)
110                 && globalRouterId.getValue().equals(this.routerId.getValue())
111                 && globalClusterId.getValue().equals(this.clusterId.getValue());
112     }
113
114     @Override
115     public KeyedInstanceIdentifier<Rib, RibKey> getInstanceIdentifier() {
116         return this.ribImpl.getInstanceIdentifier();
117     }
118
119     @Override
120     public AsNumber getLocalAs() {
121         return this.ribImpl.getLocalAs();
122     }
123
124     @Override
125     public BgpId getBgpIdentifier() {
126         return this.ribImpl.getBgpIdentifier();
127     }
128
129     @Override
130     public Set<? extends BgpTableType> getLocalTables() {
131         return this.ribImpl.getLocalTables();
132     }
133
134     @Override
135     public BGPDispatcher getDispatcher() {
136         return this.ribImpl.getDispatcher();
137     }
138
139     @Override
140     public DOMTransactionChain createPeerDOMChain(final DOMTransactionChainListener listener) {
141         return this.ribImpl.createPeerDOMChain(listener);
142     }
143
144     @Override
145     public TransactionChain createPeerChain(final TransactionChainListener listener) {
146         return this.ribImpl.createPeerChain(listener);
147     }
148
149     @Override
150     public RIBExtensionConsumerContext getRibExtensions() {
151         return this.ribImpl.getRibExtensions();
152     }
153
154     @Override
155     public RIBSupportContextRegistry getRibSupportContext() {
156         return this.ribImpl.getRibSupportContext();
157     }
158
159     @Override
160     public YangInstanceIdentifier getYangRibId() {
161         return this.ribImpl.getYangRibId();
162     }
163
164     @Override
165     public CodecsRegistry getCodecsRegistry() {
166         return this.ribImpl.getCodecsRegistry();
167     }
168
169     @Override
170     public DOMDataTreeChangeService getService() {
171         return this.ribImpl.getService();
172     }
173
174     @Override
175     public DataBroker getDataBroker() {
176         return this.ribImpl.getDataBroker();
177     }
178
179     FluentFuture<? extends CommitInfo> closeServiceInstance() {
180         if (this.ribImpl != null) {
181             return this.ribImpl.closeServiceInstance();
182         }
183         return CommitInfo.emptyFluentFuture();
184     }
185
186     @Override
187     public void close() {
188         if (this.ribImpl != null) {
189             this.ribImpl.close();
190             this.ribImpl = null;
191         }
192         if (this.serviceRegistration != null) {
193             try {
194                 this.serviceRegistration.unregister();
195             } catch (final IllegalStateException e) {
196                 LOG.warn("Failed to unregister {} service instance", this, e);
197             }
198             this.serviceRegistration = null;
199         }
200     }
201
202     void setServiceRegistration(final ServiceRegistration<?> serviceRegistration) {
203         this.serviceRegistration = serviceRegistration;
204     }
205
206     @Override
207     public Set<TablesKey> getLocalTablesKeys() {
208         return this.ribImpl.getLocalTablesKeys();
209     }
210
211     @Override
212     public boolean supportsTable(final TablesKey tableKey) {
213         return this.ribImpl.supportsTable(tableKey);
214     }
215
216     @Override
217     public BGPRibRoutingPolicy getRibPolicies() {
218         return this.ribImpl.getRibPolicies();
219     }
220
221     @Override
222     public BGPPeerTracker getPeerTracker() {
223         return this.ribImpl.getPeerTracker();
224     }
225
226     @Override
227     public String toString() {
228         return this.ribImpl != null ? this.ribImpl.toString() : "";
229     }
230
231     private RIBImpl createRib(
232             final Global global,
233             final String bgpInstanceName,
234             final BGPTableTypeRegistryConsumer tableTypeRegistry) {
235         this.afiSafi = getAfiSafiWithDefault(global.getAfiSafis(), true).values();
236         final Config globalConfig = global.getConfig();
237         this.asNumber = globalConfig.getAs();
238         this.routerId = IetfInetUtil.INSTANCE.ipv4AddressNoZoneFor(globalConfig.getRouterId());
239         this.clusterId = getGlobalClusterIdentifier(globalConfig);
240         final Map<TablesKey, PathSelectionMode> pathSelectionModes = OpenConfigMappingUtil
241                 .toPathSelectionMode(this.afiSafi, tableTypeRegistry).entrySet()
242                 .stream()
243                 .collect(Collectors.toMap(entry ->
244                         new TablesKey(entry.getKey().getAfi(), entry.getKey().getSafi()), Map.Entry::getValue));
245
246         final BGPRibRoutingPolicy ribPolicy = this.policyProvider.buildBGPRibPolicy(this.asNumber.getValue().toJava(),
247                 this.routerId, this.clusterId, RoutingPolicyUtil.getApplyPolicy(global.getApplyPolicy()));
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 }