Fix findbug issues
[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 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;
14
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;
19 import java.util.Map;
20 import java.util.Set;
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;
59
60 public final class RibImpl implements RIB, BGPRIBStateConsumer, AutoCloseable {
61
62     private static final Logger LOG = LoggerFactory.getLogger(RibImpl.class);
63
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;
75
76     private ClusterIdentifier clusterId;
77
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;
86     }
87
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);
93     }
94
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());
105     }
106
107     @Override
108     public KeyedInstanceIdentifier<Rib, RibKey> getInstanceIdentifier() {
109         return this.ribImpl.getInstanceIdentifier();
110     }
111
112     @Override
113     public AsNumber getLocalAs() {
114         return this.ribImpl.getLocalAs();
115     }
116
117     @Override
118     public BgpId getBgpIdentifier() {
119         return this.ribImpl.getBgpIdentifier();
120     }
121
122     @Override
123     public Set<? extends BgpTableType> getLocalTables() {
124         return this.ribImpl.getLocalTables();
125     }
126
127     @Override
128     public BGPDispatcher getDispatcher() {
129         return this.ribImpl.getDispatcher();
130     }
131
132     @Override
133     public DOMTransactionChain createPeerChain(final TransactionChainListener listener) {
134         return this.ribImpl.createPeerChain(listener);
135     }
136
137     @Override
138     public RIBExtensionConsumerContext getRibExtensions() {
139         return this.ribImpl.getRibExtensions();
140     }
141
142     @Override
143     public RIBSupportContextRegistry getRibSupportContext() {
144         return this.ribImpl.getRibSupportContext();
145     }
146
147     @Override
148     public YangInstanceIdentifier getYangRibId() {
149         return this.ribImpl.getYangRibId();
150     }
151
152     @Override
153     public CodecsRegistry getCodecsRegistry() {
154         return this.ribImpl.getCodecsRegistry();
155     }
156
157     @Override
158     public DOMDataTreeChangeService getService() {
159         return this.ribImpl.getService();
160     }
161
162     ListenableFuture<Void> closeServiceInstance() {
163         if (this.ribImpl != null) {
164             return this.ribImpl.closeServiceInstance();
165         }
166         return Futures.immediateFuture(null);
167     }
168
169     @Override
170     public void close() {
171         if (this.ribImpl != null) {
172             try {
173                 this.ribImpl.close();
174             } catch (final Exception e) {
175                 LOG.warn("Failed to close {} rib instance", this, e);
176             }
177             this.ribImpl = null;
178         }
179         if (this.schemaContextRegistration != null) {
180             this.schemaContextRegistration.close();
181             this.schemaContextRegistration = null;
182         }
183         if (this.serviceRegistration != null) {
184             try {
185                 this.serviceRegistration.unregister();
186             } catch (final IllegalStateException e) {
187                 LOG.warn("Failed to unregister {} service instance", this, e);
188             }
189             this.serviceRegistration = null;
190         }
191     }
192
193     void setServiceRegistration(final ServiceRegistration<?> serviceRegistration) {
194         this.serviceRegistration = serviceRegistration;
195     }
196
197     @Override
198     public ImportPolicyPeerTracker getImportPolicyPeerTracker() {
199         return this.ribImpl.getImportPolicyPeerTracker();
200     }
201
202     @Override
203     public ExportPolicyPeerTracker getExportPolicyPeerTracker(final TablesKey tablesKey) {
204         return this.ribImpl.getExportPolicyPeerTracker(tablesKey);
205     }
206
207     @Override
208     public Set<TablesKey> getLocalTablesKeys() {
209         return this.ribImpl.getLocalTablesKeys();
210     }
211
212     @Override
213     public String toString() {
214         return this.ribImpl != null ? this.ribImpl.toString() : "";
215     }
216
217     private RIBImpl createRib(
218             final Global global,
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()
228                 .stream()
229                 .collect(Collectors.toMap(entry ->
230                         new TablesKey(entry.getKey().getAfi(), entry.getKey().getSafi()), Map.Entry::getValue));
231         return new RIBImpl(
232                 new RibId(bgpInstanceName),
233                 this.asNumber,
234                 new BgpId(this.routerId),
235                 this.clusterId,
236                 this.extensions,
237                 this.dispatcher,
238                 this.codecTreeFactory,
239                 this.domBroker,
240                 toTableTypes(this.afiSafi, tableTypeRegistry),
241                 pathSelectionModes,
242                 this.extensions.getClassLoadingStrategy());
243     }
244
245     @Override
246     public BGPRIBState getRIBState() {
247         return this.ribImpl.getRIBState();
248     }
249
250     public void instantiateServiceInstance() {
251         if (this.ribImpl != null) {
252             this.ribImpl.instantiateServiceInstance();
253         }
254     }
255 }