From 9421d10ab3ee2b1ef3adc655abdc0b47774a02aa Mon Sep 17 00:00:00 2001 From: Tony Tkacik Date: Mon, 16 Feb 2015 14:50:42 +0100 Subject: [PATCH] Bug 2673: Binding cursor-based data change API Introduced Binding cursor-based data change API, which provides more low-level access to change events, but allows for more effective processing of data change events. Change-Id: I6193a4175fef85045a71cf9363bd46ba6297248c Signed-off-by: Tony Tkacik --- .../binding/api/DataObjectModification.java | 80 +++++++++++++++++++ .../binding/api/DataTreeChangeListener.java | 43 ++++++++++ .../binding/api/DataTreeChangeService.java | 54 +++++++++++++ .../sal/binding/api/DataTreeIdentifier.java | 78 ++++++++++++++++++ .../sal/binding/api/DataTreeModification.java | 37 +++++++++ 5 files changed, 292 insertions(+) create mode 100644 opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/DataObjectModification.java create mode 100644 opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/DataTreeChangeListener.java create mode 100644 opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/DataTreeChangeService.java create mode 100644 opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/DataTreeIdentifier.java create mode 100644 opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/DataTreeModification.java diff --git a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/DataObjectModification.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/DataObjectModification.java new file mode 100644 index 0000000000..2eee0e8099 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/DataObjectModification.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html. + */ +package org.opendaylight.controller.md.sal.binding.api; + +import java.util.Collection; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.opendaylight.yangtools.concepts.Identifiable; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument; + +/** + * Modified Data Object. + * + * Represents modification of Data Object. + * + */ +public interface DataObjectModification extends Identifiable { + + enum ModificationType { + /** + * + * Child node (direct or indirect) was modified. + * + */ + SUBTREE_MODIFIED, + /** + * + * Node was explicitly created / overwritten. + * + */ + WRITE, + /** + * + * Node was deleted. + * + */ + DELETE + } + + @Override + PathArgument getIdentifier(); + + /** + * Returns type of modified object. + * + * @return type of modified object. + */ + @Nonnull Class getDataType(); + + /** + * + * Returns type of modification + * + * @return type Type of performed modification. + */ + @Nonnull ModificationType getModificationType(); + + /** + * Returns after state of top level container. + * + * @param root Class representing data container + * @return State of object after modification. Null if subtree is not present. + */ + @Nullable T getDataAfter(); + + /** + * Returns unmodifiable collection of modified direct children. + * + * @return unmodifiable collection of modified direct children. + */ + @Nonnull Collection> getModifiedChildren(); + + +} diff --git a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/DataTreeChangeListener.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/DataTreeChangeListener.java new file mode 100644 index 0000000000..6b1df719ac --- /dev/null +++ b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/DataTreeChangeListener.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.md.sal.binding.api; + +import java.util.Collection; +import java.util.EventListener; +import javax.annotation.Nonnull; + +/** + * Interface implemented by classes interested in receiving notifications about + * data tree changes. This interface differs from {@link DataChangeListener} + * in that it provides a cursor-based view of the change, which has potentially + * lower overhead and allow more flexible consumption of change event. + */ +public interface DataTreeChangeListener extends EventListener { + /** + * Invoked when there was data change for the supplied path, which was used + * to register this listener. + * + *

+ * This method may be also invoked during registration of the listener if + * there is any pre-existing data in the conceptual data tree for supplied + * path. This initial event will contain all pre-existing data as created. + * + *

+ * A data change event may be triggered spuriously, e.g. such that data before + * and after compare as equal. Implementations of this interface are expected + * to recover from such events. Event producers are expected to exert reasonable + * effort to suppress such events. + * + * In other words, it is completely acceptable to observe + * a {@link DataObjectModification}, while the state observed before and + * after- data items compare as equal. + * + * @param changes Collection of change events, may not be null or empty. + */ + void onDataTreeChanged(@Nonnull Collection changes); +} diff --git a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/DataTreeChangeService.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/DataTreeChangeService.java new file mode 100644 index 0000000000..ae4e36f14a --- /dev/null +++ b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/DataTreeChangeService.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.md.sal.binding.api; + +import javax.annotation.Nonnull; +import org.opendaylight.yangtools.concepts.ListenerRegistration; + +/** + * A {@link DOMService} which allows users to register for changes to a + * subtree. + */ +public interface DataTreeChangeService extends BindingService { + /** + * Registers a {@link DataTreeChangeListener} to receive + * notifications when data changes under a given path in the conceptual data + * tree. + *

+ * You are able to register for notifications for any node or subtree + * which can be represented using {@link DataTreeIdentifier}. + *

+ * + * You are able to register for data change notifications for a subtree or leaf + * even if it does not exist. You will receive notification once that node is + * created. + *

+ * If there is any pre-existing data in the data tree for the path for which you are + * registering, you will receive an initial data change event, which will + * contain all pre-existing data, marked as created. + * + *

+ * This method returns a {@link ListenerRegistration} object. To + * "unregister" your listener for changes call the {@link ListenerRegistration#close()} + * method on the returned object. + *

+ * You MUST explicitly unregister your listener when you no longer want to receive + * notifications. This is especially true in OSGi environments, where failure to + * do so during bundle shutdown can lead to stale listeners being still registered. + * + * @param treeId + * Data tree identifier of the subtree which should be watched for + * changes. + * @param listener + * Listener instance which is being registered + * @return Listener registration object, which may be used to unregister + * your listener using {@link ListenerRegistration#close()} to stop + * delivery of change events. + */ + @Nonnull ListenerRegistration registerDataTreeChangeListener(@Nonnull DataTreeIdentifier treeId, @Nonnull L listener); +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/DataTreeIdentifier.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/DataTreeIdentifier.java new file mode 100644 index 0000000000..428957e988 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/DataTreeIdentifier.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.md.sal.binding.api; + +import com.google.common.base.Preconditions; +import java.io.Serializable; +import javax.annotation.Nonnull; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.yangtools.concepts.Immutable; +import org.opendaylight.yangtools.concepts.Path; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * A unique identifier for a particular subtree. It is composed of the logical + * data store type and the instance identifier of the root node. + */ +public final class DataTreeIdentifier implements Immutable, Path, Serializable { + private static final long serialVersionUID = 1L; + private final InstanceIdentifier rootIdentifier; + private final LogicalDatastoreType datastoreType; + + public DataTreeIdentifier(final LogicalDatastoreType datastoreType, final InstanceIdentifier rootIdentifier) { + this.datastoreType = Preconditions.checkNotNull(datastoreType); + this.rootIdentifier = Preconditions.checkNotNull(rootIdentifier); + } + + /** + * Return the logical data store type. + * + * @return Logical data store type. Guaranteed to be non-null. + */ + public @Nonnull LogicalDatastoreType getDatastoreType() { + return datastoreType; + } + + /** + * Return the {@link YangInstanceIdentifier} of the root node. + * + * @return Instance identifier corresponding to the root node. + */ + public @Nonnull InstanceIdentifier getRootIdentifier() { + return rootIdentifier; + } + + @Override + public boolean contains(final DataTreeIdentifier other) { + return datastoreType == other.datastoreType && rootIdentifier.contains(other.rootIdentifier); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + datastoreType.hashCode(); + result = prime * result + rootIdentifier.hashCode(); + return result; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof DataTreeIdentifier)) { + return false; + } + DataTreeIdentifier other = (DataTreeIdentifier) obj; + if (datastoreType != other.datastoreType) { + return false; + } + return rootIdentifier.equals(other.rootIdentifier); + } +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/DataTreeModification.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/DataTreeModification.java new file mode 100644 index 0000000000..aac51a6a4c --- /dev/null +++ b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/DataTreeModification.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html. + */ + +package org.opendaylight.controller.md.sal.binding.api; + +import javax.annotation.Nonnull; +import org.opendaylight.yangtools.yang.binding.DataObject; + +/** + * Represent root of modification. + * + * @author Tony Tkacik <ttkacik@cisco.com> + * + */ +public interface DataTreeModification { + + /** + * Get the modification root path. This is the path of the root node + * relative to the root of InstanceIdentifier namespace. + * + * @return absolute path of the root node + */ + @Nonnull DataTreeIdentifier getRootPath(); + + /** + * Get the modification root node. + * + * @return modification root node + */ + @Nonnull DataObjectModification getRootNode(); + +} -- 2.36.6