1 package org.opendaylight.controller.sal.dom.broker.impl;
3 import java.awt.PageAttributes.OriginType;
4 import java.util.ArrayList;
5 import java.util.Collections;
6 import java.util.Comparator;
7 import java.util.HashSet;
10 import java.util.Map.Entry;
12 import java.util.concurrent.atomic.AtomicLong;
14 import org.opendaylight.controller.md.sal.common.api.data.DataModification;
15 import org.opendaylight.controller.md.sal.common.api.data.DataReader;
16 import org.opendaylight.controller.md.sal.common.impl.util.AbstractLockableDelegator;
17 import org.opendaylight.controller.sal.core.api.data.DataStore;
18 import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener;
19 import org.opendaylight.yangtools.yang.common.QName;
20 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
21 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
22 import org.opendaylight.yangtools.yang.data.api.Node;
23 import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
24 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
28 import com.google.common.base.Predicate;
29 import com.google.common.collect.FluentIterable;
31 import static com.google.common.base.Preconditions.*;
33 public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataStore> implements //
35 SchemaServiceListener, //
38 private final static Logger LOG = LoggerFactory.getLogger(SchemaAwareDataStoreAdapter.class);
40 private SchemaContext schema = null;
41 private boolean validationEnabled = false;
42 private SchemaAwareDataMerger dataMerger = null;
43 private DataReader<InstanceIdentifier, CompositeNode> reader = new MergeFirstLevelReader();
46 public boolean containsConfigurationPath(InstanceIdentifier path) {
48 getDelegateReadLock().lock();
49 return getDelegate().containsConfigurationPath(path);
52 getDelegateReadLock().unlock();
57 public boolean containsOperationalPath(InstanceIdentifier path) {
59 getDelegateReadLock().lock();
60 return getDelegate().containsOperationalPath(path);
63 getDelegateReadLock().unlock();
68 public Iterable<InstanceIdentifier> getStoredConfigurationPaths() {
70 getDelegateReadLock().lock();
71 return getDelegate().getStoredConfigurationPaths();
74 getDelegateReadLock().unlock();
79 public Iterable<InstanceIdentifier> getStoredOperationalPaths() {
81 getDelegateReadLock().lock();
82 return getDelegate().getStoredOperationalPaths();
85 getDelegateReadLock().unlock();
90 public CompositeNode readConfigurationData(InstanceIdentifier path) {
91 return reader.readConfigurationData(path);
95 public CompositeNode readOperationalData(InstanceIdentifier path) {
96 return reader.readOperationalData(path);
100 public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<InstanceIdentifier, CompositeNode> requestCommit(
101 DataModification<InstanceIdentifier, CompositeNode> modification) {
102 validateAgainstSchema(modification);
103 DataModification<InstanceIdentifier, CompositeNode> cleanedUp = prepareMergedTransaction(modification);
104 return retrieveDelegate().requestCommit(cleanedUp);
107 public boolean isValidationEnabled() {
108 return validationEnabled;
111 public void setValidationEnabled(boolean validationEnabled) {
112 this.validationEnabled = validationEnabled;
115 private void validateAgainstSchema(DataModification<InstanceIdentifier, CompositeNode> modification) {
116 if (!validationEnabled) {
120 if (schema == null) {
121 LOG.info("Validation not performed for {}. Reason: YANG Schema not present.", modification.getIdentifier());
127 protected void onDelegateChanged(DataStore oldDelegate, DataStore newDelegate) {
132 public void onGlobalContextUpdated(SchemaContext context) {
133 this.schema = context;
137 public void close() throws Exception {
141 private DataModification<InstanceIdentifier, CompositeNode> prepareMergedTransaction(
142 DataModification<InstanceIdentifier, CompositeNode> original) {
147 private final Comparator<Entry<InstanceIdentifier, CompositeNode>> preparationComparator = new Comparator<Entry<InstanceIdentifier, CompositeNode>>() {
149 public int compare(Entry<InstanceIdentifier, CompositeNode> o1, Entry<InstanceIdentifier, CompositeNode> o2) {
150 InstanceIdentifier o1Key = o1.getKey();
151 InstanceIdentifier o2Key = o2.getKey();
152 return Integer.compare(o1Key.getPath().size(), o2Key.getPath().size());
156 private class MergeFirstLevelReader implements DataReader<InstanceIdentifier, CompositeNode> {
159 public CompositeNode readConfigurationData(final InstanceIdentifier path) {
160 getDelegateReadLock().lock();
162 if (path.getPath().isEmpty()) {
166 CompositeNode original = getDelegate().readConfigurationData(path);
167 ArrayList<Node<?>> childNodes = new ArrayList<Node<?>>();
168 if (original != null) {
169 childNodes.addAll(original.getChildren());
170 qname = original.getNodeType();
172 qname = path.getPath().get(path.getPath().size() - 1).getNodeType();
175 FluentIterable<InstanceIdentifier> directChildren = FluentIterable.from(getStoredConfigurationPaths())
176 .filter(new Predicate<InstanceIdentifier>() {
178 public boolean apply(InstanceIdentifier input) {
179 if (path.contains(input)) {
180 int nesting = input.getPath().size() - path.getPath().size();
188 for (InstanceIdentifier instanceIdentifier : directChildren) {
189 childNodes.add(getDelegate().readConfigurationData(instanceIdentifier));
191 if (original == null && childNodes.isEmpty()) {
195 return new CompositeNodeTOImpl(qname, null, childNodes);
197 getDelegateReadLock().unlock();
202 public CompositeNode readOperationalData(final InstanceIdentifier path) {
203 getDelegateReadLock().lock();
205 if (path.getPath().isEmpty()) {
209 CompositeNode original = getDelegate().readOperationalData(path);
210 ArrayList<Node<?>> childNodes = new ArrayList<Node<?>>();
211 if (original != null) {
212 childNodes.addAll(original.getChildren());
213 qname = original.getNodeType();
215 qname = path.getPath().get(path.getPath().size() - 1).getNodeType();
218 FluentIterable<InstanceIdentifier> directChildren = FluentIterable.from(getStoredOperationalPaths())
219 .filter(new Predicate<InstanceIdentifier>() {
221 public boolean apply(InstanceIdentifier input) {
222 if (path.contains(input)) {
223 int nesting = input.getPath().size() - path.getPath().size();
232 for (InstanceIdentifier instanceIdentifier : directChildren) {
233 childNodes.add(getDelegate().readOperationalData(instanceIdentifier));
235 if (original == null && childNodes.isEmpty()) {
239 return new CompositeNodeTOImpl(qname, null, childNodes);
241 getDelegateReadLock().unlock();