Bug 1435: Added Binding Commit Cohort APIs and adapters. 73/32573/3
authorTony Tkacik <[email protected]>
Thu, 14 Jan 2016 12:35:03 +0000 (13:35 +0100)
committerTony Tkacik <[email protected]>
Thu, 14 Jan 2016 13:16:55 +0000 (13:16 +0000)
Change-Id: I7ec8b54542af307a2ec2390d3e397f771c2bc1cc
Signed-off-by: Tony Tkacik <[email protected]>
binding/mdsal-binding-api/src/main/java/org/opendaylight/mdsal/binding/api/DataTreeCommitCohort.java [new file with mode: 0644]
binding/mdsal-binding-api/src/main/java/org/opendaylight/mdsal/binding/api/DataTreeCommitCohortRegistry.java [new file with mode: 0644]
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMDataTreeCommitCohortAdapter.java [new file with mode: 0644]
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMDataTreeCommitCohortRegistryAdapter.java [new file with mode: 0644]
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/LazyDataTreeModification.java

diff --git a/binding/mdsal-binding-api/src/main/java/org/opendaylight/mdsal/binding/api/DataTreeCommitCohort.java b/binding/mdsal-binding-api/src/main/java/org/opendaylight/mdsal/binding/api/DataTreeCommitCohort.java
new file mode 100644 (file)
index 0000000..44db3af
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2016 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.mdsal.binding.api;
+
+import com.google.common.annotations.Beta;
+import com.google.common.util.concurrent.CheckedFuture;
+import org.opendaylight.mdsal.common.api.DataValidationFailedException;
+import org.opendaylight.mdsal.common.api.PostCanCommitStep;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+/**
+ * **
+ *
+ * Commit cohort participating in commit of data modification, which can validate data tree
+ * modifications, with option to reject supplied modification, and with callbacks describing state
+ * of commit.
+ *
+ * <h2>Performance implications</h2>
+ *
+ * {@link DataTreeCommitCohort}s are hooked up into commit of data tree changes and MAY
+ * negatively affect performance of data broker / store.
+ *
+ * Implementations of this interface are discouraged, unless you really need ability to veto data
+ * tree changes, or to provide external state change in sync with visibility of commited data.
+ *
+ *
+ * <h2>Implementation requirements</h2>
+ *
+ * <h3>Correctness assumptions</h3> Implementation SHOULD use only provided
+ * {@link DataTreeModification} for validation purposes.
+ *
+ * Use of any other external mutable state is discouraged, implementation MUST NOT use any
+ * transaction related APIs on same data broker / data store instance during invocation of
+ * callbacks, except ones provided as argument. Note that this MAY BE enforced by some
+ * implementations of {@link DataBroker} or Commit coordinator
+ *
+ * Note that this may be enforced by some implementations of {@link DataTreeCommitCohortRegistry}
+ * and such calls may fail.
+ *
+ * <h3>DataTreeCandidate assumptions</h3> Implementation SHOULD NOT make any assumptions on
+ * {@link DataTreeModification} being successfully committed until associated
+ * {@link PostCanCommitStep#preCommit()} and
+ * {@link org.opendaylight.mdsal.common.api.PostPreCommitStep#commit()} callback was invoked.
+ *
+ *
+ * <h2>Usage patterns</h2>
+ *
+ * <h3>Data Tree Validator</h3>
+ *
+ * Validator is implementation, which only validates {@link DataTreeModification} and does not
+ * retain any state derived from edited data - does not care if {@link DataTreeModification} was
+ * rejected afterwards or transaction was cancelled.
+ *
+ * Implementation may opt-out from receiving {@code preCommit()}, {@code commit()}, {@code abort()}
+ * callbacks by returning {@link PostCanCommitStep#NOOP}.
+ *
+ * TODO: Provide example and describe more usage patterns
+ *
+ * @author Tony Tkacik &lt;[email protected]&gt;
+ *
+ */
+@Beta
+public interface DataTreeCommitCohort<T extends DataObject> {
+
+    CheckedFuture<PostCanCommitStep, DataValidationFailedException> canCommit(Object txId,
+            DataTreeModification<T> modification);
+
+}
diff --git a/binding/mdsal-binding-api/src/main/java/org/opendaylight/mdsal/binding/api/DataTreeCommitCohortRegistry.java b/binding/mdsal-binding-api/src/main/java/org/opendaylight/mdsal/binding/api/DataTreeCommitCohortRegistry.java
new file mode 100644 (file)
index 0000000..da73700
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016 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.mdsal.binding.api;
+
+import org.opendaylight.yangtools.concepts.ObjectRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+/**
+ *
+ * Commit Cohort registry.
+ *
+ * See {@link DataTreeCommitCohort} for more details.
+ *
+ * @author Tony Tkacik &lt;[email protected]&gt;
+ *
+ */
+public interface DataTreeCommitCohortRegistry {
+
+    /**
+     * Register commit cohort which will participate in three-phase commit protocols of write
+     * transaction in data broker associated with this instance of extension.
+     *
+     * @param subtree Subtree path on which commit cohort operates.
+     * @param cohort Commit cohort
+     * @return Registaration object for DOM Data Three Commit cohort.
+     */
+    <D extends DataObject, T extends DataTreeCommitCohort<D>> ObjectRegistration<T> registerCommitCohort(
+            DataTreeIdentifier<D> subtree, T cohort);
+
+}
diff --git a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMDataTreeCommitCohortAdapter.java b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMDataTreeCommitCohortAdapter.java
new file mode 100644 (file)
index 0000000..0d55138
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 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.mdsal.binding.dom.adapter;
+
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.CheckedFuture;
+import org.opendaylight.mdsal.binding.api.DataTreeCommitCohort;
+import org.opendaylight.mdsal.binding.api.DataTreeModification;
+import org.opendaylight.mdsal.common.api.DataValidationFailedException;
+import org.opendaylight.mdsal.common.api.PostCanCommitStep;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeCandidate;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohort;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+class BindingDOMDataTreeCommitCohortAdapter<T extends DataObject> implements DOMDataTreeCommitCohort {
+
+    private final BindingToNormalizedNodeCodec codec;
+    private final DataTreeCommitCohort<T> cohort;
+
+    BindingDOMDataTreeCommitCohortAdapter(BindingToNormalizedNodeCodec codec, DataTreeCommitCohort<T> cohort) {
+        this.codec = Preconditions.checkNotNull(codec);
+        this.cohort = Preconditions.checkNotNull(cohort);
+    }
+
+    @Override
+    public CheckedFuture<PostCanCommitStep, DataValidationFailedException> canCommit(Object txId,
+            DOMDataTreeCandidate candidate, SchemaContext ctx) {
+        DataTreeModification<T> modification = LazyDataTreeModification.create(codec, candidate);
+        return cohort.canCommit(txId, modification);
+    }
+}
diff --git a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMDataTreeCommitCohortRegistryAdapter.java b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMDataTreeCommitCohortRegistryAdapter.java
new file mode 100644 (file)
index 0000000..6ebc7c6
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016 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.mdsal.binding.dom.adapter;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.mdsal.binding.api.DataTreeCommitCohort;
+import org.opendaylight.mdsal.binding.api.DataTreeCommitCohortRegistry;
+import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohortRegistration;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohortRegistry;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
+import org.opendaylight.yangtools.concepts.ObjectRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+public class BindingDOMDataTreeCommitCohortRegistryAdapter implements DataTreeCommitCohortRegistry {
+
+    private final BindingToNormalizedNodeCodec codec;
+    private final DOMDataTreeCommitCohortRegistry registry;
+
+    BindingDOMDataTreeCommitCohortRegistryAdapter(BindingToNormalizedNodeCodec codec,
+            DOMDataTreeCommitCohortRegistry registry) {
+        this.codec = Preconditions.checkNotNull(codec);
+        this.registry = Preconditions.checkNotNull(registry);
+    }
+
+    DataTreeCommitCohortRegistry from(BindingToNormalizedNodeCodec codec, DOMDataTreeCommitCohortRegistry registry) {
+        return new BindingDOMDataTreeCommitCohortRegistryAdapter(codec, registry);
+    }
+
+    @Override
+    public <D extends DataObject, T extends DataTreeCommitCohort<D>> ObjectRegistration<T> registerCommitCohort(
+            DataTreeIdentifier<D> subtree, final T cohort) {
+        final BindingDOMDataTreeCommitCohortAdapter<D> adapter =
+                new BindingDOMDataTreeCommitCohortAdapter<>(codec, cohort);
+        final DOMDataTreeIdentifier domPath = codec.toDOMDataTreeIdentifier(subtree);
+        final DOMDataTreeCommitCohortRegistration<?> domReg = registry.registerCommitCohort(domPath, adapter);
+        return new ObjectRegistration<T>() {
+
+            @Override
+            public T getInstance() {
+                return cohort;
+            }
+
+            @Override
+            public void close() throws Exception {
+                domReg.close();
+            }
+        };
+    }
+}
index 4190f366815866ca87f70e1b74f29c30890d5426..7d2a72d58bfa00fa1acd8f2bc24313a3ebf4b743 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.mdsal.binding.dom.adapter;
 
+import com.google.common.base.Preconditions;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
@@ -15,6 +16,7 @@ import org.opendaylight.mdsal.binding.api.DataObjectModification;
 import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
 import org.opendaylight.mdsal.binding.api.DataTreeModification;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeCandidate;
 import org.opendaylight.yangtools.binding.data.codec.api.BindingCodecTreeNode;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -33,9 +35,9 @@ class LazyDataTreeModification<T extends DataObject> implements DataTreeModifica
     private final DataTreeIdentifier<T> path;
     private final DataObjectModification<T> rootNode;
 
-    LazyDataTreeModification(final LogicalDatastoreType datastoreType, final InstanceIdentifier<T> path, final BindingCodecTreeNode<T> codec, final DataTreeCandidate domChange) {
-        this.path = DataTreeIdentifier.create(datastoreType, path);
-        this.rootNode = LazyDataObjectModification.create(codec, domChange.getRootNode());
+    LazyDataTreeModification(DataTreeIdentifier<T> path, final DataObjectModification<T> modification) {
+        this.path = Preconditions.checkNotNull(path);
+        this.rootNode = Preconditions.checkNotNull(modification);
     }
 
     @Override
@@ -53,7 +55,10 @@ class LazyDataTreeModification<T extends DataObject> implements DataTreeModifica
             final LogicalDatastoreType datastoreType) {
         final Entry<InstanceIdentifier<?>, BindingCodecTreeNode<?>> codecCtx =
                 codec.getSubtreeCodec(domChange.getRootPath());
-        return new LazyDataTreeModification(datastoreType, codecCtx.getKey(), codecCtx.getValue(), domChange);
+        final DataTreeIdentifier<?> path = DataTreeIdentifier.create(datastoreType, codecCtx.getKey());
+        final DataObjectModification<?> modification =
+                LazyDataObjectModification.create(codecCtx.getValue(), domChange.getRootNode());
+        return new LazyDataTreeModification(path, modification);
     }
 
     static <T extends DataObject> Collection<DataTreeModification<T>> from(final BindingToNormalizedNodeCodec codec,
@@ -65,4 +70,15 @@ class LazyDataTreeModification<T extends DataObject> implements DataTreeModifica
         return result;
     }
 
+    static <T extends DataObject> DataTreeModification<T> create(BindingToNormalizedNodeCodec codec,
+            DOMDataTreeCandidate candidate) {
+        final Entry<InstanceIdentifier<?>, BindingCodecTreeNode<?>> codecCtx =
+                codec.getSubtreeCodec(candidate.getRootPath().getRootIdentifier());
+        final DataTreeIdentifier<?> path =
+                DataTreeIdentifier.create(candidate.getRootPath().getDatastoreType(), codecCtx.getKey());
+        final DataObjectModification<?> modification =
+                LazyDataObjectModification.create(codecCtx.getValue(), candidate.getRootNode());
+        return new LazyDataTreeModification(path, modification);
+    }
+
 }