2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.controller.sal.binding.impl.connect.dom;
10 import static com.google.common.base.Preconditions.checkNotNull;
11 import static com.google.common.base.Preconditions.checkState;
13 import java.util.Collection;
14 import java.util.Collections;
15 import java.util.concurrent.ConcurrentHashMap;
16 import java.util.concurrent.ConcurrentMap;
18 import org.opendaylight.controller.md.sal.binding.impl.AbstractForwardedDataBroker;
19 import org.opendaylight.controller.md.sal.common.api.data.DataReader;
20 import org.opendaylight.controller.md.sal.common.api.routing.RouteChangePublisher;
21 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
22 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
23 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
24 import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl;
25 import org.opendaylight.controller.sal.binding.impl.MountPointManagerImpl.BindingMountPointImpl;
26 import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl;
27 import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
28 import org.opendaylight.controller.sal.core.api.Provider;
29 import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
30 import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
31 import org.opendaylight.yangtools.concepts.ListenerRegistration;
32 import org.opendaylight.yangtools.concepts.Registration;
33 import org.opendaylight.yangtools.yang.binding.Augmentable;
34 import org.opendaylight.yangtools.yang.binding.Augmentation;
35 import org.opendaylight.yangtools.yang.binding.DataObject;
36 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
37 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
38 import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
39 import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
43 public class BindingIndependentConnector implements //
44 DataReader<InstanceIdentifier<? extends DataObject>, DataObject>, //
48 private static final Logger LOG = LoggerFactory.getLogger(BindingIndependentConnector.class);
49 private static final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier ROOT_BI = org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier
50 .builder().toInstance();
52 private BindingIndependentMappingService mappingService;
53 private org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService;
54 private DataProviderService baDataService;
56 private final ConcurrentMap<Object, BindingToDomTransaction> domOpenedTransactions;
57 private final ConcurrentMap<Object, DomToBindingTransaction> bindingOpenedTransactions;
58 private final BindingToDomCommitHandler bindingToDomCommitHandler;
59 private final DomToBindingCommitHandler domToBindingCommitHandler;
61 private Registration biCommitHandlerRegistration;
62 private RpcProvisionRegistry biRpcRegistry;
63 private RpcProviderRegistry baRpcRegistry;
65 private ListenerRegistration<DomToBindingRpcForwardingManager> domToBindingRpcManager;
67 private boolean rpcForwarding;
68 private boolean dataForwarding;
69 private boolean notificationForwarding;
71 private RpcProviderRegistryImpl baRpcRegistryImpl;
73 private NotificationProviderService baNotifyService;
75 private NotificationPublishService domNotificationService;
77 public BindingIndependentConnector() {
78 domOpenedTransactions = new ConcurrentHashMap<>();
79 bindingOpenedTransactions = new ConcurrentHashMap<>();
81 bindingToDomCommitHandler = new BindingToDomCommitHandler(bindingOpenedTransactions, domOpenedTransactions);
82 domToBindingCommitHandler = new DomToBindingCommitHandler(bindingOpenedTransactions, domOpenedTransactions);
83 rpcForwarding = false;
84 dataForwarding = false;
85 notificationForwarding = false;
89 public DataObject readOperationalData(final InstanceIdentifier<? extends DataObject> path) {
91 org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier biPath = mappingService.toDataDom(path);
92 CompositeNode result = biDataService.readOperationalData(biPath);
93 return potentialAugmentationRead(path, biPath, result);
94 } catch (DeserializationException e) {
95 throw new IllegalStateException(e);
99 private DataObject potentialAugmentationRead(InstanceIdentifier<? extends DataObject> path,
100 final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier biPath, final CompositeNode result)
101 throws DeserializationException {
102 Class<? extends DataObject> targetType = path.getTargetType();
103 if (Augmentation.class.isAssignableFrom(targetType)) {
104 path = mappingService.fromDataDom(biPath);
105 Class<? extends Augmentation<?>> augmentType = (Class<? extends Augmentation<?>>) targetType;
106 DataObject parentTo = mappingService.dataObjectFromDataDom(path, result);
107 if (parentTo instanceof Augmentable<?>) {
108 return (DataObject) ((Augmentable) parentTo).getAugmentation(augmentType);
111 return mappingService.dataObjectFromDataDom(path, result);
115 public DataObject readConfigurationData(final InstanceIdentifier<? extends DataObject> path) {
117 org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier biPath = mappingService.toDataDom(path);
118 CompositeNode result = biDataService.readConfigurationData(biPath);
119 return potentialAugmentationRead(path, biPath, result);
120 } catch (DeserializationException e) {
121 throw new IllegalStateException(e);
125 public org.opendaylight.controller.sal.core.api.data.DataProviderService getBiDataService() {
126 return biDataService;
129 protected void setDomDataService(
130 final org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService) {
131 this.biDataService = biDataService;
132 bindingToDomCommitHandler.setBindingIndependentDataService(this.biDataService);
135 public DataProviderService getBaDataService() {
136 return baDataService;
139 protected void setBindingDataService(final DataProviderService baDataService) {
140 this.baDataService = baDataService;
141 domToBindingCommitHandler.setBindingAwareDataService(this.baDataService);
144 public RpcProviderRegistry getRpcRegistry() {
145 return baRpcRegistry;
148 protected void setBindingRpcRegistry(final RpcProviderRegistry rpcRegistry) {
149 this.baRpcRegistry = rpcRegistry;
152 public void startDataForwarding() {
153 if (baDataService instanceof AbstractForwardedDataBroker) {
154 dataForwarding = true;
158 final DataProviderService baData;
159 if (baDataService instanceof BindingMountPointImpl) {
160 baData = ((BindingMountPointImpl) baDataService).getDataBrokerImpl();
161 LOG.debug("Extracted BA Data provider {} from mount point {}", baData, baDataService);
163 baData = baDataService;
166 if (baData instanceof DataBrokerImpl) {
167 checkState(!dataForwarding, "Connector is already forwarding data.");
168 ((DataBrokerImpl) baData).setDataReadDelegate(this);
169 ((DataBrokerImpl) baData).setRootCommitHandler(bindingToDomCommitHandler);
170 biCommitHandlerRegistration = biDataService.registerCommitHandler(ROOT_BI, domToBindingCommitHandler);
171 baDataService.registerCommitHandlerListener(domToBindingCommitHandler);
174 dataForwarding = true;
177 //WTF? - cycle references to biFwdManager - need to solve :-/
178 public void startRpcForwarding() {
179 checkNotNull(mappingService, "Unable to start Rpc forwarding. Reason: Mapping Service is not initialized properly!");
180 if (biRpcRegistry != null && baRpcRegistry instanceof RouteChangePublisher<?, ?>) {
181 checkState(!rpcForwarding, "Connector is already forwarding RPCs");
182 final DomToBindingRpcForwardingManager biFwdManager = new DomToBindingRpcForwardingManager(mappingService, biRpcRegistry, baRpcRegistry);
184 domToBindingRpcManager = baRpcRegistry.registerRouteChangeListener(biFwdManager);
185 biRpcRegistry.addRpcRegistrationListener(biFwdManager);
186 if (baRpcRegistry instanceof RpcProviderRegistryImpl) {
187 baRpcRegistryImpl = (RpcProviderRegistryImpl) baRpcRegistry;
188 baRpcRegistryImpl.registerRouterInstantiationListener(domToBindingRpcManager.getInstance());
189 baRpcRegistryImpl.registerGlobalRpcRegistrationListener(domToBindingRpcManager.getInstance());
190 biFwdManager.setRegistryImpl(baRpcRegistryImpl);
192 rpcForwarding = true;
196 public void startNotificationForwarding() {
197 checkState(!notificationForwarding, "Connector is already forwarding notifications.");
198 if (mappingService == null) {
199 LOG.warn("Unable to start Notification forwarding. Reason: Mapping Service is not initialized properly!");
200 } else if (baNotifyService == null) {
201 LOG.warn("Unable to start Notification forwarding. Reason: Binding Aware Notify Service is not initialized properly!");
202 } else if (domNotificationService == null) {
203 LOG.warn("Unable to start Notification forwarding. Reason: DOM Notification Service is not initialized properly!");
205 baNotifyService.registerInterestListener(
206 new DomToBindingNotificationForwarder(mappingService, baNotifyService, domNotificationService));
207 notificationForwarding = true;
211 protected void setMappingService(final BindingIndependentMappingService mappingService) {
212 this.mappingService = mappingService;
213 bindingToDomCommitHandler.setMappingService(this.mappingService);
214 domToBindingCommitHandler.setMappingService(this.mappingService);
218 public Collection<ProviderFunctionality> getProviderFunctionality() {
219 return Collections.emptyList();
223 public void onSessionInitiated(final ProviderSession session) {
224 setDomDataService(session.getService(org.opendaylight.controller.sal.core.api.data.DataProviderService.class));
225 setDomRpcRegistry(session.getService(RpcProvisionRegistry.class));
229 public void setDomRpcRegistry(final RpcProvisionRegistry registry) {
230 biRpcRegistry = registry;
234 public void close() throws Exception {
235 if (biCommitHandlerRegistration != null) {
236 biCommitHandlerRegistration.close();
240 public boolean isRpcForwarding() {
241 return rpcForwarding;
244 public boolean isDataForwarding() {
245 return dataForwarding;
248 public boolean isNotificationForwarding() {
249 return notificationForwarding;
252 public BindingIndependentMappingService getMappingService() {
253 return mappingService;
256 public void setBindingNotificationService(final NotificationProviderService baService) {
257 this.baNotifyService = baService;
261 public void setDomNotificationService(final NotificationPublishService domService) {
262 this.domNotificationService = domService;