BGPCEP-574: Remove old ImportPolicyPeerTracker
[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.Optional;
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.binding.dom.codec.api.BindingNormalizedNodeSerializer;
29 import org.opendaylight.mdsal.dom.api.DOMSchemaService;
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.BGPPeerTrackerImpl;
34 import org.opendaylight.protocol.bgp.rib.impl.CodecsRegistryImpl;
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.CodecsRegistry;
38 import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
39 import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContextRegistry;
40 import org.opendaylight.protocol.bgp.rib.spi.BGPPeerTracker;
41 import org.opendaylight.protocol.bgp.rib.spi.ExportPolicyPeerTracker;
42 import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
43 import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
44 import org.opendaylight.protocol.bgp.rib.spi.policy.BGPRibRoutingPolicy;
45 import org.opendaylight.protocol.bgp.rib.spi.state.BGPRIBState;
46 import org.opendaylight.protocol.bgp.rib.spi.state.BGPRIBStateConsumer;
47 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafi;
48 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.global.base.Config;
49 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Global;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.Attributes;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.BgpTableType;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.RibId;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.bgp.rib.Rib;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.bgp.rib.RibKey;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.TablesKey;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.BgpId;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.ClusterIdentifier;
60 import org.opendaylight.yangtools.concepts.ListenerRegistration;
61 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
62 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
63 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
64 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
65 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
66 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
67 import org.osgi.framework.ServiceRegistration;
68 import org.slf4j.Logger;
69 import org.slf4j.LoggerFactory;
70
71 public final class RibImpl implements RIB, BGPRIBStateConsumer, AutoCloseable {
72
73     private static final Logger LOG = LoggerFactory.getLogger(RibImpl.class);
74
75     private final RIBExtensionConsumerContext extensions;
76     private final BGPDispatcher dispatcher;
77     private final BindingCodecTreeFactory codecTreeFactory;
78     private final DOMDataBroker domBroker;
79     private final DOMSchemaService domSchemaService;
80     private final BGPRibRoutingPolicyFactory policyProvider;
81     private final BindingNormalizedNodeSerializer bindingSerializer;
82     private RIBImpl ribImpl;
83     private ServiceRegistration<?> serviceRegistration;
84     private ListenerRegistration<SchemaContextListener> schemaContextRegistration;
85     private List<AfiSafi> afiSafi;
86     private AsNumber asNumber;
87     private Ipv4Address routerId;
88
89     private ClusterIdentifier clusterId;
90
91     public RibImpl(
92             final RIBExtensionConsumerContext contextProvider,
93             final BGPDispatcher dispatcher,
94             final BGPRibRoutingPolicyFactory policyProvider,
95             final BindingCodecTreeFactory codecTreeFactory,
96             final DOMDataBroker domBroker,
97             final DOMSchemaService domSchemaService,
98             final BindingNormalizedNodeSerializer bindingSerializer
99     ) {
100         this.extensions = contextProvider;
101         this.dispatcher = dispatcher;
102         this.codecTreeFactory = codecTreeFactory;
103         this.domBroker = domBroker;
104         this.domSchemaService = domSchemaService;
105         this.policyProvider = policyProvider;
106         this.bindingSerializer = bindingSerializer;
107     }
108
109     void start(final Global global, final String instanceName, final BGPTableTypeRegistryConsumer tableTypeRegistry) {
110         Preconditions.checkState(this.ribImpl == null,
111                 "Previous instance %s was not closed.", this);
112         this.ribImpl = createRib(global, instanceName, tableTypeRegistry);
113         this.schemaContextRegistration = this.domSchemaService.registerSchemaContextListener(this.ribImpl);
114     }
115
116     Boolean isGlobalEqual(final Global global) {
117         final List<AfiSafi> globalAfiSafi = getAfiSafiWithDefault(global.getAfiSafis(), true);
118         final Config globalConfig = global.getConfig();
119         final AsNumber globalAs = globalConfig.getAs();
120         final Ipv4Address globalRouterId = global.getConfig().getRouterId();
121         final ClusterIdentifier globalClusterId = getClusterIdentifier(globalConfig);
122         return this.afiSafi.containsAll(globalAfiSafi) && globalAfiSafi.containsAll(this.afiSafi)
123                 && globalAs.equals(this.asNumber)
124                 && globalRouterId.getValue().equals(this.routerId.getValue())
125                 && globalClusterId.getValue().equals(this.clusterId.getValue());
126     }
127
128     @Override
129     public KeyedInstanceIdentifier<Rib, RibKey> getInstanceIdentifier() {
130         return this.ribImpl.getInstanceIdentifier();
131     }
132
133     @Override
134     public AsNumber getLocalAs() {
135         return this.ribImpl.getLocalAs();
136     }
137
138     @Override
139     public BgpId getBgpIdentifier() {
140         return this.ribImpl.getBgpIdentifier();
141     }
142
143     @Override
144     public Set<? extends BgpTableType> getLocalTables() {
145         return this.ribImpl.getLocalTables();
146     }
147
148     @Override
149     public BGPDispatcher getDispatcher() {
150         return this.ribImpl.getDispatcher();
151     }
152
153     @Override
154     public DOMTransactionChain createPeerChain(final TransactionChainListener listener) {
155         return this.ribImpl.createPeerChain(listener);
156     }
157
158     @Override
159     public RIBExtensionConsumerContext getRibExtensions() {
160         return this.ribImpl.getRibExtensions();
161     }
162
163     @Override
164     public RIBSupportContextRegistry getRibSupportContext() {
165         return this.ribImpl.getRibSupportContext();
166     }
167
168     @Override
169     public YangInstanceIdentifier getYangRibId() {
170         return this.ribImpl.getYangRibId();
171     }
172
173     @Override
174     public CodecsRegistry getCodecsRegistry() {
175         return this.ribImpl.getCodecsRegistry();
176     }
177
178     @Override
179     public DOMDataTreeChangeService getService() {
180         return this.ribImpl.getService();
181     }
182
183     ListenableFuture<Void> closeServiceInstance() {
184         if (this.ribImpl != null) {
185             return this.ribImpl.closeServiceInstance();
186         }
187         return Futures.immediateFuture(null);
188     }
189
190     @Override
191     public void close() {
192         if (this.ribImpl != null) {
193             try {
194                 this.ribImpl.close();
195             } catch (final Exception e) {
196                 LOG.warn("Failed to close {} rib instance", this, e);
197             }
198             this.ribImpl = null;
199         }
200         if (this.schemaContextRegistration != null) {
201             this.schemaContextRegistration.close();
202             this.schemaContextRegistration = null;
203         }
204         if (this.serviceRegistration != null) {
205             try {
206                 this.serviceRegistration.unregister();
207             } catch (final IllegalStateException e) {
208                 LOG.warn("Failed to unregister {} service instance", this, e);
209             }
210             this.serviceRegistration = null;
211         }
212     }
213
214     void setServiceRegistration(final ServiceRegistration<?> serviceRegistration) {
215         this.serviceRegistration = serviceRegistration;
216     }
217
218     @Override
219     public ExportPolicyPeerTracker getExportPolicyPeerTracker(final TablesKey tablesKey) {
220         return this.ribImpl.getExportPolicyPeerTracker(tablesKey);
221     }
222
223     @Override
224     public Set<TablesKey> getLocalTablesKeys() {
225         return this.ribImpl.getLocalTablesKeys();
226     }
227
228     @Override
229     public boolean supportsTable(final TablesKey tableKey) {
230         return this.ribImpl.supportsTable(tableKey);
231     }
232
233     @Override
234     public BGPRibRoutingPolicy getRibPolicies() {
235         return this.ribImpl.getRibPolicies();
236     }
237
238     @Override
239     public BGPPeerTracker getPeerTracker() {
240         return this.ribImpl.getPeerTracker();
241     }
242
243     @Override
244     public String toString() {
245         return this.ribImpl != null ? this.ribImpl.toString() : "";
246     }
247
248     private RIBImpl createRib(
249             final Global global,
250             final String bgpInstanceName,
251             final BGPTableTypeRegistryConsumer tableTypeRegistry) {
252         this.afiSafi = getAfiSafiWithDefault(global.getAfiSafis(), true);
253         final Config globalConfig = global.getConfig();
254         this.asNumber = globalConfig.getAs();
255         this.routerId = globalConfig.getRouterId();
256         this.clusterId = getClusterIdentifier(globalConfig);
257         final BGPPeerTrackerImpl peerTracker = new BGPPeerTrackerImpl();
258         final Map<TablesKey, PathSelectionMode> pathSelectionModes = OpenConfigMappingUtil
259                 .toPathSelectionMode(this.afiSafi, tableTypeRegistry, peerTracker).entrySet()
260                 .stream()
261                 .collect(Collectors.toMap(entry ->
262                         new TablesKey(entry.getKey().getAfi(), entry.getKey().getSafi()), Map.Entry::getValue));
263
264         final BGPRibRoutingPolicy ribPolicy = this.policyProvider.buildBGPRibPolicy(this.asNumber.getValue(),
265                 this.routerId, this.clusterId, RoutingPolicyUtil.getApplyPolicy(global.getApplyPolicy()));
266         final CodecsRegistryImpl codecsRegistry = CodecsRegistryImpl.create(codecTreeFactory,
267                 this.extensions.getClassLoadingStrategy());
268
269         return new RIBImpl(
270                 new RibId(bgpInstanceName),
271                 this.asNumber,
272                 new BgpId(this.routerId),
273                 this.clusterId,
274                 this.extensions,
275                 this.dispatcher,
276                 codecsRegistry,
277                 this.domBroker,
278                 ribPolicy,
279                 peerTracker,
280                 toTableTypes(this.afiSafi, tableTypeRegistry),
281                 pathSelectionModes,
282                 this.bindingSerializer);
283     }
284
285     @Override
286     public BGPRIBState getRIBState() {
287         return this.ribImpl.getRIBState();
288     }
289
290     public void instantiateServiceInstance() {
291         if (this.ribImpl != null) {
292             this.ribImpl.instantiateServiceInstance();
293         }
294     }
295
296     @Override
297     public Optional<Attributes> getAttributes(
298             RIBSupport ribSupport,
299             NodeIdentifierWithPredicates routeIdentifier, NormalizedNode<?, ?> route) {
300         return this.ribImpl.getAttributes(ribSupport, routeIdentifier, route);
301     }
302
303     @Override
304     public Optional<ContainerNode> toNormalizedNodeAttribute(
305             final RIBSupport ribSupport,
306             final NodeIdentifierWithPredicates routeIdentifier,
307             final Optional<Attributes> attributes) {
308         return this.ribImpl.toNormalizedNodeAttribute(ribSupport, routeIdentifier, attributes);
309     }
310 }