603094a0be79ee4216c1dfe62e1d7120742b19a4
[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
13 import com.google.common.base.Optional;
14 import com.google.common.base.Preconditions;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.Set;
18 import java.util.stream.Collectors;
19 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
20 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
21 import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeService;
22 import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
23 import org.opendaylight.controller.sal.core.api.model.SchemaService;
24 import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTreeFactory;
25 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
26 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
27 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
28 import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
29 import org.opendaylight.protocol.bgp.mode.api.PathSelectionMode;
30 import org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenConfigMappingService;
31 import org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenConfigProvider;
32 import org.opendaylight.protocol.bgp.rib.impl.RIBImpl;
33 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher;
34 import org.opendaylight.protocol.bgp.rib.impl.spi.BgpDeployer;
35 import org.opendaylight.protocol.bgp.rib.impl.spi.CodecsRegistry;
36 import org.opendaylight.protocol.bgp.rib.impl.spi.ImportPolicyPeerTracker;
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.impl.stats.rib.impl.BGPRenderStats;
40 import org.opendaylight.protocol.bgp.rib.spi.ExportPolicyPeerTracker;
41 import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
42 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafi;
43 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.global.base.Config;
44 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Global;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
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.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.RibId;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.Rib;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.RibKey;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.BgpId;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.ClusterIdentifier;
54 import org.opendaylight.yangtools.concepts.ListenerRegistration;
55 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
56 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
57 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
58 import org.osgi.framework.ServiceRegistration;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
61
62 public final class RibImpl implements RIB, 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 BindingCodecTreeFactory codecTreeFactory;
69     private final DOMDataBroker domBroker;
70     private final SchemaService schemaService;
71     private RIBImpl ribImpl;
72     private ServiceRegistration<?> serviceRegistration;
73     private ListenerRegistration<SchemaContextListener> schemaContextRegistration;
74     private final ClusterSingletonServiceProvider provider;
75     private List<AfiSafi> afiSafi;
76     private AsNumber asNumber;
77     private Ipv4Address routerId;
78
79     private ClusterIdentifier clusterId;
80
81     public RibImpl(final ClusterSingletonServiceProvider provider, final RIBExtensionConsumerContext contextProvider, final BGPDispatcher dispatcher,
82             final BindingCodecTreeFactory codecTreeFactory, final DOMDataBroker domBroker, final SchemaService schemaService) {
83         this.provider = Preconditions.checkNotNull(provider);
84         this.extensions = contextProvider;
85         this.dispatcher = dispatcher;
86         this.codecTreeFactory = codecTreeFactory;
87         this.domBroker = domBroker;
88         this.schemaService = schemaService;
89     }
90
91     void start(final Global global, final String instanceName, final BGPOpenConfigMappingService mappingService,
92         final BgpDeployer.WriteConfiguration configurationWriter) {
93         Preconditions.checkState(this.ribImpl == null, "Previous instance %s was not closed.", this);
94         this.ribImpl = createRib(this.provider, global, instanceName, mappingService, configurationWriter);
95         this.schemaContextRegistration = this.schemaService.registerSchemaContextListener(this.ribImpl);
96     }
97
98     Boolean isGlobalEqual(final Global global) {
99         final List<AfiSafi> globalAfiSafi = getAfiSafiWithDefault(global.getAfiSafis(), true);
100         final Config globalConfig = global.getConfig();
101         final AsNumber globalAs = globalConfig.getAs();
102         final Ipv4Address globalRouterId = global.getConfig().getRouterId();
103         final ClusterIdentifier globalClusterId = OpenConfigMappingUtil.getClusterIdentifier(globalConfig);
104         return this.afiSafi.containsAll(globalAfiSafi) && globalAfiSafi.containsAll(this.afiSafi)
105             && globalAs.equals(this.asNumber)
106             && globalRouterId.getValue().equals(this.routerId.getValue())
107             && globalClusterId.getValue().equals(this.clusterId.getValue());
108     }
109
110     @Override
111     public KeyedInstanceIdentifier<Rib, RibKey> getInstanceIdentifier() {
112         return this.ribImpl.getInstanceIdentifier();
113     }
114
115     @Override
116     public AsNumber getLocalAs() {
117         return this.ribImpl.getLocalAs();
118     }
119
120     @Override
121     public BgpId getBgpIdentifier() {
122         return this.ribImpl.getBgpIdentifier();
123     }
124
125     @Override
126     public Set<? extends BgpTableType> getLocalTables() {
127         return this.ribImpl.getLocalTables();
128     }
129
130     @Override
131     public BGPDispatcher getDispatcher() {
132         return this.ribImpl.getDispatcher();
133     }
134
135     @Override
136     public DOMTransactionChain createPeerChain(final TransactionChainListener listener) {
137         return this.ribImpl.createPeerChain(listener);
138     }
139
140     @Override
141     public RIBExtensionConsumerContext getRibExtensions() {
142         return this.ribImpl.getRibExtensions();
143     }
144
145     @Override
146     public RIBSupportContextRegistry getRibSupportContext() {
147         return this.ribImpl.getRibSupportContext();
148     }
149
150     @Override
151     public YangInstanceIdentifier getYangRibId() {
152         return this.ribImpl.getYangRibId();
153     }
154
155     @Override
156     public CodecsRegistry getCodecsRegistry() {
157         return this.ribImpl.getCodecsRegistry();
158     }
159
160     @Override
161     public Optional<BGPOpenConfigProvider> getOpenConfigProvider() {
162         return this.ribImpl.getOpenConfigProvider();
163     }
164
165     @Override
166     public DOMDataTreeChangeService getService() {
167         return this.ribImpl.getService();
168     }
169
170     @Override
171     public void close() {
172         if (this.ribImpl != null) {
173             try {
174                 this.ribImpl.close();
175             } catch (final Exception e) {
176                 LOG.warn("Failed to close {} rib instance", this, e);
177             }
178             this.ribImpl = null;
179         }
180         if (this.schemaContextRegistration != null) {
181             this.schemaContextRegistration.close();
182             this.schemaContextRegistration = null;
183         }
184         if (this.serviceRegistration != null) {
185             try {
186                 this.serviceRegistration.unregister();
187             } catch(final IllegalStateException e) {
188                 LOG.warn("Failed to unregister {} service instance", this, e);
189             }
190             this.serviceRegistration = null;
191         }
192     }
193
194     void setServiceRegistration(final ServiceRegistration<?> serviceRegistration) {
195         this.serviceRegistration = serviceRegistration;
196     }
197
198     @Override
199     public BGPRenderStats getRenderStats() {
200         return this.ribImpl.getRenderStats();
201     }
202
203     @Override
204     public ImportPolicyPeerTracker getImportPolicyPeerTracker() {
205         return this.ribImpl.getImportPolicyPeerTracker();
206     }
207
208     @Override
209     public ExportPolicyPeerTracker getExportPolicyPeerTracker(final TablesKey tablesKey) {
210         return this.ribImpl.getExportPolicyPeerTracker(tablesKey);
211     }
212
213     @Override
214     public Set<TablesKey> getLocalTablesKeys() {
215         return this.ribImpl.getLocalTablesKeys();
216     }
217
218     @Override
219     public ServiceGroupIdentifier getRibIServiceGroupIdentifier() {
220         return this.ribImpl.getRibIServiceGroupIdentifier();
221     }
222
223     @Override
224     public String toString() {
225         return this.ribImpl != null ? this.ribImpl.toString() : null;
226     }
227
228     private RIBImpl createRib(final ClusterSingletonServiceProvider provider, final Global global, final String bgpInstanceName,
229         final BGPOpenConfigMappingService mappingService, final BgpDeployer.WriteConfiguration configurationWriter) {
230         this.afiSafi = getAfiSafiWithDefault(global.getAfiSafis(), true);
231         final Config globalConfig = global.getConfig();
232         this.asNumber = globalConfig.getAs();
233         this.routerId = globalConfig.getRouterId();
234         this.clusterId = OpenConfigMappingUtil.getClusterIdentifier(globalConfig);
235         final Map<TablesKey, PathSelectionMode> pathSelectionModes = mappingService.toPathSelectionMode(this.afiSafi).entrySet()
236                 .stream().collect(Collectors.toMap(entry -> new TablesKey(entry.getKey().getAfi(), entry.getKey().getSafi()), Map.Entry::getValue));
237         return new RIBImpl(provider, new RibId(bgpInstanceName), this.asNumber, new BgpId(this.routerId), this.clusterId,
238                 this.extensions, this.dispatcher, this.codecTreeFactory, this.domBroker, mappingService.toTableTypes(this.afiSafi), pathSelectionModes,
239                 this.extensions.getClassLoadingStrategy(), configurationWriter);
240     }
241
242     @Override
243     public ClusterSingletonServiceRegistration registerClusterSingletonService(final ClusterSingletonService clusterSingletonService) {
244         return this.ribImpl.registerClusterSingletonService(clusterSingletonService);
245     }
246 }