BGPCEP-701: Remove old statistics, keep only openconfig stats
[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
9 package org.opendaylight.protocol.bgp.rib.impl.config;
10
11 import static java.util.Objects.requireNonNull;
12 import static org.opendaylight.protocol.bgp.rib.impl.config.OpenConfigMappingUtil.getAfiSafiWithDefault;
13 import static org.opendaylight.protocol.bgp.rib.impl.config.OpenConfigMappingUtil.getClusterIdentifier;
14 import static org.opendaylight.protocol.bgp.rib.impl.config.OpenConfigMappingUtil.toTableTypes;
15
16 import com.google.common.base.Preconditions;
17 import com.google.common.util.concurrent.Futures;
18 import com.google.common.util.concurrent.ListenableFuture;
19 import java.util.List;
20 import java.util.Map;
21 import java.util.Set;
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.dom.api.DOMSchemaService;
29 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
30 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
31 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
32 import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
33 import org.opendaylight.protocol.bgp.mode.api.PathSelectionMode;
34 import org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryConsumer;
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.BgpDeployer;
38 import org.opendaylight.protocol.bgp.rib.impl.spi.CodecsRegistry;
39 import org.opendaylight.protocol.bgp.rib.impl.spi.ImportPolicyPeerTracker;
40 import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
41 import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContextRegistry;
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.state.BGPRIBState;
45 import org.opendaylight.protocol.bgp.rib.spi.state.BGPRIBStateConsumer;
46 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafi;
47 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.global.base.Config;
48 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Global;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.RibId;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.Rib;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.RibKey;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.BgpId;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.ClusterIdentifier;
58 import org.opendaylight.yangtools.concepts.ListenerRegistration;
59 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
60 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
61 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
62 import org.osgi.framework.ServiceRegistration;
63 import org.slf4j.Logger;
64 import org.slf4j.LoggerFactory;
65
66 public final class RibImpl implements RIB, BGPRIBStateConsumer, AutoCloseable {
67
68     private static final Logger LOG = LoggerFactory.getLogger(RibImpl.class);
69
70     private final RIBExtensionConsumerContext extensions;
71     private final BGPDispatcher dispatcher;
72     private final BindingCodecTreeFactory codecTreeFactory;
73     private final DOMDataBroker domBroker;
74     private final DOMSchemaService domSchemaService;
75     private RIBImpl ribImpl;
76     private ServiceRegistration<?> serviceRegistration;
77     private ListenerRegistration<SchemaContextListener> schemaContextRegistration;
78     private final ClusterSingletonServiceProvider provider;
79     private List<AfiSafi> afiSafi;
80     private AsNumber asNumber;
81     private Ipv4Address routerId;
82
83     private ClusterIdentifier clusterId;
84
85     public RibImpl(final ClusterSingletonServiceProvider provider, final RIBExtensionConsumerContext contextProvider,
86             final BGPDispatcher dispatcher, final BindingCodecTreeFactory codecTreeFactory, final DOMDataBroker domBroker,
87             final DOMSchemaService domSchemaService) {
88         this.provider = requireNonNull(provider);
89         this.extensions = contextProvider;
90         this.dispatcher = dispatcher;
91         this.codecTreeFactory = codecTreeFactory;
92         this.domBroker = domBroker;
93         this.domSchemaService = domSchemaService;
94     }
95
96     void start(final Global global, final String instanceName, final BGPTableTypeRegistryConsumer tableTypeRegistry,
97             final BgpDeployer.WriteConfiguration configurationWriter) {
98         Preconditions.checkState(this.ribImpl == null,
99                 "Previous instance %s was not closed.", this);
100         this.ribImpl = createRib(global, instanceName, tableTypeRegistry, configurationWriter);
101         this.schemaContextRegistration = this.domSchemaService.registerSchemaContextListener(this.ribImpl);
102     }
103
104     Boolean isGlobalEqual(final Global global) {
105         final List<AfiSafi> globalAfiSafi = getAfiSafiWithDefault(global.getAfiSafis(), true);
106         final Config globalConfig = global.getConfig();
107         final AsNumber globalAs = globalConfig.getAs();
108         final Ipv4Address globalRouterId = global.getConfig().getRouterId();
109         final ClusterIdentifier globalClusterId = getClusterIdentifier(globalConfig);
110         return this.afiSafi.containsAll(globalAfiSafi) && globalAfiSafi.containsAll(this.afiSafi)
111                 && globalAs.equals(this.asNumber)
112                 && globalRouterId.getValue().equals(this.routerId.getValue())
113                 && globalClusterId.getValue().equals(this.clusterId.getValue());
114     }
115
116     @Override
117     public KeyedInstanceIdentifier<Rib, RibKey> getInstanceIdentifier() {
118         return this.ribImpl.getInstanceIdentifier();
119     }
120
121     @Override
122     public AsNumber getLocalAs() {
123         return this.ribImpl.getLocalAs();
124     }
125
126     @Override
127     public BgpId getBgpIdentifier() {
128         return this.ribImpl.getBgpIdentifier();
129     }
130
131     @Override
132     public Set<? extends BgpTableType> getLocalTables() {
133         return this.ribImpl.getLocalTables();
134     }
135
136     @Override
137     public BGPDispatcher getDispatcher() {
138         return this.ribImpl.getDispatcher();
139     }
140
141     @Override
142     public DOMTransactionChain createPeerChain(final TransactionChainListener listener) {
143         return this.ribImpl.createPeerChain(listener);
144     }
145
146     @Override
147     public RIBExtensionConsumerContext getRibExtensions() {
148         return this.ribImpl.getRibExtensions();
149     }
150
151     @Override
152     public RIBSupportContextRegistry getRibSupportContext() {
153         return this.ribImpl.getRibSupportContext();
154     }
155
156     @Override
157     public YangInstanceIdentifier getYangRibId() {
158         return this.ribImpl.getYangRibId();
159     }
160
161     @Override
162     public CodecsRegistry getCodecsRegistry() {
163         return this.ribImpl.getCodecsRegistry();
164     }
165
166     @Override
167     public DOMDataTreeChangeService getService() {
168         return this.ribImpl.getService();
169     }
170
171     public ListenableFuture<Void> closeServiceInstance() {
172         if (this.ribImpl != null) {
173             return this.ribImpl.closeServiceInstance();
174         }
175         return Futures.immediateFuture(null);
176     }
177
178     @Override
179     public void close() {
180         if (this.ribImpl != null) {
181             try {
182                 this.ribImpl.close();
183             } catch (final Exception e) {
184                 LOG.warn("Failed to close {} rib instance", this, e);
185             }
186             this.ribImpl = null;
187         }
188         if (this.schemaContextRegistration != null) {
189             this.schemaContextRegistration.close();
190             this.schemaContextRegistration = 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 ImportPolicyPeerTracker getImportPolicyPeerTracker() {
208         return this.ribImpl.getImportPolicyPeerTracker();
209     }
210
211     @Override
212     public ExportPolicyPeerTracker getExportPolicyPeerTracker(final TablesKey tablesKey) {
213         return this.ribImpl.getExportPolicyPeerTracker(tablesKey);
214     }
215
216     @Override
217     public Set<TablesKey> getLocalTablesKeys() {
218         return this.ribImpl.getLocalTablesKeys();
219     }
220
221     @Override
222     public ServiceGroupIdentifier getRibIServiceGroupIdentifier() {
223         return this.ribImpl.getRibIServiceGroupIdentifier();
224     }
225
226     @Override
227     public String toString() {
228         return this.ribImpl != null ? this.ribImpl.toString() : null;
229     }
230
231     private RIBImpl createRib(
232             final Global global,
233             final String bgpInstanceName,
234             final BGPTableTypeRegistryConsumer tableTypeRegistry,
235             final BgpDeployer.WriteConfiguration configurationWriter) {
236         this.afiSafi = getAfiSafiWithDefault(global.getAfiSafis(), true);
237         final Config globalConfig = global.getConfig();
238         this.asNumber = globalConfig.getAs();
239         this.routerId = globalConfig.getRouterId();
240         this.clusterId = getClusterIdentifier(globalConfig);
241         final Map<TablesKey, PathSelectionMode> pathSelectionModes = OpenConfigMappingUtil
242                 .toPathSelectionMode(this.afiSafi, tableTypeRegistry).entrySet()
243                 .stream()
244                 .collect(Collectors.toMap(entry ->
245                         new TablesKey(entry.getKey().getAfi(), entry.getKey().getSafi()), Map.Entry::getValue));
246         return new RIBImpl(this.provider,
247                 new RibId(bgpInstanceName),
248                 this.asNumber,
249                 new BgpId(this.routerId),
250                 this.clusterId,
251                 this.extensions,
252                 this.dispatcher,
253                 this.codecTreeFactory,
254                 this.domBroker,
255                 toTableTypes(this.afiSafi, tableTypeRegistry),
256                 pathSelectionModes,
257                 this.extensions.getClassLoadingStrategy(),
258                 configurationWriter);
259     }
260
261     @Override
262     public ClusterSingletonServiceRegistration registerClusterSingletonService(
263             final ClusterSingletonService clusterSingletonService) {
264         return this.ribImpl.registerClusterSingletonService(clusterSingletonService);
265     }
266
267     @Override
268     public BGPRIBState getRIBState() {
269         return this.ribImpl.getRIBState();
270     }
271 }