summary |
shortlog |
log |
commit | commitdiff |
review |
tree
raw |
patch |
inline | side by side (from parent 1:
76b4cab)
Change-Id: I62843c3c4df32dd5a5849511d41352fa6822550b
Signed-off-by: Tony Tkacik <ttkacik@cisco.com>
Signed-off-by: Robert Varga <rovarga@cisco.com>
private ListenableFuture<RpcResult<TransactionStatus>> submit(
final WriteTransactionImpl<? extends DOMStoreWriteTransaction> transaction) {
private ListenableFuture<RpcResult<TransactionStatus>> submit(
final WriteTransactionImpl<? extends DOMStoreWriteTransaction> transaction) {
- LOG.debug("Tx: {} is submitted for execution.",transaction.getIdentifier());
+ LOG.debug("Tx: {} is submitted for execution.", transaction.getIdentifier());
return executor.submit(new CommitCoordination(transaction));
}
return executor.submit(new CommitCoordination(transaction));
}
- public void merge(final LogicalDatastoreType store, final InstanceIdentifier path, final NormalizedNode<?, ?> data) {
+ public void merge(final LogicalDatastoreType store, final InstanceIdentifier path,
+ final NormalizedNode<?, ?> data) {
@Override
public RpcResult<TransactionStatus> call() throws Exception {
@Override
public RpcResult<TransactionStatus> call() throws Exception {
- Boolean canCommit = canCommit().get();
+ Boolean canCommit = canCommit().get();
+
if (canCommit) {
try {
preCommit().get();
try {
commit().get();
if (canCommit) {
try {
preCommit().get();
try {
commit().get();
- COORDINATOR_LOG.debug("Tx: {} Is commited.",transaction.getIdentifier());
- return Rpcs.getRpcResult(true, TransactionStatus.COMMITED, Collections.<RpcError>emptySet());
+ COORDINATOR_LOG.debug("Tx: {} Is commited.", transaction.getIdentifier());
+ return Rpcs.getRpcResult(true, TransactionStatus.COMMITED,
+ Collections.<RpcError> emptySet());
+
} catch (InterruptedException | ExecutionException e) {
COORDINATOR_LOG.error("Tx: {} Error during commit", transaction.getIdentifier(), e);
}
} catch (InterruptedException | ExecutionException e) {
COORDINATOR_LOG.error("Tx: {} Error during commit", transaction.getIdentifier(), e);
}
transaction.getIdentifier(), e);
}
} else {
transaction.getIdentifier(), e);
}
} else {
- COORDINATOR_LOG.info("Tx: {} Did not pass canCommit phase.");
+ COORDINATOR_LOG.info("Tx: {} Did not pass canCommit phase.", transaction.getIdentifier());
abort().get();
}
} catch (InterruptedException | ExecutionException e) {
abort().get();
}
} catch (InterruptedException | ExecutionException e) {
} catch (InterruptedException | ExecutionException e) {
COORDINATOR_LOG.error("Tx: {} Error during abort", transaction.getIdentifier(), e);
}
} catch (InterruptedException | ExecutionException e) {
COORDINATOR_LOG.error("Tx: {} Error during abort", transaction.getIdentifier(), e);
}
- return Rpcs.getRpcResult(false, TransactionStatus.FAILED, Collections.<RpcError>emptySet());
+ return Rpcs.getRpcResult(false, TransactionStatus.FAILED, Collections.<RpcError> emptySet());
}
public ListenableFuture<Void> preCommit() {
}
public ListenableFuture<Void> preCommit() {
package org.opendaylight.controller.md.sal.dom.store.impl;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
package org.opendaylight.controller.md.sal.dom.store.impl;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerRegistrationNode.DataChangeListenerRegistration;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.slf4j.Logger;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.slf4j.Logger;
+ @Override
+ public String toString() {
+ return "DOMImmutableDataChangeEvent [created=" + createdData.keySet() + ", updated=" + updatedData.keySet()
+ + ", removed=" + removedPaths + "]";
+ }
+
public static class Builder {
private NormalizedNode<?, ?> after;
public static class Builder {
private NormalizedNode<?, ?> after;
private final ImmutableMap.Builder<InstanceIdentifier, NormalizedNode<?, ?>> updated = ImmutableMap.builder();
private final ImmutableSet.Builder<InstanceIdentifier> removed = ImmutableSet.builder();
private final ImmutableMap.Builder<InstanceIdentifier, NormalizedNode<?, ?>> updated = ImmutableMap.builder();
private final ImmutableSet.Builder<InstanceIdentifier> removed = ImmutableSet.builder();
import static org.opendaylight.controller.md.sal.dom.store.impl.StoreUtils.append;
import static org.opendaylight.controller.md.sal.dom.store.impl.tree.TreeNodeUtils.getChild;
import static org.opendaylight.controller.md.sal.dom.store.impl.StoreUtils.append;
import static org.opendaylight.controller.md.sal.dom.store.impl.tree.TreeNodeUtils.getChild;
+import java.util.ArrayList;
+import java.util.Collection;
+
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
import org.opendaylight.controller.md.sal.dom.store.impl.DOMImmutableDataChangeEvent.Builder;
import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerRegistrationNode;
import org.opendaylight.controller.md.sal.dom.store.impl.tree.NodeModification;
import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
import org.opendaylight.controller.md.sal.dom.store.impl.DOMImmutableDataChangeEvent.Builder;
import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerRegistrationNode;
import org.opendaylight.controller.md.sal.dom.store.impl.tree.NodeModification;
import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerRegistrationNode.DataChangeListenerRegistration;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
public class DataChangeEventResolver {
public class DataChangeEventResolver {
+
+ private static final Logger LOG = LoggerFactory.getLogger(DataChangeEventResolver.class);
+
private static final DOMImmutableDataChangeEvent NO_CHANGE = builder().build();
private InstanceIdentifier rootPath;
private ListenerRegistrationNode listenerRoot;
private static final DOMImmutableDataChangeEvent NO_CHANGE = builder().build();
private InstanceIdentifier rootPath;
private ListenerRegistrationNode listenerRoot;
}
public Iterable<ChangeListenerNotifyTask> resolve() {
}
public Iterable<ChangeListenerNotifyTask> resolve() {
+ LOG.trace("Resolving events for {}" ,modificationRoot);
resolveAnyChangeEvent(rootPath, Optional.of(listenerRoot), modificationRoot, beforeRoot, afterRoot);
return tasks.build();
}
resolveAnyChangeEvent(rootPath, Optional.of(listenerRoot), modificationRoot, beforeRoot, afterRoot);
return tasks.build();
}
InstanceIdentifier childPath = StoreUtils.append(path, childId);
builder.merge(resolveCreateEvent(childPath, childListeners, child));
}
InstanceIdentifier childPath = StoreUtils.append(path, childId);
builder.merge(resolveCreateEvent(childPath, childListeners, child));
}
DOMImmutableDataChangeEvent event = builder.build();
if (listeners.isPresent()) {
addNotifyTask(listeners.get().getListeners(), event);
DOMImmutableDataChangeEvent event = builder.build();
if (listeners.isPresent()) {
addNotifyTask(listeners.get().getListeners(), event);
switch (childMod.getModificationType()) {
case WRITE:
case DELETE:
switch (childMod.getModificationType()) {
case WRITE:
case DELETE:
- one.merge(resolveAnyChangeEvent(childPath, childListen, childMod, childBefore, childBefore));
+ one.merge(resolveAnyChangeEvent(childPath, childListen, childMod, childBefore, childAfter));
break;
case SUBTREE_MODIFIED:
subtree.merge(resolveSubtreeChangeEvent(childPath, childListen, childMod, childBefore.get(),
break;
case SUBTREE_MODIFIED:
subtree.merge(resolveSubtreeChangeEvent(childPath, childListen, childMod, childBefore.get(),
return builder().build();
}
return builder().build();
}
- private void addNotifyTask(final ListenerRegistrationNode listenerRegistrationNode, final DataChangeScope one,
+ private void addNotifyTask(final ListenerRegistrationNode listenerRegistrationNode, final DataChangeScope scope,
final DOMImmutableDataChangeEvent event) {
final DOMImmutableDataChangeEvent event) {
+ Collection<DataChangeListenerRegistration<?>> potential = listenerRegistrationNode.getListeners();
+ if(potential.isEmpty()) {
+ return;
+ }
+ ArrayList<DataChangeListenerRegistration<?>> toNotify = new ArrayList<>(potential.size());
+ for(DataChangeListenerRegistration<?> listener : potential) {
+ if(scope.equals(listener.getScope())) {
+ toNotify.add(listener);
+ }
+ }
+ addNotifyTask(toNotify, event);
- private void addNotifyTask(final Iterable<DataChangeListenerRegistration<?>> listeners,
+ private void addNotifyTask(final Collection<DataChangeListenerRegistration<?>> listeners,
final DOMImmutableDataChangeEvent event) {
final DOMImmutableDataChangeEvent event) {
- tasks .add(new ChangeListenerNotifyTask(ImmutableSet.copyOf(listeners),event));
+ if(!listeners.isEmpty()) {
+ tasks.add(new ChangeListenerNotifyTask(ImmutableSet.copyOf(listeners),event));
+ }
}
public static DataChangeEventResolver create() {
}
public static DataChangeEventResolver create() {
import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType;
import org.opendaylight.controller.md.sal.dom.store.impl.tree.NodeModification;
import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode;
import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType;
import org.opendaylight.controller.md.sal.dom.store.impl.tree.NodeModification;
import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.TreeNodeUtils;
import org.opendaylight.controller.sal.core.spi.data.DOMStore;
import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadTransaction;
import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
import org.opendaylight.controller.sal.core.spi.data.DOMStore;
import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadTransaction;
import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
@Override
public <L extends AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>> ListenerRegistration<L> registerChangeListener(
final InstanceIdentifier path, final L listener, final DataChangeScope scope) {
@Override
public <L extends AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>> ListenerRegistration<L> registerChangeListener(
final InstanceIdentifier path, final L listener, final DataChangeScope scope) {
-
- Optional<ListenerRegistrationNode> listenerNode = TreeNodeUtils.findNode(listenerTree, path);
- checkState(listenerNode.isPresent());
+ LOG.debug("{}: Registering data change listener {} for {}",name,listener,path);
+ ListenerRegistrationNode listenerNode = listenerTree;
+ for(PathArgument arg :path.getPath()) {
+ listenerNode = listenerNode.ensureChild(arg);
+ }
synchronized (listener) {
notifyInitialState(path, listener);
}
synchronized (listener) {
notifyInitialState(path, listener);
}
- return listenerNode.get().registerDataChangeListener(listener, scope);
+ return listenerNode.registerDataChangeListener(path,listener, scope);
}
private void notifyInitialState(final InstanceIdentifier path,
}
private void notifyInitialState(final InstanceIdentifier path,
private synchronized void commit(final DataAndMetadataSnapshot currentSnapshot,
final StoreMetadataNode newDataTree, final Iterable<ChangeListenerNotifyTask> listenerTasks) {
LOG.debug("Updating Store snaphot version: {} with version:{}",currentSnapshot.getMetadataTree().getSubtreeVersion(),newDataTree.getSubtreeVersion());
private synchronized void commit(final DataAndMetadataSnapshot currentSnapshot,
final StoreMetadataNode newDataTree, final Iterable<ChangeListenerNotifyTask> listenerTasks) {
LOG.debug("Updating Store snaphot version: {} with version:{}",currentSnapshot.getMetadataTree().getSubtreeVersion(),newDataTree.getSubtreeVersion());
if(LOG.isTraceEnabled()) {
LOG.trace("Data Tree is {}",StoreUtils.toStringTree(newDataTree));
}
if(LOG.isTraceEnabled()) {
LOG.trace("Data Tree is {}",StoreUtils.toStringTree(newDataTree));
}
proposedSubtree = operationTree.apply(modification, Optional.of(metadataTree),
increase(metadataTree.getSubtreeVersion()));
proposedSubtree = operationTree.apply(modification, Optional.of(metadataTree),
increase(metadataTree.getSubtreeVersion()));
listenerTasks = DataChangeEventResolver.create() //
.setRootPath(PUBLIC_ROOT_PATH) //
.setBeforeRoot(Optional.of(metadataTree)) //
listenerTasks = DataChangeEventResolver.create() //
.setRootPath(PUBLIC_ROOT_PATH) //
.setBeforeRoot(Optional.of(metadataTree)) //
return new InitialDataChangeEvent(path, data.getData());
}
return new InitialDataChangeEvent(path, data.getData());
}
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public static <V> Function<Identifiable<V>, V> identifierExtractor() {
+ return (Function) EXTRACT_IDENTIFIER;
+ }
+
private static final class InitialDataChangeEvent implements
AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> {
private static final class InitialDataChangeEvent implements
AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> {
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public static <V> Function<Identifiable<V>,V> identifierExtractor() {
- return (Function) EXTRACT_IDENTIFIER;
- }
-
public static <V> Set<V> toIdentifierSet(final Iterable<? extends Identifiable<V>> children) {
public static <V> Set<V> toIdentifierSet(final Iterable<? extends Identifiable<V>> children) {
- return FluentIterable.from(children).transform(StoreUtils.<V>identifierExtractor()).toSet();
+ return FluentIterable.from(children).transform(StoreUtils.<V> identifierExtractor()).toSet();
}
public static String toStringTree(final StoreMetadataNode metaNode) {
StringBuilder builder = new StringBuilder();
}
public static String toStringTree(final StoreMetadataNode metaNode) {
StringBuilder builder = new StringBuilder();
- toStringTree(builder, metaNode,0);
+ toStringTree(builder, metaNode, 0);
return builder.toString();
}
return builder.toString();
}
- private static void toStringTree(final StringBuilder builder, final StoreMetadataNode metaNode,final int offset) {
+ private static void toStringTree(final StringBuilder builder, final StoreMetadataNode metaNode, final int offset) {
String prefix = Strings.repeat(" ", offset);
builder.append(prefix).append(toStringTree(metaNode.getIdentifier()));
NormalizedNode<?, ?> dataNode = metaNode.getData();
String prefix = Strings.repeat(" ", offset);
builder.append(prefix).append(toStringTree(metaNode.getIdentifier()));
NormalizedNode<?, ?> dataNode = metaNode.getData();
- if(dataNode instanceof NormalizedNodeContainer<?,?,?>) {
+ if (dataNode instanceof NormalizedNodeContainer<?, ?, ?>) {
builder.append(" {").append("\n");
builder.append(" {").append("\n");
- for(StoreMetadataNode child : metaNode.getChildren()) {
- toStringTree(builder, child, offset+4);
+ for (StoreMetadataNode child : metaNode.getChildren()) {
+ toStringTree(builder, child, offset + 4);
}
builder.append(prefix).append("}");
} else {
}
builder.append(prefix).append("}");
} else {
}
private static String toStringTree(final PathArgument identifier) {
}
private static String toStringTree(final PathArgument identifier) {
- if( identifier instanceof NodeIdentifierWithPredicates) {
+ if (identifier instanceof NodeIdentifierWithPredicates) {
StringBuilder builder = new StringBuilder();
builder.append(identifier.getNodeType().getLocalName());
builder.append(((NodeIdentifierWithPredicates) identifier).getKeyValues().values());
StringBuilder builder = new StringBuilder();
builder.append(identifier.getNodeType().getLocalName());
builder.append(((NodeIdentifierWithPredicates) identifier).getKeyValues().values());
package org.opendaylight.controller.md.sal.dom.store.impl.tree;
package org.opendaylight.controller.md.sal.dom.store.impl.tree;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.common.base.Optional;
import com.google.common.base.Optional;
-public class ListenerRegistrationNode implements StoreTreeNode<ListenerRegistrationNode>,Identifiable<PathArgument> {
+public class ListenerRegistrationNode implements StoreTreeNode<ListenerRegistrationNode>, Identifiable<PathArgument> {
+
+ private final Logger LOG = LoggerFactory.getLogger(ListenerRegistrationNode.class);
private final ListenerRegistrationNode parent;
private final Map<PathArgument, ListenerRegistrationNode> children;
private final ListenerRegistrationNode parent;
private final Map<PathArgument, ListenerRegistrationNode> children;
private final HashSet<DataChangeListenerRegistration<?>> listeners;
private ListenerRegistrationNode(final PathArgument identifier) {
private final HashSet<DataChangeListenerRegistration<?>> listeners;
private ListenerRegistrationNode(final PathArgument identifier) {
+ this(null, identifier);
- private ListenerRegistrationNode(final ListenerRegistrationNode parent,final PathArgument identifier) {
+ private ListenerRegistrationNode(final ListenerRegistrationNode parent, final PathArgument identifier) {
this.parent = parent;
this.identifier = identifier;
children = new HashMap<>();
this.parent = parent;
this.identifier = identifier;
children = new HashMap<>();
- public Iterable<DataChangeListenerRegistration<?>> getListeners() {
- return listeners;
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public Collection<org.opendaylight.controller.md.sal.dom.store.impl.DataChangeListenerRegistration<?>> getListeners() {
+ return (Collection) listeners;
}
@Override
public synchronized Optional<ListenerRegistrationNode> getChild(final PathArgument child) {
}
@Override
public synchronized Optional<ListenerRegistrationNode> getChild(final PathArgument child) {
+ return Optional.fromNullable(children.get(child));
+ }
+
+ public synchronized ListenerRegistrationNode ensureChild(final PathArgument child) {
ListenerRegistrationNode potential = (children.get(child));
ListenerRegistrationNode potential = (children.get(child));
- if(potential == null) {
+ if (potential == null) {
potential = new ListenerRegistrationNode(this, child);
children.put(child, potential);
}
potential = new ListenerRegistrationNode(this, child);
children.put(child, potential);
}
- return Optional.of(potential);
- public <L extends AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>> ListenerRegistration<L> registerDataChangeListener(
+ /**
+ *
+ * Registers listener on this node.
+ *
+ * @param path Full path on which listener is registered.
+ * @param listener Listener
+ * @param scope Scope of triggering event.
+ * @return
+ */
+ public <L extends AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>> ListenerRegistration<L> registerDataChangeListener(final InstanceIdentifier path,
final L listener, final DataChangeScope scope) {
final L listener, final DataChangeScope scope) {
- DataChangeListenerRegistration<L> listenerReg = new DataChangeListenerRegistration<L>(listener, scope,this);
+
+ DataChangeListenerRegistration<L> listenerReg = new DataChangeListenerRegistration<L>(path,listener, scope, this);
listeners.add(listenerReg);
return listenerReg;
}
listeners.add(listenerReg);
return listenerReg;
}
private void removeThisIfUnused() {
private void removeThisIfUnused() {
- if(parent != null && listeners.isEmpty() && children.isEmpty()) {
+ if (parent != null && listeners.isEmpty() && children.isEmpty()) {
parent.removeChildIfUnused(this);
}
}
parent.removeChildIfUnused(this);
}
}
}
private boolean areChildrenUnused() {
}
private boolean areChildrenUnused() {
- for(ListenerRegistrationNode child : children.values()) {
- if(!child.isUnused()) {
+ for (ListenerRegistrationNode child : children.values()) {
+ if (!child.isUnused()) {
// FIXME Remove unnecessary
}
// FIXME Remove unnecessary
}
-
-
-
- public static class DataChangeListenerRegistration<T extends AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>> extends AbstractObjectRegistration<T>
- implements ListenerRegistration<T> {
+ public static class DataChangeListenerRegistration<T extends AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>>
+ extends AbstractObjectRegistration<T> implements
+ org.opendaylight.controller.md.sal.dom.store.impl.DataChangeListenerRegistration<T> {
private final DataChangeScope scope;
private ListenerRegistrationNode node;
private final DataChangeScope scope;
private ListenerRegistrationNode node;
+ private final InstanceIdentifier path;
- public DataChangeListenerRegistration(final T listener, final DataChangeScope scope, final ListenerRegistrationNode node) {
+ public DataChangeListenerRegistration(final InstanceIdentifier path,final T listener, final DataChangeScope scope,
+ final ListenerRegistrationNode node) {
this.scope = scope;
this.node = node;
}
this.scope = scope;
this.node = node;
}
- protected DataChangeScope getScope() {
+ @Override
+ public DataChangeScope getScope() {
node.removeListener(this);
node = null;
}
node.removeListener(this);
node = null;
}
+
+ @Override
+ public InstanceIdentifier getPath() {
+ return path;
+ }