From 5f0d949e98b09557790f567b9e7d2470a560dde8 Mon Sep 17 00:00:00 2001 From: Tony Tkacik Date: Thu, 14 Jan 2016 13:35:03 +0100 Subject: [PATCH] Bug 1435: Added Binding Commit Cohort APIs and adapters. Change-Id: I7ec8b54542af307a2ec2390d3e397f771c2bc1cc Signed-off-by: Tony Tkacik --- .../binding/api/DataTreeCommitCohort.java | 74 +++++++++++++++++++ .../api/DataTreeCommitCohortRegistry.java | 36 +++++++++ ...BindingDOMDataTreeCommitCohortAdapter.java | 38 ++++++++++ ...OMDataTreeCommitCohortRegistryAdapter.java | 56 ++++++++++++++ .../dom/adapter/LazyDataTreeModification.java | 24 +++++- 5 files changed, 224 insertions(+), 4 deletions(-) create mode 100644 binding/mdsal-binding-api/src/main/java/org/opendaylight/mdsal/binding/api/DataTreeCommitCohort.java create mode 100644 binding/mdsal-binding-api/src/main/java/org/opendaylight/mdsal/binding/api/DataTreeCommitCohortRegistry.java create mode 100644 binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMDataTreeCommitCohortAdapter.java create mode 100644 binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMDataTreeCommitCohortRegistryAdapter.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 index 0000000000..44db3af9cd --- /dev/null +++ b/binding/mdsal-binding-api/src/main/java/org/opendaylight/mdsal/binding/api/DataTreeCommitCohort.java @@ -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. + * + *

Performance implications

+ * + * {@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. + * + * + *

Implementation requirements

+ * + *

Correctness assumptions

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. + * + *

DataTreeCandidate assumptions

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. + * + * + *

Usage patterns

+ * + *

Data Tree Validator

+ * + * 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 <ttkacik@cisco.com> + * + */ +@Beta +public interface DataTreeCommitCohort { + + CheckedFuture canCommit(Object txId, + DataTreeModification 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 index 0000000000..da73700553 --- /dev/null +++ b/binding/mdsal-binding-api/src/main/java/org/opendaylight/mdsal/binding/api/DataTreeCommitCohortRegistry.java @@ -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 <ttkacik@cisco.com> + * + */ +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. + */ + > ObjectRegistration registerCommitCohort( + DataTreeIdentifier 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 index 0000000000..0d551387a5 --- /dev/null +++ b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMDataTreeCommitCohortAdapter.java @@ -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 implements DOMDataTreeCommitCohort { + + private final BindingToNormalizedNodeCodec codec; + private final DataTreeCommitCohort cohort; + + BindingDOMDataTreeCommitCohortAdapter(BindingToNormalizedNodeCodec codec, DataTreeCommitCohort cohort) { + this.codec = Preconditions.checkNotNull(codec); + this.cohort = Preconditions.checkNotNull(cohort); + } + + @Override + public CheckedFuture canCommit(Object txId, + DOMDataTreeCandidate candidate, SchemaContext ctx) { + DataTreeModification 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 index 0000000000..6ebc7c654a --- /dev/null +++ b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMDataTreeCommitCohortRegistryAdapter.java @@ -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 > ObjectRegistration registerCommitCohort( + DataTreeIdentifier subtree, final T cohort) { + final BindingDOMDataTreeCommitCohortAdapter adapter = + new BindingDOMDataTreeCommitCohortAdapter<>(codec, cohort); + final DOMDataTreeIdentifier domPath = codec.toDOMDataTreeIdentifier(subtree); + final DOMDataTreeCommitCohortRegistration domReg = registry.registerCommitCohort(domPath, adapter); + return new ObjectRegistration() { + + @Override + public T getInstance() { + return cohort; + } + + @Override + public void close() throws Exception { + domReg.close(); + } + }; + } +} diff --git a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/LazyDataTreeModification.java b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/LazyDataTreeModification.java index 4190f36681..7d2a72d58b 100644 --- a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/LazyDataTreeModification.java +++ b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/LazyDataTreeModification.java @@ -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 implements DataTreeModifica private final DataTreeIdentifier path; private final DataObjectModification rootNode; - LazyDataTreeModification(final LogicalDatastoreType datastoreType, final InstanceIdentifier path, final BindingCodecTreeNode codec, final DataTreeCandidate domChange) { - this.path = DataTreeIdentifier.create(datastoreType, path); - this.rootNode = LazyDataObjectModification.create(codec, domChange.getRootNode()); + LazyDataTreeModification(DataTreeIdentifier path, final DataObjectModification modification) { + this.path = Preconditions.checkNotNull(path); + this.rootNode = Preconditions.checkNotNull(modification); } @Override @@ -53,7 +55,10 @@ class LazyDataTreeModification implements DataTreeModifica final LogicalDatastoreType datastoreType) { final Entry, 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 Collection> from(final BindingToNormalizedNodeCodec codec, @@ -65,4 +70,15 @@ class LazyDataTreeModification implements DataTreeModifica return result; } + static DataTreeModification create(BindingToNormalizedNodeCodec codec, + DOMDataTreeCandidate candidate) { + final Entry, 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); + } + } -- 2.36.6