Binding2 runtime - API #1 18/58318/1
authorMartin Ciglan <martin.ciglan@pantheon.tech>
Mon, 22 May 2017 12:24:28 +0000 (14:24 +0200)
committerMartin Ciglan <martin.ciglan@pantheon.tech>
Tue, 6 Jun 2017 10:15:59 +0000 (10:15 +0000)
- BindingService, DataTreeModification, transactions basics & its relatives
- Javadocs provided
- test coverage for classes

Change-Id: I2d032ec3a0a565941266610194fb8d176c5392ff
Signed-off-by: Martin Ciglan <martin.ciglan@pantheon.tech>
(cherry picked from commit 827c2b1cea519c8a3a3e3789ecbf7ed6f84a0e07)

12 files changed:
binding2/mdsal-binding2-api/pom.xml
binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/BindingService.java [new file with mode: 0644]
binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/BindingTransactionChain.java [new file with mode: 0644]
binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/DataTreeIdentifier.java [new file with mode: 0644]
binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/DataTreeModification.java [new file with mode: 0644]
binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/ReadTransaction.java [new file with mode: 0644]
binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/TransactionFactory.java [new file with mode: 0644]
binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/TreeNodeModification.java [new file with mode: 0644]
binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/WriteTransaction.java [new file with mode: 0644]
binding2/mdsal-binding2-api/src/test/java/org/opendaylight/mdsal/binding/javav2/api/DataTreeIdentifierTest.java [new file with mode: 0644]
binding2/mdsal-binding2-api/src/test/java/org/opendaylight/mdsal/binding/javav2/api/TreeNodeModificationTest.java [new file with mode: 0644]
binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding/javav2/spec/base/InstanceIdentifier.java

index b86089253e2abe2cd640751cb6b941423d67a362..97a373e3d9363acdedb6d99c393261ebf8fad81c 100644 (file)
             <groupId>org.opendaylight.mdsal</groupId>
             <artifactId>mdsal-binding2-spec</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal</groupId>
+            <artifactId>yang-binding</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>yang-common</artifactId>
diff --git a/binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/BindingService.java b/binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/BindingService.java
new file mode 100644 (file)
index 0000000..e24e5ef
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.mdsal.binding.javav2.api;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Marker interface for MD-SAL services which are available for users of MD-SAL.
+ *
+ * <p>
+ * BindingService is marker interface for infrastructure services provided by
+ * the SAL. These services may be session-specific, and wrapped by custom
+ * delegator patterns in order to introduce additional semantics / checks
+ * to the system.
+ *
+ */
+@Beta
+public interface BindingService {
+}
diff --git a/binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/BindingTransactionChain.java b/binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/BindingTransactionChain.java
new file mode 100644 (file)
index 0000000..9399f24
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.mdsal.binding.javav2.api;
+
+import com.google.common.annotations.Beta;
+import org.opendaylight.mdsal.binding.javav2.spec.base.InstanceIdentifier;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+import org.opendaylight.mdsal.common.api.TransactionChain;
+
+/**
+ * A chain of transactions.
+ *
+ * <p>
+ * For more information about transaction chaining and transaction chains
+ * see {@link TransactionChain}.
+ *
+ * @see TransactionChain
+ *
+ */
+@Beta
+public interface BindingTransactionChain extends TransactionFactory, TransactionChain<InstanceIdentifier<?>, TreeNode> {
+
+    @Override
+    ReadTransaction newReadOnlyTransaction();
+
+    @Override
+    WriteTransaction newWriteOnlyTransaction();
+}
diff --git a/binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/DataTreeIdentifier.java b/binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/DataTreeIdentifier.java
new file mode 100644 (file)
index 0000000..dc8864c
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.mdsal.binding.javav2.api;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import java.io.Serializable;
+import java.util.Objects;
+import javax.annotation.Nonnull;
+import org.opendaylight.mdsal.binding.javav2.spec.base.InstanceIdentifier;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.yangtools.concepts.Immutable;
+import org.opendaylight.yangtools.concepts.Path;
+
+/**
+ * A unique identifier for a particular subtree. It's composed of the logical
+ * data store type and the instance identifier of the root node.
+ */
+@Beta
+public final class DataTreeIdentifier<T extends TreeNode> implements Immutable,
+        Path<DataTreeIdentifier<?>>, Serializable {
+
+    private static final long serialVersionUID = 1L;
+    private final InstanceIdentifier<T> rootIdentifier;
+    private final LogicalDatastoreType datastoreType;
+
+    private DataTreeIdentifier(final LogicalDatastoreType datastoreType, final InstanceIdentifier<T> rootIdentifier) {
+        this.datastoreType = Preconditions.checkNotNull(datastoreType);
+        this.rootIdentifier = Preconditions.checkNotNull(rootIdentifier);
+    }
+
+    public static <T extends TreeNode> DataTreeIdentifier<T> create(final LogicalDatastoreType datastoreType,
+        final InstanceIdentifier<T> rootIdentifier) {
+        return new DataTreeIdentifier<>(datastoreType, rootIdentifier);
+    }
+
+    /**
+     * Return the logical data store type.
+     *
+     * @return Logical data store type. Guaranteed to be non-null.
+     */
+    @Nonnull
+    public LogicalDatastoreType getDatastoreType() {
+        return datastoreType;
+    }
+
+    /**
+     * Return the {@link InstanceIdentifier} of the root node.
+     *
+     * @return Instance identifier corresponding to the root node.
+     */
+    @Nonnull
+    public InstanceIdentifier<T> getRootIdentifier() {
+        return rootIdentifier;
+    }
+
+    /**
+     * Checks whether this identifier contains some other.
+     * @param other Other path, may not be null.
+     * @return true/false
+     */
+    @Override
+    public boolean contains(@Nonnull final DataTreeIdentifier<?> other) {
+        return datastoreType == other.datastoreType && rootIdentifier.contains(other.rootIdentifier);
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof DataTreeIdentifier)) {
+            return false;
+        }
+        final DataTreeIdentifier<?> other = (DataTreeIdentifier<?>) obj;
+        if (datastoreType != other.datastoreType) {
+            return false;
+        }
+        return rootIdentifier.equals(other.rootIdentifier);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rootIdentifier, datastoreType);
+    }
+}
diff --git a/binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/DataTreeModification.java b/binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/DataTreeModification.java
new file mode 100644 (file)
index 0000000..e35ad05
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.mdsal.binding.javav2.api;
+
+import com.google.common.annotations.Beta;
+import javax.annotation.Nonnull;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+
+/**
+ * Represents root of modification.
+ */
+@Beta
+public interface DataTreeModification<T extends TreeNode> {
+
+    /**
+     * 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<T> getRootPath();
+
+    /**
+     * Get the modification root node.
+     *
+     * @return modification root node
+     */
+    @Nonnull
+    TreeNodeModification<T> getRootNode();
+}
diff --git a/binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/ReadTransaction.java b/binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/ReadTransaction.java
new file mode 100644 (file)
index 0000000..ec79e93
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.mdsal.binding.javav2.api;
+
+import com.google.common.annotations.Beta;
+import java.util.function.BiConsumer;
+import org.opendaylight.mdsal.binding.javav2.spec.base.InstanceIdentifier;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+import org.opendaylight.mdsal.common.api.AsyncReadTransaction;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.common.api.ReadFailedException;
+
+/**
+ * A transaction that provides a stateful read-only view of the data tree.
+ *
+ * <p>
+ * For more information on usage and examples, please see the documentation in
+ *  {@link org.opendaylight.mdsal.common.api.AsyncReadTransaction}.
+ */
+@Beta
+public interface ReadTransaction extends AsyncReadTransaction<InstanceIdentifier<?>, TreeNode> {
+
+    /**
+     * Reads data from the provided logical data store located at the provided path.
+     *
+     *<p>
+     * If the target is a subtree, then the whole subtree is read (and will be
+     * accessible from the returned data object).
+     *
+     * @param store
+     *            Logical data store from which read should occur.
+     * @param path
+     *            Path which uniquely identifies subtree which client want to
+     *            read
+     * @param callback result callback
+     * @param <T> result type
+     */
+    <T extends TreeNode> void read(LogicalDatastoreType store, InstanceIdentifier<T> path,
+        BiConsumer<ReadFailedException, T> callback);
+}
diff --git a/binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/TransactionFactory.java b/binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/TransactionFactory.java
new file mode 100644 (file)
index 0000000..82c2675
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.mdsal.binding.javav2.api;
+
+import com.google.common.annotations.Beta;
+import org.opendaylight.mdsal.binding.javav2.spec.base.InstanceIdentifier;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+import org.opendaylight.mdsal.common.api.AsyncDataTransactionFactory;
+
+/**
+ * A factory which allocates new transactions to operate on the data tree.
+ *
+ * <p>
+ * For more information on usage, please see the documentation in {@link AsyncDataTransactionFactory}.
+ *
+ * @see AsyncDataTransactionFactory
+ */
+@Beta
+public interface TransactionFactory extends AsyncDataTransactionFactory<InstanceIdentifier<?>, TreeNode> {
+
+    @Override
+    ReadTransaction newReadOnlyTransaction();
+
+    @Override
+    WriteTransaction newWriteOnlyTransaction();
+}
diff --git a/binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/TreeNodeModification.java b/binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/TreeNodeModification.java
new file mode 100644 (file)
index 0000000..fd531c9
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.mdsal.binding.javav2.api;
+
+import com.google.common.annotations.Beta;
+import java.util.Collection;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.mdsal.binding.javav2.spec.base.IdentifiableItem;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeArgument;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+import org.opendaylight.mdsal.binding.javav2.spec.structural.Augmentation;
+import org.opendaylight.mdsal.binding.javav2.spec.structural.TreeChildNode;
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
+
+/**
+ * Modified Tree Node.
+ *
+ *<p>
+ * Represents modification of tree node {@link TreeNode}
+ *
+ *<p>
+ * @param <T> Type of modified object
+ *
+ */
+@Beta
+public interface TreeNodeModification<T extends TreeNode> extends Identifiable<TreeArgument> {
+
+    /**
+     * Represents type of modification which has occured.
+     *
+     */
+    enum ModificationType {
+        /**
+         * Child node (direct or indirect) was modified.
+         *
+         */
+        SUBTREE_MODIFIED,
+        /**
+         * Node was explicitly created / overwritten.
+         *
+         */
+        WRITE,
+        /**
+         * Node was deleted.
+         *
+         */
+        DELETE,
+        /**
+         * This node has appeared because it is implied by one of its children. This type is usually produced when a
+         * structural container is created to host some leaf entries. It does not have an associated before-image.
+         * Its semantics is a combination of SUBTREE_MODIFIED and WRITE, depending on which context it is being
+         * interpreted.
+         * Users who track the value of the node can treat it as a WRITE. Users transforming a {@link DataTreeCandidate}
+         * to operations on a {@link org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification}
+         * should interpret it as a SUBTREE_MODIFIED and examine its children.
+         * This is needed to correctly deal with concurrent operations on the nodes children, as issuing a write on the
+         * DataTreeModification could end up removing any leaves which have not been present at the DataTree which
+         * emitted this event.
+         */
+        APPEARED,
+        /**
+         * This node has disappeared because it is no longer implied by any children. This type is usually produced when
+         * a structural container is removed because it has become empty. It does not have an associated after-image.
+         * Its semantics is a combination of SUBTREE_MODIFIED and DELETE, depending on which context it is being
+         * interpreted.
+         * Users who track the value of the node can treat it as a DELETE, as the container has disappeared.
+         * Users transforming a {@link DataTreeCandidate} to operations on a
+         * {@link org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification} should interpret
+         * it as a SUBTREE_MODIFIED and examine its children.
+         * This is needed to correctly deal with concurrent operations on the nodes children, as issuing a delete on the
+         * DataTreeModification would end up removing any leaves which have not been present at the DataTree which
+         * emitted this event.
+         */
+        DISAPPEARED
+    }
+
+    @Nonnull
+    @Override
+    TreeArgument getIdentifier();
+
+    /**
+     * Returns type of modified object.
+     *
+     * @return type of modified object.
+     */
+    @Nonnull Class<T> getDataType();
+
+    /**
+     * Returns type of modification.
+     *
+     * @return type Type of performed modification.
+     */
+    @Nonnull ModificationType getModificationType();
+
+    /**
+     * Returns before-state of top level container. Implementations are encouraged, but not required
+     * to provide this state.
+     *
+     * @return State of object before modification. Null if subtree was not present, or the
+     *         implementation cannot provide the state.
+     */
+    @Nullable
+    T getDataBefore();
+
+    /**
+     * Returns after-state of top level 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<TreeNodeModification<? extends TreeNode>> getModifiedChildren();
+
+    /**
+     * Returns child list item modification if {@code child} was modified by this modification.
+     *
+     * @param childType Type of list item - must be list item with key
+     * @param <C> type of child class
+     * @return Modification of {@code child} if {@code child} was modified, null otherwise.
+     * @throws IllegalArgumentException If supplied {@code childType} class is not valid child according
+     *         to generated model.
+     */
+    <C extends TreeChildNode<? super T, ?>> Collection<TreeNodeModification<C>> getModifiedChildren(
+            @Nonnull Class<C> childType);
+
+    /**
+     * Returns container child modification if {@code child} was modified by this
+     * modification.
+     *
+     *<p>
+     * For accessing all modified list items consider iterating over {@link #getModifiedChildren()}.
+     *
+     * @param child Type of child - must be only container
+     * @param <C> type of child class
+     * @return Modification of {@code child} if {@code child} was modified, null otherwise.
+     * @throws IllegalArgumentException If supplied {@code child} class is not valid child according
+     *         to generated model.
+     */
+    @Nullable <C extends TreeChildNode<? super T, ?>> TreeNodeModification<C> getModifiedChildContainer(
+            @Nonnull Class<C> child);
+
+    /**
+     * Returns augmentation child modification if {@code augmentation} was modified by this
+     * modification.
+     *
+     *<p>
+     * For accessing all modified list items consider iterating over {@link #getModifiedChildren()}.
+     *
+     * @param augmentation Type of augmentation - must be only container
+     * @param <C> type of augmentation class
+     * @return Modification of {@code augmentation} if {@code augmentation} was modified, null otherwise.
+     * @throws IllegalArgumentException If supplied {@code augmentation} class is not valid augmentation
+     *         according to generated model.
+     */
+    @Nullable <C extends Augmentation<T> & TreeNode> TreeNodeModification<C> getModifiedAugmentation(
+            @Nonnull Class<C> augmentation);
+
+
+    /**
+     * Returns child list item modification if {@code child} was modified by this modification.
+     *
+     * @param listItem Type of list item - must be list item with key
+     * @param listKey List item key
+     * @param <C> type of list item class
+     * @param <K> type of list key
+     * @return Modification of {@code child} if {@code child} was modified, null otherwise.
+     * @throws IllegalArgumentException If supplied {@code listItem} class is not valid child according
+     *         to generated model.
+     */
+    <C extends IdentifiableItem<T, K> & TreeChildNode<? super T, ?>, K extends IdentifiableItem<T, K>>
+        TreeNodeModification<C> getModifiedChildListItem(@Nonnull Class<C> listItem, @Nonnull K listKey);
+
+    /**
+     * Returns a child modification if a node identified by {@code childArgument} was modified by
+     * this modification.
+     *
+     * @param childArgument Path Argument of child node
+     * @return Modification of child identified by {@code childArgument} if {@code childArgument}
+     *         was modified, null otherwise.
+     * @throws IllegalArgumentException If supplied path argument is not valid child according to
+     *         generated model.
+     *
+     */
+    @Nullable
+    TreeNodeModification<? extends TreeNode> getModifiedChild(TreeArgument childArgument);
+
+}
diff --git a/binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/WriteTransaction.java b/binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/WriteTransaction.java
new file mode 100644 (file)
index 0000000..5065a7d
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.mdsal.binding.javav2.api;
+
+import com.google.common.annotations.Beta;
+import org.opendaylight.mdsal.binding.javav2.spec.base.InstanceIdentifier;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+import org.opendaylight.mdsal.common.api.AsyncWriteTransaction;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+
+/**
+ * A transaction that provides mutation capabilities on a data tree.
+ *
+ * <p>
+ * For more information on usage and examples, please see the documentation in {@link AsyncWriteTransaction}.
+ */
+@Beta
+public interface WriteTransaction extends AsyncWriteTransaction<InstanceIdentifier<?>, TreeNode> {
+
+    /**
+     * Stores a piece of data at the specified path. This acts as an add / replace
+     * operation, which is to say that whole subtree will be replaced by the specified data.
+     *
+     * <p>
+     * This method does not automatically create missing parent nodes. It is equivalent to invoking
+     * {@link #put(LogicalDatastoreType, InstanceIdentifier, TreeNode, boolean)}
+     * with <code>createMissingParents</code> set to false.
+     *
+     * <p>
+     * For more information on usage and examples, please see the documentation in {@link AsyncWriteTransaction}.
+     * <p>
+     * If you need to make sure that a parent object exists but you do not want modify
+     * its pre-existing state by using put, consider using {@link #merge} instead.
+     *
+     * @param store
+     *            the logical data store which should be modified
+     * @param path
+     *            the data object path
+     * @param data
+     *            the data object to be written to the specified path
+     * @param <T> data tree type
+     * @throws IllegalStateException
+     *             if the transaction has already been submitted
+     */
+    <T extends TreeNode> void put(LogicalDatastoreType store, InstanceIdentifier<T> path, T data);
+
+    /**
+     * Stores a piece of data at the specified path. This acts as an add /
+     * replace operation, which is to say that whole subtree will be replaced by
+     * the specified data.
+     *
+     * <p>
+     * For more information on usage and examples, please see the documentation
+     * in {@link AsyncWriteTransaction}.
+     *
+     * <p>
+     * If you need to make sure that a parent object exists but you do not want
+     * modify its pre-existing state by using put, consider using {@link #merge}
+     * instead.
+     *
+     * <p>
+     * Note: Using <code>createMissingParents</code> with value true, may
+     * introduce garbage in data store, or recreate nodes, which were deleted by
+     * previous transaction.
+     *
+     * @param store
+     *            the logical data store which should be modified
+     * @param path
+     *            the data object path
+     * @param data
+     *            the data object to be written to the specified path
+     * @param createMissingParents
+     *            if true, any missing parent nodes will be automatically
+     *            created using a merge operation.
+     * @param <T> data tree type
+     * @throws IllegalStateException
+     *             if the transaction has already been submitted
+     */
+    <T extends TreeNode> void put(LogicalDatastoreType store, InstanceIdentifier<T> path, T data,
+        boolean createMissingParents);
+
+    /**
+     * Merges a piece of data with the existing data at a specified path. Any pre-existing data
+     * which is not explicitly overwritten will be preserved. This means that if you store a container,
+     * its child lists will be merged.
+     *
+     * <p>
+     * This method does not automatically create missing parent nodes. It is equivalent to invoking
+     * {@link #merge(LogicalDatastoreType, InstanceIdentifier, TreeNode, boolean)}
+     * with <code>createMissingParents</code> set to false.
+     *
+     * <p>
+     * For more information on usage and examples, please see the documentation in
+     * {@link AsyncWriteTransaction}.
+     *
+     *<p>
+     * If you require an explicit replace operation, use {@link #put} instead.
+     * @param store
+     *            the logical data store which should be modified
+     * @param path
+     *            the data object path
+     * @param data
+     *            the data object to be merged to the specified path
+     * @param <T> data tree type
+     * @throws IllegalStateException
+     *             if the transaction has already been submitted
+     */
+    <T extends TreeNode> void merge(LogicalDatastoreType store, InstanceIdentifier<T> path, T data);
+
+    /**
+     * Merges a piece of data with the existing data at a specified path. Any
+     * pre-existing data which is not explicitly overwritten will be preserved.
+     * This means that if you store a container, its child lists will be merged.
+     *
+     * <p>
+     * For more information on usage and examples, please see the documentation
+     * in {@link AsyncWriteTransaction}.
+     *
+     * <p>
+     * If you require an explicit replace operation, use {@link #put} instead.
+     *
+     * @param store
+     *            the logical data store which should be modified
+     * @param path
+     *            the data object path
+     * @param data
+     *            the data object to be merged to the specified path
+     * @param createMissingParents
+     *            if true, any missing parent nodes will be automatically created
+     *            using a merge operation.
+     * @param <T> data tree type
+     * @throws IllegalStateException
+     *             if the transaction has already been submitted
+     */
+    <T extends TreeNode> void merge(LogicalDatastoreType store, InstanceIdentifier<T> path, T data,
+        boolean createMissingParents);
+
+    @Override
+    void delete(LogicalDatastoreType store, InstanceIdentifier<? extends TreeNode> path);
+}
diff --git a/binding2/mdsal-binding2-api/src/test/java/org/opendaylight/mdsal/binding/javav2/api/DataTreeIdentifierTest.java b/binding2/mdsal-binding2-api/src/test/java/org/opendaylight/mdsal/binding/javav2/api/DataTreeIdentifierTest.java
new file mode 100644 (file)
index 0000000..67ad776
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.mdsal.binding.javav2.api;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.opendaylight.mdsal.binding.javav2.spec.base.InstanceIdentifier;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+
+public class DataTreeIdentifierTest {
+
+    private static final DataTreeIdentifier<TestTreeNode1> TEST_IDENTIFIER1 = DataTreeIdentifier.create(
+            LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(TestTreeNode1.class));
+    private static final DataTreeIdentifier<TestTreeNode2> TEST_IDENTIFIER2 = DataTreeIdentifier.create(
+            LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(TestTreeNode2.class));
+
+    @Test
+    public void basicTest() throws Exception {
+        assertEquals(LogicalDatastoreType.OPERATIONAL, TEST_IDENTIFIER1.getDatastoreType());
+        assertEquals(InstanceIdentifier.create(TestTreeNode1.class), TEST_IDENTIFIER1.getRootIdentifier());
+    }
+
+    @Test
+    public void containsTest() {
+        assertTrue("Contains", TEST_IDENTIFIER1.contains(DataTreeIdentifier.create(LogicalDatastoreType.OPERATIONAL,
+                InstanceIdentifier.create(TestTreeNode1.class))));
+        assertFalse("Not Contains", TEST_IDENTIFIER1.contains(TEST_IDENTIFIER2));
+    }
+
+    @Test
+    public void hashCodeTest() {
+        assertEquals("hashCode", TEST_IDENTIFIER1.hashCode(), DataTreeIdentifier.create(
+                LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(TestTreeNode1.class)).hashCode());
+        assertNotEquals("hashCode", TEST_IDENTIFIER1.hashCode(), TEST_IDENTIFIER2.hashCode());
+    }
+
+    @Test
+    public void equalsTest() {
+        assertTrue("Equals", TEST_IDENTIFIER1.equals(TEST_IDENTIFIER1));
+        assertTrue("Equals", TEST_IDENTIFIER1.equals(DataTreeIdentifier.create(LogicalDatastoreType.OPERATIONAL,
+                InstanceIdentifier.create(TestTreeNode1.class))));
+        assertFalse("Different", TEST_IDENTIFIER1.equals(DataTreeIdentifier.create(LogicalDatastoreType.CONFIGURATION,
+                InstanceIdentifier.create(TestTreeNode1.class))));
+        assertFalse("Different", TEST_IDENTIFIER1.equals(TEST_IDENTIFIER2));
+        assertFalse("Equals null", TEST_IDENTIFIER1.equals(null));
+        assertFalse("Different object", TEST_IDENTIFIER1.equals(new Object()));
+    }
+
+    private static class TestTreeNode1 implements TreeNode {
+    }
+
+    private static class TestTreeNode2 implements TreeNode {
+    }
+}
diff --git a/binding2/mdsal-binding2-api/src/test/java/org/opendaylight/mdsal/binding/javav2/api/TreeNodeModificationTest.java b/binding2/mdsal-binding2-api/src/test/java/org/opendaylight/mdsal/binding/javav2/api/TreeNodeModificationTest.java
new file mode 100644 (file)
index 0000000..0e6c067
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.mdsal.binding.javav2.api;
+
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Test;
+
+public class TreeNodeModificationTest {
+
+    @Test
+    public void notificationMethodEnumTest() throws Exception {
+        assertNotNull(TreeNodeModification.ModificationType.values());
+    }
+}
index 0a777378e81e128809fa07ad00c41abe108f7ce2..bd346dd96cf5823b5957d4b404710f34406041ef 100644 (file)
@@ -26,6 +26,7 @@ import org.opendaylight.mdsal.binding.javav2.spec.structural.Augmentation;
 import org.opendaylight.mdsal.binding.javav2.spec.structural.TreeChildNode;
 import org.opendaylight.yangtools.concepts.Identifiable;
 import org.opendaylight.yangtools.concepts.Immutable;
+import org.opendaylight.yangtools.concepts.Path;
 import org.opendaylight.yangtools.util.HashCodeBuilder;
 
 /**
@@ -62,7 +63,8 @@ import org.opendaylight.yangtools.util.HashCodeBuilder;
  *
  */
 @Beta
-public class InstanceIdentifier<T extends TreeNode> implements Immutable, Serializable {
+public class InstanceIdentifier<T extends TreeNode> implements Path<InstanceIdentifier<? extends TreeNode>>, Immutable,
+        Serializable {
     private static final Field PATHARGUMENTS_FIELD;
     private static final long serialVersionUID = 2L;
     /*
@@ -285,6 +287,7 @@ public class InstanceIdentifier<T extends TreeNode> implements Immutable, Serial
      * @param other
      * @return
      */
+    @Override
     public final boolean contains(final InstanceIdentifier<? extends TreeNode> other) {
         Preconditions.checkNotNull(other, "other should not be null");