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