2 * Copyright (c) 2014 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.md.sal.binding.impl;
10 import java.util.HashMap;
11 import java.util.HashSet;
13 import java.util.Map.Entry;
16 import org.eclipse.xtext.xbase.lib.Exceptions;
17 import org.opendaylight.controller.md.sal.binding.api.BindingDataChangeListener;
18 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
19 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
20 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
21 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
22 import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener;
23 import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;
24 import org.opendaylight.controller.sal.binding.impl.forward.DomForwardedBroker;
25 import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
26 import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
27 import org.opendaylight.yangtools.concepts.Delegator;
28 import org.opendaylight.yangtools.concepts.ListenerRegistration;
29 import org.opendaylight.yangtools.yang.binding.DataObject;
30 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
31 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
32 import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
33 import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
34 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
35 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
39 public abstract class AbstractForwardedDataBroker implements Delegator<DOMDataBroker>, DomForwardedBroker, SchemaContextListener {
41 private static final Logger LOG = LoggerFactory.getLogger(AbstractForwardedDataBroker.class);
42 // The Broker to whom we do all forwarding
43 private final DOMDataBroker domDataBroker;
45 // Mapper to convert from Binding Independent objects to Binding Aware
47 private final BindingIndependentMappingService mappingService;
49 private final BindingToNormalizedNodeCodec codec;
50 private BindingIndependentConnector connector;
51 private ProviderSession context;
53 protected AbstractForwardedDataBroker(final DOMDataBroker domDataBroker,
54 final BindingIndependentMappingService mappingService) {
55 this.domDataBroker = domDataBroker;
56 this.mappingService = mappingService;
57 this.codec = new BindingToNormalizedNodeCodec(mappingService);
60 protected BindingToNormalizedNodeCodec getCodec() {
64 protected BindingIndependentMappingService getMappingService() {
65 return mappingService;
69 public DOMDataBroker getDelegate() {
74 public void onGlobalContextUpdated(final SchemaContext ctx) {
75 codec.onGlobalContextUpdated(ctx);
78 public ListenerRegistration<BindingDataChangeListener> registerDataChangeListener(final LogicalDatastoreType store,
79 final InstanceIdentifier<?> path, final BindingDataChangeListener listener,
80 final DataChangeScope triggeringScope) {
81 DOMDataChangeListener domDataChangeListener = new TranslatingDataChangeInvoker(store, path, listener,
83 org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = codec.toNormalized(path);
84 ListenerRegistration<DOMDataChangeListener> domRegistration = domDataBroker.registerDataChangeListener(store, domPath, domDataChangeListener, triggeringScope);
85 return new ListenerRegistrationImpl(listener, domRegistration);
88 protected Map<InstanceIdentifier<?>, DataObject> fromDOMToData(
89 final Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, ? extends NormalizedNode<?, ?>> normalized) {
90 Map<InstanceIdentifier<?>, DataObject> newMap = new HashMap<>();
91 for (Map.Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, ? extends NormalizedNode<?, ?>> entry : normalized
94 Entry<InstanceIdentifier<? extends DataObject>, DataObject> binding = getCodec().toBinding(entry);
95 newMap.put(binding.getKey(), binding.getValue());
96 } catch (DeserializationException e) {
97 LOG.debug("Ommiting {}",entry,e);
103 private class TranslatingDataChangeInvoker implements DOMDataChangeListener {
104 private final BindingDataChangeListener bindingDataChangeListener;
105 private final LogicalDatastoreType store;
106 private final InstanceIdentifier<?> path;
107 private final DataChangeScope triggeringScope;
109 public TranslatingDataChangeInvoker(final LogicalDatastoreType store, final InstanceIdentifier<?> path,
110 final BindingDataChangeListener bindingDataChangeListener, final DataChangeScope triggeringScope) {
113 this.bindingDataChangeListener = bindingDataChangeListener;
114 this.triggeringScope = triggeringScope;
118 public void onDataChanged(
119 final AsyncDataChangeEvent<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> change) {
120 bindingDataChangeListener.onDataChanged(new TranslatedDataChangeEvent(change,path));
124 private class TranslatedDataChangeEvent implements AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> {
125 private final AsyncDataChangeEvent<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> domEvent;
126 private InstanceIdentifier<?> path;
128 public TranslatedDataChangeEvent(
129 final AsyncDataChangeEvent<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> change) {
130 this.domEvent = change;
133 public TranslatedDataChangeEvent(
134 final AsyncDataChangeEvent<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> change,
135 final InstanceIdentifier<?> path) {
136 this.domEvent = change;
141 public Map<InstanceIdentifier<?>, DataObject> getCreatedData() {
142 return fromDOMToData(domEvent.getCreatedData());
146 public Map<InstanceIdentifier<?>, DataObject> getUpdatedData() {
147 return fromDOMToData(domEvent.getUpdatedData());
152 public Set<InstanceIdentifier<?>> getRemovedPaths() {
153 final Set<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> removedPaths = domEvent
155 final Set<InstanceIdentifier<?>> output = new HashSet<>();
156 for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier instanceIdentifier : removedPaths) {
158 output.add(mappingService.fromDataDom(instanceIdentifier));
159 } catch (DeserializationException e) {
160 Exceptions.sneakyThrow(e);
168 public Map<InstanceIdentifier<?>, ? extends DataObject> getOriginalData() {
169 return fromDOMToData(domEvent.getOriginalData());
174 public DataObject getOriginalSubtree() {
176 return toBindingData(path,domEvent.getOriginalSubtree());
180 public DataObject getUpdatedSubtree() {
182 return toBindingData(path,domEvent.getUpdatedSubtree());
186 public String toString() {
187 return "TranslatedDataChangeEvent [domEvent=" + domEvent + "]";
191 private static class ListenerRegistrationImpl extends AbstractListenerRegistration<BindingDataChangeListener> {
192 private final ListenerRegistration<DOMDataChangeListener> registration;
194 public ListenerRegistrationImpl(final BindingDataChangeListener listener,
195 final ListenerRegistration<DOMDataChangeListener> registration) {
197 this.registration = registration;
201 protected void removeRegistration() {
202 registration.close();
206 protected DataObject toBindingData(final InstanceIdentifier<?> path, final NormalizedNode<?, ?> data) {
208 return getCodec().toBinding(path, data);
209 } catch (DeserializationException e) {
216 public BindingIndependentConnector getConnector() {
217 return this.connector;
221 public ProviderSession getDomProviderContext() {
226 public void setConnector(final BindingIndependentConnector connector) {
227 this.connector = connector;
231 public void setDomProviderContext(final ProviderSession domProviderContext) {
232 this.context = domProviderContext;
236 public void startForwarding() {